zoukankan      html  css  js  c++  java
  • x86指令格式

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

    格式


     x86指令格式

    • 指令前缀 

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

     

    • 操作码

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

    • ModR/M

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

    •  SIB

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

     

    • 位移

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

    • 立即数

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

     

    实例


     课后练习

     1 00F63689 : E8 C5F9FFFF
     2 00F6368E : 6A 58
     3 00F63690 : 68 A037F600
     4 00F63695 : E8 72040000
     5 00F6369A : 33DB
     6 00F6369C : 895D E4
     7 00F6369F : 895D FC
     8 00F636A2 : 8D45 98
     9 00F636A5 : 50
    10 00F636A6 : FF15 FC10F600
    11 00F636AC : C745 FC FEFFFFFF
    12 00F636B3 : C745 FC 01000000
    13 00F636BA : 64:A1 18000000
    14 00F636C0 : 8B70 04
    15 00F636C3 : BF 5CC2F600
    16 00F636C8 : 6A 00
    17 00F636CA : 56
    18 00F636C0 : 57

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

    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

    结果

     1 00F63689 : call 00F63053
     2 00F6368E : push 0x58
     3 00F63690 : push 00F637A0
     4 00F63695 : call 00F63B0C
     5 00F6369A : xor ebx,ebx
     6 00F6369C : mov dword ptr ss:[ebp-0x1C],ebx
     7 00F6369F : mov dword ptr ss:[ebp-0x04],ebx
     8 00F636A2 : lea eax, dword ptr ss:[ebp-0x68]
     9 00F636A5 : push eax
    10 00F636A6 : call 00F610FC
    11 00F636AC : mov dword ptr ss:[ebp-0x04], -0x02
    12 00F636B3 : mov dword ptr ss:[ebp-0x04], 00000001
    13 00F636BA : mov eax, fs:[0x18]
    14 00F636C0 : lea esi,dword ptr ss:[eax+0x04]
    15 00F636C3 : mov edi, 00F6C25C
    16 00F636C8 : push 00
    17 00F636CA : push esi
    18 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位大小的双字

  • 相关阅读:
    [ACM_模拟] ZJUT 1155 爱乐大街的门牌号 (规律 长为n的含k个逆序数的最小字典序)
    [ACM_搜索] ZOJ 1103 || POJ 2415 Hike on a Graph (带条件移动3盘子到同一位置的最少步数 广搜)
    [ACM_动态规划] POJ 1050 To the Max ( 动态规划 二维 最大连续和 最大子矩阵)
    [ACM_搜索] POJ 1096 Space Station Shielding (搜索 + 洪泛算法Flood_Fill)
    [JAVA] java_实例 获得系统字体
    [JAVA] java仿windows 字体设置选项卡
    [JAVA] 一个可以编辑、编译、运行Java简单文件的记事本java实现
    [ACM_模拟] POJ 1094 Sorting It All Out (拓扑排序+Floyd算法 判断关系是否矛盾或统一)
    JS的数组相关知识
    JS的join方法
  • 原文地址:https://www.cnblogs.com/QKSword/p/8735119.html
Copyright © 2011-2022 走看看