0x00 放个屁~
最近放寒假抽空学了汇编,感触颇深,所以打算挖点坑分享下我在学习过程中看到的一些惊艳的事物。我其实是倒腾前端的,所以如果有一些关于C的术语说错了见谅轻喷啊啊~
0x01 解释一下~
在C语言中,structs可以被看作是一个变量合集,其中的变量可以是不同类型的,被存储在内存中的同一位置,看代码先:
struct
编译环境:Ubuntu (x86) 所以一个int只有4 byte。
结果:
4
80
84
其中,我定义了一个名为test的数据类型,并初始化至变量t。在main中第一行输出了t.a在内存中的大小,第二行输出了t.b这个array在内存中的大小。其中sizeof(t.a)与sizeof(int)完全相同且sizeof(t.b)与
(20个int的大小)也相同,可以看出GCC为结构体内的每一个变量预留了与其类型相配的空间。
0x02 反编译一下~
修改上面的程序:
struct
采用GCC的O0编译并用radare2反编译后得到如下关于main函数的汇编代码:
push rbp ;把栈底入栈
mov rbp, rsp ;将栈顶变为当前栈底
xor eax, eax ;给eax赋值0
lea rcx, _t2 ;给rcx赋值t2的地址
lea rdx, _t1 ;给rcx赋值t1的地址
mov dword ptr [rdx], 1 ;给t1所在位置赋值1
mov dword ptr [rcx], 2 ;给t2所在位置赋值2
pop rbp ;把之前栈底pop到栈底寄存器
retn ;回去
其中对于_t1与_t2在汇编代码中的定义:
__common:0000000100001000 _t1 db ? ;
__common:0000000100001001 db ? ;
__common:0000000100001002 db ? ;
__common:0000000100001003 db ? ;
__common:0000000100001004 public _t2
__common:0000000100001004 _t2 db ? ;
__common:0000000100001005 db ? ;
__common:0000000100001006 db ? ;
__common:0000000100001007 db ? ;
可见定义的struct在编译后变为了4个define byte,也就是一个int,因此GCC更像是将之前的代码看作成如下形式:
int
实际上,这两个程序编译再反编译后得到的汇编代码是一样的。
0x03 总个结~
所以啊,你辛辛苦苦定义的struct在编译器看起来还是个累赘。。
0x04 Reference
[1]. Reverse engineering for beginners