好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

汇编指令之opcode快速入门.pdf

6页
  • 卖家[上传人]:mg****85
  • 文档编号:45897851
  • 上传时间:2018-06-20
  • 文档格式:PDF
  • 文档大小:192.97KB
  • / 6 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 汇编指令之汇编指令之 OpCodeOpCodeOpCodeOpCode 快速入门快速入门: : : :最近一直被一些初学者问及有关于汇编指令的长度问题, 因此为此专门撰写本文, 以求为不 知 OpCode 为何物,或者正为汇编长短不一的指令而烦恼的朋友一个最为快速的指引 其实,OpCode 并不复杂,在本文中我不打算细致入微的告诉大家 OpCode 的原理,不会为 大家带来一大堆有关于什么是定长指令、 什么是变长指令的理论知识, 更不会带着各位读者 玩 OpCode Hacking,我只会告诉你“怎么了”、“为什么”以及“如何解决” 1 1、我的汇编指令怎么了?、我的汇编指令怎么了? 哦,天啊!怎么我今天突然发现汇编指令竟然是长短不一的!你还没发现吗?那么请过目:1E8 31880000 CALL 00430B862E9 17FEFFFF JMP 0042817138B4424 04 MOV EAX, DWORD PTR SS:[ESP+4]485C0 TEST EAX, EAX556 PUSH ESI68BF1 MOV ESI, ECX 我们可以看见“CALL 00430B86”这条汇编指令竟然占用了 5 个字节,而“PUSH ESI”则只占 用了 1 个字节, 汇编指令的脾气犹如一只滑头的猴子一样让你摸不到头脑, 它很明显的告诉 了你“嘿!兄弟,你别想搞懂我!”你也许会感到很郁闷,但是我并不这么想,因为如果我要 想自己搞一个反汇编引擎,或者是我要在我的壳里加上代码混淆功能……嗯,算了,就算是 我想娱乐一下搞搞免杀吧,那么我终归是要搞懂它的,为什么?因为如果搞懂它的话,那么 我就没办法做到这些! 很明显我们的汇编指令继承了 Intel 工程师的狡猾本质,为了尽可能的减少体积,所以它们 的体积被设计的不尽相同。

      哇哦! 很多读者此时似乎已经想明白是怎么回事了, 肯定是不同的指令对应的字节数不一样, 恩……这样只要我们搞到一张表就可以了! 不是吗?一张可以描述每个指令所用二进制码的 表格,然后我们就万事大吉了 但是很不幸,我在初次接触 OpCode 时也想出了这个“超级点子”,但是很可惜我的“超级点 子”与各位读者的一样,并没有为我解决任何问题,请过目:7B8 01000000 MOV EAX, 188BC3 MOV EAX, EBX98BC7 MOV EAX, EDI 看到了吗,一样的指令,一样的目的操作数,得到的确是完全不同的机器码……2 2、这是为什么?、这是为什么? 嗯,我想这个问题是很明显的,源操作数如果是一个寄存器的话,那么能有几种可能呢?按 照规则来讲貌似只有不超过 50 种可能,那么如果被操作数是一个数值呢?你想想,32 位能 表示多少数,将其乘以 2 就是最终的可能性了,这么多的可能性一定不是区区两个 16 位数 就能表示过来的 所以说我们的 OpCode 的长度不是一成不变是有道理的,那么既然如此,那么既然 CPU 可 以正确时识别它, 这里面肯定有什么方法是可以计算这些的, 没错! 这些确实是可以计算的, 而且正像我们上面所设想的那样,Intel 也确实为我们准备了表格,只不过不是一张,只不过有些复杂…… 首先,我们要现拥有这些,以下是我提供的一些连接,因为我们需要这些,请你下载他们:相 关 文 档相 关 文 档 .7z(3.14MB,下 载 次 数 :1307) ( 下 载 页 面 拥有了这些文档后,我们就可以开始“破译”它了,现在加入我们要“破译”的是“ADD EAX,1” 这条指令,请各位读者跟我一起做…… 我们先打开《处理器指令参考》手册(x86eas.hlp),找到汇编指令 ADD,我满看到了如下解 释: 注:前面的标号是笔者为了大家方便阅读而加上去的。

      Opcode Instruction Description 01 04 ib ADD AL,imm8 Add imm8 to AL 02 05 iw ADD AX,imm16 Add imm16 to AX 03 05 id ADD EAX,imm32 Add imm32 to EAX 04 80 /0 ib ADD r/m8,imm8 Add imm8 to r/m8 05 81 /0 iw ADD r/m16,imm16 Add imm16 to r/m16 06 81 /0 id ADD r/m32,imm32 Add imm32 to r/m32 07 83 /0 ib ADD r/m16,imm8 Add sign-extended imm8 to r/m16 08 83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32 09 00 /r ADD r/m8,r8 Add r8 to r/m8 10 01 /r ADD r/m16,r16 Add r16 to r/m16 11 01 /r ADD r/m32,r32 Add r32 to r/m32 12 02 /r ADD r8,r/m8 Add r/m8 to r8 13 03 /r ADD r16,r/m16 Add r/m16 to r16 14 03 /r ADD r32,r/m32 Add r/m32 to r32 解释: imm 是立即数的意思,而 imm8就是指8个比特大小的立即数,下面将一一对上面的简写作出 解释 imm:立即数,例如01、123、0FAB 等 r:寄存器,如 r16就代表 ax、cx 等,r32就代表 eax、ebx 等 m:内存地址,如[01]、[123]、[0FFFF]等 r/m:寄存器或内存 ib:代表 OpCode 后面跟着一个 byte 型数值 iw:代表 OpCode 后面跟着一个 word 型数值 id:代表 OpCode 后面跟着一个 dword 型数值 /0:代表此 OpCode 存在 ModR/M 结构(后面有讲) /r:代表此 OpCode 存在 ModR/M 结构(后面有讲)这是什么意思呢?我们以第一条信息为例,它的意思是,如果 OpCode 的表现形式为 04 后 面在跟一个字节, 那么它的指令格式 (Description) 必然是“ADDAL,8 位立即数”, 例如“ADD AL,11”。

      啊哈,那么问题到这就解决了,我们上面的“ADD EAX,1”符合第 8 行的“ADD r/m32,imm8”, 那么它的 OpCode 就应该是“83 01”了吧……结果估计大家已经猜到了“事情没那么简单”, 实际上我们的汇编指令“ADD EAX,1”所对应的 OpCode 是如下玩意:1083C0 01 ADD EAX, 1 我们可以看到它很神奇的多出来个“C0”不知道是干什么的,这让我们很郁闷!3 3、我们如何解决这个问题?、我们如何解决这个问题? 到这里,我们就要步入正轨了,通过这一节我们要搞明白那个“C0”究竟是怎么出来的 既然要步入正轨,我们就要了解一下 Intel 的指令结构(在 24319102.PDF 的第 31 页) ,具体 情况如下:Prefixes:前缀(最多 4 个前缀,每个 1 字节,并不是必需的) code:主操作码(1-3 字节不等) ModR/M:固定 1 字节大小,并不是必需的 SIB:固定 1 字节大小,并不是必需的 Displacement:偏移量(1、2、4 字节,并不是必需的) Immediate:立即数(1、2、4 字节,并不是必需的)由上可见,其实 Intel 指令格式中只有一个是必须存在的,就是“主操作码”,也就是我们在 上一节查到的那堆东西。

      不过其他结构索然是可有可无, 但是往往在某些时候它们当中的某 些结构是必须添加上去的,例如上个例子中的“ADD EAX,1”就是如此 在我们讲解 Prefixes 之前,首先请大家务必牢记一件事,就是 OpCode 的结构是绝对不能被 打乱的,例如 Prefixes 肯定是要在 code 前面,而 Immediate 肯定是在最后面 好了,记住上面的基本原则后,我就为大家简单讲解一下这个前缀(Prefixes)究竟做了些 什么,非要把指令结构搞得这么复杂,我在 24319102.PDF 的第 31 页下面找到了这些信息:—F0H—LOCK prefix. —F2H—REPNE/REPNZ prefix (used only with string instructions) —F3H—REP prefix (used only with string instructions). —F3H—REPE/REPZ prefix (used only with string instructions). —F3H—Streaming SIMD Extensions prefix.这都是什么意思呢?我们拿第一个来说,Intel 对它的解释是锁定前缀,首先各位的汇编语 言要过关,所谓的锁定就是将我们的指令变为原子指令,具体例子如下:11F0:8300 01 LOCK ADD DWORD PTR DS:[EAX], 1 ; 锁定前缀12F0:0FB10A LOCK CMPXCHG DWORD PTR DS:[EDX], ECX ; 锁定前缀 这两条指令前都多了个“LOCK”,但是请注意,这只是一个特例,并不是所有的前缀都会导 致汇编指令前非要加些什么,这点一定要注意。

      Intel 手册给了我们很多其他的前缀,功能也各不相同,本文中作者不可能对其一一进行解 释,因此深入的学习就要靠各位自己的努力了 而关于操作码,我们在上一节中已经讲了,这里不再多说,因此直接进入“ModR/M”与“SIB” 中 关于“ModR/M”,我认为它在汇编指令中应该是最难的了(虽然只是简单的查表,不过我说 的是编程实现) ,有关于 ModR/M 的表格在 Intel 指令手册 24319102.PDF 的第 36 页,读到这里的朋友不妨先去看看 看完后千万不要头大,我们那一条指令解释一下,就什么都清楚了,其实很简单的,我们仍 然拿“add EAX,1”为例吧 我在倒数第 8 行找到了目的操作数,Intel 在表中描述如下:EffectiveAddress Mod R/M EAX/AX/AL/MM0/XMM0 11 000但是我们的源操作数要怎么找呢?上面一行似乎并没有符合的, 这就要看我们此条汇编语句 在定义时指定了那里,还记得我们在上一节中查到的信息吗:83 /0 ib ADD r/m32,imm8 Add sign-extended imm8 to r/m32在上一节我仅告诉各位“/0”是代表此 OpCode 里存在 ModR/M 结构,但并没有多说什么,其 实这里的“/0”就是代表此表中竖排(列)中第一排,其内容如下: r8(/r) AL r16(/r) AX r32(/r) EAX mm(/r) MM0 xmm(/r) XMM0 /digit (Opcode) 0 REG = 000到这里, 其实我们的“ModR/M”已经出来了, 我们将其以“Mod”“R/M”“/digit”“REG”的方式组 合到一起后,正好组合为如下数值:/digit REG Mod R/M 0 000 11 000 = 000011000 = C0h其实在他们的交汇处我们可以看到 Intel 已经帮我们算好了,真实一张贴心的表呀。

      “ModR/M”解决了,还剩最后的“SIB”了,要想学习“SIB”,我们先要搞明白他什么时候会出 现,因此我找到了第 36 页下面的注释:NOTES: 1.The [--][--] nomenclature means a SIB follows the ModR/M byte. 2.……注释一的大致意思是“[--][--]”表示 ModR/M 后跟随有一个 SIB 字节,因此我们现在创造一 个带。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.