反汇编的应用1-软件破解

以下的案例主要介绍反汇编的使用价值,即在软件加解密方面的应用。能够非常好地体会到主要的汇编指令在实践中的应用,也能够认识到Ollydbg在软件调试过程中的威力。

选用的演示样例程序CRACKME.exe程序来自看雪论坛的“从零開始用ollydbg cracking”系列。本文仅仅做学习交流用途,不作其它不论什么用途。

 

以下开工:

1. 採用ollydbg打开CRACKME.exe,命令:f3。

2. 注冊的正确与否,程序会弹出窗体,窗体上会带有字符串,那我们这里就以正确与否的字符串作为线索;命令:右键->search for-> all referred strings。

3. 找到例如以下的string:Great work,mate! now try the next CrackMe!",而且双击进入,跳转到调用该字符串的地方;

4. 从下图可见,以下两个弹出窗体就是最后看到注冊信息对错的提醒窗体。那么以这两个为线索。查看是从哪里跳转到这两个函数调用起始处的;


5. 鼠标停在push 30处,能够看到以下的观察窗体显示:local call from 0040124C;

也即意味着push 30处是由0040124C处跳转过来的。那么查看该处的指令;


6. 此处关键的指令就在401241处。通过该处指令的比較,来确定后面序列号的正确与否,再来选择后面的跳转。

7. 通过在CMP EAX, 0指令处打断点,我们F9执行程序,程序弹出注冊窗体,我们输入:


然后按ok后。整个程序就停在我们下断点的地方。例如以下图所看到的,


8. 依据右边的凝视。上述的流程就非常清晰。401228处的指令将usernameabc字符串地址压入。然后进行处理后。将结果保存在EAX中。后面的将序列号123也做相同的处理。能够推測对于序列号操作的结果应该输出在EBX中,这样后面的CMP EAX, EBX这条语句才说得通。

9. 我们F7单步跟入40122D的函数调用,看到例如以下的处理过程:


简单跟踪下的话。能够发现上述的代码等同于以下的C语言代码:

int nameCrack(char* str)
{
	char t;
	int sum = 0;

	while(*str)
	{
		int t = (int)(*str);
		
		if(t > 0x5A)
			sum += (int)(t-0x20);
		str++;
	}

	sum = sum ^ 0x5678;
	return sum;
}

对于我们的输入abc,上述函数的输出为:0x56BE;

10. 相同地。我们对于401238处的指令也进行跟踪调试:


上述的代码等同于以下的C代码:

int numCrack(char* str)
{
	int sum = 0;

	while(*str)
	{
		int c = (int)*str - 0x30;
		sum = 10*sum + c;
		str++;
	}
	return (sum ^ 0x1234);
}

11.依据调试。EAX和EBX的值分别为:56BE和124F。两者不同,因此解密失败。为了让两者同样,我们保持abc不变。改变序列号来实现。

12. 56BE与0x1234亦或操作后的值的十进制表示为:17546。因此我们仅仅要输入的字符串操作的值sum等于17546就可以。又由于数字的ASSIC码是从”0x31”開始的。

而代码中有减去0x30的操作。因此我们输入的数字仅仅要是17546就可以。



注意事项:

1. 调试时请关闭杀毒软件的实时保护,否则,CRACKME.exe会被删除;

2. “从零開始用ollydbgcracking”系列教材中对该问题的分析是从API GetWindowTextA入手;详细分析上也是大同小异。

 

解密过程中的经常使用命令小结:

1. 定位使用的模块,ctrl + N。

2. 通过查看堆栈,找到GetWindowTextA使用的buffer的地址;

3. 採用Follow in dump找到buffer地址后,能够设定memoryon access类型的break point,这样一旦訪问到buffer中的信息,就能够暂停,加速定位;


posted @ 2017-07-10 17:38  yxysuanfa  阅读(625)  评论(0编辑  收藏  举报