首页
社区
课程
招聘
[原创]32位反汇编引擎开发笔记:Step.5_变长指令复习2 - 指令前缀
发表于: 2020-10-10 13:08 3490

[原创]32位反汇编引擎开发笔记:Step.5_变长指令复习2 - 指令前缀

2020-10-10 13:08
3490

Step.1_引擎大纲

Step.2_框架搭建

Step.3_经典定长指令的解析

Step.4_变长指令复习1

Step.5_变长指令复习2 - 指令前缀

Step.6_引擎核心->函数封装

上一节中我们学习了变长指令相关知识,对于指令6部分已经完成了大部分的解析,还剩余一部分 : 前缀

这节我们将通过学习什么是前缀,前缀在指令中起到了什么样的作用来完成变长指令的学习

什么是前缀?

前缀是用来描述一条指令的宽度、段寄存器等属性的一个字节数据.前缀既可以加在变长指令之前,也可以加在定长指令之前,每条指令可以有一个或多个前缀,多个前缀共同修饰一条指令

前缀在指令中起到了什么样的作用?

当一条指令中包含了前缀部分,那么这条指令的宽度、段寄存器等属性将会被指定,不再使用默认属性

简单描述完前缀的一些定义和作用,我们用几条汇编指令来体验一下前缀的作用

上面三条指令很好的向我们了证明了前缀的作用: 指定段寄存器、修改地址宽度、多前缀并用

接下来我们逐个分析一下前缀指令

指令前缀共有4种 , 分别为 : 操作数长度前缀, 地址长度前缀, 段超越前缀, 锁定前缀和重复前缀

我们都知道,对于32位系统而言,默认寄存器都是32位长度. 对于64位系统而言,默认寄存器都是64位长度

可是我们并没有听说Intel为16位操作系统单独推出一套方案来解决寄存器问题,所以Intel提供了操作数长度前缀来使32位汇编支持16位操作系统.

0x66就是操作数长度前缀,当一条指令前面加上66前缀,那么这条指令将会视为16位长度下的指令,我们举个例子说明下:

我们都知道在32位下 ,若想入栈可以用到其中一个指令 PUSH EAX, 这条指令是将32位的寄存器EAX压入栈中
可是在16位操作系统下我们想要压入的应该是AX而不是EAX,我们在OD里看一下是如何实现的

我们可以看到, PUSH AX相比于PUSH EAX仅仅多了一个前缀0x66, 这就是操作数长度前缀的具体应用,用于更改操作宽度,我们再来看一条指令A3 78563412 -> mov dword ptr ds:[0x12345678],eax
我们在前面添加一个66看下发生了什么变化:

可以看到,整行指令变成了16位的MOV赋值语句,以上就是0x66前缀的大致效果

地址长度前缀的用法与操作数长度前缀的用法是类似的

我们都知道在一条指令中,操作数与被操作数,最多只能有一个为内存,如果内存操作数长度为16位,则需要0x67前缀修饰

我们再举个例子来看一下:

8B10 -> mov edx,dword ptr ds:[eax]

这是一条我们熟悉的汇编语句,用于将eax地址中的值赋值给edx,宽度4字节

然后我们在前面加上67再观察语句变化

可以发现 EAX 被拆成了两个16位的寄存器 BX SI

段超越前缀共有六个,分别代表CS DS ES FS GS SS六个段寄存器,只要在指令前加上段超越前缀,那么当前指令的默认段寄存器将变为前缀对应的段寄存器(此处不做演示)

上文我们简单了解了前缀的作用,前缀的种类,可以发现前缀既可以加在定长指令前,也可以加在变长指令前,一条指令可以有多个前缀

那么为了我们后面变长指令解析的开发变得容易一些,我们需要对定长指令解析部分的代码进行扩展,使其能正确的对指令前缀进行解析,下一章我们将会扩展已有代码,完善定长指令的解析

 
 
 
 
 

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2020-10-13 17:43 被SSH山水画编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//