反汇编的应用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中的信息,就能够暂停,加速定位;