反汇编
反汇编就是我们把一系列的机器码转换成改程序的助记符。如果我们拿到一份机器码程序,而我们想要知道他的功能和工作方式,可以对机器码进行反汇编。
反编译一个简单的C程序
使用的C程序
int g (int x)
{
return x + 4;
}
int f (int x)
{
return g(x);
}
int main (void)
{
return f(6) + 1;
}
使用的反汇编指令为:
gcc -S -o main.s main.c
得到的汇编程序经过处理后如下所示:
g:
pushl %ebp //esp-4指向7,ebp入栈
movl %esp, %ebp //esp的值赋给ebp,ebp指向7
movl 8(%ebp), %eax //将ebp+8后指向的栈地址内的数(即6)赋值给eax
addl $4, %eax //将eax内数加上4并存入eax,此时eax值为10
popl %ebp //将栈7出栈放入ebp,即ebp指向栈4,esp+4指向6
ret //将栈6出栈放入eip,esp+4指向5,回到f方法
f:
pushl %ebp //esp-4指向4,ebp入栈
movl %esp, %ebp //esp的值赋给ebp,ebp指向4
subl $4, %esp //esp-4指向5
movl 8(%ebp), %eax //将ebp+8后指向的栈地址内的数(即6)赋值给eax
movl %eax, (%esp) //eax将数值赋给esp当前所指位置,即栈5
call g //esp-4指向6,将eip入栈,调转到g方法
leave //将ebp的值赋给esp,esp指向4,将栈4出栈放入ebp,ebp指向1,esp+4指向3
ret //将栈3出栈放入eip,esp+4指向2,回到main方法
main:
pushl %ebp //此时ebp指向0,esp-4指向1,ebp入栈
movl %esp, %ebp //esp的值赋给ebp,ebp指向1
subl $4, %esp //esp-4指向2
movl $6, (%esp) //将6存入栈2中
call f //将eip入栈,esp-4指向3调转到f方法
addl $1, %eax //将eax的值加1(即10+1),存入eax中
leave //将ebp的值赋给esp,esp指向1,将栈1出栈放入ebp,ebp指向0,esp+4指向0
ret //将eip出栈放入eip,然后就是main方法的上层方法了
-
总结:
计算机通过eip来存储下一条指令的地址; 通过eax传递函数返回值; 每次调用一个方法时重新开辟一个新的栈空间。
-
作者:沈鑫 原创作品转载请注明出处 《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
反汇编常用的几种方法
- 使用gcc -S test.c 或者gcc -S test.c>out.txt
- 使用gdb调试,在调试中输入disass 函数名 就可以
-
objdump -D test
(一般常用1,2两种)