常见寄存器以及常见汇编指令,常见爆破指令 good

CPU的任务就是执行存放在存储器里的指令序列。为此,除要完成算术逻辑操作外,还需要担负CPU和存储器以及I/O之间的数据传送任务。早期的CPU芯片只包括运算器和控制器两大部分。到了近几年,为了使存储器速度能更好地与运算器的速度相匹配,又在芯片中引入了高速缓冲存储器。

除了高速缓冲存储器之外的组成,大体上可以分为3个部分:
   1.算术逻辑部件ALU(arithmetic logic unit)用来进行算术和逻辑运算。这部分与我们的关系不太大,我们没必要管它。
   2.控制逻辑。同样与我们的关系不大。
   3.这个才是最最重要的。工作寄存器,它在计算机中起着重要的作用,每一个寄存器相当于运算器中的一个存储单元,但它的存取速度却贼快贼快,比存储器要快很多了。它用来存放计算过程中所需要的或所得到的各种信息,包括操作数地址、操作数及运算的中间结果等。下面我们专门的介绍这些寄存器。

大体上来说,你需要掌握的寄存器,有十六个,我一个一个给介绍给你:
      首先,介绍通用寄存器。
      一共八个,分别是EAX、EBX、ECX、EDX、ESP、EBP、EDI、ESI。
      其中,EAX—EDX这四个寄存器又可称为数据寄存器,你除了直接访问外,还可分别对其高十六位和低十六位(还计的我说它们是32位的吗?)进行访问。它们的低十六位就是把它们前边儿的E去掉,即EAX的低十六位就是AX。而且它们的低十六位又可以分别进行八位访问,也就是说,AX还可以再进行分解,即AX还可分为AH(高八位)AL(低八位)。其它三个寄存器请自行推断。这样的话,你就可以应付各种情况,如果你想操作的是一个八位数据,那么可以用
      MOV AL (八位数据)或MOV AH
      十六位数据,可以用MOV AX
      三十二位的话,就用MOV EAX
      ───────────────────────
      │ │ │ │
      │ │ │ │
      │ 高十六位 EAX AH AX AL │
      │ │ │ │
      │ │ │ │
      ───────────────────────
      这四个寄存器,主要就是用来暂时存放计算过程中所用的操作数、结果或其它信息。
      而ESP、EBP、EDI、ESI这四个呢,就只能用字来访问,它们的主要用途就是在存储器寻址时,提供偏移地址。因此,它们可以称为指针或变址寄存器。话说回来,从386以后,所有的寄存器都可以用来存储内存地址。(这里给你讲一个小知识,你在破解的时候是不是看到过[EBX]这样的形式呢?这就是说此时EBX中装的是一个内存地址,而真正要访问的,就是那那个内存单元中所存储的值)。

      在这几个寄存器中,ESP称为堆栈指针寄存。堆栈是一个很重要的概念,它是以“后进先出”方式工作的一个存储区,它必须存在于堆栈段中,因而其段地址存放于SS寄存器中。它只有一个出入口,所以只有一个堆栈指针寄存器。ESP的内容在任何时候都指向当前的栈顶。我这样说你可能会觉的还是不明白,那我举个例子吧,知道民工盖房吧,假设有两个民工,一个民工(以下简称民工A)要向地上铺砖,另一个民工(以下简称民工B)给民工A递砖,民工A趴在地上,手边是民工B从远处搬来的板砖,他拿起来就用,民工B从远处搬来后,就还放在那一堆砖上,这样,民工A拿着用后,民工B随既就又补了上去,这就是后进先出。你在脑子里想象一下这个这程。有没有想明白,民工A永远是从最上边开始拿砖。堆栈就是这样,它的基址开始于一个高地址,然后每当有数据入栈,它就向低地址的方向进行存储。相应的入栈指令是PUSH。每当有数据入栈,ESP就跟着改变,总之,它永远指向最后一个压入栈的数据。之后,如果要用压入堆栈的数据,就用出栈指令将其取出。相应的指令是POP,POP指令执行后,ESP会加上相应的数据位数。

      特别是现在到了Win32系统下面,堆栈的作用更是不可忽视,API所用的数据,均是靠堆栈来传送的,即先将要传送的数据压入堆栈,然后CALL至API函数,API函数会在函数体内用出栈指令将相应的数据出栈。然后进行操作。以后你就会知道这点的重要性了。许多明码比较的软件,一般都是在关键CALL前,将真假两个注册码压入栈。然后在CALL内出栈后进行比较。所以,只要找到个关键CALL,就能在压栈指令处,下d命令来查看真正的注册码。具体内容会在后面详细介绍,本章暂不予讨论。

      另外还有EBP,它称为基址指针寄存器,它们都可以与堆栈段寄存器SS联用来确定堆栈中的某一存储单元的地址,ESP用来指示段顶的偏移地址,而EBP可作为堆栈区中的一个基地址以便访问堆栈中的信息。ESI(源变址寄存器)和EDI(目的变址寄存器)一般与数据段寄存器DS联用,用来确定数据段中某一存储单元的地址。这两个变址寄存器有自动增量和自动减量的功能,可以很方便地用于变址。在串处理指令中,ESI和EDI作为隐含的源变址和目的变址寄存器时,ESI和DS联用,EDI和附加段ES联用,分别达到在数据段和附加段中寻址的目的。目前暂时不明白不要紧。

      接下来,接下来,介绍一下专用寄存器,呵呵,有没有被这个名字吓倒?看起来怪专业的。
      所谓的专用寄存器,有两个,一个是EIP,一个是FLAGS。
      我们先来说这个EIP,可以说,EIP算是所有寄存器中最重要的一个了。它的意思就是指令指针寄存器,它用来存放代码段中的偏移地址。在程序运行的过程中,它始终指向下一条指令的首地址。它与段寄存器CS联用确定下一条指令的物理地址。当这一地址送到存储器后,控制器可以取得下一条要执行的指令,而控制器一旦取得这条指令就马上修改EIP的内容,使它始终指向下一条指令的首地址。可见,计算机就是用EIP寄存器来控制指令序列的执行流程的。

      那些跳转指令,就是通过修改EIP的值来达到相应的目的的。
      再接着我们说一下这个FLAGS,标志寄存器,又称PSW(program status
      word),即程序状态寄存器。这一个是存放条件标志码、控制标志和系统标志的寄存器。
      其实我们根本不需要太多的去了解它,你目前只需知道它的工作原理就成了,我举个例子吧:
      Cmp EAX,EBX ;用EAX与EBX相减, NZ 00470395 ;不相等的话,就跳到这里;
      这两条指令很简单,就是用EAX寄存器装的数减去EBX寄存器中装的数。来比较这两个数是不是相等,
当Cmp指令执行过后,就会在FLAGS的ZF(zero flag)零标志位上置相应值,如果结果为0,也就是他们两个相等的话,ZF置1,否则置0。其它还有OF(溢出标志)SF(符号标志)CF(进位标志)AF(辅助进位标志)PF(奇偶标志)等。

      这些你目前没必要了解那么清楚,会用相应的转移指令就行了。
      最后要介绍的就是段寄存器了(刚才是谁说的樱红?反正不是我)
      这部分寄存器一共六个,分别是CS代码段,DS数据段,ES附加段,SS堆栈段,FS以及GS这两个还是附加段。
      其实现在到了Win32环境下,段寄存器以经不如DOS时代那样重要了。 所以,我们知道就行了。

 

你可以去参考一些书籍。我始终觉的,你案头有一本讲汇编的书是非常非常有必要的,我这边儿是清华版的《80x86汇编语言程序设计》沈美明主编,46元。  

      我们接下来就再讲一讲一些常用的汇编指令吧。(由于考虑到目前以经有了相应的帖子,所以,我只是从汇编指令中,挑出一些最常用,需要掌握的,更多内容,还请参见书本。)

      CMP A,B
      比较A与B其中A与B可以是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址。这个指令太长见了,许多明码比较的软件,就用这个指令。

      MOV A,B 把B的值送给A其中,A与B可是寄存器或内存地址,也可同时是两个寄存器,但不能同都是内存地址。
      Xor a,a异或操作,主要是用来将a清空
      LEA装入地址,例如LEA DX,string 将字符的地址装入DX寄存器
      PUSH 压栈
      POP 出栈
      ADD 加法指令 格式:ADD DST,SRC 执行的操作:(DST)<-(SRC)+(DST)
      SUB 减法指令 格式UB DST,SRC 执行的操作:(DST)<-(DST)-(SRC)
      MUL 无符号乘法指令 格式: MUL SRC
      执行的操作:字节操作(AX)<-(AL)*(SRC);字操作(DX,AX)<-(AX)*(SRC);双字操作:(EDX,EAX)<-(EAX)*(SRC)

      DIV 无符号除法指令 格式IV SRC
      执行的操作:字节操作:16们被除数在AX中,8位除数为源操作数,结果的8位商在AL中,8位余数在AH中。表示为:
      (AL)<-(AX)/(SRC)的商,(AH)<-(AX)/(SRC)的余数。字操作:32位被除数在DX,AX中。其中DX为高位字,16位除数为源操作数,结果的16位商在AX中,16位余数在DX中。表示为:(AX)<-(DX,AX)/(SRC)的商,(DX)<-(DX,AX)/(SRC)的余数。

      双字操作:64位的被除数在EDX,EAX中。其中EDX为高位双字;32位除数为源操作数,结果的32位商在EAX中,32位余数在EDX中。表示为:

      (EAX)<-(EDX,EAX)/(SRC)的商,(EDX)<-(EDX,EAX)/(SRC)的余数。
      NOP 无作用,可以用来抹去相应的语句,这样的话,嘿嘿嘿…
      CALL调用子程序,你可以把它当作高级语言中的过程来理解。
      控制转移指令:
      JE 或JZ 若相等则跳
      JNE或JNZ 若不相等则跳
      JMP 无条件跳
      JB 若小于则跳
      JA 若大于则跳
      JG 若大于则跳
      JGE 若大于等于则跳
      JL 若小于则跳
      JLE 若小于等于则跳

      Q:汇编对我来说不成问题,可我为什么总是不上手呢?
      A:呵呵,这样的老鸟倒还有不少,他们把汇编用的相当熟练,但是,只是因为经验的原因,所以才觉的不上手的,许多人当初不也都这样吗?最起码我就是,见了CALL就跟进,呵呵,倒跟了不少API,所以对于这部分,你只需多练练手以及掌握一些分析的技巧就成了。

      Q:寄存器可以随便用么,有没有什么限制?写个程序的时候那些变量什么的可以放在任意的寄存器么?
      A:呵呵,我现在就来回答楼上朋友的问题。
      寄存器有它的使用机制,及各个寄存器都有着明确的分工。
      如小翠儿
      如数据寄存器(EAX-EDX),它们都是通用寄存器,及在软件中,任何数据都可存放于此。但是除此之外,它们又可以都可以用于各自的专用目的。

      例如:
      EAX可以作为累加器来使用,所以它是算术运算的主要寄存器。在乘除法等指令中指定用来存放操
作数。比如在乘法中,你可以用AL或AX或EAX来装被乘数,而AX或DX:AX或EAX或EDX:EAX则用来装最后的积。

      EBX一般在计算存储器地址时,它经常用作基址寄存器。
      ECX则常用来保存计数值,如在移位指令它用来装位移量、循环和串处理指令中作隐含的计数器。
                 最后就剩下EDX了,一般在作双字长运算时把DX和AX组在一起存放一个双字长数(你还记的什么是双字长吧,举个例子,比如说有一个数二进制数据01101000110101000100100111010001,你要把它寄存起来,就可以把0110100011010100(即高十六位)放在DX中,把0100100111010001(即低十六位)放在AX中,这个数表示为DX:AX)当然完全可以用一个EDX就把这个数给装下。所以,还可以用EDX:EAX来装一个64位数据,这个你会推断出来吧。

      而ESP、EBP、EDI、ESI,我上边儿以经大概介绍的差不多了,所以这里不说它们了。
      当然还有其它的一些限制,因为我们只是要看程序的汇编代码(人家写好了的,肯定不会犯错误吧),而不是要去写,所以可以不必掌握。有性趣的话,去看相关书籍。

      另外再说一下你的最后一个问题“写个程序的时候那些变量什么的可以放在任意的寄存器么?
      ”这句话我不明白你要问的是什么。我想你可能是把一些关点给搞错了,变量这词通常都是出现在高级语言中的,而你用高级语言写程序的话,完全不用理解那些寄存器什么的,这些都跟高级语言没什么关系。但是最终,高级语言也还是把你写的程序转换为对寄存器、内部存储器的操作。

 

                 所谓的机器码。就是你看到的那些个十六进制数据了。它们与汇编指令是一一对应的。
      以下这几个是爆破时要用到的,其它的如果感兴趣,可自行查看相关资料:
      JZ=74;JNZ=75;JMP=EB;Nop=90

摘自《破解基础知识》PYG 5.4 Craker引导学习小组≯本电子书由[PYG]菜儿编辑制作 版权归原作者所有:2006-9-6 

 

你可能感兴趣的:(Go)