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 🙂
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;
}
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
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP