新CrackMe160之093 - kesan
-
去灰
用UE打开程序文件,搜索文本button,一直向下搜索到出现"注册"左右时即可,看前后是否有Enabled参数,其后的值便是关键, 成功找到0005099Fh这个位置08改为09,保存后,注册按钮即可亮起 -
破解
Delphi写的程序,使用IDR查看源码可知,算法在Edit2Change事件中, 注册按钮只验证[447849]是否为1, 具体看Edit2Change事件
Unit1::TForm1.Edit2Change
00445034 push ebp
00445035 mov ebp,esp
00445037 xor ecx,ecx
00445039 push ecx
0044503A push ecx
0044503B push ecx
0044503C push ecx
0044503D push ebx
0044503E push esi
0044503F push edi
00445040 mov ebx,eax
00445042 xor eax,eax
00445044 push ebp
00445045 push 445190
0044504A push dword ptr fs:[eax]
0044504D mov dword ptr fs:[eax],esp
00445050 mov byte ptr ds:[447848],0; gvar_00447848
00445057 lea edx,[ebp-4]
0044505A mov eax,dword ptr [ebx+2D0]; TForm1.Edit1:TEdit
00445060 call TControl.GetText
00445065 lea edx,[ebp-8]
00445068 mov eax,dword ptr [ebx+2D4]; TForm1.Edit2:TEdit
0044506E call TControl.GetText
00445073 mov eax,dword ptr [ebp-4]
00445076 call @LStrLen
0044507B mov esi,eax
0044507D mov eax,dword ptr [ebp-8]
00445080 call @LStrLen
00445085 mov edi,eax
00445087 cmp dword ptr [ebp-4],0
>0044508B je 0044515C
00445091 cmp dword ptr [ebp-8],0
>00445095 je 0044515C
0044509B mov byte ptr ds:[447848],1; gvar_00447848
004450A2 mov byte ptr ds:[447849],0; gvar_00447849
004450A9 cmp esi,4 ; 用户名长度5位以上
>004450AC jle 00445155
004450B2 cmp edi,8 ; 注册码8位
>004450B5 jne 00445155
004450BB xor eax,eax
004450BD push ebp
004450BE push 4450EE
004450C3 push dword ptr fs:[eax]
004450C6 mov dword ptr fs:[eax],esp
004450C9 lea eax,[ebp-10]
004450CC mov ecx,dword ptr [ebp-8]
004450CF mov edx,4451A8; '$' ; 注册码前面补$
004450D4 call @LStrCat3
004450D9 mov eax,dword ptr [ebp-10]
004450DC call StrToInt ; 转数字(前面补了$,转出来的数字直接就是16进制的)
004450E1 mov dword ptr [ebp-0C],eax
004450E4 xor eax,eax
004450E6 pop edx
004450E7 pop ecx
004450E8 pop ecx
004450E9 mov dword ptr fs:[eax],edx
>004450EC jmp 00445112
<004450EE jmp @HandleOnException
004450F3 dd 1
004450F7 dd 407354;EConvertError
004450FB dd 4450FF
004450FF mov byte ptr ds:[447849],0; gvar_00447849
00445106 call @DoneExcept
>0044510B jmp 0044516D
0044510D call @DoneExcept
00445112 mov edx,12DFD16
00445117 mov eax,esi
00445119 test eax,eax
>0044511B jle 00445138
0044511D mov esi,1
00445122 mov ecx,dword ptr [ebp-4] ; 循环开始
00445125 mov cl,byte ptr [ecx+esi-1]
00445129 xor cl,0CA
0044512C and ecx,0FF
00445132 add edx,ecx
00445134 inc esi
00445135 dec eax
<00445136 jne 00445122 ; 循环结束
00445138 xor edx,19840808
0044513E cmp edx,dword ptr [ebp-0C] ; 对比
>00445141 je 0044514C
00445143 mov byte ptr ds:[447849],0; gvar_00447849
>0044514A jmp 0044515C
0044514C mov byte ptr ds:[447849],1; gvar_00447849
>00445153 jmp 0044515C
00445155 mov byte ptr ds:[447849],0; gvar_00447849
0044515C mov eax,dword ptr [ebx+2D8]; TForm1.Button1:TButton
00445162 mov dl,byte ptr ds:[447848]; gvar_00447848
00445168 mov ecx,dword ptr [eax]
0044516A call dword ptr [ecx+5C]; TControl.SetEnabled
0044516D xor eax,eax
0044516F pop edx
00445170 pop ecx
00445171 pop ecx
00445172 mov dword ptr fs:[eax],edx
00445175 push 445197
0044517A lea eax,[ebp-10]
0044517D call @LStrClr
00445182 lea eax,[ebp-8]
00445185 mov edx,2
0044518A call @LStrArrayClr
0044518F ret
<00445190 jmp @HandleFinally
<00445195 jmp 0044517A
00445197 pop edi
00445198 pop esi
00445199 pop ebx
0044519A mov esp,ebp
0044519C pop ebp
0044519D ret
从上面代码可以分析出具体算法为: code = (0x12DFD16 + SUM((user[i] ^ 0xCA) & 0xFF)) ^ 0x19840808
#include <stdio.h>
#include <string.h>
int main() {
char user[21] = {0};
unsigned long code = 0x12DFD16;
printf("用户名: ");
fgets(user, sizeof(user), stdin);
int i, len = strlen(user) - 1, sum = 0;
if(len < 5) { printf("用户名5位以上"); return 0; }
user[len] = 0;
for(i=0; i<len; i++){ code += (user[i] ^ 0xCA) & 0xFF; }
printf("注册码: %08X", code ^ 0x19840808); //小写也行%08x
getchar();
return 0;
}
运行示例:
用户名: 093-kesan
注册码: 18aa0c33
使用的工具连接(工具有点多有点大,可以先下OD,其它的后面慢慢下) 点击前往下载
下面是我的OD的界面布局,我觉得这4个是最常用的界面,其它的我基本上没用到~


浙公网安备 33010602011771号