• 反汇编测试


    反汇编测试


    任务详情

    1 通过输入gcc -S -o main.s main.c 将下面c程序”week0303学号.c“编译成汇编代码
    int g(int x){
        return x+3;
    }
    int f(int x){
         int i = 学号后两位;
        return g(x)+i;
    }
    int main(void){
        return f(8)+1;
    }
    
    2. 参考http://www.cnblogs.com/lxm20145215----/p/5982554.html,使用gdb跟踪汇编代码,在纸上画出f中每一条语句引起的eip(rip),ebp(rbp),esp(rsb),eax(rax)的值和栈的变化情况。提交照片,要有学号信息。
    

    完成过程

    1.编译情况

    image-20211101202835776

    2.发现在树莓派arm64架构下无法完成,便转到kali上做了。

    image-20211101205559577

    使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器:

    image-20211101205848876

    进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:

    image-20211101210029858

    用x mian查看主函数的内存地址:

    首先,结合display命令和寄存器或pc内部变量,做如下设置:display /i $pc,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。

    image-20211102091745502

    call指令将下一条指令的地址入栈,此时%esp,%ebp和堆栈的值为:

    image-20211102093213399

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

    image-20211102093527513

    先为传参做准备:

    image-20211102093801321

    f函数的汇编代码:

    image-20211102093949549

    实参入栈:

    image-20211102094125998

    主函数汇编代码:

    image-20211102094502986


    知识点

    跟着博客做完整个人还是很晕,于是想梳理一下知识点。

    1.寄存器

    参考博客:https://www.cnblogs.com/lihaozy/archive/2011/08/01/2124315.html

    (1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。

    (2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

    (3)Eax用来保存所有API函数的返回值。

    (4)寄存器AX和AL通常称为累加器(Accumulator),用累加器进行的操作可能需要更少时间。累加器可用于乘、除、输入/输出等操作,它们的使用频率很高;

    (5)寄存器BX称为基地址寄存器(Base Register)。它可作为存储器指针来使用;

    (6)寄存器CX称为计数寄存器(Count Register)。在循环和字符串操作时,要用它来控制循环次数;在位操作中,当移多位时,要用CL来指明移位的位数;

    (7)寄存器DX称为数据寄存器(Data Register)。在进行乘、除运算时,它可作为默认的操作数参与运算,也可用于存放I/O的端口地址。

    (8)寄存器ESI、EDI、SI和DI称为变址寄存器(Index Register),它们主要用于存放存储单元在段内的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。变址寄存器不可分割成8位寄存器。作为通用寄存器,也可存储算术逻辑运算的操作数和运算结果。它们可作一般的存储器指针使用。在字符串操作指令的执行过程中,对它们有特定的要求,而且还具有特殊的功能。

    2.gdb指令

    参考博客:https://blog.csdn.net/moonsheep_liu/article/details/39099969

    3.学习汇编语言

    参考博客:https://www.ruanyifeng.com/blog/2018/01/assembly-language-primer.html


    重新尝试反汇编

    试图理解反汇编

    1.首先在main函数设置断点 b main

    2.使用display设置显示内容。

    display /x $esp
    display /x $ebp
    display /x $eax
    display /i $pc
    

    3.使用run指令跳到main函数开始处,使用x(examine) /nfu + 内存地址查看堆栈内容。

    push 命令将$0x8放入stack,因为是int型占用4个字节,所以esp寄存器减去4

    这时可以看到栈底地址是0xffffd168。

    image-20211102140922607

    4.使用si步入下一条指令,使用x(examine) /nfu + 内存地址查看堆栈内容(之后每一步都要用到,不重复说明)。

    call指令调用f函数,f函数的地址在0x5655619e

    image-20211102140103395

    5.push命令将ebp里的值写入f函数这个帧,内容为0x565561bd,这是因为后面要用到这个寄存器,就先把里面的值取出来,用完后再写回去。这时,push指令会再将 ESP 寄存器里面的地址减去4个字节(累计减去8)。

    image-20211102135701329

    6.mov指令用于将一个值写入某个寄存器。这一行代码表示,从ebp寄存器存的地址在 Stack 取出数据。根据前面的步骤,可以推算出这里取出的是8,再将8写入ESP寄存器。

    image-20211102141232311

    这里没有使用push指令,但是esp减去了4(累计减去12),堆栈中也存入了ebp的地址0xffffd168,参照阮一峰的理解是

    image-20211102142015117

    7.sub指令代表第一个寄存器中的值减去第二个寄存器中的值,将结果存入第一个寄存器中。这里就是用10(我的学号)减去esp中的值(此处应该是8),得到了2,存入?

    (此处不理解)将我的学号传入f函数中,堆栈中存入了0xf7de2fd6。

    image-20211102142513989

    此处因为进入了f函数中,所以ebp指向了f函数的栈底0xffffd15c。

    8.call指令调用(此处应该是一个奇奇怪怪的函数,估计是某个库函数,用来初始化函数调用的?),建立该函数的帧。

    esp减去了16,说明存入了4个东西(为什么呢)

    image-20211102144144974

    9.mov指令将esp的地址存入了eax寄存器中,地址为0x565561a9,存入了堆栈中,esp中的值减去4。

    image-20211102144312122

    10.ret指令用于终止当前函数的执行,将运行权交还给上层函数。也就是,当前函数的帧将被回收。

    随着函数的终止,系统就回到刚才f函数中断的地方,继续往下执行。

    image-20211102144615115

    11.add指令是将0x2e57与eax寄存器中的值相加,存到?

    此处应该发生了pop指令,esp寄存器的值加上4。

    image-20211102145139156

    12.movl指令将0xa(10,我的学号)传入地址(ebp的地址减去4,这里应该是i的地址)中,此处movl中的l为长字节的意思(虽然感觉用mov也可以)。

    image-20211102145312214

    13.push将地址(ebp的值0+8,就是8)中的值取出来写入f函数这个帧,esp减去4。

    image-20211102150055177

    14.call指令调用g函数,建立g函数的帧。

    image-20211102150843846

    15.push命令将ebp中的值(地址0xffffd15c的值,此处应是0xa)写入g函数帧里,esp的地址减去4。

    image-20211102151703325

    16.mov将esp中的值写入ebp中(为传回上层函数做准备)。

    image-20211102152132580

    17.call指令调用不知名函数。

    image-20211102152327988

    18.mov指令将寄存器eax中的值存入地址(寄存器esp的值)中。

    image-20211102152432179

    19.ret指令终止函数,返回上层函数的帧。

    image-20211102152623460

    20.add指令将0x2e6f与寄存器eax中的值(0x56556191)相加,存入eax中。

    image-20211102152811118

    21.mov指令将寄存器ebp中的值(此处为0)加8,存入eax寄存器中。

    image-20211102153038631

    22.add指令将3加上eax中的值存入eax中(3+8=11)。

    image-20211102153332093

    23.pop指令

    image-20211102153504867

    24.ret指令终止当前函数。

    image-20211102153626430

    25.add指令将4与esp寄存器中的值(此处为8)相加,存入esp寄存器中。

    image-20211102153806067

    25.mov指令将地址(寄存器ebp的值减去4)中的值存入寄存器edx中。

    image-20211102154141197

    26.add指令将edx中的值与eax中的值相加(11+8=21),存入eax中。

    image-20211102154222592

    27.leave指令用于释放当前堆栈中的内容。

    image-20211102181539933

    28.ret指令用于终止函数。

    image-20211102181824981

    29.add指令将4与寄存器esp中的值相加,存到esp中(4+8 = 12)

    image-20211102181911321

    30.add指令将1与寄存器eax中的值相加,存到eax中(21+1 = 22)。

    image-20211102181948090

    31.leave指令释放当前堆栈的内容。

    image-20211102182052262

    32.ret指令结束当前函数调用,之后就是系统调用,很多看不完。

    image-20211102182324016

    总结

    ​ 看了一整天,看麻了!

  • 相关阅读:
    Python字符串学习相关问题
    Python函数学习遇到的问题
    How to configure ODBC DSN to access local DB2 for Windows
    如何在Eclipse CDT中编译含有多个main函数的项目
    MakeFile 文件的作用
    云技术:负载均衡SLB
    云技术:弹性计算ECS
    《老罗的Android之旅》导读PPT
    服务器集群负载均衡技术
    杭电ACM 1004题
  • 原文地址:https://www.cnblogs.com/sisterben/p/15500525.html
Copyright © 2020-2023  润新知