1、OPCode
操作码(Operation Code,OPCode):描述机器语言指令中,指定要执行某种操作的机器码。
OPCode与指令的对应关系:
同类型的指令,OPCode不一定相同;
B8 01000000 mov eax,1
B8C7 mov eax,edi
OPCode相同,指令不一定相同;
90 nop
90 xchg ax,ax
主要数据域:6个
前缀(Prefixes):大小1Byte,描述指令的前缀情况,划分为5个集合,一个OPCode可能有几个Prefixes;
66 切换操作数大小
67 切换地址大小
F2/F3 重复操作前缀
2E/36/3E/26/64/65 修改默认段(段超越前缀)
F0 锁定前缀
代码(Code)
构造模式(MODR/M):主要解析逻辑集中在ModR/M域,通过查找Intel手册解析该域确定指令的具体格式;
分为三部分:模式(Mod)、寄存器(Reg)、寄存器(R/M)
SIB:辅助解析;
分为三部分:比例(Scale)、索引(Index0)、基数(Base)
位移(Displacement)
立即数(Immediate)
注:
a.以上数据域只有代码(Code)必须存在,指令长度在1~16字节之间;
b.我们查找的内容在Intel手册的“OPCode Map”中,也称为“操作码映射表”,作用是列出汇编指令与OPCode的对应关系;
2、手工在Intel手册中查找OPCode的汇编代码:
F0:26:C7 8491AA000000 11000000
F0 - Prefixes:锁定前缀,即 Lock
26 - Prefixes:修改默认段,即段超越前缀,查"Opcode Map"如图,段超越前缀为 ES
C7 - Code:查"Opcode Map"如图,可知:Grp 11 MOV Ev,Iz
84 - ModR/M:转为二进制 10 000 100
模式(Mod)段 :2位 10
寄存器(Reg)段 :3位 000
寄存器(R/M)段 :3位 100
查"ModR/M"表如图,得到 [..][..]+disp32
91 - SIB:转为二进制 10 010 001
比例(Scale)段 :2位 10
索引(Index)段 :3位 010
基数(Base)段 :3位 001
查"SIB"表如图,可知 [EDX*4]+ECX
AA000000 - Displacement:此为小端模式,即为 0xAA
11000000 - Immediate:小端模式,即为 0x11
综上,得到:
LOCK MOV ES:[EDX*4+ECX+0xAA],0x11
即为:
LOCK MOV DWORD PTR ES:[EDX*4+ECX+0x0AA],0x11
3、内联汇编
内联汇编可以有两种形式,一种是行内联汇编,一种是块内联汇编,二者可交叉使用;
行内联汇编:
__asm mov eax,a
__asm add eax,b
__asm mov c,eax
块内联汇编:
__asm{
mov eax,a
add eax,b
mov c,eax
}
4、裸函数
定义:没有任何可执行代码的空函数,在内存中仅仅是一条地址信息.
使用关键字“__declspec(naked)”定义;
例:
void __declspec(naked) TestFun( ){
__asm ret }