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 }