这个程序有提供了两个功能,一个账户密码形式的和直接输入KEY形式的。爆破
账户密码形式 Serial/Name
. 错误提示:Sorry , The serial is incorect !,不用管。在OD中直接单步走,走出MessageBox函数后返回的第一个函数,个人目测了下还不是关键地方。因为没有什么特别的跳转指令就继续跑出这层函数返回上层。返回之后往上看反汇编代码。
. 那么想要跳过这个错误提示信息则需要将 0042F803处的JNZ给nop掉。nop掉后F9让程序跑起来,然后重新点击【Check it Baby!】。OD中继续在MessageBox处中断了。并且程序弹出了GOOD窗口。
. 话说,这个功能中,账户低于4位字符的话~~也会有一个错误提示框!,记得在点击【Check it Baby!】先下MessageBox断点哦~~~
. OD中断下后网上返回两层,返回第一层瞟了一眼没有看到什么跳转指令则网上层继续返回
. 如果想要输入的账户长度不大于4,只需要把JGE给修改成JMP让其强制跳转即可!!!
爆破输入KEY Serial
. 同理,先下MessageBox断点~,然随便输入,点击【Check it Baby!】弹出的消息为:Try Again!!。OD在MessageBox中断下来了。 按照惯例,走出MessageBOx后看看有没有什么跳转,如果有则查看跳转到哪,没有则继续网上层返回。
这里修改上面的JNZ改为NOP,不管返回什么都往下走。修改后F9跑程序!爆破成功~~~~~~~~
这个功能只需要输入KEY就行了。不防尝试找下正确的KEY到底是什么!!!!既然知道正确和错误的跳转地点,那么尝试下再跳转地点下个INT3看看,CALL的参数是什么。
函数中并没有使用push来传入参数,只是用了两个内存数据给了两个寄存器EAX和EDX。这种情况明显不是__stdcall或者__cdecl。 不妨看下寄存器给定的值到底是什么。
真相只有一个~~~~~ EAX为我输入的字符串SSSSS,那EDX是另一个字符串,是不是解密的KEY输入一下EDX的内容就知道了。。。。。。
分析 Serial/Name 算法
. Serial/Name爆破算是玩了,仅仅是爆破。感觉就像是找了一部A片随便看下然后撸一发就完了就关掉的感觉。我不仅仅是要撸一发,还得好好的琢磨琢磨各种姿势和过程….(七夕这天作为一名单身汪,只能这么屌丝了。。。)
想找注册算法首先得找到注册成功的爆破点。想找注册算法首先得找到注册成功的爆破点。
[Asm] 纯文本查看 复制代码
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC ; 这个CALL的返回值
0042FB03 |. 75 1A jnz XAcid_bur.0042FB1F ; 上一个CALL的返回值不等于0则跳转到错误消息
0042FB05 |. 6A 00 push 0x0
0042FB07 |. B9 CCFB4200 mov ecx,Acid_bur.0042FBCC
0042FB0C |. BA D8FB4200 mov edx,Acid_bur.0042FBD8
0042FB11 |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB16 |. 8B00 mov eax,dword ptr ds:[eax]
0042FB18 |. E8 53A6FFFF call Acid_bur.0042A170
0042FB1D |. EB 18 jmp XAcid_bur.0042FB37 ; 强制跳转,跳过了错误显示。
0042FB1F |> 6A 00 push 0x0
0042FB21 |. B9 74FB4200 mov ecx,Acid_bur.0042FB74
0042FB26 |. BA 80FB4200 mov edx,Acid_bur.0042FB80
0042FB2B |. A1 480A4300 mov eax,dword ptr ds:[0x430A48]
0042FB30 |. 8B00 mov eax,dword ptr ds:[eax]
0042FB32 |. E8 39A6FFFF call Acid_bur.0042A170 ; 函数内调用了MessageBox显示错误
call Acid_bur.004039FC为判断函数返回0则为真的注册码。那么我们在这里下断看看。这个程序直接是明文比较的。观察寄存器就能看到我输入的密码4567,和计算出来的密码。。
自己测试过,直接输入账户1234密码CW-4018-CRACKED显示GOOD,正确的。但是我要的是算法。查看明文KEY:CW-4018-CRACKED可知是由,字符串,数字,字符串组成。那么,我们则可以尝试使用IDA了。通过IDA搜索是否存在CRACKED字符串。
运气好,找到了。那么。在内存地址0042FAB3。OD中GO过去刚好离爆破点很近啊~~~爆破点在0042FB03处。那么我们可以单步在这里附近单步下看看函数具体做了写什么。范围取值在0042FA79到0042FAFE之间。因为0042FA79计算账户长度>=4的跳转点以及0042FAFE函数call
[Asm] 纯文本查看 复制代码
0042FA79 |> \8D55 F0 lea edx,[local.4]
0042FA7C |. 8B83 DC010000 mov eax,dword ptr ds:[ebx+0x1DC]
0042FA82 |. E8 D1AFFEFF call Acid_bur.0041AA58 ; 获取账户,字符串,字符串首地址存储在EBP-0X10处
0042FA87 |. 8B45 F0 mov eax,[local.4]
0042FA8A |. 0FB600 movzx eax,byte ptr ds:[eax] ; DWORD DATA = (DWORD)buff[0];
0042FA8D |. F72D 50174300 imul dword ptr ds:[0x431750] ; DATA * 0x43175 == DATA * 0x29
0042FA93 |. A3 50174300 mov dword ptr ds:[0x431750],eax ; 0x431750 = DATA * 0x29;
0042FA98 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FA9D |. 0105 50174300 add dword ptr ds:[0x431750],eax ; 0x431750 *= 2
0042FAA3 |. 8D45 FC lea eax,[local.1]
0042FAA6 |. BA ACFB4200 mov edx,Acid_bur.0042FBAC
0042FAAB |. E8 583CFDFF call Acid_bur.00403708 ; 将CW字符串首地址存储在EBP-0x4处
0042FAB0 |. 8D45 F8 lea eax,[local.2]
0042FAB3 |. BA B8FB4200 mov edx,Acid_bur.0042FBB8 ; CRACKED
0042FAB8 |. E8 4B3CFDFF call Acid_bur.00403708 ; 将字符串地址存储在EBP-0X8处
0042FABD |. FF75 FC push [local.1]
0042FAC0 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; UNICODE "-"
0042FAC5 |. 8D55 E8 lea edx,[local.6]
0042FAC8 |. A1 50174300 mov eax,dword ptr ds:[0x431750]
0042FACD |. E8 466CFDFF call Acid_bur.00406718 ; 将0x431750存储的十六进制转换成字符串,地址存储在EBP-0x18处
0042FAD2 |. FF75 E8 push [local.6]
0042FAD5 |. 68 C8FB4200 push Acid_bur.0042FBC8 ; UNICODE "-"
0042FADA |. FF75 F8 push [local.2]
0042FADD |. 8D45 F4 lea eax,[local.3]
0042FAE0 |. BA 05000000 mov edx,0x5
0042FAE5 |. E8 C23EFDFF call Acid_bur.004039AC ; 字符串拼接。(EBP-0X4)+(EBP-0X18)+(EBP-0X8) 存储在ebp-0xC
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]
0042FAFE |. E8 F93EFDFF call Acid_bur.004039FC ; 输入的密码与程序计算出来的KEY做比较
0042FB03 |. 75 1A jnz XAcid_bur.0042FB1F ; 上一个CALL的返回值不等于0则跳转到错误消息
那么转换成C语言就是
[C] 纯文本查看 复制代码
void Decryption(char* mima)
{
char szBuff[260];
unsigned long data = (unsigned long)mima[0];
data *= 0X29;
data *= 2;
sprintf(szBuff, "CW-%d-CRACKED", data);
printf("%s \r\n", szBuff);
}
因为在计算KEY中,只使用了用户的第一个字母,后三位没用。所以,账户abcd和aaaa使用的KEY是相同的 完毕~~~~~
|