《逆向工程权威指南》—第3章3.3节 GCC的其他特性

    xiaoxiao2024-01-15  160

    本节书摘来自异步社区《逆向工程权威指南》一书中的第3章3.3节 GCC的其他特性,作者【乌克兰】Dennis Yurichev(丹尼斯),更多章节内容可以访问云栖社区“异步社区”公众号查看。

    3.3 GCC的其他特性只要C语言代码里使用了字符串型常量(可参照3.1.1节的范例),编译器就会把这个字符串常量置于常量字段,以保证其内容不会发生变化。不过GCC有个有趣的特征:它可能会把字符串拆出来单独使用。

    我们来看下面这段程序:

    #include <stdio.h> int f1() { printf ("world\n"); }; int f2() { printf ("hello world\n"); }; int main() { f1(); f2(); };

    多数的C/C++编译器(包括MSVC编译器)会分配出两个直接对应的字符串,不过GCC 4.8.1的编译结果则更为可圈可点。

    指令清单3.10 在IDA中观察GCC 4.8.1 的汇编指令

    > f1 proc near s = dword ptr -1Ch sub esp, 1Ch mov [esp+1Ch+s], offset s ; "world\n" call _puts add esp, 1Ch retn f1 endp f2 proc near s = dword ptr -1Ch sub esp, 1Ch mov [esp+1Ch+s], offset aHello ; "hello " call _puts add esp, 1Ch retn f2 endp aHello db 'hello' s db 'world', 0xa, 0 在``` 打印字符串“hello world”的时候,这两个词的指针地址实际上是前后相邻的。在调用puts()函数进行输出时,函数本身不知道它所输出的字符串分为两个部分。实际上我们在汇编指令清单中可以看到,这两个字符串没有被“切实”分开。 在f1()函数调用puts()函数时,它输出字符串“world”和外加结束符(数值为零的1个字节),因为puts()函数并不知道字符串可以和前面的字符串连起来形成新的字符串。 相关资源:敏捷开发V1.0.pptx
    最新回复(0)