【破文标题】CRACKME分析
【破文作者】逍遥风
【破解工具】OD
【破解平台】WINXP
----------------------------------------------------------------------
OD载入程序后,在命令行下断bp GetDlgItemTextA.很容易来到关键处。
向上找到算法开始的地方开始分析
来到这里
004010D3 |. 6A 50 PUSH 50 ; /Count = 50 (80.)
004010D5 |. 68 B0344000 PUSH tsrh-cra.004034B0 ; |Buffer = tsrh-cra.004034B0
004010DA |. 68 DE000000 PUSH 0DE ; |ControlID = DE (222.)
004010DF |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010E2 |. E8 43020000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
004010E7 |. 83F8 05 CMP EAX,5 ; 检验注册名位数
004010EA |. 7D 26 JGE SHORT tsrh-cra.00401112 ; 大于5位就跳走
004010EC |. B8 66354000 MOV EAX,tsrh-cra.00403566
004010F1 |. E8 05020000 CALL tsrh-cra.004012FB
004010F6 |. 6A 40 PUSH 40 ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
004010F8 |. 68 52354000 PUSH tsrh-cra.00403552 ; |tsrh crackme *easy*
004010FD |. 68 00304000 PUSH tsrh-cra.00403000 ; |Text = "Kill this Nag!!!"
00401102 |. 6A 00 PUSH 0 ; |hOwner = NULL
00401104 |. E8 27020000 CALL <JMP.&USER32.MessageBoxA> ; \MessageBoxA
00401109 |. 33C0 XOR EAX,EAX
0040110B |. 5E POP ESI
0040110C |. 5F POP EDI
0040110D |. 5B POP EBX
0040110E |. C9 LEAVE
0040110F |. C2 1000 RETN 10
00401112 |> E8 DC000000 CALL tsrh-cra.004011F3 ; 关键CALL(1)
00401117 |. 6A 50 PUSH 50 ; /Count = 50 (80.)
00401119 |. 68 90314000 PUSH tsrh-cra.00403190 ; |Buffer = tsrh-cra.00403190
0040111E |. 68 4D010000 PUSH 14D ; |ControlID = 14D (333.)
00401123 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
00401126 |. E8 FF010000 CALL <JMP.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA
0040112B |. A1 90314000 MOV EAX,DWORD PTR DS:[403190] ; 取注册名位数
00401130 |. 3D 74737268 CMP EAX,68727374 ; 比较注册码的前4位是否为68727374(既tsrh)
00401135 |. 75 23 JNZ SHORT tsrh-cra.0040115A ; 不相等就跳向失败
00401137 |. 05 20320000 ADD EAX,3220 ; 注册名前4位的HEX值加上0x3220
0040113C |. 50 PUSH EAX ; 所得的和储存
0040113D |. 33C0 XOR EAX,EAX ; EAX清零
0040113F |. E8 EA000000 CALL tsrh-cra.0040122E ; 关键CALL(2),计算结果设为甲
00401144 |. 58 POP EAX
00401145 |. 85C0 TEST EAX,EAX
00401147 |. 74 11 JE SHORT tsrh-cra.0040115A
00401149 |. 33C2 XOR EAX,EDX
0040114B |. 8BD0 MOV EDX,EAX
0040114D |. 8BF0 MOV ESI,EAX
0040114F |. 33C0 XOR EAX,EAX
00401151 |. E8 31010000 CALL tsrh-cra.00401287 ; 关键CALL(3)
00401156 |. 84C0 TEST AL,AL
00401158 |. 75 1F JNZ SHORT tsrh-cra.00401179 ; 不相等就跳向失败
----------------------------------------------------------------------
来到第一个关键CALL。计算SN1
004011F3 /$ A3 14354000 MOV DWORD PTR DS:[403514],EAX ; 储存注册名长度
004011F8 |. BF D3070000 MOV EDI,7D3 ; 取定值0x7D3
004011FD |. 033D 14354000 ADD EDI,DWORD PTR DS:[403514] ; 注册名长度与0x7DC相加
00401203 |. 57 PUSH EDI ; /<%d>
00401204 |. 68 1B354000 PUSH tsrh-cra.0040351B ; |tsrh-%d- (标志性的东东)
00401209 |. 68 20334000 PUSH tsrh-cra.00403320 ; |s = tsrh-cra.00403320
0040120E |. E8 05010000 CALL <JMP.&USER32.wsprintfA> ; 相加后的和转换成对应的十进制数
00401213 |. 83C4 0C ADD ESP,0C
00401216 |. 68 20334000 PUSH tsrh-cra.00403320 ; /String = ""
0040121B |. E8 34010000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA
00401220 |. 8B3D 14354000 MOV EDI,DWORD PTR DS:[403514]
00401226 |. BE 01000000 MOV ESI,1
0040122B |. 8BC8 MOV ECX,EAX
0040122D \. C3 RETE ; 得到的结果作为SN1
----------------------------------------------------------------------
来到第二个关键CALL。计算字符串“甲”
0040122E /$ 56 PUSH ESI
0040122F |. 68 20334000 PUSH tsrh-cra.00403320
00401234 |. E8 1B010000 CALL <JMP.&KERNEL32.lstrlenA> ; \取固定字符串(1)tsrh-2009-,并取其长度
00401239 |. 8B3D 14354000 MOV EDI,DWORD PTR DS:[403514] ; 作第一次计算
0040123F |. BE 01000000 MOV ESI,1 ; 使ESI=1
00401244 |. 8BC8 MOV ECX,EAX ; 使ECX=固定字符串(n)长度
00401246 |> B8 B0344000 MOV EAX,tsrh-cra.004034B0 ; 取注册名,开始计算
0040124B |. 0FB64406 FF MOVZX EAX,BYTE PTR DS:[ESI+EAX-1] ; 取注册名每一位的ASCC码
00401250 |. 04 0C ADD AL,0C ; 注册名每一位的ASCII码加上0x0C,结果设为A(n)
00401252 |. 0FB6D0 MOVZX EDX,AL
00401255 |. 83EA 11 SUB EDX,11 ; 所得的和A减去0x11,结果设为B(n)
00401258 |. 03D0 ADD EDX,EAX ; A+B,和设为C(n)
0040125A |. 2BD1 SUB EDX,ECX ; 所得的和C减去固定字符串(n)的长度。差设D(n)
0040125C |. 33C2 XOR EAX,EDX ; A(n)与D(n)做XOR运算,结果设为E(n)
0040125E |. 50 PUSH EAX ; /<%X>
0040125F |. 68 18354000 PUSH tsrh-cra.00403518 ; |%x
00401264 |. 8D81 20334000 LEA EAX,DWORD PTR DS:[ECX+403320] ; |
0040126A |. 50 PUSH EAX ; |s
0040126B |. E8 A8000000 CALL <JMP.&USER32.wsprintfA> ; \wsprintfA
00401270 |. 83C4 0C ADD ESP,0C ; 储存结果E(n)
00401273 |. 68 20334000 PUSH tsrh-cra.00403320 ; /String = "tsrh-2009-"(这个2009会根据注册名的不同而不同)
00401278 |. E8 D7000000 CALL <JMP.&KERNEL32.lstrlenA> ; \lstrlenA
0040127D |. 8BC8 MOV ECX,EAX ; 与固定字符串和并,得到固定字符串(2),并取其长度
0040127F |. 46 INC ESI ; 每计算一次ESI加1
00401280 |. 4F DEC EDI ; 每计算一次EDI-1
00401281 |.^ 75 C3 JNZ SHORT tsrh-cra.00401246 ; 循环计算
00401283 |. 33C0 XOR EAX,EAX
00401285 |. 5E POP ESI
00401286 \. C3 RETN ; 计算结果作为“甲”
--------------------------------------------------------------------
来到第三个关键CALL。计算SN2
00401287 /$ 53 PUSH EBX
00401288 |. BE 01000000 MOV ESI,1
0040128D |> B8 B0344000 /MOV EAX,tsrh-cra.004034B0 ; ASCII "lovetc"
00401292 |. 0FB64406 FF |MOVZX EAX,BYTE PTR DS:[ESI+EAX-1] ; 取注册名每一位的ASCII码
00401297 |. 85C0 |TEST EAX,EAX
00401299 |. 74 34 |JE SHORT tsrh-cra.004012CF
0040129B |. 40 |INC EAX ; 注册名每一位的ASCC码+1
0040129C |. BA 20334000 |MOV EDX,tsrh-cra.00403320 ; 取字符串“甲”,放进EDX
004012A1 |. 0FB65416 0B |MOVZX EDX,BYTE PTR DS:[ESI+EDX+B] ; 将甲分为3部分tsrh-X-Y,取Y部分每一位的ASCII码
004012A6 |. 33C2 |XOR EAX,EDX ; 与注册名ASCII码加1后的做XOR运算
004012A8 |> 83F8 41 |/CMP EAX,41 ; 结果大于41(A)吗?
004012AB |. 7D 05 ||JGE SHORT tsrh-cra.004012B2
004012AD |. 83C0 08 ||ADD EAX,8 ; 小于就加8,直到大于41为止
004012B0 |.^ EB F6 |\JMP SHORT tsrh-cra.004012A8
004012B2 |> 83F8 5A |/CMP EAX,5A ; 与5A(Z)相比
004012B5 |. 7E 05 ||JLE SHORT tsrh-cra.004012BC ; 小于Z吗
004012B7 |. 83E8 03 ||SUB EAX,3 ; 不小于就减3
004012BA |.^ EB F6 |\JMP SHORT tsrh-cra.004012B2
004012BC |> 83C6 09 |ADD ESI,9
004012BF |. BB 20334000 |MOV EBX,tsrh-cra.00403320 ; 取字符串“甲”
004012C4 |. 89041E |MOV DWORD PTR DS:[ESI+EBX],EAX ; 用计算后的值替换甲对应位置的值
004012C7 |. 83EE 08 |SUB ESI,8
004012CA |. 83FE 10 |CMP ESI,10 ; 大于16次就跳走
004012CD |.^ 75 BE \JNZ SHORT tsrh-cra.0040128D ; 循环计算
004012CF |> 33C0 XOR EAX,EAX
004012D1 |. 5B POP EBX
004012D2 |. E8 01000000 CALL tsrh-cra.004012D8
004012D7 \. C3 RETN ; 计算结果作为SN2
----------------------------------------------------------------------
算法总结:
1)注册名必须大于5位,注册码形式为tsrh-SN1-SN2。
2)定值0x7D3(2003)与注册名位数相加,再转换成对应的10进制数得到SN1
3)计算SN2:
A(n)=(注册名每一位的ASCII值+0x0C)
B(n)=(注册名每一位的ASCII值+0x0C)-0x11
A(n)+ B(n)=C(n) , C(n)减固定字符串(n)的长度=D(n)
E(n)= A(n)XOR D(n) 。把E(n)依次合并在tsrh-SN1-之后。得到“甲”
4)注册名每一位ASCII码加1后的值与Y的每一位做XOR运算,得到的值合并成SN2
----------------------------------------------------------------------
【版权声明】本文只为交流,转载请保留作者及文章完整性
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法