逆向工程C++

Mic*_*ael 5 c++ compiler-construction reverse-engineering ida

今天我决定使用IDA Pro反编译一个用Visual C++编写的简单"Hello world"程序.

根据我以前的知识,我确信我不会在可执行入口点找到对printf的立即调用,我是对的.我发现很多代码都不是由我编写的,并且在编译过程中由编译器添加.

我希望更好地了解在编译过程中添加的代码.它有什么作用?是否有任何"技巧"快速找到"主"并跳过反汇编生成的所有不必要的代码?

我能找到的最好的是这篇文章:http: //www.codeproject.com/Articles/4210/C-Reverse-Disassembly,说使用visual c ++编译的可执行文件的执行顺序如下:

  1. CrtlStartUp

  2. 主要

  3. CrtlCleanUp

我能得到更详细的答案吗?

ex0*_*du5 4

您可能会遇到 C++ 标准所要求的各种内容。

最重要的是,需要有代码在调用 main 之前处理主翻译单元中任何静态的构造,以及在 main 离开之后处理它们的销毁的函数。此外,该标准需要一个函数atexit,允许您注册在 main 返回后调用的附加函数。

因此,启动代码至少需要能够构建将在从 main 返回时调用的函数的数据结构。这是一个动态数据结构,因为它需要由程序添加到运行时,并且调用顺序与注册相反(因此通常您需要一个可以轻松添加到您走过的地方的数据结构)。

但此外,该标准要求在其他翻译单元中执行任何函数之前创建其他翻译单元中的静态。通常,编译器会简单地安排链接器中的所有内容,以便在 main 之前调用所有内容,但这不是必需的。那些以不同方式执行操作的编译器需要为链接的其他翻译单元代码中的初始化例程提供 thunk,该例程将在第一个函数调用时调用。

如果您使用任何标准库,这将是一项相当大的工作。请记住,std::cout 是一个静态对象(静态生命周期,而不是静态链接 - 令人困惑的重载词警报)。因此,这意味着建立与控制台的通信,控制台将具有您的平台调用所需的任何 API。标准中有很多这样的对象。

然后,可能有一些特定于您的平台和/或编译器的东西,它们以某种有用的方式准备进程,或者解析环境变量,或者加载“标准”动态/共享库,或者类似的东西。

通常,退出只是遍历该列表并以某种方式向环境提供 main 的返回值,因为大多数现代操作系统会自行清理,但除此之外可能还有系统特定的东西。