-
-
[原创]32位反汇编引擎开发笔记:Step.5_变长指令复习2 - 指令前缀
-
发表于: 2020-10-10 13:08 3490
-
Step.5_变长指令复习2 - 指令前缀
上一节中我们学习了变长指令
相关知识,对于指令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期)
赞赏
- 利用OLLVM编译windows驱动 30404
- [求助]SetWindowLong、SetWindowLongPtr无效问题 6915
- [求助]大佬们求一份21H2镜像,最好是VM镜像,原版也可以 6970
- [原创]X86内核笔记_6_APC相关 22425
- [原创]X86内核笔记_5_句柄 15487