TransWikia.com

Order of arguments in __usercall

Reverse Engineering Asked by Cawottex on November 16, 2020

i have the following function with five arguments:

    ; int __cdecl trampolineRegister(void)    
    a4= dword ptr  8
    a5= dword ptr  0Ch
    
    push    ebp
    mov     ebp, esp
    add     eax, [ebp+a4]
    add     eax, [ebp+a5]
    add     eax, ecx
    add     eax, edx
    cmp     ebp, esp
    call    j___RTC_CheckEsp
    pop     ebp
    retn

With this caller code :

mov     ecx, 0Ah
mov     edx, 0Ah
push    ecx             ; a5
mov     eax, 0Fh        ; a1
push    edx             ; a4
mov     ecx, 0Ah        ; a3
mov     edx, 1Eh        ; a2
call    j_?trampolineRegister@@YAHXZ 

IDA apply this prototype :

int __usercall trampolineRegister@<eax>(int a1@<eax>, int a2@<edx>, int a3@<ecx>, int a4, int a5)

But
My question is :

Is the order of the arguments is correct ?
What is the order of placement for arguments passing by registers?

Thank you 🙂

2 Answers

The order of arguments is going to be determined from the calling convention. Given that the arguments are passed eax, edx, ecx, stack1, stack2, it appears it could be the register calling convention from a Delphi compiler.

From Wikipedia:

Borland register

Evaluating arguments from left to right, it passes three arguments via EAX, EDX, ECX. Remaining arguments are pushed onto the stack, also left to right. It is the default calling convention of the 32-bit compiler of Delphi, where it is known as register. This calling convention is also used by Embarcadero's C++Builder, where it is called __fastcall. In this compiler, Microsoft's fastcall can be used as __msfastcall. GCC and Clang can be made to use a similar calling convention by using __stdcall with the regparm function attribute or the -mregparm=3 switch. (The stack order is inverted.) It is also possible to produce a caller clean-up variant using cdecl or extend this to also use SSE registers. A cdecl-based version is used by the Linux kernel on i386 since version 2.6.20 (released February 2007).

Answered by Shane Reilly on November 16, 2020

j___RTC_CheckEsp is most probably not delphi compiled exe but borland c++ compiled executable probably using the -pr switch

Register

(Command-line switch: -pr)

This option forces the compiler to generate all subroutines and all functions using the Register parameter-passing convention, which is equivalent to declaring all subroutine and functions with the _ _fastcall keyword. With this option enabled, functions or routines expect parameters to be passed in registers.

example code compiled with bcc32 and linked with ilink32
(borland antique compiler and linker circa 19xx )
just a mean 8.7 megabyte all inclusive awesomeness

code

#include <windows.h>
int DemoBcc55RegisterCall( int a,int b, int c, int d,int e,int f ) 
{
    return a+b+c+d+e+f;
}
int WINAPI WinMain(HINSTANCE , HINSTANCE ,    LPSTR , int )
{
    char buff[0x100] ={0};
    int res= DemoBcc55RegisterCall(3,4,5,6,7,8);
    wsprintf(buff, "Function Returned %dn" ,res);
    MessageBoxA(NULL,buff,"bcc_register_calling_convention",MB_OK);
    return 0;  
}

executed enter image description here

disassembly of relevent areas in main and function

0:000> u 401185
testbcc!_GetExceptDLLinfo+0x12c:
00401185 6a06            push    6
00401187 6a07            push    7
00401189 6a08            push    8
0040118b b905000000      mov     ecx,5
00401190 ba04000000      mov     edx,4
00401195 b803000000      mov     eax,3
0040119a e8b1ffffff      call    testbcc!_GetExceptDLLinfo+0xf7 (00401150)
0040119f 50              push    eax
0:000> uf 401150
testbcc!_GetExceptDLLinfo+0xf7:
00401150 55              push    ebp
00401151 8bec            mov     ebp,esp
00401153 03d0            add     edx,eax
00401155 03ca            add     ecx,edx
00401157 034d10          add     ecx,dword ptr [ebp+10h]
0040115a 034d0c          add     ecx,dword ptr [ebp+0Ch]
0040115d 034d08          add     ecx,dword ptr [ebp+8]
00401160 8bc1            mov     eax,ecx
00401162 5d              pop     ebp
00401163 c20c00          ret     0Ch
0:000>

Answered by blabb on November 16, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP