﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-飞的更高-文章分类-asm</title><link>http://www.cnitblog.com/kaihuayu/category/7975.html</link><description /><language>zh-cn</language><lastBuildDate>Thu, 06 Oct 2011 08:09:30 GMT</lastBuildDate><pubDate>Thu, 06 Oct 2011 08:09:30 GMT</pubDate><ttl>60</ttl><item><title>浓缩汇编基础</title><link>http://www.cnitblog.com/kaihuayu/articles/53403.html</link><dc:creator>开花的树</dc:creator><author>开花的树</author><pubDate>Sat, 03 Jan 2009 13:52:00 GMT</pubDate><guid>http://www.cnitblog.com/kaihuayu/articles/53403.html</guid><wfw:comment>http://www.cnitblog.com/kaihuayu/comments/53403.html</wfw:comment><comments>http://www.cnitblog.com/kaihuayu/articles/53403.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/kaihuayu/comments/commentRss/53403.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/kaihuayu/services/trackbacks/53403.html</trackback:ping><description><![CDATA[<p>1.0 关于汇编语言<br>&nbsp;&nbsp; 汇编语言是创造出来代替原始的只能由处理器理解的二进制代码的,也就是在OD中常见的机器码!用机器码来写程序,可以想象其难度吧,所以汇编语言就出现了,汇编代码是直接描述处理器可以执行的代码,也就是在OD中最常见的反汇编代码了!(当然,有点不一样),而汇编语言是和cpu相关的,和机器语言是一一对应的!</p>
<p>2.0 关于cpu<br>&nbsp;&nbsp; CPU的任务就是执行存放在存储器里的指令序列。为此，除要完成算术逻辑操作外，还需要担负CPU和存储器以及I/O之间的数据传送任务。早期的CPU芯片只包括运算器和控制器两大部分。到了近几年，为了使存储器速度能更好地与运算器的速度相匹配，又在芯片中引入了高速缓冲存储器（知道为什么P4比P4赛扬贵那么多了吧?）。<br>&nbsp;&nbsp; 看主要的部件:<br>&nbsp;&nbsp; 1.算术逻辑部件ALU（arithmetic logic unit）用来进行算术和逻辑运算。这部分与我们的关系不太大，我们没必要管它。 <br>&nbsp;&nbsp; 2.控制逻辑。同样与我们的关系不大。 <br>&nbsp;&nbsp; 3.工作寄存器。意识了吧,寄存器呀!喂,,寄存器呀!~</p>
<p>3.0 寄存器<br>&nbsp;&nbsp; 所要了解的是8个32位的寄存器,分别是eax,ebx,ecx,edx,esp,ebp,edi,esi<br>&nbsp;&nbsp; eax-edx这四个是通用寄存器,虽然各个都有各自的用途,不过你可以用它们来做任何事!是32位的,自然有低位和高位,我们又可以通过ax,bx,cx,dx来访问其低十六位,但高十六位是无法访问的!比如eax=12345678h,那么低十六位ax=5678h!而十六位的自然也有低位和高位,不过高八位是可以访问的,如ax可以分为ah和al,看字面就知道,ah(high)高八位,al就为低八位了!前面的例子,ax=5678h,那么ah=56h,al=78h!这四个寄存器主要是用来暂放计算结果或什么什么的!<br>&nbsp;&nbsp; esp-esi这四个主要是寻址时用来存放偏移或指针,所以,也就称为指针寄存器或变址寄存器了~如在OD中看到的[eax],其实eax中存放的是一个内存地址,而实际要访问的是那个内存地址里的内容!<br>&nbsp;&nbsp; esp(堆栈指针寄存器):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 很重要的一个概论,堆栈有着先进后出的特点，就好像有一个圆柱形的筒子,该直径刚好是一个乒乓球的直径,所以最先放进去的球当然会最后出来.而esp呢,永远是指着最顶的那个球的,也就是永远都指向栈顶!在od中也很常见了,比如push和pop就是对栈的操作,push把一个数据压入栈中,也就是把一个球放进去,再去调用push时就再放进一个,而esp则指向第二个放进去的那个球了!使用pop呢就从栈中弹出一个数据,前面说了,堆栈有着先进后出的特点,所以用pop呢就从最后放进去的那个球先出了(除非你破坏筒子(破坏堆栈?那是不可能的,程序马上死给你看))!而esp还是指向栈顶!<br>&nbsp;&nbsp; 取个代码例子:<br>&nbsp;&nbsp; (1) mov ecx, 100&lt;---------100传入ecx<br>&nbsp;&nbsp; (2) mov eax, 200&lt;---------200传入eax<br>&nbsp;&nbsp; (3) push ecx &lt;------------ecx先进了<br>&nbsp;&nbsp; (4) push eax&lt;-------------再来是eax<br>&nbsp;&nbsp; (5) pop ebx&lt;--------------从栈顶取出一个,也是最后进去的那一个,结果存到ebx<br>&nbsp;&nbsp; (6) pop ecx&lt;--------------从栈顶取出一个,也就是刚刚先进去的那个了,结果存到ecx<br>最后ebx=200,ecx=100<br>&nbsp;&nbsp; 到了win32的平台下,api大家都知道了吧!api的参数都是靠堆栈来传递的,比如说一个FindWindow,在C里我这样调用<br>-&gt;::FindWindow(NULL,"a")-&gt;而反汇编之后在系统底层反汇编代码就象这个样子:<br>&nbsp;&nbsp; push xxxxxxxx-&gt;xxxxxxxx为"a"的内存地址<br>&nbsp;&nbsp; push yyyyyyyy-&gt;yyyyyyyy为空中止字符串的指针<br>&nbsp;&nbsp; call zzzzzzzz-&gt;调用FindWindow<br>&nbsp;&nbsp; 而在call里面先使用pop弹出先前压入栈的参数再使用</p>
<p>&nbsp;&nbsp; ebp(基址指针寄存器):<br>&nbsp;&nbsp; 它称为基址指针寄存器，它们都可以与堆栈段寄存器SS(堆栈段)联用来确定堆栈中的某一存储单元的地址，ESP用来指示段顶的偏移地址，而EBP可作为堆栈区中的一个基地址以便访问堆栈中的信息。</p>
<p>&nbsp;&nbsp; ESI（源变址寄存器）和EDI（目的变址寄存器）一般与数据段寄存器DS联用，用来确定数据段中某一存储单元的地址。这两个变址寄存器有自动增量和自动减量的功能，可以很方便地用于变址。</p>
<p>&nbsp;&nbsp; 还有两个专用寄存器,分别是eip和flags<br>&nbsp;&nbsp; flags:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个是标志寄存器了,存放条件标志码、控制标志和系统标志的寄存器!在od中也见很多了,比如zf(零标志),用cmp比较时,把两个操作数相减,为0就置zf为1,否则zf为0。而jnz就是看zf是否为0,为0就跳!这样说起来似乎更乱了,建议大家去记那些大于就跳,小于就跳的,比较简单(jnz就是不相等就跳)``哦呵呵!!至于其它标志,这里不再阐述了,可以去参看汇编速查!<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cmp eax,ebx&lt;-比较eax和ebx,两个相减,为0的话zf就为一,否则zf为0<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jnz xxxxxxx&lt;-判断zf是否为0,为0就跳到xxxxxxx处,也就是所谓的不相等就跳</p>
<p>&nbsp;&nbsp; eip(指令指针寄存器):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个很好理解,根据od来说,载入一个程序后,比如代码像这样:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0043C412 &gt;/$&nbsp;&nbsp; 55&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp; ebp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;-载入后停在这,看寄存器窗口eip这时为43c412<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0043C413&nbsp;&nbsp; |.&nbsp;&nbsp; 8BEC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp, esp&nbsp;&nbsp;&nbsp;&nbsp; &lt;-f8运行一步之后,eip为43c413<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0043C415&nbsp;&nbsp; |.&nbsp;&nbsp; 6A FF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp; -1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;-eip为43c415<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0043C417&nbsp;&nbsp; |.&nbsp;&nbsp; 68 C8B64800&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp; 0048B6C8&nbsp;&nbsp;&nbsp;&nbsp; &lt;-eip为43c417<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有人会说"原来eip是指示当前执行到代码处的地址的!"&nbsp;&nbsp; ,这不对!!因为f8运行还没通过那条代码,所以还不算已经执行了,没错,eip指向的就是下一条将要执行的指令的指针!<br>段寄存器:<br>&nbsp;&nbsp;&nbsp;&nbsp; cs代码段,ds数据段,ss堆栈段,es附加段<br>&nbsp;&nbsp;&nbsp;&nbsp; 在Win32编程中段的概念已经不重要了!而在Crack时你总不会是在调是dos时代的程序吧!-!</p>
<p>4.0 常用汇编指令<br>&nbsp;&nbsp; mov ax,cx&nbsp;&nbsp; &lt;-很常用了,把cx的值送入ax中,cx值保持不变<br>&nbsp;&nbsp; cmp eax,ecx&lt;-很常见了吧,比较eax和ecx,置标志位!方法前面说过了<br>&nbsp;&nbsp; xor eax,eax&lt;-看这个,eax与自己异或,是清零的操作!<br>&nbsp;&nbsp; lea eax,str&lt;-并不传送数据,只传送该数据的地址,将str字符串的地址传到eax<br>&nbsp;&nbsp; push eax&nbsp;&nbsp;&nbsp; &lt;-进栈操作,前面说过了,eax进栈<br>&nbsp;&nbsp; pop&nbsp;&nbsp; ebx&nbsp;&nbsp;&nbsp; &lt;-出栈操作,前面也说了,弹出位于栈顶的数据存入ebx<br>&nbsp;&nbsp; ADD 加法指令 格式:ADD DST，SRC 执行的操作：(DST)&lt;-(SRC)+(DST) <br>&nbsp;&nbsp; SUB 减法指令 格式:SUB DST，SRC 执行的操作：(DST)&lt;-(DST)-(SRC) <br>&nbsp;&nbsp; MUL 无符号乘法指令 格式: MUL SRC&nbsp;&nbsp; 执行的操作：字节操作(AX)&lt;-(AL)*(SRC)；字操作(DX,AX)&lt;-(AX)*(SRC)；双字操作：(EDX,EAX)&lt;-&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (EAX)*(SRC) <br>&nbsp;&nbsp; DIV 无符号除法指令 格式:DIV SRC&nbsp;&nbsp; 执行的操作:字节操作：16们被除数在AX中，8位除数为源操作数，结果的8位商在AL中，8位余数在AH中&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 。表示为： <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (AL)&lt;-(AX)/(SRC)的商，(AH)&lt;-(AX)/(SRC)的余数。字操作:32位被除数在DX,AX中。其中DX为高位字，16位除数为源操作数，结果的16位商在AX中，16位余数在DX中。表示为：(AX)&lt;-(DX,AX)/(SRC)的商，(DX)&lt;-(DX,AX)/(SRC)的余数。<br>&nbsp;&nbsp; nop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;-&nbsp;&nbsp; 无操作,去掉指令用的吧!去掉一个跳转,让程序直接往下走,就到注册成功处啦(扯远了````)<br>&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;- 调用子程序或函数用的</p>
<p>&nbsp;&nbsp; 关于跳转指令，可以查看汇编速查手册,别强迫自己把所有的都一下记住,浪费精力,不懂时再查一下，久了就记住了!<br>&nbsp;&nbsp; <br>5.0 高级语言程序的汇编浅解析<br>&nbsp;&nbsp; 汇编语言要和硬件直接打交道,写病毒是方便点啦!!而在高级语言中,如C中我们要面向的是问题的解决,对于硬件资源操作,编译器搞定了!在这里稍微讲一下高级语言中与反汇编代码相应的一些地方:<br>&nbsp;&nbsp; 1、定义变量<br>&nbsp;&nbsp;&nbsp;&nbsp; int a;<br>&nbsp;&nbsp;&nbsp;&nbsp; 一个变量其实是存放在一个内存地址里,如果对a进行赋值"a=10",在反汇编中就有可能表现为:<br>&nbsp;&nbsp;&nbsp;&nbsp; mov word ptr[007e58c2],A<br>&nbsp;&nbsp;&nbsp;&nbsp; 像这个样子,而a所对应的内存地址就是0x007e58c2了,当然是乱写的一个地址而已,系统怎样分配?(天知道...)</p>
<p>2、比如一个数组<br>&nbsp;&nbsp;&nbsp;&nbsp; char str[]="hello";<br>&nbsp;&nbsp;&nbsp;&nbsp; 占用了6个字节,最后一个是以0结尾的空字节,数组名可以当做数组的指针!str[0]='h',str[0]相应一个变量地址,比如为[0040e123],那么[0040e124]就为'e',[0040e125]就为'l'....了`</p>
<p>3、指针<br>&nbsp;&nbsp;&nbsp; char *p;<br>&nbsp;&nbsp;&nbsp; 指针也是一个变量,所以它也对应一个内存地址!但访问时应该是访问其指向的内存地址的内容,而不是这个指针变量的内容,其内容只是一个地址而已!假如该指针变量地址为007e1000,那么语句p=a,这句在高级语言里是让指针p指向a这个内存单元!p里的内容是a的地址,*p实际上是a的内容了!而反汇编有可能表现成这样:<br>&nbsp;&nbsp; mov [007e1000],007e2000&lt;-假如007e2000为变量a的地址,那么就是把a的地址传到007e1000这个内容里了!</p>
<p>4、函数调用<br>&nbsp;&nbsp; sub(a,b);<br>&nbsp;&nbsp; 假如sub是自定义的一个减法函数,作用为参数一减去参数二,上面语句为在C中调中时传递参数!前面有说过了,Win32平台下函数调用的参数是通过堆栈来传递的,那么反汇编就是:<br>&nbsp;&nbsp; (假如a=2,b=1)<br>&nbsp;&nbsp; mov eax,2<br>&nbsp;&nbsp; mov ebx,1<br>&nbsp;&nbsp; push eax<br>&nbsp;&nbsp; push ebx<br>&nbsp;&nbsp; call 取地址(sub)<br>&nbsp;&nbsp; .......</p>
<img src ="http://www.cnitblog.com/kaihuayu/aggbug/53403.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/kaihuayu/" target="_blank">开花的树</a> 2009-01-03 21:52 <a href="http://www.cnitblog.com/kaihuayu/articles/53403.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>