[逆向]寻找PE文件的main与winmain

0x01 定义

main是C/C++的标准入口函数名,程序执行总是从main函数开始,如果有有其他函数,则完成对其他函数的调用后再返回到主函数,最后由main函数结束整个程序,其他函数是不能调用main函数的。在执行程序时,由系统先行调用main函数。

WinMain是windows API窗体程序的入口函数,该函数的功能是被系统调用,作为一个32位应用程序的入口点。WinMain函数应初始化应用程序,显示主窗口,进入一个消息接收一发送循环,这个循环是应用程序执行的其余部分的顶级控制结构。

0x02 区别

二者在同一环境下的不同区别:

Windows支持两种类型的应用程序:

一种是基于控制台用户界面的应用程序(Console User Interface,简称CUI),
另一种是基于图形用户界面的程序(Graphic User Interface,简称GUI)。

0x03 函数详解

3.1 main函数

在 Microsoft C 中,程序启动时调用的函数称为 main。 没有针对 main 声明的原型,可以用零个、两个或三个参数对其进行定义:

int main( void )
int main( int argc, char *argv[] )
int main( int argc, char *argv[], char *envp[] )

其中三个参数的解释如下:

argc 表示有多少个命令行参数,第一个就是执行程序名,所以argc最少为1。 
argv 是具体程序运行的地址与相搭配的参数。 
envp 是系统的环境变量,很少有介绍的。“名称=值”的形式,以NULL结束。

3.2 winmain函数

WinMain是用于应用程序入口点的常规名称,他的句法如下:

int __clrcall WinMain(
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR     lpCmdLine,
  int       nShowCmd
);

其中四个参数的解释如下:

hInstance        类型:HINSTANCE,应用程序当前实例的句柄,也就是他所处的基地址。
hPrevInstance    类型:HINSTANCE,应用程序先前实例的句柄。此参数始终为NULL。
lpCmdLine        类型:LPSTR,应用程序的命令行,不包括程序名称。
nShowCmd         待定

0x04 实验查找

这里用两个程序分别进行查询main函数与winmain函数:

  1. Fport.exe --> main函数

    扫描二维码关注公众号,回复: 9963287 查看本文章
  2. 360zipInst.exe --> winmain函数

单独用IDA与OD进行查找:不过还是IDA方便理解一些

4.1 IDA查找main函数

ida打开之后,直接找到start:

反汇编查看伪代码:这里可以看到它是以v7返回值退出的,着重看v7:

这里的sub_407D10函数其实就是main函数:

v7 = sub_407D10(dword_41BFC8, dword_41BFCC);

双击步入函数,里面存在相应的命令行显示字符串:

整个的函数逻辑也会存在其中,我们再拿OD调试一下

4.2 OD查找main函数

F8单步运行到这里,观察OD的栈面板窗口,程序运行到main函数时,经常会伴随着栈的活动:

这三个数值,其实就是上面所介绍到的main函数的3个参数,来一一对应一下:

Arg1 对应的就是 argc ,表示有多少个命令行参数,第一个就是执行程序名,所以argc最少为1 这里的数值也是 = 00000001

选中 Arg2 ,追踪一下数据:

可以看到数据面板窗口其中就存在着一个物理地址,而这个地址正好对应了 main函数中的 argv ,由于我们运行时,没有搭配任何参数,所以参数为空。

同样的方法,再来看一下Arg3,这里对应的就是相应的系统环境了:

三个参数的数值都可以对应上main函数的参数,那么这里的 Fport.00407D10 也就是整个程序的主入口了

为了进一步证明,F2下个断点,F9运行到断点处,F7进到函数里面:

相应的命令行字符串直接在旁边显示了出来,找对地方了!

4.3 IDA查找main函数

猜你喜欢

转载自www.cnblogs.com/-mo-/p/12524691.html
今日推荐