逆向工程(4):程序行为分析

文中软件下载链接:http://pan.baidu.com/s/1nt1tvkP 密码:zeav

目标:破解软件的NAG
工具:OD

1.遇到的问题:
这款软件打开首先会有一个NAG
032916_0407_41.png
点击Start Program后进入主程序
032916_0407_42.png

关闭程序后,又会再弹出一个很丑的广告
032916_0407_43.png

我们的目标就是去除这些消息框。

基本的思路如下(如果你是新手,一定要认真理解并且上机操作):

1. 一路F8(单步步过)直到遇见弹出NAG的CALL指令。
2. F7进入CALL,在重复1操作直到遇见更深一层的弹出NAG的CALL。
3. 重复1和2操作,注意,我们还没有学习dll的注入,如果更深层CALL调用了dll,我们不必进入,可以在外围进行破解。(该程序会讲述这一过程)
4. 最优秀的破解方式是找到注册版本能(直接或者间接)跳过广告的语句(例如jmp)。这样对程序的损害最小,可能的错误隐患也最小。
5. 如果没有分析出程序机制,用暴力NOP填充也是可以的,不过可能会有意想不到的事发生,为了保证程序良好运行,我们通常在NOP填充后还得继续打补丁

建议读者在这里停止阅读,下载好本章需要破解的软件,自己先动手操作一次,1个小时后在继续阅读我们剩下的章节。

2.开始破解
我们把程序载入OD
032916_0407_44.png

一路F8按下去,不幸的是我们在不久后进入了一个循环,在寄存器窗口我们可以看到这是在读取我们程序的位置信息,我们可不想一步一步等它循环

032916_0407_45.png
我们选择在循环外下一个断点(F2),如下:
032916_0413_46.png

再运行(F9)程序,我们的程序会自动暂停在断点处。
按F2去除该断点继续执行

我们继续向下F8 ,在某一CALL处弹出了NAG
032916_0423_47.png
很显然,我们要在这个CALL处下断点(F2),然后点击image008重新载入程序,点击image009,程序暂停在了这一CALL,我们F7进入CALL

image010
进入这个CALL后,我们只看到一条call,这条call将会带我们进入mfc42.dll中,然而我们不得不进入。

我们进入这个CALL,继续F8,我们已经跳转到了mfc42.dll中
image011
在如下位置的CALL弹出了NAG,同样方法下断点,重新载入执行到该断点处F7进入
image012

进入如图所示位置
image013
并且已经离开了mfc42.dll
image014

一路上没有发现什么可用的信息,经过一小段时间的F8,我们来到了如图所示位置
image015

如果我们继续深入这个call,就又进入了dll中,这不是我们想要的结果,我们可以选择就在这一层面处理这个NAG,不再深入挖掘。
在这个call之后,我们找到了另一个call

image016
执行这个call我们打开了主程序。
(读者自行尝试找到这个call)

3.程序分析

1. 我们在这个位置发现了一个跳转语句(je),这个跳转语句如果成立,就可以跳过这个NAG
image017
image018

2. 在下面又发现了一个跳转(jnz),同样可以跳过NAG
image019

3. 继续探索,我们又发现了一个跳转(jle,好多跳转啊),它同样可以跳过NAG
image020

4. 最暴力的方法:我们可以用NOP填充这个call
image028

看看,我们居然总结出了4种破解NAG的方法。
我们先分析程序正常的运行机制是怎样的。
image022

4.打补丁
1.我们尝试第一种破解方法:

将je 004899D8强制跳转,结果发现程序执行流程变成如下:

image023

我们发现,改变第一个je虽然跳过了讨厌的NAG,但是也跳过了主程序,所以我们还需要修改jmp 00489E93,将这一句用NOP填充掉。
具体流程就不演示了,经过前几篇教程的演示,各位应该都知道强制跳转(JMP),NOP填充的知识了。

2. 我们尝试第二种破解方法:

将jnz 00489A29改为强制跳转,结果发现程序执行流程变成如下:

image024

很显然,我们发现了一个很完美的破解方法,我们猜测这个jnz是判断用户是否购买了正版,因为它非常完美地避开了NAG,直达主程序。

3. 我们尝试第三种破解方法:

我们将jle 00489998强制跳转,流程如下
image025
如果在将jle强制跳转,我们在00489A15之前会遇到一个call
image026
这个call将弹出一个消息框提示你试用期已经过了,请购买正版
image027

很明显,我们修改的jle是程序判断是否过试用期的机制。
我们有很多中破解方法,比如直接把jle改成强制跳转到主程序,
比如NOP掉过试用期的call和jmp 00489E93
等等等等,读者可以自己尝试,一定会有不小的收获


修改后不要忘了保存哟

4. 我们尝试第四种破解方法
我们暴力的将call用NOP填充掉
image028
程序的执行流程如下:
image029

你肯定很奇怪我们只是NOP掉了这个call,为什么会导致后面的流程改变呢?
这是因为可能这个call里面进行了另一些处理,这些处理涉及到了接下来跳转判断的参数,我们NOP掉了这个call,自然也NOP掉了这些对于参数的处理。

同样,这样需要我们继续打补丁,方法上面都讲述了,这里不再累赘。

希望读者都自己动手操作一下,理解下程序行为,这对逆向是很有帮助的!

在平时的逆向中,要学会分析程序的行为,画出(至少大脑中要出现)这种类似的流程图,这可以帮助我们很直观地理解程序行为!

5.收尾
接下来我们还有一点收尾工作:
image030

这个NAG会在我们关闭主程序后弹出。
在弹出广告后,我们暂停程序(一定要暂停哦!),点击(显示调用堆栈),打开后我们将看到调用的call

image033
其中最引人注目的是被红色框起来的这一部分,我们记得第一个NAG也是使用了同样的call
于是我们右键点击,显示调用:
image034

来到了程序调用该CALL处,将其NOP填充掉
image036

然后保存。

我们将修改完成的程序运行一次,直接进入了主程序,关闭后也没有广告出现!
image037

本节教程就到这里为止,希望大家都动手操作一次,才能真正理解教程中的知识。大家也要在空闲时间学习汇编知识,这样才能将逆向做的如鱼得水。

发表评论

发表评论

*

沙发空缺中,还不快抢~