2021-2022-1 20212824《Linux内核原理与分析》第二周作业

本文详细分析了一个32位x86汇编程序,涉及栈操作、函数调用及返回过程。通过实例解释了main、f和g三个函数的汇编代码,阐述了ESP和EBP寄存器的作用,以及栈的增长方向和call指令的工作原理。此外,还介绍了如何通过patch命令修补文件。
摘要由CSDN通过智能技术生成

前置知识

32位-x86 cpu的寄存器 在这里插入图片描述
简单的汇编指令解释
在这里插入图片描述
栈长这样 小数字是标号,大数字是地址
在这里插入图片描述

实验一 反汇编c程序

先写一个小文件用来试验

// main.c
int g(int x)
{
    return x + 2824;
}
    
int f(int x)
{
    return g(x);
}
    
int main(void)
{
    return f(66) + 2021;
}

然后把这个小程序汇编一下,命令如下
gcc –S –o main.s main.c -m32
在这里插入图片描述
然后加下来开始分析一下这个汇编后的文件
在这里插入图片描述

图是没有截全的,但是可以看见第五行有个g:,这就是对应原来.c中的g函数
且代码中有很多.开头的字符串,如.text.cfi_def_cfa啥的。这些.打头的字符串是链接阶段会用到的辅助信息

.打头的字符串有点多,可能会影响我们分析汇编代码,所以接下来可以把这些辅助信息都删除,精简一下。
删除代码如红框中所示g/\.s*/d
在这里插入图片描述
得到精简后的汇编文件
在这里插入图片描述
17行的main:和8行的f:代表.c文件中的俩函数(还有一个g函数,截图没截进来)

这个esp是栈顶指针寄存器,永远指向栈顶的

首先执行main函数

pushl	%ebp		1//将ESP寄存器指向堆栈中标号1的位置,然后讲EBP中的值放入标号1中(其实就是ebp入栈),与此同时EIP寄存器已经指向了下一行代码
movl 	%esp, %ebp	2//使EBP也指向标号1的位置,同时EIP寄存器指向下一行代码
sub 	$4, %esp	3//将ESP寄存器的值减4,其实就是把ESP向下移动一个标号,指向标号2,同时EIP指向下一行代码
movl	$66, (%esp)	4//把立即数66放入ESP指向的标号2的位置,同时EIP指向下一行代码
call 	f 			5//EIP自动+1指向下一行,eip入栈,调用f函数。eip的入栈是为了执行完f函数的时候能回到main函数
addl 	$2021,%eax	20//立即数2021放到eax里头
leave				21//栈回到初始状态
ret					22//pop EIP,所有东西都结束

f函数的分析

pushl	%ebp			6//把ESP的值向下移一位到标号4,然后把EBP的值标号1放到标号4的位置,
movl	%esp,%ebp		7//让EBP指向ESP的位置,即标号4
sub		4,%esp			8//ESP寄存器的值-4,即指向标号5
movl	8(%ebp),%eax	9//通过EBP变址寻址,EBP的值+8,指向标号2的位置,然后标号2存储的是立即数66.将66放入到EAX中
movl	%eax,(%esp)		10//把EAX中的值放到ESP所指向的位置,即标号5
call g					11//eip入栈,调用g函数,eip的入栈是为了执行完g函数之后,能够回到f函数
leave					18//这东西就相当于move %ebp,%esp;pop %ebp
ret						19//pop eip,返回到main函数

g函数(其实都大同小异)

pushl	%ebp			12//ebp入栈
movl	%esp,%ebp		13//让EBP和ESP指向当前栈顶
movl	8(%ebp),%eax	14//EBP指向的位置向上移两个
addl	$2824,%eax		15//把立即数2824加到EAX里头 2824+66=2890
popl	%ebp			16//把第12步中入栈的ebp ,pop掉
ret						17//返回到f函数

所有函数的头两条指令都用于初始化自己的调用堆栈空间

总结和问题

0.刚开始的时候理解不了esp指针的变动规则,后来发现这东西是栈顶指针,栈顶变它就变。
0.0 栈这个玩意儿是向下增长的,
1.每次执行call func指令的时候,都会把eip+1的值压到栈里,为了之后用
2.栈是向下长的
3.如果搞不清楚,就画一个栈自己整一下
4.这里有个动图,虽然里头的立即数和我的不一样,但是总体的执行过程是一样的
在这里插入图片描述

实验二 时间片轮转多道程序内核

patch 用于修补文件的命令

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值