欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

【翻译】The Svin 的OpCode教程

【翻译】The Svin 的OpCode教程

说明:
    1. 这篇教程原文分为8帖,后继的会在不久的将来面世.
    2. 原帖并没有标题,标题是翻译的时候加上去的.
    3. 由于原作者是俄罗斯人,英语不是太好(有语法错误),有些语句我是根据自己的理解翻译过来的.
    4. 不知道有前辈翻译过这个没有?至少我在google上没有找到.
    5. 希望这个对你有用.
                            一 概览
    这本书为那些像本人一样渴求知识而不得的人而写.
    这套教程的风格是通过练习得出结论,而不是依据结论来做练习 .换句话说,这篇教程包含很多的例子和练习.深入学习本教程理论最好的方法是做所有的练习,以及试验所有的例子.
    这本教程并不讲汇编语言编程,我们讲的是"OpCode".
What "OpCode" is?
    这是课程要解决的主要问题,现在我给一个简短的回答.
    当我们在源代码中写入"lod**",在编译阶段汇编器(如 ml.exe)遇到"lod**",它会在可执行文件(或.obj文件)中用一个字节ACh来替代它.
    ACh就是所谓的OpCode,"lod**"则是助记符(mnemonic).
    助记符"lod**"对汇编器ml.exe说,"给我用字节ACh替换lod**".处理器并不知道lod**是什么.当寄存器EIP指向ACh字节时,处理器解码器对字节ACh解码,通过这个字节处理器就知道程序要将寄存器ESI指向的一个字节的内容送入AL寄存器.
    OpCode就是如此简单.
    你可能会说:一个助记符是某个特定的操作码的别称.
    但是,事实并没有如此简单.对于"lod**"这个特定的助记符来说,它确实对应ACh,并且操作码ACh也唯一确定助记符"lod**".然而并非所有的情形都是这样.我们很快会见到"为什么不"的例子.
    就像现实生活中一个名称往往并不唯一对应一个事物一样,OpCode和助记符的关系如下:不同的OpCode可能有同样的助记符;一个OpCode可能有几个助记符对应.有些事情可能很简单但却会吓倒初学者,在不久的将来我将会做详细的解释.
    查看OpCode或mnemonics的方法有很多种,我认为最快且最好的方法是使用调试器.我将在OllyDbg中试验所有的例子.
    Exersize1. 在调试器中输入助记符和OpCode
    1. 用OD打开任意一个Win32可执行文件,加载完成后在代码窗口中双击某一行,在弹出的指令输入对话框中输入lod**回车,你将看到(类似下面的内容):
       0040108C>  AC    LODS  [BYTE  DS:ESI]
       第一列(0040108c)是指令在内存中的地址,第二列(AC)是OpCode,第三列(LODS [BYTE DS:ESI])是OpCode AC的助记符.
    2. 你可以试着输入一些你其他的助记符,并观察他们的OpCode.
    3. 按CTRL + e,你将看到一个对话框,在HEX + 00 对应的文本框中输入 AC回车,可以看到第二列和第三列如下:
       AC    LODS  [BYTE  DS:ESI]
    4. 试着输入一些其他的OpCode,并观察对应的助记符.
    Exersize2. 一个助记符对应一个OpCode吗?
    1. 按CTRL+ e,输入OpCode 90,回车,可以看到OD将90认为是 NOP:
       0040108E  90    NOP
    2. 输入助记符 "NOP",同样看到:
       0040108E  90    NOP
    3. 输入助记符      XCHG  EAX, EAX
    糟糕! OllyDbg并没有插入我们的指令,而是用NOP代替!!!
    不用着急,这是OllyDbg的问题,当看到OpCode 90的时候它总是显示NOP,而不是 xchg eax,eax.对我们来说这两个助记符"xchg eax,eax"和"nop"都显示90h.
    由此可见,一个事物(OpCode)不只对应一个名字(助记符).
    我再重复一次:在计算机世界里有的只是OpCode,助记符只是这些OpCode的名字,这些助记符组成的系统就是汇编语言,助记符并不完美,因为没有完美的语言--任何语言的描述和现实总是有或多或少的区别的.
    在我们得出某些结论之前,我们先来做第二部分的练习.
    Exersize3.
    1. 输入助记符    add eax,1  ,你将看到
       0040108E  83C0 01      add  eax,1
    2. 输入OpCode   05 01000000  ,我们将惊奇的发现
       0040108E  05 01000000  add  eax,1
    同样的助记符但是不一样的OpCode!
    事实上它们不仅大小不同,结构也不一样.第一个(83C0 01)3字节长,包含3个域;第二个(05 01000000)5字节长,但只有两个域.
    在我们学习这些域之前,我们先来想一想:当你看着这两个OpCOde: 
    83C0 01
    05 01000000
    你是否想到:
    第一个OpCode中 01和第二个OpCode中 01000000 是加到 EAX 的立即数?
    既然助记符向OpCode可以有多种转换的方式,那么到底什么OpCode将会被插入exe文件中?这是由什么决定的呢?
    答案是:这是由汇编器决定的.
    当我们在数据段中写入一些值时,我们往往会使用:somevar  db  0AH,0DH;而在代码段中我们不需要输入名字而只需定义值:db  ACH.所以你可以用16进制写代码段,比如用
    Mov    esi,offset  somedata          Mov    esi,offset comedata
    Lod**                         代替   db    ACH
    好了,又到了我断开网络的时候了,我必须把我所写发送出去,否则我什么也不能提交.下次我们将从OpCode的结构开始,只是一个介绍而已,还涉及OpCOde的一些重要而一般的特性.你将发现这是多么的易学和实用.
原文链接

注意:上传附件及图片大小不得大于30M。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功