zoukankan      html  css  js  c++  java
  • 反汇编测试

    1.通过输入gcc -S -o main.s main.c 将下面c程序”week0303学号.c“编译成汇编代码

    2.使用gdb跟踪汇编代码,在纸上画出f中每一条语句引起的eip(rip),ebp(rbp),esp(rsb),eax(rax)的值和栈的变化情况。提交照片,要有学号信息。

    相关知识:
    esp:寄存器存放当前线程的栈顶指针
    ebp:寄存器存放当前线程的栈底指针
    eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。
    eax:是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

    一个标准的函数起始代码:

    push ebp ;保存当前ebp
    mov ebp,esp ;EBP设为当前堆栈指针
    sub esp, xxx ;预留xxx字节给函数临时变量.

    使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器
    这里我遇到了一个问题,有下图的报错

    后来上网查了资料,解决办法是输入命令sudo apt-get install gcc-multilib

    进入之后先在main函数处设置一个断点,再run一下.

    使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值

    这里我发现了一条陌生的指令,<__x86.get_pc_thunk.ax>,其他的指令都差不多可以理解。

    后来上网查了资料,get_pc_thunk.xx是一个子程序,是被调用的,程序调用时,会把调用者的下一条指令的地址压栈保存(用于返回),所以进入get_pc_thunk.xx时,栈顶esp就是调用者的下一条指令地址。

    <__x86.get_pc_thunk.ax>这样的一条指令,就类似下面的操作:

    __get_pc_thunk.ax:
    movel (%esp),%eax
    return

    就是把esp的内容赋值给eax。

    call 0x56556213 <__x86.get_pc_thunk.ax>执行时,会把该指令的下一条指令的地址压栈保存。也就是把指令add 0x2ddd,%eax的地址0x565561ff压入栈中

    所以当进入子程序0x56556213<__x86.get_pc_thunk.ax>时,主要是执行:

    movel (%esp),%eax

    我的单步运行也证明了这一点:

    当调用者call 0x56556213<__x86.get_pc_thunk.ax>执行完毕返回时,将要执行的是:

    add 0x2ddd,%eax

    这里eax原始值就是该条指令本身的地址(在<__x86.get_pc_thunk.ax>中给eax赋值的)!然后加上0x2ddd,就是在本条指令偏移0x2ddd地址。

    所以call 0x56556213<__x86.get_pc_thunk.ax>的意义就是为了获取下一条指令的地址。

    利用了调用子程序会将下一条指令地址压栈的特性,提前获取下一条指令的地址。

    接着来分析

    由图可知,esp所在的地址为0xffffd0dc,所以此时主函数的栈基址为0xffffd0dc,用x(examine)指令查看内存地址中的值

    结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。下面展示每一步时%esp、%ebp和堆栈内容的变化:

    执行到call函数时,esp和ebp的地址发生了变化,变为了0xffffd0d8

    运行到即将调用f函数时,call指令将下一条指令的地址入栈,此时%esp,%ebp的值分别为0xffffd0d4和0xffffd0d8:

    这样就真正进入了f函数,下面是f函数的汇编代码

    将上一个函数的基址入栈,从当前%esp开始作为新基址

    实参的计算在%eax中进行

    通过一步一步调试,我记录了每一步运行时esp、ebp、eip、eax的变化

    指令 esp ebp eip eax 堆栈
    push %ebp 0xffffd0d0 0xffffd0d8 0x565561ca 0x56558fdc 0x5655620b
    mov %esp,%ebp 0xffffd0cc 0xffffd0d8 0x565561cb 0x56558fdc 0xffffd0d8,0x5655620b
    sub $0x10,%esp 0xffffd0cc 0xffffd0cc 0x565561cd 0x56558fdc 0xffffd0d8,0x5655620b
    call 0x56556213 0xffffd0bc 0xffffd0cc 0x565561d0 0x56558fdc 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    add $0x2e07,%eax 0xffffd0bc 0xffffd0cc 0x565561d5 0x565561d5 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    movl $0x10,-0x4(%epb) 0xffffd0bc 0xffffd0cc 0x565561da 0x56558fdc 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    pushl 0x8(%ebp) 0xffffd0bc 0xffffd0cc 0x565561e1 0x56558fdc 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    call 0x565561ad 0xffffd0b8 0xffffd0cc 0x565561e4 0x56558fdc 0x8,0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    add $0x4,%esp 0xffffd0b8 0xffffd0cc 0x565561e9 0xb 0x8,0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    mov -0x4(%ebp),%edx 0xffffd0bc 0xffffd0cc 0x565561ec 0xb 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    add %edx,%eax 0xffffd0bc 0xffffd0cc 0x565561ef 0xb 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    leave 0xffffd0bc 0xffffd0cc 0x565561f1 0xb 0x56556241,0xf7fe22d0,0x0,0x0,0xffffd0d8,0x5655620b
    ret 0xffffd0d0 0xffffd0d8 0x565561f2 0xb 0x5655620b

    参考:
    https://www.k2zone.cn/?p=1911
    https://blog.csdn.net/u012060033/article/details/79218909此时

  • 相关阅读:
    网络安全分析
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1464 Function
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1014 Cantor表
    java实现 洛谷 P1540 机器
    java实现 洛谷 P1540 机器
  • 原文地址:https://www.cnblogs.com/ffffatal/p/15490925.html
Copyright © 2011-2022 走看看