首页
论坛
专栏
课程

[翻译]使用OllyDbg从零开始Cracking 第四章-汇编指令

2014-2-14 21:39 29545

[翻译]使用OllyDbg从零开始Cracking 第四章-汇编指令

2014-2-14 21:39
29545
今年过年在家里休假的时候,无意中看到一篇帖子【使用OllyDbg从零开始Cracking 传说有40多章,为什么没有了?】,里面提到了俄罗斯人写的一系列OD破解的教程。然后我在坛子里面搜了一下这篇教程,发现有个叫BGCoder的大哥翻译了前3章,后面的章节没有继续翻译了,很遗憾。仔细阅读了一下,教程写的非常好。这么好的教程不翻译完可惜了,我本想根据BGCoder提供的链接下载剩余的教程,我擦,发现几年过去了,链接已经失效了。郁闷,可是我还是不死心,将教程的俄文名称在谷歌中搜索了一下,发现有个老毛子的论坛有这篇文章,然后我就进入论坛,但是只发现一篇,没有全集,然后就在论坛里面找哇找,皇天不负有心人,终于找到了教程的合集。
     前几天在坛子里看留言的时候发现BGCoder说了,这系列文章不是俄罗斯人写的,而是一个西班牙人写的,俄罗斯人也是翻译的。,然后BGCoder就感觉很郁闷,发现翻译的不是原版,就没有心情翻译了之类的云云...呵呵,也许是这样BGCoder就不想翻译了吧。
     然后我找到了原版作者的网站,发现果然有西班牙语的这系列教材,并且还有1600多篇高阶教程(近几年软件的脱壳和破解的教程)。这58篇教程是位高阶教程打基础的,貌似作者觉得新手直接看高阶教程,难以理解,所以才写了这58篇基础教程。作者想的真周到。结果我看了看西班牙语版,谷歌翻译了一下,我擦,翻译的文不对题。擦,还是翻译老毛子版的吧,容易翻译一些。
     在百度空间也可以搜索到4-7章的翻译,我看了一下,地址如下:http://hi.baidu.com/hardcom/item/f7ce0d126b8b78e05f53b1b8这几篇文章作者就是直接扔到翻译器中,然后可能直接复制粘贴了,简直难以阅读,本来想从第8章开始翻译,现在看来还是得接着BGCoder的从第4章开始翻译,因为能力有限,所以翻译有的地方可能不准确,请见谅.
     以上就是我想翻译的缘由。

下面是第四章的内容:
                                             第4章-汇编指令
之前的章节主要是理论知识,现在我们要在OllyDbg中实践一下,为后面打开基础。
OllyDbg中几乎所有的标志我都有考虑,如果你遇到了我没有给出的指令,你可以查阅更加全面的汇编指南。
NOP(无操作)
运行这条指令不会对寄存器,内存以及堆栈造成任何影响,英文单词的意思是”无操作”,也就是说,它没有特殊的用途。例如,你用一个短指令来替换一个长指令的话,如果处理器没有错误,多余的空间将会被NOP填充。
适当数目的nop指令可以将其他指令完全替换掉。
下面使用OllyDbg重新载入CrueHead'а(CrackMe的作者)的CrackMe。

我们可以看到反汇编的源代码,如上图第一条指令是PUSH 0,占两个字节,在这条指令上面单击鼠标右键选择Assemble.

或者直接使用快捷键-空格键,在弹出窗口的编辑框中输入NOP。

写入NOP指令后单击Assemble按钮。

这里我们可以看到OD设计的非常智能,考虑到PUSH指令占两个字节,OD会使用两条NOP指令进行替换,而不是使用一条NOP进行替换。
现在,在原来PUSH 0的地方显示的两条NOP指令,单击F7,指令一条NOP指令,可以看到,这里只改变了EIP(保存了下一条要执行指令的地址)寄存器的值,并没有影响到其他寄存器,堆栈或者标志位。
现在我们需要在数据窗口查看这两个字节,它们的内存地址分别是401000和401001。

在数据窗口中,鼠标右键选择-“Go to”-“Expression”,输入你需要转到的地址。

这里我们需要输入401000。

红色突出显示的是刚刚修改过的字节。前两个是90,然后E8,FF和04,00,00。这是一个Call指令的所有剩余字节。
OD可以撤销我们修改的指令吗?
呵呵,当然啦。
在数据窗口或者反汇编窗口中,鼠标拖选中两个字节。

然后单击鼠标右键,选择“UNDO SELECTION”。

这样就恢复了原来的PUSH指令。

在数据窗口中的话,你就可以看到它原始的字节了。

以上是关于NOP指令的所有内容。
堆栈相关指令的说明
我们之前说过,堆栈就像一个信箱一样,越顶部的信越先被取出来。
PUSH 
PUSH指令-将操作数压入堆栈中。我们可以看到,CrueHead'а(CrackMe的作者)的CrackMe的第一条指令就是PUSH指令。

“PUSH 0”指令将把0存入到堆栈的顶部,此时并没有压入堆栈,指令执行后,我们看看堆栈如何变化。堆栈的地址在你的机器上可能会有所不同,但效果是一样的。

堆栈地址在我的机器上是12FFC4,可能与你机器上的不同,因为堆栈每次可能放置在不同的位置,其初始内容也可能有所不同,即这里的7C816D4F和你的也可能不同。按F7,将0压入堆栈,堆栈顶部的就是0了。

按下F7,堆栈顶部我们可以看到加入了0。下面的12FFC4中仍然是7C816D4F,堆栈中的其他值并没有改变。
主要的变化就是堆栈的顶部变成了12FFC0(这是PUSH 0指令执行的结果),新压入的数据总是在堆栈的顶部,并不会改变下面的数据。
这里也可以看到,ESP的值变成了12FFC0。

当然PUSH指令不仅仅可以压入数值:
PUSH EAX的话,那么堆栈的顶部将保存EAX的值。
同样的适用于其他的寄存器,你也可以压入特定内存地址中的值。
PUSH [401008]
注意,这和下面这条指令的解释是不同的。
PUSH 401008
(没有方括号)
如果你使用的“PUSH 401008”,那么堆栈中将被放置401008。

执行以后,我们可以看到下面的结果:

如果换成是“PUSH [401008]”

[401008]表示401008这个内存单元中存储的内容,这个时候我们得去数据窗口中查看它的值是多少。
在数据窗口中鼠标右键单击-Go to-Expression,输入401008,可以看到:

这四个字节是CA 20 40 00。按F7执行这条PUSH执行。

堆栈中我们可以看到在数据窗口中颠倒过来的值,即,它们被倒序放置。
读/写的内容在内存中倒序放置时处理器的特点之一。要怪你只能怪处理器的厂商了,嘿嘿。
通常情况下,没有用方框号括起来的只是一个数字。
现在我们知道,OD中“PUSH [401000]”的意思了。

PUSH DWORD PTR DS:[401008]
像这样的,除非有明确规定,否则OD都是认为你要操作的是4个字节的内存,也就是DWORD。其他格式会在其他指令中予以说明。
POP 
POP指令是出栈:它会取出堆栈顶部的第一个字母或者第一个值,然后存放到指定的目标地址内存单元中。例如,POP EAX从栈顶中取出第一个值存放到EAX中,随后的一个值随即变成栈顶。
我们还是看到CrueHead'а的CrackMe的开始的语句:

将第一条指令替换成“POP EAX”,注意在第一行,按空格键:


以下是执行此操作,堆栈变化情况的说明:

ESP中存放的是12FFC4,它存放的是堆栈的顶部的内存地址。

我们可以看到EAX的值是0(我这里的情况)。
按F7键。

我们可以看到,原来堆栈顶部的值消失了,现在ESP为12FFC8。

原本在堆栈顶部的7C816D4F现在到了EAX中。
同样地,如果用户是“POP ECX”,那么上面的值将会到ECX寄存器中或者你指定其他寄存器中。
我们这里就研究了入栈和出栈指令。
PUSHAD 
PUSHAD指令把所有通用寄存器的内容按一定顺序压入到堆栈中,PUSHAD也就相当于’PUSH EAX,PUSH ECX,PUSH EDX,PUSH EBX,PUSH ESP,PUSH EBP,PUSH ESI, PUSH EDI’。
让我们来看看。
再次载入CrueHead'а的CrackMe,调用右键菜单来修改指令为PUSHAD。


这是我当前寄存器组的情况。

按下F7键,看看现在堆栈的情况:

看到所有寄存器的值都被压入堆栈了。12FFC4存放的是之前堆栈顶部的值,然后上面就是0(PUSH EAX),12FFBC存放的是ECX的内容,接下来是EDX寄存器的内容,以此类推。
POPAD 
该指令与PUSHAD正好相反,它从堆栈中取值,并将它们放到相应的寄存器中。POPAD等价于“POP EDI,POP ESI,POP ESP,POP ESP,POP EBX,POP EDX,POP ECX,POP EAX”。
正如前面的例子,我们将第一条指令修改为POPAD:

由于堆栈中保存的是之前寄存器组的值,执行POPAD其返回原来的状态。

因为之前执行了PUSHAD,所以恢复的寄存器及其值和之前相同。

PUSHAD-POPAD指令经常被使用,例如:某个时刻你需要保存所有寄存器的内容,然后修改寄存器的值,或者进行堆栈的相关操作,然后使用POPAD恢复它们原来的状态。
也有以下的用法:
PUSHA 等价于 'PUSH AX, CX, DX, BX, SP, BP, SI, DI'。
POPA 等价于 'pop DI, SI, BP, SP, BX, DX, CX, AX'。
PUSHA,POPA和PUSHAD,POPAD就像姐妹一样,只不过它们在16位程序中使用,所以我们不感兴趣,OllyDbg是一个32位程序的调试器。
赋值指令的说明
MOV 
该指令将第二个操作数赋值给第一个操作数,例如:
MOV EAX, EBX
EBX值赋值给EAX。继续用OD载入CrueHead'а的CrackMe。

两个寄存器的值是不一样的,我们只是看寄存器:

在我的机器上,EAX为0,EBX为7FFD7000。这些初始值有可能与你机器上的不一样,我们只是看赋值的过程,按F7键,EBX的值就赋值给了EAX。

明白了吗?
MOV指令操作数有很多可以选择,例如:
MOV AL, CL
这条指令时将CL的值赋值给AL。在OD中写上这句。

寄存器:

请记住,AL-是EAX的最后两位数字以及CL-是ECX的最后两位数字。按F7

可以看到只是将B0赋值给AL了,并不改变EAX和ECX的其他内容,即EAX的最后两位数字。
也可以给内存单元赋值,反之亦然一个寄存器的内容。

上图这种情况下,将要给EAX给的值是405000这个内存单元中的值,正如前面提到的,DWORD意味着你必须移动4个字节。如果该指令给出了一个不存在的内存单元可能会导致错误。我们可以用OD很容易的检查出来。

在数据窗口中右键单击选择Go to-Expression转到405000处.


可以看到内存中的内容是-00100000。由于内存中内容是倒序存放的,那么EAX中将被装入00001000,按下F7键,看看会发生什么。

这里是1000,是从内存中读取出来的。现在,如果我们想写一个值到这个地址:
MOV DWORD PTR DS:[400500],EAX
写入该指令。

在数据窗口中查看405000:

然后,按F7键发生异常:

注意异常的描述,是由于我们要写入400500这个内存地址导致的内存访问异常。
如果移动的是4个字节使用DWORD,移动两个字节的话使用WORD。
例如:
MOV AX,WORD PTR DS:[405008]
将405008内存单元中的两个字节赋值给AX。这种情况下,我们不能用EAX,这里移动的只有两个字节,所以你必须使用一个16位的寄存器。
在数据窗口中查看405008.

按F7赋值给AX的只有两个字节。如下:

MOVSX (带符号扩展的传送指令)
第二个操作数可能一个寄存器也可能是内存单元,第一个操作数的位数比第二个操作数多,第二个操作数的符号位填充第一个操作数剩余部分。 下面是一个例子。
这里我们还是在OD中载入CrueHead'а的CrackMe。

这里我不会说太多,因为我想在座各位自己来计算这个操作数求值,嘿嘿。
在OD中,反汇编窗口和数据窗口中间有一个解释窗口。

这里我们可以看到,解释窗口向我们展示了我们操作数里面存放的值。我这里,BX存放的是F000。

同时可以看到,EAX的值为0,所以这些东西总是可以帮助我们理解OD要执行的指令(我希望你已经掌握了其中的概念和寻址方式,嘿嘿)。
按F7键。

看到AX,BX中存放的是F000,并且EAX剩余部分填充为了FFFF,因为F000是一个负的16位数字。如果BX存放1234,EAX将等于00001234,即左边的字节将会被0填充,因为1234是一个正的16位数字。
16位数和32位数的正数和负数的概念是一样的,只不过16位数的范围是0000到FFFF。0000到7FFF是正数,8000到FFFF是负数。
如果我们把BX修改为7FFF,把EAX修改为0,然后执行这条指令会发生什么呢。

AX被赋值为了7FFF,其余部分被填充为0了-因为7FFF是正数。我们还可以把BX修改为8000(负)。

按F7键。

AX被赋值为了8000,剩余的部分为FFFF,因为8000是负数。
MOVZX (带0扩展的传送指令)
MOVZX类似于前面的语句,但是这种情况下,剩余的部分不根据第二个操作数的正负来进行填充。我们这里不提供范例,因为和上面是相似的,剩余的部分总是被填充为0。
LEA (取地址指令)
类似于MOV指令, 但是第一个操作数是一个通用寄存器,并且第二个操作数是一个内存单元。当计算的时候要依赖于之前的结果的话,那么这个指令就非常有用。
我们在OD中写入以下指令:

在这种情况下,有括号,但不需要获取ECX+38指向内存的值,只需要计算ECX+38的值即可。我这里,ECX的值为
12FFB0。

在这个例子中,LEA指令就计算ECX + 38的值,然后将计算的结果赋值给EAX。
解释窗口中显示了两个操作数。

它表示,该操作数是12FFE8,也就是ECX+38的值,并且EAX的值为0。
按F7键。

指定的地址被存放到了EAX中,因为完成的是赋值操作,所以我们会认为操作数是内存单元中的值,但是实际上
操作数仅仅是内存单元的地址,而不是里面的内容。
XCHG (交换 寄存器/内存单元 和 寄存器) 
该指令交换两个操作数的值,例如:
XCHG EAX,ECX
EAX的值将被存放到ECX中。反之亦然。我们在OD中来验证这一点。

在我的机器上,EAX的值为0,ECX的值为12FFB0。

按F7键,看到他们交换了数值。

你也可以使用这个指令来交换寄存器和内存单元的值,本节之前有提到。

按下F7键:

这个例子我们在MOV指令使用过,这里我们对该内存地址没有写权限。
好了,这就是常用指令的第一部分,是非常有用的以及有趣的,我给出的例子能够体现这一点。在接下来的部分,我们将继续研究指令。

这么多图片,传的我手的麻了,神马时候坛子的编辑功能才能改变呀,忘了吃饭,饿死我了,吃饭去了,闪人...

下面是DOC版以及本章的附件。
使用OllyDbg从零开始Cracking 第四章.doc
ollydbg01-Crackme.7z


[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

上传的附件:
最新回复 (60)
安于此生 34 2014-2-14 21:55
2
0
自己坐沙发  嘿嘿
Kisesy 2014-2-14 21:56
3
0
这个好,期待更新~
zsyf 2014-2-14 22:03
4
0
像我等新手太欢迎且需要这样的文章了,非常感谢楼主,并期待更新!
option 2014-2-14 22:04
5
0
哥们能给个原文的链接吗?
另外,西文间翻译用谷歌是比较好的选择,但是到中文的神仙都看不懂,还不如不翻译。
啊滨 2014-2-14 22:04
6
0
好吧 刚看完 这是沙发吗?
熔岩 2014-2-14 22:11
7
0
感谢您的翻译,辛苦了

PS:你换头像了
安于此生 34 2014-2-14 22:15
8
0
恩,换头像鸟
安于此生 34 2014-2-14 22:16
9
0
沙发我自己坐了,哈哈哈
安于此生 34 2014-2-14 22:18
10
0
为什么我的Kx一直没涨咧,为毛咧...都2个多月没涨了  
china 5 2014-2-14 22:22
11
0
感谢辛苦翻译。

希望能把原版教程发一份到网盘。我搜索了下找不到下载,而且看不懂俄文论坛。

同时建议把所有的翻译集中一下,放到百度网盘,做好DOC或者PDF都行。
安于此生 34 2014-2-14 22:23
12
0
恩,稍后上传网盘
china 5 2014-2-14 22:27
13
0
伙计,辛苦了。
china 5 2014-2-14 22:31
14
0
西班牙语更看不懂,作者站点是哪,也麻烦提供一下吧。
安于此生 34 2014-2-14 23:07
15
0
http://www.ricardonarvaja.info/  原西班牙作者的网站,里面教程很全...

作者很犀利呀,2014年依然在更新教程呀,哈哈哈,貌似以前有个病毒编写的教程也是西班牙人写的...具体是谁忘了
shakesky 2014-2-14 23:46
16
0
这个好,服务大众,惠民工程,举双手支持。
china 5 2014-2-14 23:57
17
0
暂停翻译老毛子的。

我从作者站点找到了英文版本的,正在往百度网盘传。

等会开个专门的帖子分享。
悠扬笛曲 1 2014-2-15 00:03
18
0
功在千秋,赞一个。楼主提醒了大家。感谢。。。
安于此生 34 2014-2-15 00:11
19
0
,我以为都是西班牙语的,里面有很多个版本,PDF,DOC,CHM的都有...
哈哈,有英文版的看起来就很爽啦
英文版翻译起来比较容易,坛子里面弟兄可以帮着一起弄,速度把58篇全部搞定...
option 2014-2-15 09:31
20
0
用谷歌浏览器的翻译功能,翻译成英文好看点
安于此生 34 2014-2-15 09:35
21
0
英文版的已经昨天晚上由china上传到网盘了,不翻译俄文的了,翻译英文版的
killbr 2014-2-15 17:27
22
0
大哥 二哥  全给召唤 来了,哇卡卡~~~
这次有的研究了~~~~~
另外这两天 我还看到部小甲鱼的OD视频使用教程24篇也非常不错~~
注册了22个小号,一起组队到他们论坛刷分才下载到10多个所需要附件,还差6个就整齐了~~
killbr 2014-2-15 17:29
23
0
可以派遣任务啊,一位朋友,翻译好一篇,论坛不少人才
58篇摆平英文版本 就不难了,真是造福世人了~~~~~~
xiaoabing 2014-2-15 17:36
24
0
同意
killbr 2014-2-15 17:41
25
0
上仙 请看
好像 您最上面的 两个链接中的 相关配套软件,少了一个 四十七集啊,请看截图~~
上传的附件:
安于此生 34 2014-2-15 17:47
26
0
不是我上传的,是china上传的,可能漏掉了
killbr 2014-2-15 18:15
27
0
http://hi.baidu.com/hardcom/item/f7ce0d126b8b78e05f53b1b8这篇驴唇不对马嘴的,前些日子我也看到过了,后来一生气直接咔嚓了电脑中的存档,就算不看也不能胡凑啊~~
也太对不起编文章的前人了吧。
安于此生 34 2014-2-15 18:16
28
0
你说的有人翻译了前7章,4-7章你就是看得这个博客的吗?
killbr 2014-2-15 21:44
29
0
哥们到处 都混来看看

吾爱破解啊,看雪啊,看的文章多了,也就不知在哪里看到的了。
也许是吧,我也忘了,反正入门级的那几篇还是记着最早是在这里看到的。
安于此生 34 2014-2-15 22:03
30
0
原来如此...
china 5 2014-2-15 22:21
31
0
47用的程序是46的,我刚看了,原版就这样的,只是作者没写而已。

文件不少。
游人啊k 2014-2-15 22:39
32
0
不错,建议加精。。
安于此生 34 2014-2-15 22:55
33
0
哦哦哦
killbr 2014-2-16 09:16
34
0
再次感谢 两位上仙~~~~~~~~
安于此生 34 2014-2-16 14:35
35
0
翻译第5章中...
yangya 2014-2-16 21:12
36
0
高级篇的有木有英文版的?
安于此生 34 2014-2-16 21:18
37
0
只有西班牙语的,我也打算翻译...
高级篇作者目前依然在更新,目前1600多篇,工程量有点大呀...
yangya 2014-2-16 22:34
38
0
高级篇的连接在哪了?
chixiaojie 2014-2-16 22:40
39
0
这个好,翻译辛苦,应该精华。

并永久收录在 软件加密与解密技术精华合集
安于此生 34 2014-2-16 22:43
40
0
高级篇链接:http://ricardonarvaja.info/WEB/CURSO%20NUEVO/TEORIAS%20NUMERADAS/
上传的附件:
yangya 2014-2-17 18:20
41
0
[QUOTE=安于此生;1261493]高级篇链接:http://ricardonarvaja.info/WEB/CURSO%20NUEVO/TEORIAS%20NUMERADAS/
[/QUOTE]

看到了,里面还有IDA的教程,可惜没有英文版的。
安于此生 34 2014-2-17 18:22
42
0
翻译撒...
kxljalger 2014-2-17 19:14
43
0
牛人啊。佩服佩服
安于此生 34 2014-2-17 19:19
44
0
翻译其实是个苦逼活...
yangya 2014-2-17 21:12
45
0
看不懂西班牙文,是英文版的倒是还能看懂。
安于此生 34 2014-2-17 21:19
46
0
西班牙语的照样翻译呀...  各种奇招都用上...嘿嘿嘿
yangya 2014-2-17 22:56
47
0
楼主学过西班牙语?
KIDzyd 2014-2-18 15:22
48
0
支持lz,希望能一直更新下去,lz会俄语啊?好厉害
寒窗苦读 2014-3-5 17:18
49
0
楼主果然威武,赞一个!
白菜C 2014-5-1 11:51
50
0
支持,顶楼
游客
登录 | 注册 方可回帖
返回