October 5th, 2006, 10:58 PM
Assembly Function Paramters and Return
I would like to call a function in a dll from a VB 2005 program with the syntax:
Function function_name() As Boolean 'replace with actual return type
In order to do this I need to know what paramaters the function takes and what if anything is returned, but I do not have any documentation. I was able to dissable the DLL in the PE Explorer trial version. Is it possible to deterimine from the assembly code the number of paramaters and their data types along with the return data type (if there is a return)?
The assembly code is
10001650 8B442404 mov eax,[esp+04h]
10001654 83EC7C sub esp,0000007Ch
10001657 53 push ebx
10001658 55 push ebp
10001659 56 push esi
1000165A 57 push edi
1000165B 6878C00010 push L1000C078
10001660 50 push eax
10001661 E8BF0E0000 call SUB_L10002525
10001666 8BD8 mov ebx,eax
10001668 33ED xor ebp,ebp
1000166A 83C408 add esp,00000008h
1000166D 3BDD cmp ebx,ebp
1000166F 750B jnz L1000167C
10001671 5F pop edi
10001672 5E pop esi
10001673 5D pop ebp
10001674 83C8FF or eax,FFFFFFFFh
10001677 5B pop ebx
10001678 83C47C add esp,0000007Ch
1000167B C3 retn
and the code for L1000C078 is
1000C078 72 db 72h; 'r'
1000C079 62 db 62h; 'b'
1000C07A 00 db 00h;
1000C07B 00 db 00h;
1000C07C 00 db 00h;
1000C07D 00 db 00h;
1000C07E 00 db 00h;
1000C07F 00 db 00h;
October 6th, 2006, 09:19 PM
Not in any useful manner, no. It is the caller, not the callee, that has to set the arguments up in the stack space; the extended base pointer (EBP), which points to the first of the current function's local stack frame, is then used together with a positive offset (that is, one pointing higher in the stack, above the current stack frame, into the caller's local stack where the arguments are held) to locate the arguments. I should add that, due to the way the stack works in p-mode, all arguments - regardless of actual size - are stored in increments of doublewords (four bytes). Finally, in the C calling convention (which IIUC would be used here), the arguments are pushed onto the stack in reverse order (with the last argument being the highest on the stack); this is followed by the return address, which is automatically pushed onto the stack by the call instruction, and the caller's EBP, which by convention is pushed by the called function. Thus, if a function has three arguments, a char, a double and an int, to access the int you would then need an offset of 20 (four bytes, for the caller's EBP, four for the caller's return address, four for the char, and eight for the double):
If you look at the code, this function never makes any such memory accesses. Curiously, it does a similar thing in the first line, storing into EAX the doubleword above the current stack pointer (which at that point holds the return address) which would indeed be an argument if the function takes any; however, all it does is pass it as an argument to yet another function. Also, as I said earlier, all arguments passed on the stack are stored in groups of doublewords, regardless of the actual size; thus, all we know about the argument is that it is at most 32 bits wide, and that the called function is only acting as a trampoline to another function (which given that it's a DLL isn't too surprising I suppose). The actual order in which the function saves the 'sacred' registers (EBP, EBX, EDI, and ESI) is unusual, meaning that the offset from EBP (if it were used, which it isn't) would need to be larger than the way I described it, but it doesn't matter so long as the code is consistent in how it handles them.
mov eax, [ebp + 20]
Interestingly, the functions also creates a local memory space of 0x07c bytes (124 in decimal), presumably for some sort of buffer space, in addition to the fixed (and thus non-reentrant) data space at 0x01000C078 whose address is also pushed as an argument to the second called function. What it is used for is unclear.
See this article and this one for more details on argument passing; while they refer specifically to gcc, it applies generally most system functions in Windows as well. Now, this is the calling convention for ordinary functions; it is possible that DLL functions work differently, but if they do, I'm not aware of it.
Comments and corrections welcome.
Last edited by Schol-R-LEA; October 7th, 2006 at 05:35 PM.