opcode原理

前缀域

  • 切换操作数大小前缀 : 066h

    • 可以将32位的操作数切换成16位的操作数

  1. B8 00010000 | MOV EAX,0x100    
    66:B8 0001 | MOV AX,0x100  

    8918       | MOV DWORD PTR DS:[EAX],EBX  
    66:8918     | MOV WORD PTR DS:[EAX],BX
  • 切换地址大小(切换寻址模式) : 067h

    • 用于将32位存储器的寻址方式切换成16位的寻址方式(16位的存储器寻址方式中,只能使用bx,si,di,bp寄存器作为内存地址) , 而32位汇编中,可以使用任意寄存器.

  1. 66:8918   | MOV WORD PTR DS:[EAX],BX  
    67:8918   | MOV DWORD PTR DS:[BX+SI],EBX
  • 重复操作前缀:0f2h,0f3h

  1. F2:A4     | REPNE MOVSB    
    F3:A4     | REP MOVSB    
    F2:45     | INC EBP   ; 没有起作用  
  • 修改默认段:

  1. 3E:8945 00| MOV DWORD PTR DS:[EBP],EAX;3E->ds
    26:8918   | MOV DWORD PTR ES:[EAX],EBX;26->es
    36:8918   | MOV DWORD PTR SS:[EAX],EBX;36->ss
    2E:8918   | MOV DWORD PTR CS:[EAX],EBX;2E->cs
    64:8918   | MOV DWORD PTR FS:[EAX],EBX;64->fs
    65:8918   | MOV DWORD PTR GS:[EAX],EBX;65->gs

机器码翻译成反汇编的方法

  1. 83C404A178812801A35481280168548128018B0D7481280151684881280168448128016840812801FF15A4922801
  1. 查表(intel提供的1字节指令映射表)

    1. 将第一个字节取出, 取查表(例如 83h)

    2. 以高4位作为y轴,以低4位作为x轴, 坐标相交之处,就是这个code域对应的指令了, 如果查找的是group,那么还需要进一步去查group表,(依然使用机器码去查)

      1. 接着需要用83h的下一个字节(C4)作为modR/M域再进一步确认使用group中的哪一个. 将c4展开为二进制11000100

    3. 无论是直接在1字节对照表中,还是在group表中, 得到的都是指令格式: ADD Ev,Ib

      格式解析:

      1. ADD - 指令的助记符

      2. Ev,Ib 说明指令有两个操作数

      3. E - 第一个操作数是寄存器或内存操作数

      4. v - 第一个操作数的大小和当前处理器模式一样(32位时,操作数大小就是32位的)

      5. I - 第二个操作数是一个立即数, 说明在指令的modR/M域后面还有一个Imm域, 保存着指令的立即数操作数(立即数域:04)

      6. b-立即数的大小是一个字节. 说明立即数域的长度是1字节

    4. 目前可以确认指令是: Add Ev,04

    5. Ev中使用的寄存器的名字, 由modR/M域来提供. 需要去查询modR/M

      1. modR/M表的组成:

        1. 表的左列, 是寄存器或内存操作, 在表的顶列,是纯寄存器操作数.

        2. 当操作数的类型是G的时候, 表示操作是纯寄存器. 应当到表的顶列去取出寄存器的名字.

        3. 当操作数的类型是E的时候, 表示操作数可能是寄存器,可能是存储器, 应当在表的左列取出操作数.

        4. 无论在那列, 都有很多寄存器, 此时需要使用操作数的大小来选择一款寄存器.

    6. 当前求出的指令就是: Add esp , 04;

  2. ModR/M域保存着指令的比较复杂的寻址方式。它携带着一下信息

    1. 操作数名称(寄存器、内存地址)

    2. 是否存在SIB域

    3. 是否存在相对偏移

      ModR/M域占一个字节,可以将这一个字节拆分成一下格式。

      89 D8 move eax,eb

      D8=11011000

      Mod Reg R/M

      11 011 000

  3. SIB域主要保存那些寄存器寻址的操作数中,带有乘法运算的部分。

    例如:mov eax,[ebx*4]

13字节汇编指令的赏析

LOCK MOV DWORD PTR ES:[EDX*4+ECX+0AA],11

F0:26:C7 87 91 AA000000 11000000

前缀 OPCODE MODR/M SIB DISPLACEMENT IMMEDIATE

F0:26 C7 84 91 AA000000 11000000

解析例子


  1. ;例子1

    83C404
    A178812801
    A354812801
    6854812801
    8B0D74812801
    51684881280168448128016840812801FF15A4922801

    code域: A1
    mov eax,Ov
    O - 存储器直接寻址方式,
    说明指令的下一个字节就是一个内存地址
    v - 操作数的大小就是`dword ptr`
    mov eax,dword ptr[0x01288178]

    code域: A3
    mov Ov,eax
    mov dword ptr[0x1288154],eax

    6854812801
    code域: 68
    push Iz
    I - 立即数
    z -
    push 1288154



    8B0D74812801
    code域: 8B
    Mov Gv,Ev
    ModR/M域: 0D
    Gv : 在表的顶部: ecx
    Ev : 在表的左边: disp32 - 偏移域
    偏移域 : 74812801=>0x01288174
    mov ecx,[0x1288174]


    ; 例子2

    C7048100100000
    C784810010000000100000
    898C8100100000

    code: C7 => mov Ev,Iz
    modR/M: 04
    Ev => [--][--]
    SIB : 81 左边找到的寄存器 + 顶上找到的寄存器
      然后将找到寄存器作为存储器寻址方式写上
    eax*4+ecx
    mov [eax*4+ecx] ,01000h

    code: C7 => mov Ev,Iz
    modR/M: 84
    Ev => [--][--]+disp32
    SIB : 81 => eax*4+ecx
    disp32 : 00100000 => 1000h
    [--][--]+disp32 => [ eax*4+ecx+01000h]
    Iz : 00100000
    最终的指令: mov [eax*4+ecx+01000h],01000h
  2.  
  3. code : 89 => Mov Ev,Gv
    modR/M: 8C =>
    Ev => [--][--]+disp32
    Gv => ecx
    SIB : 81 => eax*4+ecx
    disp32 => 00100000
    最终的指令 :Mov [eax*4+ecx+01000h],ecx


    ; 例子3

    E912563545
    E865123314
    FF2556781234

    code:E9 => jmp Jz
    J => 操作是一个偏移值(立即数)
    z => 32
    最终的指令:
    jmp eip+45355612+5(指令自身长度)

    code : E8 => call jz
    最终的指令:
    call eip+14331265+5

    code FF:
    modR/M 25 -> 00100101 => jmp Ev
    Ev => disp32
    disp32 => 56781234 => 034127856h
    最终的指令
    jmp [034127856h]

汇编4OPCODE的更多相关文章

  1. u-boot源码汇编段简要分析

    Hi,大家好!我是CrazyCatJack,你们可以叫我CCJ或者疯猫.今天我给大家带来的是u-boot的源代码汇编段分析,以后还会给大家讲解后续的C代码,请持续关注哦^_^ 先简单说一下u-boot ...

  2. GCC 预处理、编译、汇编、链接..

    1简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objective ...

  3. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

  4. Beennan的内嵌汇编指导(译)Brennan's Guide to Inline Assembly

    注:写在前面,这是一篇翻译文章,本人的英文水平很有限,但内嵌汇编是学习操作系统不可少的知识,本人也常去查看这方面的内容,本文是在做mit的jos实验中的一篇关于内嵌汇编的介绍.关于常用的内嵌汇编(AT ...

  5. 从linux0.11中起动部分代码看汇编调用c语言函数

    上一篇分析了c语言的函数调用栈情况,知道了c语言的函数调用机制后,我们来看一下,linux0.11中起动部分的代码是如何从汇编跳入c语言函数的.在LINUX 0.11中的head.s文件中会看到如下一 ...

  6. C内嵌汇编-格式

    C内嵌汇编-格式: __asm__(汇编语句部分:输出部分:输入部分破坏描述部分);C内嵌汇编以关键字"__asm__"或"asm"开始, 下辖四个部分, 各部 ...

  7. 20145212——GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 测试代码 #include <stdio.h> short val = 1; int vv = 2; int g(int xxx) { return xxx + ...

  8. C程序汇编运行模式简析

    SJTUBEAR 原创作品转载请注明出处 /<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 1. 汇编 ...

  9. 生成ARM汇编

    使用ndk即可生成arm汇编 1.首先写好hello.c 2.编写makefile #ndk根目录 NDK_ROOT=E:\Android\android-ndk-r10b #编译器根目录 TOOLC ...

随机推荐

  1. BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS

    BZOJ_3073_[Pa2011]Journeys_线段树优化建图+BFS Description Seter建造了一个很大的星球,他准备建造N个国家和无数双向道路.N个国家很快建造好了,用1..N ...

  2. Oracle 安装报错 [INS-06101] IP address of localhost could not be determined 解决方法输入日志标题

    安装Oracle 11gR2,报错:[INS-06101] IP address of localhost could not be determined 出现这种错误是因为主机名和/etc/host ...

  3. HTTP node静态资源请求加载demo

    MIME type的缩写为(Multipurpose Internet Mail Extensions)代表互联网媒体类型(Internet media type),MIME使用一个简单的字符串组成, ...

  4. spring+mybatis下delete和insert返回值-2147482646

    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"&g ...

  5. Collection View Programming Guide for iOS---(五)---Incorporating Gesture Support

      Incorporating Gesture Support 结合手势支持 You can add greater interactivity to your collection views th ...

  6. Java 在线反编译

    使用jd-gui反编译java提示 // INTERNAL ERROR // 的类,用在线反编译直接反编译.class http://www.showmycode.com/

  7. bzoj 2331: [SCOI2011]地板【插头dp】

    一开始设计了四种状态,多了一种已经拐弯但是长度为0的情况,后来发现不用,设012表示没插头,没拐弯的插头,拐了弯的插头,然后转移的话12,21,22都不合法,剩下的转移脑补一下即可,ans只能在11, ...

  8. Codeforces Round #408 (Div. 2) D

    Description Inzane finally found Zane with a lot of money to spare, so they together decided to esta ...

  9. Throwing Dice LightOJ - 1064 || (勉强能用的)分数类

    Throwing Dice LightOJ - 1064 方法: 设ans[i][j]表示i个骰子点数恰好为j的概率.那么ans[1][1]到ans[1][6]都为1/6. 显然,$ans[i][j] ...

  10. adb logcat教程

    1.速查 $adb logcat -g //打印和缓冲区使用情况 $adb logcat -c main //清除main缓存区 $adb logcat -v threadtime -f /data/ ...