我先给各位补一点课,就是对函数的调用。除了一些DELPHI程序之外,对函数参数的传递大都用堆栈来完成,简单地说就是把函数的各个参数先PUSH进去,然后再CALL这个函数。在函数内部呢,一般[ebp+8]是第一个参数,[ebp+C]是第二个参数,每次多加4依此类推。而函数内部的局部变量常用[ebp-4][ebp-8]...等等。(原因讲起来有点复杂,先记住就行了)函数的返回值在EAX里。
一般来说,软件的判断注册部分都是一个函数,在函数开头最经典的两句就是
push ebp
mov ebp,esp
这和堆栈处理有关,我们菜鸟先不用太明白,知道这通常是一个函数的开始就行了。向上找找有没有丫,找到了没有,在最上面哪(我上面没有列出来)。如果你想完整地判断它的算法的话,一般从这里开始就行了。在这个程序中前面都是一些初始化之类的东东,所以我把前面一部分省略了。(这也是破解时的原则,不要在无关紧要的地方费功夫,在高级语言中,代码有很大部分是机器自动生成的,电脑一行行写代码不知道累,人脑一行行读代码怎么受得了?你的脑袋是几GHz的CPU?常见有些没有破解经验的汇编高手,完全懂得每行代码的意思,就是找不到关键的地方,原来他跟了半天都是在API里转,白做无用功了。)
好了,现在可以动态调试了。我们在开头这里下个断点,一步步向下看,出现了一个CALL GetDlgItem,我们来看一看函数说明(手头一份这个是必需的)
HWND GetDlgItem(
HWND hDlg, // handle of dialog box
int nIDDlgItem // identifier of control
);
呵呵,简单的说这个函数就是让程序确定一个对话框上的控件,第一个参数是对话框的句柄,第二个参数是对话框上某个控件的ID,函数会返回该控件的句柄,这样在下面就可以用这个句柄来操作了。看程序:
看见第一行没有,DialogID_0001,CONTROL_ID:0066,压进去了一个66作为第二个参数:控件ID(注意API调用是从右至左,也就是最后面一个参数先PUSH),用 资源查看工具 看看ID为66的是甚么呀,呵呵就是那个输入用户名的文本框嘛。好了,现在我们有文本框的句柄了,存在EAX里。接着向下看,又一个API,是GetWindowText。看看说明:代码:
* Possible Reference to Dialog: DialogID_0001, CONTROL_ID:0066, "" | :00401085 6A66 push 00000066 ;控件ID :00401087 53 push ebx ;对话框句柄 * Reference To: USER32.GetDlgItem, Ord:0000h | :00401088 E8159C0000 Call 0040ACA2
好了,现在 D ebp+FFFFFF48 看看,是不是输入的用户名?(说明,在OLLY或SICE里这个是[ebp-B8]的形式,其实是一样的)代码:
:0040108D 6A64 push 00000064 ;最大长度 :0040108F 8D9548FFFFFF lea edx, dword ptr [ebp+FFFFFF48];把[ebp+FFFFFF48]先放在EDX里 :00401095 52 push edx ;缓冲区地址[ebp+FFFFFF48] :00401096 50 push eax ;EAX?是上面那个API的返回值呀,控件句柄 * Reference To: USER32.GetWindowTextA, Ord:0000h | :00401097 E8129C0000 Call 0040ACAE
这是干甚么牙?要不要进4010C4这个CALL 401630看看?且慢!我前面说过了,不要在无关紧要的地方费力,(啪!一个鸡蛋扔上来:谁知道这里是不是重要啊?)别急嘛,一般来说,先粗略地跟一遍,试着猜猜CALL的作用。如果发现返回值很可疑,再跟进细看也不迟。(这就需要一定的“直觉”了,英文叫“Sence”,台湾老大叫“触机”或者“先死:D”,别担心,破解得多了自然会有这种感觉,这种感觉很难说出来,有时候一见那种阵势就知道关键地方到了)代码:
:004010BD 8D8548FFFFFF lea eax, dword ptr [ebp+FFFFFF48] :004010C3 50 push eax :004010C4 E867050000 call 00401630
代码:
:004010C9 59 pop ecx :004010CA 8945D8 mov dword ptr [ebp-28], eax ;记住,上面的返回结果在[ebp-28] :004010CD 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4] :004010D3 52 push edx :004010D4 E857050000 call 00401630
代码:
:004010F0 837DD803 cmp dword ptr [ebp-28], 00000003 :004010F4 7E7B jle 00401171 :00401102 837DD832 cmp dword ptr [ebp-28], 00000032 :00401106 7D69 jge 00401171
代码:
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:0040111C(C) | :0040110C 0FBE840D48FFFFFF movsx eax, byte ptr [ebp+ecx-000000B8] :00401114 41 inc ecx :00401115 33C1 xor eax, ecx :00401117 03D8 add ebx, eax :00401119 3B4DD8 cmp ecx, dword ptr [ebp-28] :0040111C 75EE jne 0040110C
代码:
:0040111E 6BC006 imul eax, 00000006 ;EAX其实是上面最后一轮计算的结果,乘6 :00401121 C1E307 shl ebx, 07 ;EBX是几轮计算累加起来的结果,左移7位 :00401124 03C3 add eax, ebx ;加起来 :00401126 8945C8 mov dword ptr [ebp-38], eax :00401129 FF75C8 push [ebp-38] ;上面的结果,作为一个参数 * Possible StringData Ref from Data Obj ->"%lX" | :0040112C 6838B44000 push 0040B438 ;"%lX"有点眼熟哟 :00401131 8D8D80FEFFFF lea ecx, dword ptr [ebp+FFFFFE80] :00401137 51 push ecx ;这是什么呢? :00401138 E8873D0000 call 00404EC4 :0040113D 83C40C add esp, 0000000C
代码:
:00401140 8D8580FEFFFF lea eax, dword ptr [ebp+FFFFFE80];眼熟吗,刚才的转换结果呀 :00401146 50 push eax ;EAX指向上面转换得到的字符串 :00401147 8D95E4FEFFFF lea edx, dword ptr [ebp+FFFFFEE4];这个很早了,向前面找找是啥 :0040114D 52 push edx ;EDX指向我们输入的假注册码 * Reference To: KERNEL32.lstrcmpA, Ord:0000h | :0040114E E8339C0000 Call 0040AD86 :00401153 85C0 test eax, eax :00401155 750D jne 00401164 ;关键跳转哟
简单的C程序哟,你也可以用你熟悉的语言写一个。代码:
#include#include #include void main() { int EAX=0,EBX=0,len; char name[50]={0}; char password[50]={0}; printf("Please input your name:"); scanf("%s",name); len=strlen(name); for (int i=0;i
| 另类破解鸽子连接密码 | 03-21 | |
| 教菜鸟写注册机 | 12-27 | |
| QQ聊天记录察看器 5.2算法分析 | 12-04 | |
| 如何汉化一个软件 | 12-02 | |
| 扭曲变换加密 【目前防止软件被破 | 11-02 | |
| 破解利器Olldbg脚本教学(二)- | 10-31 | |
| 破解利器Olldbg脚本教学(一)- | 10-30 | |
| 破解|利器|ollydbg|教学|Run tra | 10-28 | |
| 破解WebEasyMail v3.6.2.1 企业版 | 10-24 | |
| 破解利器OllyDBG入门系列(五)- | 10-18 | |
| 破解利器OllyDBG入门系列(四)- | 10-17 | |
| 揭开高级游戏黑客的面纱,轻松打 | 10-17 | |