如果想要了解C++内部的实现原理,没有什么比观察C++代码对应的汇编代码来的更直接了。本系列主要从汇编角度研究C++代码和汇编的对应关系,揭示C++内部的机制和原理。在第一篇文章中我将从一个简单的C++程序着手快速解释一下C++反汇编代码的基本的结构和内容,相当于一个简单的Preview。而在后续的文章中,我将根据不同的Topic,详细解释C++代码对应的反汇编代码。
一个简单的C++程序示例如下:
class my_class { public : my_class() { m_member = 1; }
void method(int n) { m_member = n; }
~my_class() { m_member = 0; }
private : int m_member; };
int _tmain(int argc, _TCHAR* argv[]) { my_class a_class; a_class.method(10);
return 0; } |
可以直接Debug的时候看到Assembly代码,不过这样获得的代码注释比较少。比较理想的方法是利用VC编译器的一个选项/FAs来生成对应的汇编代码。/FAs还会在汇编代码中加入注释注明和C++代码的对应关系,十分有助于分析。在VS2005中可以这样打开/FAs:
Build代码,可以在输出目录下发现对应的.ASM文件。本文将逐句分析汇编代码和C++的对应关系。
首先是WinMain:
_TEXT SEGMENT _wmain PROC push ebp ; 保存旧的ebp mov ebp, esp ; ebp保存当前栈的位置 push -1 ; 建立SEH(Structured Exception Handler)链 ; -1表示表头,没有Prev push __ehhandler$_wmain ; SEH异常处理程序的地址 mov eax, DWORD PTR fs:0 ; fs:0指向TEB的内容,头4个字节是当前SEH链的地址 push eax ; 保存起来 sub esp, d8H ; 分配d8H字节的空间 push ebx push esi push edi lea edi, DWORD PTR [ebp-e4H] ; 确定局部变量的起始地址。e4H = d8H + 4 * 3,跳过之前建立SEH链所用的3个Push指令所占用的栈的空间,以及sub esp, d8h为局部变量分配的d8H字节空间 mov ecx, 36H ; 36H*4H=d8H,也就是用36H个ccccccccH填满刚才分配的d8H字节空间 mov eax, ccccccccH rep stosd mov eax, DWORD PTR ___security_cookie xor eax, ebp push eax ; ebp ^ __security_cookie压栈保存 lea eax, DWORD PTR [ebp-0cH] |