逆向实战
应各位的建议,加了注释,喜欢的看官点个赞支持一下,哈哈!
逆向CallingConvention.exe,还原为C代码,记录过程。
程序入口
如何查找程序入口?
main 函数被调用前要先调用的函数如下:
GetVersion() _heap_init() GetCommandLineA() _crtGetEnvironmentStringsA() _setargv() _setenvp() _cinit() 这些函数调用结束后就会调用main 函数,根据main 函数调用的特征,将3 个参数压入栈内作为函数的参数。
回到反汇编图,我们可以看到OD给我们注释出来的GetCommandLineA()函数下面紧接着push了三个寄存器,这就是我们判断程序入口最简单的方法了!
main函数
简要分析:
这里通过push压入了三个参数,通过mov 寄存器,立即数传入了两个参数,符合__fastcall调用约定的传参"手法";因为__fastcall的传参顺序是从右往左,因此函数1的调用如右:func1(1,3,4,6,7)
通过Main函数识别出来程序大致框架如下:
- 函数3为编译器自动添加的堆栈平衡检查函数,故在此不用考虑。
void __fastcall func1(int a,int b,int c,int d,int e){}//函数2我们暂时不知道是什么,先写到这void __cdecl func2(int x,int y){}void main(int argc,char *argv[]){ func1(1,3,4,6,7); func2(m,n);}func1函数
简要分析:
mov [local.2],edx实现将mov dword ptr ds:[ebp-8],edx,即给局部变量赋值,不熟悉这部分的朋友可以函数调用与堆栈图分析相关知识点。
这里push了三个参数,并且是在函数内部平衡的堆栈,可以基本判断调用方式为stdcall(这种调用约定在函数内部使用ret n的方式平衡堆栈,待分析func3的时候再论)。
你问我堆栈平衡怎么看,继续往下看吧,紧接着func3向下面分析:
mov [local.3],eax:这句的作用是将调用func3的返回结果eax放到[ebp-0c]中;紧接着又push了两个寄存器,调用func4,并且我们可以看到在call func4之后有条add esp,0x8,这就是堆栈平衡,目的是让堆栈恢复到调用前的状态,由于是在func4外部平衡的堆栈,我们也叫做外平栈,调用约定为C和CPP默认的__cdecl!
从以上汇编代码识别出func1的框架如下:
void __fastcall func1(int a,int b,int c,int d,int e){ int x=1; int y=3; func3(x,y,c); func4(); func4();}func3函数
简要分析:
[arg.1]即我们之在main函数看到的传入的第一个参数(最左边的),其它的不再赘述,经过一番加法运算后将返回值放到eax中,看伪代码吧。
func3函数大致框架如下:
int __cdecl func3(int x,int y,it z){ return x+y+z;}func1函数补充如下:
void __fastcall func1(int a,int b,int c,int d,int e){ int x=1; int y=3; int z=func3(x,y,c); func4(x,y); func4();}这里再提一下,x即[ebp-4],y即[ebp-8],z即[ebp-0c],对应func1函数部分的[local.1],[local.2],[local.3].
func4函数
简要分析
同上,不再赘述,直接看伪代码吧!
func4的函数框架如下:
int cdecl func4(int x.int y){ return x+y;}func1函数补充如下:
void __fastcall func1(int a,int b,int c,int d,int e){ int x=1; int y=3; int z=func3(x,y,c); int p=func4(x,y); func4(p,z); //运算后eax=0C}同理,p代表func1函数部分的[local.4].
到此,func1基本逆向完成,回到main函数,继续func2的逆向,如下:
func2函数
进到func2函数内部,发现其应该是printf函数,那么回到main函数,继续完善,如下:
Main函数
int cdecl func4(int x,int y){ return x+y;}void __fastcall func1(int a,int b,int c,int d,int e){ int x=1; int y=3; int z=func3(x,y,c); int p=func4(x,y); func4(p,z); //运算后eax=0C}void main(int argc,char *argv[]){ printf("%d",func1(1,3,4,6,7));}
来源:http://www.12558.net
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |