Linux基本反汇编结构与GDB入门

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数,而Windows下却是相反。

1、基本操作指令

简单的操作数类型说明,一般有三种,

(1)立即数操作数,也就是常数值。立即数的书写方式是“$”后面跟一个整数,比如$0x1F,这个会在后面的具体分析中见到很多。

(2)寄存器操作数,它表示某个寄存器的内容,用符号Ea来表示任意寄存器a,用引用R[Ea]来表示它的值,这是将寄存器集合看成一个数组R,用寄存器表示符作为索引。

(3)操作数是存储器引用,它会根据计算出来的地址(通常称为有效地址)访问某个存储器位置。用符号Mb[Addr]表示对存储在存储器中从地址Addr开始的b字节值的引用。通常可以省略下标b。

图1表示有多种不同的寻址模式,一个立即数偏移Imm,一个基址寄存器Eb,一个变址或索引寄存器Ei和一个伸缩因子s。有效地址被计算为Imm+R[Eb]+R[Ei]*s,对于这中寻址方式,我们可以在数组或者结构体中进行对元

注:操作数可以是立即数值、寄存器值或是来自存储器的值,伸缩因子必须是1、2、4、或者是8。从上面的图我们就可以大致了解操作数的类型了。

在操作指令中,最频繁使用的指令是执行数据传送的指令。对于传送指令的两个操作数不能都指向存储器位置(我的理解是一般存储器存储的都是地址,不能够对地址和地址进行操作)。将一个值从一个存储器位置拷到另一个存储器位置需要两条指令——第一条指令将源值加载到寄存器中,第二条将该寄存器值写入到目的位置。下面给出源操作数和目的操作数的五种可能组合。

1、movl $0x4050, %eax 立即数——寄存器

2、movl %ebp, %esp 寄存器——寄存器

3、movl (%edi, %ecx), %eax 存储器——寄存器

4、movl $-17, (%esp) 立即数——存储器

5、movl %eax, -12(%ebp) 寄存器——存储器

注意这里的指令mov可能有不同的形式,不同平台的汇编一般是有些不一样的,

结合例子来进行讲解一下指令的具体操作,在这里将会正式接触到Linux下的GCC开发环境和GDB调试器,不过都是比较简单的应用。我的Linux操作系统是Ubuntu9.10,其它版本的差别应该不大,

如果我们要编写一个程序,我们可以用Linux下自带的vi或vim编辑器,studyrush@studyrush-desktop:~/C$ vi exchange.c

vi 后面加我们要创建的程序文件的名字,在这里是exchange.c

studyrush@studyrush-desktop:~/C$ gcc -o exchange exchange.c

gcc -o exchange exchange.c 或gcc exchange –o exchange这两者都可以对源文件进行编译,-o exchange 表示对我们要输出的文件名称,可能表达的不够准确,大家可以先熟悉一下gcc编译器,应该就会明白的了。

studyrush@studyrush-desktop:~/C$ ./exchange 点加斜线再加输出文件名就表示运行程序,下面是运行的结果。

a = 3,

b = 4

使用GDB可以参考附件里面的教程,这份教程写的很不错,看雪论坛本身也有,大家可以看这个贴(/showthread.php?t=77746),现在我只是把它放在附件里面。

studyrush@studyrush-desktop:~/C$ gdb exchange

命令disas就表示反汇编(disassembly),后面再加上要显示的函数名,我们就可以看到函数对应的反汇编代码了。

(gdb) disas exchange

Dump of assembler code for function exchange:

0x080483c4 : push %ebp

0x080483c5 : mov %esp,%ebp

0x080483c7 : sub $0x10,%esp

0x080483ca : mov 0x8(%ebp),%eax

0x080483cd : mov (%eax),%eax

0x080483cf : mov %eax,-0x4(%ebp)

0x080483d2 : mov 0x8(%ebp),%edx

0x080483d5 : mov 0xc(%ebp),%eax

0x080483d8 : mov %eax,(%edx)

0x080483da : mov -0x4(%ebp),%eax

0x080483dd : leave

0x080483de : ret

End of assembler dump.

进一步来分析上面的反汇编代码,这里的代码可能与前面的讲的指令操作有一些不同,因为这是很正常的,不同的操作系统应该有所差别,这也是汇编语言一般与平台有关,移植性并不好。

push %ebp

mov %esp,%ebp

sub $0x10,%esp

对有过反汇编的人对上面的代码肯定不会陌生,这里就是将ebp进栈,保存esp 的值,并为局部变量预留空间。要记得源操作数与目的操作数的位置,前面有讲的。这里也一定程度对C语言中的指针使用进行了说明。看源代码可以知道。mov 0x8(%ebp),%eax

mov (%eax),%eax

mov %eax,-0x4(%ebp)

mov 0x8(%ebp),%eax 取得xp,其实是指针本身,即是地址,汇编表示即可为mov %ebp + 8, %eax,这里就是存储器——寄存器的操作方式。

mov (%eax),%eax 这里是取得指针指向的值,即*xp,(%eax)表示取%eax 中的地址指向的值,比如

寄存器值地址值

%eax 0x100 0x100 0xFF

(%eax)的值就是0xFF了。

相关文档
最新文档