Linux内核分析第一周课程小结

              Linux内核分析第一周课程小结

 

张家骥 + 原创作品转载请注明出处 Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

第一部分:课堂笔记

Linux内核采用AT&T汇编格式。

 

ABIApplication Binary Interface

 1.指令编码

 2.寄存器约定

 3.大多数指令可以直接访问内存

 

EIP自加一,加一指的是加一条指令的长度,指令可能是不定长指令。

 

CPU在实际去指令时根据CSeip来准确定位一个指令

 

RAX  R的指64位的寄存器,如:RIPRFLAGSRSIRBP

 

movl %eax%edx%开头的说明是寄存器表示符,movll指的是32位,movbmovwmovq分别指的是8位,16位和64位。

 

movl $0x123%edx$开头的说明是立即数。

 

Movl 0x123%edx 直接寻址,数字前没有$,表示直接访问这个内存地址

 

Movl (ebx)%edx 间接寻址,以ebx的内容作为内存地址

 

Movl  4(%ebx)%edx 变址寻址,先给ebx4,再以其内容为内存地址

 

Pushl  %eax 等价于  subl $4%esp  

Movl %eax,(%esp

 

Popl %eax 等价于  movl (%esp)%eax

addl     $4,%esp

 

Call   0x12345 相当于  pushl   %eip

Movl   $0x12345eip

Ret 相当于  popl    %eip

 

Leave 撤销函数堆栈

等价于   Movl  %ebp%esp

 Popl    %ebp

eip寄存器不能被直接修改,只能通过特殊指令间接修改。

 

函数的返回值默认使用eax存储返回给上一级函数。

 

最初eip指向main:。

 

第二部分:实验

反汇编一个简单的C程序

实验具体要求

1)实验部分(以下命令为实验楼64位Linux虚拟机环境下适用,32位Linux环境可能会稍有不同) 使用

gcc –S –o main.s main.c -m32

命令编译成汇编代码,如下代码中的数字请自行修改以防与他人雷同


我使用的具体代码为:

 

使用如下命令编译生成汇编代码:


在生成的main.s文件中,以点开头的都是用户链接时的辅助信息,不能被实际执行,删除以.开头的内容后,剩余部分如下:

************************************************************************************************************************************************************************

g:

pushl %ebp

movl %esp, %ebp

movl 8(%ebp), %eax

addl $7, %eax

popl %ebp

ret

f:

pushl %ebp

movl %esp, %ebp

subl $4, %esp

movl 8(%ebp), %eax

movl %eax, (%esp)

call g

leave

ret

main:

pushl %ebp

movl %esp, %ebp

subl $4, %esp

movl $7, (%esp)

call f

addl $7, %eax

leave

ret

************************************************************************************************************************************************************

 

一开始假设ebpesp都指向同一位置,用ebp1和esp1标注,接下来,ebpesp的变动过程通过它们数字角标的依次增大(esp2,esp3)来表示。

首先从main函数开始分析:

pushl %ebp  esp1->esp2, ebp1入栈

movl %esp, %ebp ebp1->ebp2

subl $4, %esp esp2->esp3

movl $7, (%esp) 立即数7入栈

call f esp3->esp4,eip入栈,eip被修改为f

 

pushl %ebp esp4->esp5,ebp2入栈

movl %esp, %ebp ebp2->ebp3

subl $4, %esp esp5->esp6

movl 8(%ebp), %eax eax=7

movl %eax, (%esp) eax的内容7入栈

call g esp6->esp7eip入栈,eip被修改为g

 

pushl %ebp esp7->esp8,ebp3入栈

movl %esp, %ebp ebp3->ebp4

movl 8(%ebp), %eax eax=7

addl $7, %eax eax=14

 

popl %ebp esp8->esp9,ebp4->ebp5

ret  esp9->esp10,eip出栈

leave esp10->esp11

esp11->esp12,ebp5->ebp6

ret esp12->esp13,eip出栈

addl $7, %eax eax=21

leave esp13->esp14

esp14->esp15,ebp6->ebp7

ret main函数退出,图中未画出。因为一开始假设了ebpesp指向同一位置,所以会出现esp跳到ebp之上的情况。更合理的假设应该是ebpesp之前的一个位置,它们之间隔了一个Old eip,这样ret执行后,eip被设置为了原来的内容。


 

 

第三部分:自己对“计算机是如何工作的”理解。

编写程序每一条高级语言都被编译成一条或多条机器指令,这些指令和程序所需要的数据都会在执行时,会被加载到内存中,CPU中的EIP寄存器总是指向下一条将要被执行的指令,当前要被执行的指令会被送入指令寄存器IR中,然后CPU通过硬件逻辑分析IR出中的这条指令的类型,操作码,操作数,执行这条指令,然后取下一条指令继续分析执行。如果程序中有函数调用之类非顺序执行的情况,会有相应指令将当前EIP的值压入栈中,然后修改EIP的值为需要跳转的指令的地址,然后继续从跳转处顺序执行,再函数返回时再从栈中取出EIP,继续执行。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值