I'm wondering if there is a way to create and call a procedure dynamically in Win32. Not just load it dynamically like with DLLs, but actually create/modify it. I've tried this:



include masm32.inc
includelib masm32.lib

; ...

.code

; ...

funcMem db 512 dup (0)

; ...

testProc proc param1:DWORD, param2:DWORD
LOCAL buf[80]:BYTE

invoke dwtoa,param1,addr buf
invoke MessageBox,NULL,addr buf, addr buf, MB_OK
invoke dwtoa,param2,addr buf
invoke MessageBox,NULL,addr buf, addr buf, MB_OK
ret
testProc endp
__testProcEnd:

; ...

mov eax,offset __testProcEnd
sub eax,offset testProc
mov funcLen,eax

; ...

; funcLen holds length of the function
invoke MemCopy,addr testProc,addr funcMem,funcLen
lea eax,funcMem
push (DWORD PTR 6)
push (DWORD PTR 5)
call eax


The idea is to copy the testProc procedure to a new memory location and call it from that location, but when I run the code the program crashes. What am I missing? Can this be done?
Posted on 2004-11-01 22:25:22 by sirchess
MASM creates a jump table...
Posted on 2004-11-02 00:36:39 by roticv
MASM creates a jump table...


that means, that a call messagebox is not a call dword where some_address is an address inside your .exe which is filled in by the module loader, but it creates a



call some_offset

some_offset: jmp [some_address]


pair. since calls use relative addressing, you can't move code containg such calls (without relocating the calls which is quite much work). Actually, I didn't know that MASM creates jump tables, since I always used TASM, but if roticv says so, I believe him immediately :)
Posted on 2004-11-02 04:48:19 by lifewire
lifewire is correct, if you can force MASM to call the api directly calling api is not a problem (It is possible, Vortex posted some marcos on how to do it).

However there should not be any calls to any address such as your call to dwtoa. Instead do something like


mov eax, dwtoa
push xx
push xx
...
call eax
Posted on 2004-11-02 05:57:57 by roticv
Those macros can be found at:

http://www.asmcommunity.net/board/viewtopic.php?t=17566
Posted on 2004-11-02 09:49:36 by Vortex
something to the effect of


lea eax,MessageBoxA
mov eax,[eax+2]
mov eax,[eax]

would work to the effect.

however, beware of such on 9x system. on 9x, the kernel has a "feature" that "obfuscates" API addresses, by providing a "thunk" to that certain API address (even if you use GetProcAddress). I can't recall completely, but Matt Pietrek describes this in his Undoc. 9x (or was it 95 programming secrets - can't remember). so the most reliable way to retreive an accurate address of the API would be to iterate through the EAT, and such.
Posted on 2004-11-02 16:42:53 by Drocon
Hello all,

Didn't get a chance to read this until just now. So what you all are saying is that it was calling the function, but the function calls inside the function were causing problems. I didn't even think to check that :oops:

since calls use relative addressing, you can't move code containg such calls (without relocating the calls which is quite much work).

I'm not sure if I understand this exactly. Are you saying that the address used for normal calls is relative to the call location? And "call eax" is not relative? Could someone elaborate on this a little please (or point to a tut)?

Drocon:
As I am on Win98, this sounds interesting, but I'm afraid you lost me with "iterate through the EAT, and such" :P What does EAT stand for, and how would one "iterate through" it?

Thanks!
Posted on 2004-11-02 19:04:22 by sirchess
I'm not sure if I understand this exactly. Are you saying that the address used for normal calls is relative to the call location? And "call eax" is not relative? Could someone elaborate on this a little please (or point to a tut)?

Go do some disassembling and you will discover that call xxx where xx is a label is actually encoded as E8 followed by a dword. The dword is displacement from the end of the opcode.

Get the kernel32.dll base and search for the api you need aka GetProcAddress and LoadLibrary and you can get any function.

Drocon,
That looks like the kind of code Elicz uses if I remember correctly.
Posted on 2004-11-03 04:51:06 by roticv
I took out the API and dword calls in the proc, but it still crashes when I try to call a copy. It appears to crash when it tries to return...if I put an infinite loop in the function, it just sits there, instead of giving the usual "illegal operation" message.

From this I would guess that maybe somehow the wrong code address gets popped when the function returns???

Here is the function as I have it now:


testProc proc param1:DWORD, param2:DWORD
ret
testProc endp
__testProcEnd:

When I look at the .exe with a hex editor, the function is 7 bytes long, those bytes being "55 8B EC C9 C2 08 00"

C2 is the near ret with the 08 following to fix the stack (is the 00 part of this too, or not even part of the function?)
What does the "55 8B EC C9" signify? I couldn't find an instruction code for 55...8B could be a mov, but then again since I don't know what 55 is it could be anything...

I'm afraid I don't have much experience with disassembling :( any help would be appreciated.
Posted on 2004-11-03 17:53:51 by sirchess


push ebp ; 55h
mov ebp, esp ; 8Bh ECh
leave ; C9h
retn 8 ; C2h 08 00
Posted on 2004-11-03 20:42:14 by roticv
Thanks all for the help, I got it working finally. More importantly though I know how it works :)
Posted on 2004-11-03 22:41:13 by sirchess