程序入口
一、程序入口
1.main()函数
平时我们所写的c语言代码的运行起点是main,但这不是程序的真正入口
2.入口函数
在vc6中,查看入口函数的操作是在调试窗口中找到打开callstack窗口

可以看到是名为KERNEL32的东西调用了mainCRTStartup()函数然后这个函数又调用了我们的main()函数。
这个mainCRTStartup()就是函数的真正入口,这个函数也会进行很多初始化操作(控制台环境下)
GetVersion() //获得当前操作系统的版本
_heap_init() //初始化堆的空间大小
GetCommandLineA() //获取命令行的参数
_crtGetEnvironmentStringsA() //获取环境变量
_setargv()
_setenvp()
_cinit()
另外的,在windows环境下,函数入口为(w)WinMainCRTStartup()
3.怎么找到程序入口
在mainCRTStartup()调用的函数中,主函数有三个参数,所以在OD中只需要找到传入三个参数的函数,使用回车跳转两次即可找到main函数。

跳转到了main函数

二、逆向程序CallingConvention.exe
首先找到压入三个参数的部分,找到函数入口,跳转到main函数

可以看到main里第一个函数有五个参数并采用_fastcall调用约定,暂时将这个函数定义为fun()

然后继续跟进下一个call
在这里可以看到ecx被临时拿回去用来填充缓冲区又被还回来了
下面将参数4入栈后,再将3、1入栈

然后进入下一个call
这里就是另一个函数,暂时命名为fun2(),内平栈,应该是_stdcall
函数功能是三个数相加,返回相加后的值(8)

再返回来看后面的,将结果存入缓冲区后
将3和1入栈,然后call了另一个函数

简单的两个数相加,外平栈,是_cdecl

接下来是将上一个函数的结果放入缓冲区(4),并用上一个相加函数将之前得到的两个和相加并返回(12)

还原代码如下
#include "stdafx.h"
int _cdecl fun3(a,b){
return a+b;
}
int _stdcall fun2(x,y,z)
{
return x+y+z;
}
int _fastcall fun(a,b,c,d,e)
{
int x=fun2(a,b,c); //1+3+4=8
int y=fun3(a,b); //1+3=4
return fun(x,y); //4+8=12
}
int main(int argc, char* argv[])
{
int m;
m=fun(1,3,4,6,7); //12
return 0;
}

浙公网安备 33010602011771号