从反汇编代码分析c语言在x86上的工作原理
来源:互联网 发布:python 线程同步 编辑:程序博客网 时间:2024/04/27 18:01
一.首先给出c语言程序代码:
//文件名:main.cint g(int x){ return x+700;}int f(int x){ return g(x);}int main(){ return f(5)+1;}
二.用GCC 将C语言程序代码编译为汇编代码:
在命令行中输入命令:gcc –S –o main.s main.c -m32
编译输出的汇编代码如图2-1所示:
图2-1(实验截图)
为了更加方便地去分析程序,首先对汇编代码进行进一步的处理,去掉了以'.'号开头的代码,处理后的汇编代码如下:
g:pushl%ebpmovl%esp, %ebpmovl8(%ebp), %eaxaddl$700, %eaxpopl%ebpretf:pushl%ebpmovl%esp, %ebpsubl $4, %espmovl8(%ebp), %eaxmovl%eax, (%esp)callgleaveretmain:pushl%ebpmovl%esp, %ebpsubl$4, %espmovl$5, (%esp)callfaddl $1, %eaxleaveret
三.汇编程序分析
程序看上去很简单,但是当操作系统将我们的程序加载到内存中时执行时,操作系统会对程序内的偏移地址进行重定位操作。此时程序在内存中地址将变得十分的复杂。显然这对我们的程序分析是十分不利的.因此在开始分析程序之前我们有必要做一些事先的约定假设。当然这些预定假设并不会对程序的准确性和严密性产生丝毫的影响。
假设如下:
3个函数g()、f()、main()的开始地址分别为200、300、400,
在进入main函数之前寄存器ebp和esp的值如下:ebp=100;esp=90;
好了下面正式开始我们的分析
;首先重main函数开始
;进入main函数
pushl %ebp ;将栈基地址压栈 。寄存器状态:ebp=100;esp=86;
;内存单元87-100存放的是main函数外部的栈基地址
movl %esp, %ebp ;将栈相对的清空了 。寄存器状态:ebp=86;esp=86;
subl $4, %esp ;栈顶指针减4 。寄存器状态:ebp=86;esp=82;
movl $5, (%esp) ;立即数5存放在内存单元82-85 中。
;调用函数f(5)
call f ;这里一共完成了两个动作:将EIP指针自增后圧栈然后将EIP指针指向f()函数的地址。
;寄存器状态:eip=300 ;ebp=86;esp=78;
;进入函数f
pushl%ebp ;内存单元74-77存放86
movl %esp, %ebp ; esp=74;ebp=74;
subl $4, %esp ;esp=70
movl 8(%ebp), %eax ;取出参数
movl %eax, (%esp) ;将eax的值5存放到地址70-73
;进入函数g()
call g ;调用函数g,eip圧栈(地址为66-69),esp=66,ebp=74;eip=200
pushl %ebp ;内存单元62-65存放74 ;ebp=74;esp=62;
movl %esp, %ebp ;ebp=esp=62;
movl 8(%ebp), %eax ;从地址62+8的位置取出32位整数5放入寄存器eax中。
addl $700, %eax ; 寄存器eax自增700,后eax=705
popl %ebp ;清理堆栈,ebp=74;esp=66
ret ;函数返回到g,等价于 popl eip ;esp=70 ebp=74
;已经离开函数g,返回值存放在寄存器eax中。
;准备离开函数f
leave ;离开函数,popl-> ebp ,esp=ebp=86;
ret ;返回到main函数中
;已经离开函数f,返回值存放在寄存器eax中。
addl $1, %eax ;eax =706寄存器
leave ;清理main函数的堆栈
ret
;main函数已经返回
总结:
1.不关在高级语言中函数是如何相互调用的,最终都会被编译器编译为指令序列。
2.c语言中函数的参数通过栈传递
3.在子程序中使用了的寄存器必须在调用子程序前圧栈,这一步骤称为保存现场。子程序使用完毕返回时必须将上一次圧栈的寄存器值恢复到寄存器,这一步骤称为恢复现场。这里的保存现场和恢复现场由编译器处理。
2.宏指令enter和leave 实现了高级语言中函数与函数间的逻辑隔离。
宏指令:enter 被展开为:
pushl%ebp
movl %esp, %ebp
宏指令:leave 被展开为:
movl %ebp,%esp
popl %ebp
作者:徐崇龙
2015年3月8日
原创作品转载请注明出处
《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000
0 0
- 从反汇编代码分析c语言在x86上的工作原理
- C语言反汇编代码分析,理解计算机工作原理
- x86平台 通过反汇编简单的从程序,分析理解计算机是如何工作的。
- Linux汇编代码学习,反汇编简单的c及分析汇编代码工作过程
- 反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- c代码反汇编,观察堆栈工作原理
- C语言的反汇编代码
- C语言的反汇编代码
- c语言反汇编代码
- 反汇编一个简单的C程序,分析汇编代码
- 通过汇编一个简单的C程序,分析汇编代码理解计算机工作原理
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的(原创)
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 通过反汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的
- 在x86汇编中使用C语言的全局变量
- C语言的反汇编
- XHTML 2.0与HTML 5之争
- 1084. Broken Keyboard (20)建立查询表
- CocoaPods pod install/pod update更新慢的问题
- PHP程序优化
- iOS开发 -定制TableViewCell
- 从反汇编代码分析c语言在x86上的工作原理
- 利用VMware在Windows下构建Linux学习环境
- Android中 source添加 onCreateOptionsMenu()失败
- hdoj 1114 Piggy-Bank
- 触发器
- Linux内核地址映射模型
- 用Smali写一个加法程序
- Java学习之网络编程--概念
- Linux下使用modprobe加载驱动