News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Generic Thunking

Started by JR, November 17, 2009, 11:46:19 PM

Previous topic - Next topic

JR

Howdy all -

I was recently writing a bunch of little 16 bit .com files for the heck of it. Just going through old books and such coding examples. I had a thought of how one would call a win32 function from a 16 bit com program. I see all the examples in C using

LoadLibraryEx32W - to load 32 bit library
GetProcAddress32W - to get address of 32 bit function

followed by a call to

CallProc32W - to run the 32 bit code.

Seems easy enough and i see CalllProc32W in \masm\include\WOW32.inc and the corresponding lib file.

i compile/link this little code

.model tiny


.data
    strDLL db "nothinyet",0
   
.code
    org 100h
start:
    mov dl,41h
    mov ah,2
    int 21h
    ret
end start


with this script


\masm32\bin\ml /Gc /c console.asm
\masm32\bin\link16 /tiny console.obj, console.com;

So my question is what needs to be added in order to call the LoadLibraryEx32W function?
I have tried to make a .def file with this in it
IMPORTS
kernel.LoadLibraryEx32W

but either that .def file or my link16 syntax is wrong. Anyone know the correct steps to call these functions from 16 bit program using masm?

jj2007

I use generic thunking a lot, but from an old 16-bit Basic dialect. I am curious if your problem can be solved...
You might look at this pdf, and the MS Support page. The latter says the thunk compiler produces an *.asm file...

JR

Thank you for the reply. I did see that PDF already. It also says to use LoadLibraryEx32W. Thats basically my question, how do I call/invoke LoadLibraryEx32W from masm. I do not know where to link it. I don't see it in any lib file.

japheth

Hi,

Generic Thunking is supposed to be used from Win16 programs. AFAIK you cannot call LoadLibraryEx32W from a 16-bit DOS program.

However, the underlying API is also available for DOS programs - it's called BOP or so. Here's a sample. It calls MessageBoxA() from 16-bit.

D16.ASM, the 16-bit DOS program calling Win32



;--- dos 16bit program using BOPs

.286
.MODEL SMALL

.stack 400h

.data

hVdd dw 0
szW32D db "W32D",0
szInit db "Init",0
szDisp db "Dispatch",0
szCap  db "DOS",0
szHello db "Hello from 16-bit",0
dErr1  db "loading W32D.DLL failed",13,10,'$'

.code

start:
mov ax,@data
mov ds,ax
assume ds:DGROUP
mov si,offset szW32D
mov bx,offset szDisp
mov di,offset szInit
push ds
pop es
db 0c4h, 0c4h, 58h, 0 ;LoadModule
jc loadfailed
mov hVdd,ax

mov bx, offset szHello
mov di, offset szCap
mov cx,1 ;function "MessageBoxA"
mov ax,hVdd
db 0c4h, 0c4h, 58h, 2 ;Dispatch

mov ax,hVdd
db 0c4h, 0c4h, 58h, 1 ;UnloadModule
exit:
mov ax,4c00h
int 21h
loadfailed:
mov dx,offset dErr1
mov ah,9
int 21h
jmp exit

END start


W32D.ASM, the source of the 32bit dll (=VDD) which is dynamically loaded by the 16-bit DOS program:



;--- Win32 VDD dll

.386
.MODEL FLAT, stdcall
option proc:private

getECX proto
getEBX proto
getEDI proto
getDS  proto
VdmMapFlat proto :dword, :dword, :dword
MessageBoxA proto :dword, :dword, :dword, :dword
MB_OK equ 0
VDM_V86 equ 0

.code

;--- Init

Init proc public

ret
align 4

Init endp

;--- Dispatch

Dispatch proc public uses ebx esi edi

invoke getECX
.if (ax == 1)
invoke getDS
mov esi, eax
invoke getEBX
invoke VdmMapFlat, esi, eax, VDM_V86
mov ebx, eax
invoke getEDI
invoke VdmMapFlat, esi, eax, VDM_V86
mov edi, eax
invoke MessageBoxA, 0, ebx, edi, MB_OK
.endif
ret
align 4

Dispatch endp

DllMain proc public hInstance:dword, reason:dword, lpReserved:dword

mov eax, 1
ret
align 4
DllMain endp

END DllMain


The .DEF file W32D.DEF required to link the dll


LIBRARY W32D
EXPORTS
Init
Dispatch


and finally, a MAKE.BAT to create the 2 binaries:


@echo off
jwasm.exe -Fl d16.asm
jwasm.exe -coff w32d.asm
link16 d16.obj, d16.exe;
link w32d.obj /dll /out:w32d.dll /libpath:\win32inc\lib ntvdm.lib user32.lib /def:w32d.def



JR

Wow, thanks a lot for the response. I will go over it in detail. One last question on the topic. Is this type of call possible using the memory model TINY. I'm going to try it when i have a chance but i thought I'd throw that out there.

thanks again.

:cheekygreen:

JR

For those interested I found this page after japheth told me it was called BOP.

http://www.ragestorm.net/tutorial?id=27

Another example of calling 32 bit from dos 16 bit using bop. It explains this odd instruction in japheth's example.

db 0c4h, 0c4h, 58h, 0


0x401000

Someone tried to make the same but for the 64 systems? from 32 to 64. Thank you!

FORTRANS

Quote from: JR on November 18, 2009, 05:06:28 AM
One last question on the topic. Is this type of call possible using the memory model TINY.


Hi,

   The DOS memory model should not have any effect on
calling (or thunking) a routine.  The model is a set of rules
for segmentation, which does not apply to Win32.

Regards,

Steve N.

JR

Just an update. I copied the code and compiled / linked it w/out errors after some modifications for my system. I t fails to load the Dll when it runs though. I am using win 2003 server sp2. I'm looking into it.

I had to modify the makeit bat like so

@echo off
\masm32\bin\ml /Gc /c /Fl console.asm
\masm32\bin\ml /c /coff w32d.asm
\masm32\bin\link16 console.obj, console.com
\masm32\bin\link w32d.obj /dll /out:w32d.dll /libpath:\masm32\lib ntvdm.lib user32.lib /def:w32d.def


just due to my masm install

japheth

Quote from: JR on November 20, 2009, 09:15:12 PM
Just an update. I copied the code and compiled / linked it w/out errors after some modifications for my system. I t fails to load the Dll when it runs though. I am using win 2003 server sp2. I'm looking into it.

I had to modify the makeit bat like so

@echo off
\masm32\bin\ml /Gc /c /Fl console.asm
\masm32\bin\ml /c /coff w32d.asm
\masm32\bin\link16 console.obj, console.com
\masm32\bin\link w32d.obj /dll /out:w32d.dll /libpath:\masm32\lib ntvdm.lib user32.lib /def:w32d.def


just due to my masm install


Hmm, I'm unsure if the import library ntvdm.lib contained in Masm32 will work. At least you have to ensure that it truly refers to NTVDM.EXE, not NTVDM.DLL.

JR

Here is my call stack.

ChildEBP RetAddr  Args to Child             
0105fa98 7c827c39 77e668cb ffffffff 00000000 ntdll!KiFastSystemCallRet
0105fa9c 77e668cb ffffffff 00000000 00000104 ntdll!ZwTerminateProcess+0xc
0105fb90 77e6690d 00000000 77e8f3b0 ffffffff kernel32!_ExitProcess+0x63
0105fba4 0f035e76 00000000 0f061f81 00000000 kernel32!ExitProcess+0x14
0105fbac 0f061f81 00000000 0009f477 0f00bab0 ntvdm!host_terminate+0x23
0105fbb8 0f00bab0 00000200 00000000 00000001 ntvdm!terminate+0x74
0105ff04 0f00950a 0105ff34 0f0094d1 00000001 ntvdm!cmdGetNextCmd+0x30b
0105ff0c 0f0094d1 00000001 01752a20 0f005bac ntvdm!CmdDispatch+0xf
0105ff18 0f005bac 0f0060b4 77e63ec7 01750e78 ntvdm!MS_bop_4+0x2e
0105ff1c 0f0060b4 77e63ec7 01750e78 00000000 ntvdm!EventVdmBop+0x29
0105ff34 0f01b694 01073af8 0105ff78 0f00dcc9 ntvdm!cpu_simulate+0x160
0105ff40 0f00dcc9 00000002 01750e78 77e63ec7 ntvdm!host_main+0x5f
0105ff78 0f010517 00000002 01750e78 01750ec0 ntvdm!main+0x2e
0105ffc0 77e6f23b 00000000 00000000 7ffda000 ntvdm!mainCRTStartup+0x14d
0105fff0 00000000 0f0103ca 00000000 78746341 kernel32!BaseProcessStart+0x23

when i check the RET address for that ms_bop it is in the EXE and not the dll. I'll keep plugging away. When it finally works i'm sure i will have learned something.

japheth

Quote from: JR on November 23, 2009, 04:46:06 PM
Here is my call stack.

ChildEBP RetAddr  Args to Child             
0105fa98 7c827c39 77e668cb ffffffff 00000000 ntdll!KiFastSystemCallRet
0105fa9c 77e668cb ffffffff 00000000 00000104 ntdll!ZwTerminateProcess+0xc
0105fb90 77e6690d 00000000 77e8f3b0 ffffffff kernel32!_ExitProcess+0x63
0105fba4 0f035e76 00000000 0f061f81 00000000 kernel32!ExitProcess+0x14
0105fbac 0f061f81 00000000 0009f477 0f00bab0 ntvdm!host_terminate+0x23
0105fbb8 0f00bab0 00000200 00000000 00000001 ntvdm!terminate+0x74
0105ff04 0f00950a 0105ff34 0f0094d1 00000001 ntvdm!cmdGetNextCmd+0x30b
0105ff0c 0f0094d1 00000001 01752a20 0f005bac ntvdm!CmdDispatch+0xf
0105ff18 0f005bac 0f0060b4 77e63ec7 01750e78 ntvdm!MS_bop_4+0x2e
0105ff1c 0f0060b4 77e63ec7 01750e78 00000000 ntvdm!EventVdmBop+0x29
0105ff34 0f01b694 01073af8 0105ff78 0f00dcc9 ntvdm!cpu_simulate+0x160
0105ff40 0f00dcc9 00000002 01750e78 77e63ec7 ntvdm!host_main+0x5f
0105ff78 0f010517 00000002 01750e78 01750ec0 ntvdm!main+0x2e
0105ffc0 77e6f23b 00000000 00000000 7ffda000 ntvdm!mainCRTStartup+0x14d
0105fff0 00000000 0f0103ca 00000000 78746341 kernel32!BaseProcessStart+0x23

when i check the RET address for that ms_bop it is in the EXE and not the dll. I'll keep plugging away. When it finally works i'm sure i will have learned something.

Or just upload your w32d.dll binary. My version worked, so I probably can tell in a minute what's wrong with yours.

JR

Binary attached. Thanks as always.

japheth

The problem is exactly what I did mention some posts ago: you're using an invalid ntvdm.lib for linking.

This is what MS dumpbin tells about your w32d.dll:

-------------------------------------------------------------------------------------
Microsoft (R) COFF/PE Dumper Version 7.10.3077
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file w32d.dll

File Type: DLL

  Section contains the following imports:

    ntvdm.dll
              10002000 Import Address Table
              1000205C Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                   56 getEBX
                   58 getEDI
                   52 getDS
                   27 VdmMapFlat
                   57 getECX

    user32.dll
              10002018 Import Address Table
              10002074 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference

                  1B1 MessageBoxA

  Summary

        1000 .rdata
        1000 .reloc
        1000 .text
-------------------------------------------------------------------------------------


the string marked red is to be ntvdm.exe. To fix this problem use another ntvdm.lib in the link step.

JR

Thanks again. It works. Sorry for wasting your time. I was going to ask where I would get another lib file for that but I found it.... on your site

:U