学习于逆向工程核心原理IA-32指令章节

格式


x86指令格式

  • 指令前缀 

出现特定操作码时用作补充说明,图中的冒号前的64就是指令前缀

  • 操作码

实际的指令,如图中的FF、89、80都是操作码

  • ModR/M

辅助说明操作码的操作数(操作数的个数、种类[寄存器、内存地址、常量]),图中的

  •  SIB

用来辅助说明ModR/M,辅助寻址,图中的两个24都是SIB。操作码的操作数为内存地址时,需要与ModR/M一起使用

  • 位移

操作码的操作数为内存地址时,用来表示位移操作,图中的D0A44500为位移,图中小端序排列

  • 立即数

操作码的操作数为常量时,该常量就被称为立即数,图中的02000000为立即数

实例


课后练习

 00F63689 : E8 C5F9FFFF
00F6368E : 6A
00F63690 : A037F600
00F63695 : E8
00F6369A : 33DB
00F6369C : 895D E4
00F6369F : 895D FC
00F636A2 : 8D45
00F636A5 :
00F636A6 : FF15 FC10F600
00F636AC : C745 FC FEFFFFFF
00F636B3 : C745 FC
00F636BA : :A1
00F636C0 : 8B70
00F636C3 : BF 5CC2F600
00F636C8 : 6A
00F636CA :
00F636C0 :

操作数类型的含义看附件处

E8 C5F9FFFF
E8 : near callf64 Jz
Jz操作数,看附件处可知是指相对偏移量,FFFFF9C5为call目的地址的偏移量(向上),所以偏移为-63B(FFFFF9C5是一个负数,以16进制的补码形式显示,00000000-FFFFF9C5=-63B),再加上指令的5个字节为-636,指令所在地址为00F63689,所以汇编代码为:call 00F63053

6A 58
6A : PUSHd64 Ib
Ib是一个字节的立即数,所以汇编代码为:push 0x58

68 A037F600
68 :PUSHd64 lz
lz是立即数(4个字节),所以汇编代码为:push 00F637A0

E8 72040000
E8 : near callf64 Jz
和上面一样,但是这里的偏移量是00000472(向下偏移),加上指令的5个字节为00000477,指令所在地址为00F63695,汇编代码为:call 00F63B0C

33DB
33 : XOR Gv,Ev
Gv表示寄存器,Ev为寄存器(DB在C0~FF之间)
DB为ModR/M
DB的二进制形式 = 11011011
拆分ModR/M = 11|011|011(Mod:11,Reg:011,R/M:011)
在ModR/M表里找到寄存器为ebx,ebx
所以汇编代码为:xor ebx,ebx

895D E4
89 : MOV Ev,Gv
Ev为内存地址(5D在00~BF之间),Gv表示寄存器
5D为ModR/M
二进制形式 = 01011101
拆分ModR/M = 01|011|101(Mod:01,Reg:011,R/M:101)
命令可得:MOV [EBP]+disp8, EBX
disp8指1个字节的偏移,E4可得-1c
所以汇编代码为:mov dword ptr ss:[ebp-0x1C],ebx
(ebp+或ebp-地址,一般指堆栈里,所以用dword ptr ss:[]这样的形式)

895D FC
89 :MOV Ev,Gv
同上,所以指令为:mov dword ptr ss:[ebp-0x04],ebx

8D45 98
8D :LEA Gv, M
Gv表示寄存器,M表示内存地址
ModR/M:45
二进制形式 = 01000101
拆分ModR/M = 01|000|101(Mod:01,Reg:000,R/M:101)
命令可得:LEA EAX, [EBP]+disp8
98的补码为-68(怎么看出补码,一个字节范围-128~127,如果是大于7F即127,就是补码)
所以指令为:lea eax, dword ptr ss:[ebp-0x68]

50
50 :pushd64 rAX/r8
就是push eax

FF15 FC10F600
FF :INC/DEC Grp5^1A
ModR/M:15
二进制形式 = 00010101
拆分ModR/M = 00|010|101(Mod:00,Reg:010,R/M:101)
所以Grp5为near callf64 Ev
Ev = [disp32],Ev为内存地址(15在00~BF之间)
指令为call 00F610FC(根据后面的group为主,前面的INC/DEC推测因为Reg不是000或001,所有没有用到)

C745 FC FEFFFFFF
C7 :Grp11^1A-MOV Ev, Iz
ModR/M:45
二进制形式 = 01000101
拆分ModR/M = 01|000|101(Mod:01,Reg:000,R/M:101)
Grp11为MOV Ev, Iz
Ev是内存地址(45在00~BF之间),Iz是立即数
根据Mod=01,R/M=101,指令化为:MOV [EBP]+disp8,Iz
最后FC(-0x04),FFFFFFFE(-0x02)
指令为:mov dword ptr ss:[ebp-0x04], -0x02

C745 FC 01000000
同上,指令为:mov dword ptr ss:[ebp-0x04], 00000001

64:A1 18000000
64为前缀,可知SEG=FS
A1 :MOV rAX, Ov
Ov存放fs:[]
所有指令为mov eax, fs:[0x18]

8B70 04
8D :LEA Gv,M
Gv表示寄存器,M表示内存地址
ModR/M:70
二进制形式 = 01110000
拆分ModR/M = 01|110|000(Mod:01,Reg:110,R/M:000)
LEA ESI,[EAX]+disp8
指令为:lea esi,dword ptr ss:[eax+0x04]

BF 5CC2F600
BF : MOV rDI/r15, Iv
rDI/r15是寄存器edi
Iv是一个立即数:00F6C25C
指令为:mov edi, 00F6C25C

6A 00
6A : PUSHd64 Ib
Ib是一个字节大小的立即数,所以
指令为:push 00

56
56 :push esi

57
57 :push edi

结果

 00F63689 : call 00F63053
00F6368E : push 0x58
00F63690 : push 00F637A0
00F63695 : call 00F63B0C
00F6369A : xor ebx,ebx
00F6369C : mov dword ptr ss:[ebp-0x1C],ebx
00F6369F : mov dword ptr ss:[ebp-0x04],ebx
00F636A2 : lea eax, dword ptr ss:[ebp-0x68]
00F636A5 : push eax
00F636A6 : call 00F610FC
00F636AC : mov dword ptr ss:[ebp-0x04], -0x02
00F636B3 : mov dword ptr ss:[ebp-0x04],
00F636BA : mov eax, fs:[0x18]
00F636C0 : lea esi,dword ptr ss:[eax+0x04]
00F636C3 : mov edi, 00F6C25C
00F636C8 : push
00F636CA : push esi
00F636C0 : push edi

附件


x86汇编格式Opcode:https://github.com/QKSword/Opcode-map

双字节操作码:https://pdos.csail.mit.edu/6.828/2007/readings/i386/appa.htm

操作数类型的含义 

常用寻址方法

E :内存地址(00~BF)或寄存器(C0~FF)
A ModR/M byte follows the opcode and specifies the operand. The operand is either a general-purpose register or a menory address
ModR/M字节在操作码后面并指定操作数。操作数是一个通用寄存器或一个内存地址

G :寄存器
The reg field of the ModR/M byte selects a general register(for example, AX(000))
ModR/M字节的寄存器字段选择通用寄存器(例如:AX(000))

I :立即数
Immediate data : the operand value is encoded in subsequent bytes of the instruction
立即数:操作数的值在指令的后续字节中编码

J :相对偏移
The instruction contains a relative offset to the instruction pointer register(for example, JMP(0E9), LOOP)
这个指令包括了指令指针寄存器的相对偏移量(例如:JMP(0E9),LOOP)

M :内存地址
The ModR/M byte may refer only to menory(for example, BOUND, LES, LDS, LSS, LFS, LGS, CMPXCHG8B)
ModR/M字节可能只涉及内存(例如:BOUND,LES,LDS,LSS,LFS,LGS,CMPXCHG8B)

X :内存地址
Memory addressed by the DS:rSI register pair(for example, MOVS, CMPS, OUTS, or LODS)
由DS:rSI寄存器对寻址的内存地址(例如:MOVS,CMPS,OUTS,LODS)

Y :内存地址
Memory addressed by the ES:rDI register pair(for example, MOVS,CMPS,INS,STOS,or SCAS)
由ES:rDI寄存器对寻址的内存地址(例如:MOVS,CMPS,INS,SIOS或SCAS)

操作数类型
b
Byte,regardless of operand-size attribute
字节,不管操作数大小属性如何

d
Doubleword, regardless of operand-size attribute
双字节,不管操作数大小属性如何

v
Word, doubleword or quadword(in 64-bit mode), depengding on operand-size attribute
字,双字或四字(64位模式),取决于操作数大小

z
Word for 16-bit operand-size or doubleword for 32 or 64-bit operand-size
16位操作数大小的字,32位或64位大小的双字

x86指令格式的更多相关文章

  1. x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式

    目录 x64汇编第二讲,复习x86汇编指令格式,学习x64指令格式 一丶x86指令复习. 1.1什么是x86指令. 1.2 x86与x64下的通用寄存器 1.3 OpCode 1.4 7种寻址方式 二 ...

  2. 【译】x86程序员手册06 - 2.4指令格式

    2.4 Instruction Format 指令格式 The information encoded in an 80386 instruction includes a specification ...

  3. ASM:《X86汇编语言-从实模式到保护模式》第14章:保护模式下的特权保护和任务概述

    ★PART1:32位保护模式下任务的隔离和特权级保护  这一章是全书的重点之一,这一张必须要理解特权级(包括CPL,RPL和DPL的含义)是什么,调用门的使用,还有LDT和TSS的工作原理(15章着重 ...

  4. 对X86汇编的理解与入门

    本文描述基本的32位X86汇编语言的一个子集,其中涉及汇编语言的最核心部分,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令.逻辑计算指令.算数运算指令),以及函数的调用规则.个人认为:在理 ...

  5. Intel汇编指令格式解析

    环境: win7_x64旗舰版.VS2015企业版 一.Intel保护模式.实地址模式和虚拟8086模式指令格式(x86) 图在Intel手册2.1章节 1.1)Instruction Prefixe ...

  6. Linux系统下x86和ARM的区别有哪些?

    问题: 最近在用三星的一款i5处理器的Windows平板,和iPad,以及其他使用ARM处理器的手机相比,发热量大很多,甚至需要借助风扇来散热,耗电量也大了不少. 那么就很奇怪,在主频相差不大,并且实 ...

  7. 寄存器理解 及 X86汇编入门

    本文整理自多材料源,感谢原址分享,请查看末尾Url I, 汇编语言分类: 汇编语言和CPU息息相关,但是不能把汇编语言完全等同于CPU的机器指令.不同架构的CPU指令并不相同,如x86,powerpc ...

  8. 恶意代码分析实战-x86反汇编速成班

    x86反汇编速成 x86体系结构 3种硬件构成: 中央处理器:负责执行代码 内存(RAM):负责存储所有的数据和代码 输入/输出系统(I/O):为硬盘.键盘.显示器等设备提供接口 内存 一个程序的内存 ...

  9. 3.4 复杂的x86指令举例

    计算机组成 3 指令系统体系结构 3.4 复杂的x86指令举例 x86作为复杂指令系统的代表,自然会有不少相当复杂的指令.在这一节我们将会看到其中有代表性的一些例子. 关于复杂的x86指令,我们这里举 ...

随机推荐

  1. Java知识回顾 (7) 继承、多态与接口、封装

    一.继承 1.1 继承的特性 子类拥有父类非 private 的属性.方法. 子类可以拥有自己的属性和方法,即子类可以对父类进行扩展. 子类可以用自己的方式实现父类的方法. Java 的继承是单继承, ...

  2. [转]通过设置nginx的client_max_body_size解决nginx+php上传大文件的问题

    转:http://blog.csdn.net/zhengwish/article/details/51602059 通过设置nginx的client_max_body_size解决nginx+php上 ...

  3. ceph:如何处理rados --striper上传失败的对象

    如何处理使用rados --striper上传失败的对象? `Remove striped objects from a ceph pool without using the striper lib ...

  4. 转 信号量与PV操作

    在计算机操作系统中,PV操作是进程管理中的难点.首先应弄清PV操作的含义:PV操作由P操作原语和V操作原语组成(原语是不可中断的过程),对信号量进行操作,具体定义如下:    P(S):①将信号量S的 ...

  5. java 根据身份证号码获取出生日期、性别、年龄

      1.情景展示 如何根据身份证号,计算出出生日期.性别.年龄? 2.解决方案 从网上找的别人的,因为并没有实际用到,所以并未对其优化! /** * 通过身份证号码获取出生日期.性别.年龄 * @pa ...

  6. [k8s] flexvolume workflow

  7. git 创建tag , 查看tag , 删除tag

    简介  用git了很久了,也喜欢这个版本控制工具,今天来分享下,怎么用命令创建tag,查看tag,删除tag和把本地tag推到远程git服务器上 C:\Users\\WandaPuHuiProject ...

  8. 一对一voip,直播连麦,在线会议,兼容webrtc,IM音视频

    功能 IM消息系统 一对一 高清音视频实时通信,可无缝切换P2P传输,节省服务器带宽 一对多互动直播 多对多在线会议 手机实时录屏传输 高度定制化 网络检测,动态码率与动态帧率,抗网络抖动,微信级效果 ...

  9. nohup.out文件过大解决方法 定时任务清空

    0.1和2分别表示标准输入.标准输出和标准错误信息输出,可以用来指定需要重定向的标准输入或输出. 在一般使用时,默认的是标准输出,既1.当我们需要特殊用途时,可以使用其他标号.例如,将某个程序的错误信 ...

  10. npm安装package.json中的模块依赖

    npm 一键安装 package.json里的依赖时有2种情况: 1.package.json不存在时 运行命令: npm init可自动创建package.json文件 2.package.json ...