天天看点

《C++反汇编与逆向分析技术揭秘》阅读笔记——第三章 认识启动函数,找到用户入口

  第三章主要讲解了程序的启动函数和找main函数的方法,对于在逆向过程中定位函数入口点有很大帮助。

3.1 程序真正的入口

  VC++开发的程序在调试时总是从main和WinMain函数开始,这容易令人误以它们是程序的第一条指令执行处。但其实main和WinMain也需要被调用,所以它们并不是“应用程序入口”,而是“语法规定的用户入口”。在应用程序加载时,操作系统会分析执行文件内的数据,分配相关资源,读取执行文件中的代码和数据到合适的内存单元,然后执行入口代码。入口代码并不是main和WinMain,通常是mainCRTStartup、wmainCRTStartup、WinMainCRTStartup或wWinMainCRTStartup。其中mainCRTStartup、wmainCRTStartup是控制台环境下多字节编码和Unicode编码的启动函数,而WinMainCRTStartup和wWinMainCRTStartup则是Windows环境下多字节编码和Unicode编码的启动函数。这部分的实现较为复杂,具体是如何实现的,以我的水平暂时不深究。

3.2了解VC++6.0的启动函数

  作者演示了使用VC++6.0的栈回溯功能查看mainCRTStartup函数的内部实现,让我们了解到了程序在调用main和WinMain函数前进行了一系列初始化操作,如通过GetVersion函数获取当前运行平台的版本号,通过_heap_init函数初始化堆空间,通过GetCmommandLineA函数获取命令行参数信息的首地址,通过_crtGetEnvironmentStringsA函数获取环境变量信息的首地址,通过_setargv函数获取命令行参数的个数以及命令行参数信息,通过_setenvp函数存放环境变量首地址数组的首地址,通过_cinit函数实现全局数据和浮点寄存器的初始化。这样就获取了main函数需要的三个参数,调用main函数时就可以将_argc(命令行参数个数)、_argv(命令行参数信息)、envp(环境变量信息)三个全局变量作为参数从右往左入栈传递到main函数中。

3.3main函数的识别

  识别main函数最重要的是找特征,也即main函数被调用前调用的函数和main函数的三个参数。

  在OD中,我们找到GetCommand函数,之后往下看,基本可确定这是在对main函数的调用做铺垫,三个参数传入后便是调用main函数,我们跳转过去便是main函数。

《C++反汇编与逆向分析技术揭秘》阅读笔记——第三章 认识启动函数,找到用户入口
《C++反汇编与逆向分析技术揭秘》阅读笔记——第三章 认识启动函数,找到用户入口

  在IDA中,我们可以在函数窗口直接看到main函数名,则更易找到main函数。

《C++反汇编与逆向分析技术揭秘》阅读笔记——第三章 认识启动函数,找到用户入口

疑惑点:在这一章并没有介绍main函数的三个参数具体有什么作用,是什么形式。

继续阅读