• 《信息安全系统设计基础》代码调试分析


    GCC编译

    • 安装库,使用sudo apt-get install libc6-dev-i386命令。

    • 然后执行命令gcc -g code.c -o code -m32命令就可以在64位的机器上生成32位汇编代码

    分析过程

    • 使用gdb调试代码。
    • 使用break main指令在main函数处设置断点,然后调试,直到mian函数处。
    • 使用diassemble指令获取汇编代码

    依次如下指令调试汇编代码,并查看%esp、%ebp和堆栈内容:

    1、使用si指令单步跟踪一条机器指令

    2、使用i r指令查看各寄存器的值(在这里要看%eip、%eax、%esp和%ebp)

    3、使用x/na %esp对应的值指令查看堆栈变化

    代码分析

    代码在这里

    指令

    %eip

    %esp

    %ebp

    %eax

    堆栈

    push $0x8

    0x804840b

    0xffffd588

    0xffffd588

    0xf7fbadbc

    0x0

    call 0x80483ef

    0x804840d

    0xffffd584

    0xffffd588

    0xf7fbadbc

    0x8 0x0

    push %ebp

    0x80483ef

    0xffffd580

    0xffffd588

    0xf7fbadbc

    0x8048412 0x8 0x0

    mov %esp,%ebp

    0x80483f0

    0xffffd57c

    0xffffd588

    0xf7fbadbc

    0xffffd588 0x8048412 0x8 0x0

    mov 0x804a01c,%edx

    0x80483f2

    0xffffd57c

    0xffffd57c

    0xf7fbadbc

    0xffffd588 0x8048412 0x8 0x0

    0x8(%ebp),%eax

    0x80483f8

    0xffffd57c

    0xffffd57c

    0xf7fbadbc

    0xffffd588 0x8048412 0x8 0x0

    Add %edx,%eax

    0x80483fb

    0xffffd57c

    0xffffd57c

    0x8

    0xffffd588 0x8048412 0x8 0x0

    Push %eax

    0x80483fd

    0xffffd57c

    0xffffd57c

    0xa

    0xffffd588 0x8048412 0x8 0x0

    Call 0x80483db

    0x80483fe

    0xffffd578

    0xffffd57c

    0xa

    0xa

    0xffffd588 0x8048412 0x8 0x0

    Push%ebp

    0x80483db

    0xffffd574

    0xffffd57c

    0xa

    0x8048403 0xa 0xffffd588 0x8048412 0x8 0x0

    Mov %esp,%ebp

    0x80483dc

    0xffffd570

    0xffffd57c

    0xa

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    Movzwl 0x804a018,%eax

    0x80483de

    0xffffd570

    0xffffd570

    0xa

    0xffffd570

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    Movswl %ax,%edx

    0x80483e5

    0xffffd570

    0xffffd570

    0x1

    0xffffd570

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    mov 0x8(%ebp),%eax

    0x80483e8

    0xffffd570

    0xffffd570

    0x1

    0xffffd570

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    Add %edx,%eax

    0x80483eb

    0xffffd570

    0xffffd570

    0xa

    0xffffd570

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    Pop %ebp

    0x80483ed

    0xffffd570

    0xffffd570

    0xb

    0xffffd570

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    ret

    0x80483ee

    0xffffd574

    0xffffd57c

    0xb

    0x8048403 0xa

    0xffffd588 0x8048412 0x8 0x0

    Add $0x4,%esp

    0x8048403

    0xffffd578

    0xffffd57c

    0xb

    0xa

    0xffffd588 0x8048412 0x8 0x0

    leave

    0x8048406

    0xffffd57c

    0xffffd57c

    0xb

    0xffffd588 0x8048412 0x8 0x0

    ret

    0x8048407

    0xffffd580

    0xffffd588

    0xb

    0x8048412 0x8 0x0

    Add $0x4,%esp

    0x8048412

    0xffffd584

    0xffffd588

    0xb

    0x8 0x0

    Mov $0x3,edx

    0x8048415

    0xffffd588

    0xffffd588

    0xb

    0x0

    Add %edx,%eax

    0x804841a

    0xffffd588

    0xffffd588

    0xb

    0x0

    leave

    0x804841c

    0xffffd588

    0xffffd588

    0xe

    0x0

    ret

    0x804841d

    0xffffd58c

    0x0

    0xe

     

    在这里我对实验楼中的课后练习题的代码进行了分析:

    int g(int x)
    {
      return x + 3;
    }
    
    int f(int x)
    {
      return g(x);
    }
    
    int main(void)
    {
      return f(8) + 1;
    }
    

    汇编代码及分析:

    g:
     pushl  %ebp         // 将%ebp入栈
     movl  %esp, %ebp    // esp指向ebp
    movl 8(%ebp), %eax //把保存在%ebp+8处的值x传送给%eax addl $3, %eax //执行语句x+3,将结果返回给%eax popl %ebp //弹出%ebp的值 ret f: pushl %ebp //将ebp入栈 movl %esp, %ebp //esp指向ebp subl $4, %esp //esp+4 movl 8(%ebp), %eax //将%ebp+8位置的值保存给%eax movl %eax, (%esp) //将eax的值给esp所值的位置 call g //调用g函数,将返回地址压入栈中,然后调到函数g的第一条指令 leave //为返回准备栈 ret main: //主函数 pushl %ebp //将ebp入栈 movl %esp, %ebp //esp指向ebp subl $4, %esp //esp+4 movl $8, (%esp) //将8给esp所指的地址 call f //调用f函数,将返回地址压入栈中,然后调到函数f的第一条指令 addl $1, %eax //执行表达式return f(8)+1,将%eax中的值加一再返回 leave ret

    代码调试中的问题

    使用gcc -g code.c -o code -m32命令时,如果系统提示以下错误:

    是因为虚拟机缺少了一个库,使用命令sudo apt-get install libc6-dev-i386进行安装就行了。

  • 相关阅读:
    php留言
    linux系统的初化始配置
    Alertmanager 配置解析
    Prometheus 配置解析
    Prometheus Consul 自动发现
    测试find 命令删除文件速度
    win10 安装wsl2 centos
    kubernetes api 的两种身份认证 以及kubectl生成kubeconfig
    Elasticsearch集群平滑下线data节点
    Fiddler Everywhere 安卓手机抓包配置
  • 原文地址:https://www.cnblogs.com/20145336yang/p/6132032.html
Copyright © 2020-2023  润新知