Shark恒 发表于 2015-1-20 16:39

使用OllyDbg从零开始Cracking 第二十七章-Visual Basic程序的破解-Part2

                   第二十七章-VisualBasic程序的逆向-Part2Visual Basic程序逆向续本章我们继续讨论VB应用程序逆向的话题,上一章我们解决的是一个带NAG窗口的CrackMe。我们是用那个patch过的OD来弄的,本章我们也会用到,但是本章我们还会介绍另一种更加简便,更加省时的方法。首先我们还是用那个patch过的OD来分析,弄清楚了具体原理以后,我们再来介绍那种简便的方法。本章我们实验的对象名称叫做killme,这个程序启动的时候会弹出一个烦人的NAG窗口,我们需要想办法把它剔除掉。我们直接运行起来的话,可以看到弹出一个NAG窗口。我们可以看到Continue按钮是灰色的(不可用),当定时器由5减少到0后,Continue按钮就被激活了,我们单击Continue按钮。NAG关闭了,并且弹出主程序窗口,我们用OD加载该程序。我们按F9键运行起来。定时器时间到了后,Continue按钮就被激活了。我们可以想象一下,NAG窗口关闭后,代码中应该会有一个无条件跳转到主窗口代码执行,所以我们给代码段设置内存访问断点(该内存访问断点实际上只是内存执行断点),接着单击Continue按钮。单击Continue按钮后,我们断在了这里。我们可以看到404B60处JMP指令会跳转到40D090地址处开始执行,也就是说主窗口程序实际上是从40D090处开始执行的,这里说主窗口程序可能不太准确,因为我们可以看到这里有好几处JMP分支会跳转到程序的不同部分执行。我们给这几处JMP指令分别设置断点,然后来看看每个分支跳转分别在什么情况下被触发。我们重新启动该程序。刚刚我们看到了单击NAG窗口上的Continue按钮后,会执行JMP 40D090这个分支。现在我们重新启动程序后,断在了JMP 40D250这个分支处。NAG窗口还没有显示。我们继续运行起来。我们可以看到断在了JMP 40D4F0这个分支处。这个时候NVG窗口已经显示出来了,上面显示了数字5。我们继续运行。又断在了JMP 40D4F0这个分支处。这个时候NVG窗口上的数字变为了4。我们会发现JMP 40D4F0这个分支一共会断下来5次。也就是说,这个分支过程与定时器相关。让我们来跟进到这个分支中一探究竟。没看出什么特别的地方,我们继续按F8键跟踪。我们跟到了一处条件跳转JE 40D64F处。我们来分析一下看看这个条件跳转是不是决定定时器停止并激活Continue按钮的关键跳转。上面是一个浮点比较指令,由于上下文的线索并不太多,所以我们暂时还看不出它的作用是什么。我们给这个JE 40D64F设置一个断点,接着运行起来。断在了JE 40D64F这个分支处,并且该跳转将成立,我们多运行几次会发现,计时器减至0之前这个跳转一直都是成立的,只有当定时器显示为0时,该跳转才不成立。所以我们可以得知,该条件跳转是用来判断定时器是否为0的。我们将这一行NOP掉看看会发生什么。好了,已经NOP掉了,这样这里就不会跳转到40D64F处了,我们运行起来。我们可以看到,定时器并没有减至0,而Continue按钮已经被激活了。所以我们对于该条件跳转是用来判断定时器是否为0的假设是成立的。好了,现在我们这个NAG窗口关闭,当当前这个函数返回到VB的DLL中时,那么该NAG窗口将继续显示,所以我们需要定位该函数何时返回到VB的模块中,定位到返回指令后,我们可以将返回指令指定返回到显示主窗口程序的分支40D090即可,这样NAG窗口就会主动关闭而不需要人为的单击Continue按钮了。现在我们重新启动程序。我们来到刚刚NOP掉的那一行。我们删掉之前设置的所有断点,接着给TESTAH,40这一行设置一个断点,运行起来。断了下来,我们按F8键往下跟踪,看看哪里会返回到VB的DLL中,返回到了VB的DLL中的话程序就会运行起来。这样NAG窗口就会显示出来并等待我们按Continue或者Exit键。我们到达了40D713处的RETN指令处,但是我们会发现该处会返回到紧接着的下一行40D714处,并不是返回到VB的DLL中,所以我们继续跟踪。我们跟踪到了40D730处的RETN 4指令处,从解释窗口中我们可以看出来这里将返回到MSVBVM60.DLL中。接着程序将运行起来了。NAG窗口将继续显示,为了剔除掉NAG窗口,这里我们可以尝试将该RETN 4修改为JMP指令,让其直接跳转到显示主窗口的代码处(40D090)。还有一点需要注意,这里RETN 4占3个字节,但是JMP 40D090占5个字节。我们还可以注意到40D738起始处有几个字节的NOP空间可以利用。所以我们可以先跳转到40D739处。接着我们在40D739写入JMP 40D090指令即可。这样就可以直接跳转到显示主程序的代码开始执行,NVG也被关闭了。我们直接运行起来看看效果。我们可以看到主窗口直接显示出来,NAG不见了。好,现在我们将之前做的修改(NOP掉的,两处跳转)保存到文件。我们单击鼠标右键选择-Copy to executable-All modifications,这样就可以保存所有修改了。选择Copy all。单击鼠标右键选择Save file。好了,保存名为killmeclean.exe,直接双击运行起来,我们会发现NAG窗口还是出现了,不过几秒钟后就消失了,然后主窗口就弹出来了。就是说NAG窗口还没有被完全剔除掉,所以我们还是来到之前分析的多分支处。运行起来。我们可以看到在NAG窗口创建之前断在了404B7A处,我们运行起来以后,几秒钟后,就断在了404B87处,并且这个时候NAG窗口被创建并显示出来了。所以JMP 40D250这个分支应该是创建并显示NAG窗口的分支。我们用OD加载刚刚我们patch过的killmeclean这个程序,我们将创建NAG窗口的跳转NOP掉。NOP掉创建NAG窗口的分支后将直接转入定时器计时的分支执行,我们按F9键运行起来看看效果。我们可以看到直接弹出了主窗口,并没有显示NAG窗口,我们保存所有修改到文件,然后直接双击运行看看效果。我们可以看到直接就弹出了主窗口,并没有出现NAG窗口,嘿嘿。这样我们将手工剔除了这个NAG窗口。4C法-这样方式更加快捷方便,该法是基于VB程序的特性来的。下面我们就来介绍这种方法,我们用OD加载killme程序,停在了入口点处。我们会注意到VB程序有个特点-入口点处都是一个PUSH指令,然后一个CALL指令。(如果你遇到的不是这种情况的话,那么该程序可能被加过壳)PUSH将要压入堆栈的是40436C,现在我们在数据窗口中定位到这个地址。正如你说看到的,这就是VB程序的头部,这里我们将40436C加上4C。也就是40436C + 4C也就是4043B8。这里我们可以看到4043B8指向的内存单元中保存的是40440C。(PS:这里作者写成了4044C0,我已经更正为40440C)我们在数据窗口中定位到40440C这个地址。这里我们可以看到两块类似的数据,每块50(十六进制)个字节的长度,每块数据的第24(十六进制)个字节处都有一个标志。该标志指定了每块代码出现的顺序。我们一起来看看吧。40440c+24=404430 我们可以看到第一块的中标志是00,表示该部分代码将首先执行,而第二块中的01表示随后才会执行,所以这里我们将各两个标志的值颠倒一下。这样首先弹出的就是主窗口了,嘿嘿。然后才是NAG窗口,其实NAG窗口根本不会弹出来,因为主窗口关闭后,应用程序就退出了,NAG窗口压根就没有机会弹出来。这样我们就用4C法方便快捷的搞定了这个NAG程序,但是这样方式并不适用于所有的程序,所以为什么一开始我要给大家介绍分析VB程序的常规手法,了解原理对我们非常有帮助。这里留两个CrackMe给大家练习,一易一难,名称分别为CrackMe(这个程序的运行需要MSVBVM50.DLL的支持),CrackMe2。大家尝试一下看看能不能找出序列号以及剔除NAG窗口,下一章我们再来讲解这两个例子。
本系列文章汉化版转载看雪论坛
感谢原作者:RicardoNarvaja(西班牙人) 原作者个人主页:http://www.ricardonarvaja.info/
感谢热心翻译的朋友:1~3章译者:BGCoder4~58章译者:安于此生
全集配套程序下载地址:链接: http://pan.baidu.com/s/1eQzTWfo 密码: vytv


hahaya 发表于 2019-8-21 16:31


这句话意思是开始F9运行程序,等continue按钮可以点击之后,查看内存,然后在程序的代码段下硬件访问断点吗?

但是我这么做之后程序就一直是暂停状态,我继续运行就又被断了,根本点击不了程序的按钮。
请问我是哪里操作有问题呀,本人小白,请各位指导。

ghostxu 发表于 2022-1-19 14:00

感谢发布原创作品!

xujinwen 发表于 2022-1-19 16:00

谢谢大佬!

莫大 发表于 2022-1-19 16:34

先顶了再看,好习惯!{:6_198:}

莫大 发表于 2022-1-19 16:54

先顶了再看,好习惯!{:6_198:}

xujinwen 发表于 2022-1-19 22:56

谢谢楼主分享

xujinwen 发表于 2022-1-20 15:40

谢谢楼主分享

kalove 发表于 2022-1-20 22:22

支持~谢谢大神的分享~

别管我了行 发表于 2022-3-1 03:49

页: [1] 2
查看完整版本: 第二十七章-Visual Basic程序的逆向-Part2