2017-2018-1 20179203《Linux内核原理与分析》第二周作业

攥写人:李鹏举 学号:20179203

原创作品转载请注明出处

( 学习课程:《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000 )

一、 Linux反汇编一个简单的C程序的技术准备

1.1 vim编辑器

 想要反汇编一个C程序首先就需要编写一个C语言的程序,确保其可以正确执行,然后再就行反汇编。而编写C语言程序最简单的方式就是通过vim编辑器进行文字编辑。对于我在实践当中感受到的vim中最重要的几个命令。第一个是当想加入任何内容的时候通过i字母可以将模式切换到插入模式下。此外虽然vim中有直接删除的命令,但是我还是建议在插入这种模式下进行全部的修改,毕竟在这种模式下的修改基本和我们常接触的编辑方式一样,比较方便。然后就是需要记住退出与保存的方式,首先要按按键,然后输入wq!代表保存修改并且强制退出,q!代表只退出不保存。初步的文本编辑基本掌握以上技巧就可以进行,随着学习的深入,我也会深入的讲述vim的其他各类技巧。
 备注: 命令行的左下角会提示当前vim编辑器的模式,如果处于某种模式下,例如插入等,则需要按ESC按键,退出这一模式再选择进入其他模式。.

1.2 C程序完整编译过程

 通过课上所学我们知道C语言程序的完整编译过程,本次实验的目的在于观察一个C语言在Linux中的汇编代码,分析其堆栈变化等,了解Linux中的编译全过程。因此首先我们要先知道完整的编译过程。首先我们通过gcc进行C语言的汇编,gcc的完整编译过程大致为:预处理->编译->汇编->链接。前三个步骤分别对应了-E、-S、-c三个选项。而本次实验主要用到的语句实验指导书中已经提供给了我们gcc –S –o main.s main.c -m32.

二、 实验具体步骤

2.1 实验代码

int g(int x)
{
  return x + 8;
}
 
int f(int x)
{
  return g(x);
}
 
int main(void)
{
  return f(12) + 2;
}

2.2 实验过程截图

1.建立文件并写入实验所用代码
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第1张图片
2.使用gcc -S -o lipengju.s lipengju.c -m32 将lipengju.c编译成汇编代码lipengju.s
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第2张图片
3.打开lipengju.s文件,会看到机器转换之后的汇编代码
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第3张图片
4.将以"."开头的行删去,得到纯净的汇编代码
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第4张图片
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第5张图片

2.3 实验结果分析:栈的变化

1.开始时eip指向18行,ebp esp都在堆栈0的位置
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第6张图片
2.执行eip处的指令,pushl %ebp,将ebp值压栈
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第7张图片
3.eip执行至19行,movl %esp,%ebp,将esp值赋给ebp
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第8张图片
4.eip执行至20行,subl $4,%esp,将esp向下移一格
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第9张图片
5.movl $24,(%esp),将24存入此时esp所指的位置
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第10张图片
6.call f,调用f函数,将eip 23压栈,此时eip指向f函数
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第11张图片
7.pushl %ebp,将此时ebp值压栈
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第12张图片
8.movl %esp,%ebp,将esp值赋给ebp
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第13张图片
9.subl $4,%esp,esp向下移一格

10.movl 8(%ebp),%eax,将ebp向上两格装的值赋给eax,所以此时eax=24

11.movl %eax,(%esp),将eax的值赋给esp此时指向的格
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第14张图片
12.call g,调用g函数,eip 15压栈,此时eip指向g函数
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第15张图片
13.pushl %ebp,将此时ebp值压栈

14.movl %esp,%ebp,将esp值赋给ebp
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第16张图片
15.movl 8(%ebp),%eax,将ebp上两格的装的值赋给eax,此时eax=33

16.addl $11,%eax,给eax加11,加上之后,eax=44

17.popl %ebp,弹栈,此时ebp赋值为栈中所存的ebp 4,esp缩进退一格
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第17张图片
18.ret,弹栈,此时eip赋值为栈中所存eip 15,esp缩进一格

19.leave(leave指令为如下步骤)

leave
movl %ebp,%esp
popl %ebp
所以此时堆栈指针会变为
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第18张图片
20.ret,弹栈,此时eip指向弹栈的eip 23

21.addl $1,%eax,将eax加1,此时eax为45

22.leave操作(先 movl %ebp,%esp,将ebp赋值给esp)
2017-2018-1 20179203《Linux内核原理与分析》第二周作业_第19张图片

此为C语言过程中所有的堆栈变化。.

三、实验体会:

 本次实验为Linux核心的学习打下了一个很好的基础。对于Linux内核分析的学习分析语言是最基础的,这样根据堆栈一步步的进行汇编语言的分析让我重新回忆起了汇编语言,相信这对于未来的学习非常的重要。而对应的内容在书本上也有很详细的介绍,对于程序的调试分析,是一个程序员的基础,由于对于Linux系统编程方面接触较少,很少有机会在这个环境下进行C的编程,就更不要说具体的调试工作了。学习Linux系统、分析其内核基础编程都是很重要的,本次实验分析中我暂时没有遇到问题,老师同学们如果看到我的分析中有错误欢迎指出,我好思考改正;或者在分析汇编过程中有哪里觉得不知道原因的,欢迎提出我们共同探讨。

你可能感兴趣的:(2017-2018-1 20179203《Linux内核原理与分析》第二周作业)