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

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进行安装就行了。

原文地址:https://www.cnblogs.com/20145336yang/p/6132032.html