说明:此篇内容仅作为学习研究,进行非法行为,后果自负
为了保证破解的稳定性,我使用windows xp进行相关的操作
程序无壳
先打开软件,用户名111,注册码222,当然是注册失败
od分析内容,经过不断的试验,发现用户名长度小于4就失败
如果长度小于4就会走到无条件跳转的地方,跳过正确
如果用户名长度大于4,就会跳过无条件跳转,然后程序能向下走
程序向下走,就来到这个地方,很关键
call函数之后,就进行了判断,不相等就跳过了正确的地方,此处就是关键点了,下断点,运行程序,修改汇编程序
破解成功
0042FA52 |. E8 D96EFDFF call Acid_bur.00406930 ; 得到长度的函数
0042FA57 |. 83F8 04 cmp eax,0x4 ; 这是判断长度,用户名长度小于4,就直接退出
0042FA5A |. 7D 1D jge short Acid_bur.0042FA79
0042FA5C |. 6A 00 push 0x0
0042FA5E |. B9 74FB4200 mov ecx,Acid_bur.0042FB74 ; Try Again!
0042FA63 |. BA 80FB4200 mov edx,Acid_bur.0042FB80 ; Sorry , The serial is incorect !
0042FA68 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FA6D |. 8B00 mov eax,dword ptr ds:[eax]
0042FA6F |. E8 FCA6FFFF call Acid_bur.0042A170 ; 弹框MessageBox
0042FA74 |. E9 BE000000 jmp Acid_bur.0042FB37 ; 无条件跳过成功的部分
0042FA79 |> 8D55 F0 lea edx,[local.4]
0042FA7C |. 8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82 |. E8 D1AFFEFF call Acid_bur.0041AA58
0042FA87 |. 8B45 F0 mov eax,[local.4] ; 读取用户名到eax
0042FA8A |. 0FB600 movzx eax,byte ptr ds:[eax] ; 读取用户名第一个字符,我输入的用户名1111
0042FA8D |. F72D 50174300 imul dword ptr ds:[0x431750] ; *0x29
0042FA93 |. A3 50174300 mov dword ptr ds:[0x431750],eax ; 0x29*0x31
0042FA98 |. A1 50174300 mov eax,dword ptr ds:[0x431750] ; eax=0x7d9
0042FA9D |. 0105 50174300 add dword ptr ds:[0x431750],eax ; 0x7d9+0x7d9=0xfb2
0042FAA3 |. 8D45 FC lea eax,[local.1]
0042FAA6 |. BA ACFB4200 mov edx,Acid_bur.0042FBAC ; CW
0042FAAB |. E8 583CFDFF call Acid_bur.00403708 ; 和下面的是同个函数403708
0042FAB0 |. 8D45 F8 lea eax,[local.2]
0042FAB3 |. BA B8FB4200 mov edx,Acid_bur.0042FBB8 ; CRACKED
0042FAB8 |. E8 4B3CFDFF call Acid_bur.00403708
0042FABD |. FF75 FC push [local.1] ; Acid_bur.0042FBAC
0042FAC0 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; -
0042FAC5 |. 8D55 E8 lea edx,[local.6]
0042FAC8 |. A1 50174300 mov eax,dword ptr ds:[0x431750] ; 前面计算的结果放到eax
0042FACD |. E8 466CFDFF call Acid_bur.00406718 ; 计算出来的结果转10进制
0042FAD2 |. FF75 E8 push [local.6] ; 4018就是前面算出来结果的10进制形式
0042FAD5 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; -
0042FADA |. FF75 F8 push [local.2] ; Acid_bur.0042FBB8
0042FADD |. 8D45 F4 lea eax,[local.3]
0042FAE0 |. BA 05000000 mov edx,0x5
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC
0042FAEA |. 8D55 F0 lea edx,[local.4]
0042FAED |. 8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3 |. E8 60AFFEFF call Acid_bur.0041AA58
0042FAF8 |. 8B55 F0 mov edx,[local.4] ; 读取假注册码
0042FAFB |. 8B45 F4 mov eax,[local.3] ; 生成注册码CW-4018-CRACKED
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC
0042FB03 75 1A jnz short Acid_bur.0042FB1F ; 这个会跳过正确提示框
0042FB05 |. 6A 00 push 0x0
0042FB07 |. B9 CCFB4200 mov ecx,Acid_bur.0042FBCC ; Congratz !!
0042FB0C |. BA D8FB4200 mov edx,Acid_bur.0042FBD8 ; Good job dude =)
0042FB11 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB16 |. 8B00 mov eax,dword ptr ds:[eax]
0042FB18 |. E8 53A6FFFF call Acid_bur.0042A170 ; 弹出框MessageBox
这个函数的算法就是取输入的用户名第一个字符,然后乘以0x29,然后算出来的值再加一倍,化为10进制,作为真实注册码的一部分,并自动生成CW,CRACKED,-,然后相连就是真实注册码了,用用户名并没有进行处理
知道算法,写注册机就非常简单了
#include <iostream>
using namespace std;
int main()
{
int name;
cout<<"Please input name:"<<endl;
name = getchar();
if(name>0x21)
{
name*=0x29;
name*=2;
printf("The Seria:\nCW-%4d-CRACKED",name);
}
else
{
cout<<"Input Error";
}
return 0;
}
运行结果如下:
联系客服