-
-
[原创]看雪CTF2016 第五题分析-5-CrackMe-冰怜泯灭
-
发表于: 2016-11-10 17:47 2702
-
这题比较简单,OD载入,代码窗口很容易找到:
0040112B |. 66:81BC24 2C010000 EA cmp word ptr ss:[arg.3], 3EA ; 事例 111 (WM_COMMAND) of switch CrackMe.40110A
00401135 |. 0F85 5B010000 jne 00401296
0040113B |. 884C24 20 mov ss:[local.63], cl
0040113F |. B9 3F000000 mov ecx, 3F
00401144 |. 33C0 xor eax, eax
00401146 |. 8D7C24 21 lea edi, [local.63+1]
0040114A |. F3:AB rep stos dword ptr es:[edi]
0040114C |. 8BB424 24010000 mov esi, ss:[arg.1]
00401153 |. 8B1D A0504000 mov ebx, ds:[<&USER32.GetDlgItem>]
00401159 |. 66:AB stos word ptr es:[edi]
0040115B |. 8D4424 20 lea eax, [local.63]
0040115F |. BF 01000000 mov edi, 1
00401164 |. 50 push eax ; /lParam => offset LOCAL.63
00401165 |. 68 FF000000 push 0FF ; |wParam = 255.
0040116A |. 6A 0D push 0D ; |Msg = WM_GETTEXT
0040116C |. 68 E9030000 push 3E9 ; |/ItemID = 1001.
00401171 |. 56 push esi ; ||hDialog => [ARG.1]
00401172 |. FFD3 call ebx ; |\USER32.GetDlgItem
00401174 |. 8B2D A4504000 mov ebp, ds:[<&USER32.SendMessageA>] ; |
0040117A |. 50 push eax ; |hWnd
0040117B |. FFD5 call ebp ; \USER32.SendMessageA
0040117D |. 33C9 xor ecx, ecx
0040117F |. 85C0 test eax, eax
00401181 |. 76 17 jbe short 0040119A
00401183 |> 8A540C 20 /mov dl, ss:[ecx+esp+20]
00401187 |. 80FA 30 |cmp dl, 30 ; //注册码全是数字
0040118A |. 7C 0C |jl short 00401198
0040118C |. 80FA 39 |cmp dl, 39
0040118F |. 7F 07 |jg short 00401198
00401191 |. 41 |inc ecx
00401192 |. 3BC8 |cmp ecx, eax
00401194 |.^ 72 ED \jb short 00401183
00401196 |. EB 02 jmp short 0040119A
00401198 |> 33FF xor edi, edi
0040119A |> 83F8 06 cmp eax, 6 ; //长度必须是6
0040119D |. 75 56 jne short 004011F5
0040119F |. 85FF test edi, edi
004011A1 |. 74 52 jz short 004011F5
004011A3 |. 8D4C24 20 lea ecx, [local.63]
004011A7 |. 50 push eax ; /Arg2
004011A8 |. 51 push ecx ; |Arg1 => offset LOCAL.63
004011A9 |. E8 52FEFFFF call 00401000 ; \CrackMe.00401000, //调用解码函数,对00406030的代码解码
004011AE |. 83C4 08 add esp, 8
004011B1 |. E8 0AFFFFFF call 004010C0 ; //调用函数对解码后的内容进行和校验,正确返回1
004011B6 |. 85C0 test eax, eax
004011B8 |. 74 2C jz short 004011E6
004011BA |. 6A 00 push 0 ; //校验正确,调用解码后的函数提示成功
004011BC |. 68 E9030000 push 3E9
004011C1 |. 56 push esi
004011C2 |. FFD3 call ebx
004011C4 |. 8B3D A8504000 mov edi, ds:[<&USER32.EnableWindow>]
004011CA |. 50 push eax ; |hWnd
004011CB |. FFD7 call edi ; \USER32.EnableWindow
004011CD |. 6A 00 push 0
004011CF |. 68 EA030000 push 3EA
004011D4 |. 56 push esi
004011D5 |. FFD3 call ebx
004011D7 |. 50 push eax
004011D8 |. FFD7 call edi
004011DA |. 55 push ebp
004011DB |. 56 push esi
004011DC |. BA 30604000 mov edx, offset 00406030 ; 入口点
004011E1 |. FFD2 call edx
004011E3 |. 83C4 08 add esp, 8
004011E6 |> 8D4424 20 lea eax, [arg.8]
004011EA |. 6A 06 push 6 ; /Arg2 = 6
004011EC |. 50 push eax ; |Arg1
004011ED |. E8 0EFEFFFF call 00401000 ; \CrackMe.00401000, //再次调用解码函数恢复原来的数据
004011F2 |. 83C4 08 add esp, 8
004011F5 |> 5F pop edi ; 默认情况下 of switch CrackMe.40110A
004011F6 |. 5E pop esi
004011F7 |. 5D pop ebp
004011F8 |. 33C0 xor eax, eax
004011FA |. 5B pop ebx
004011FB |. 81C4 10010000 add esp, 110
00401201 |. C2 1000 retn 10
00401000 /$ 81EC 08010000 sub esp, 108 ; //解码函数
00401006 |. 53 push ebx
00401007 |. 55 push ebp
00401008 |. 56 push esi
00401009 |. 57 push edi
0040100A |. 33D2 xor edx, edx
0040100C |. B9 3F000000 mov ecx, 3F
00401011 |. 33C0 xor eax, eax
00401013 |. 8D7C24 19 lea edi, [local.63+1]
00401017 |. 885424 18 mov ss:[local.63], dl
0040101B |. F3:AB rep stos dword ptr es:[edi]
0040101D |. 66:AB stos word ptr es:[edi]
0040101F |. AA stos byte ptr es:[edi]
00401020 |. 8D7C24 18 lea edi, [local.63]
00401024 |. 33C0 xor eax, eax
00401026 |> 884404 18 /mov ss:[eax+esp+18], al
0040102A |. 40 |inc eax
0040102B |. 3D 00010000 |cmp eax, 100
00401030 |.^ 7C F4 \jl short 00401026
00401032 |. 8BAC24 20010000 mov ebp, ss:[arg.2]
00401039 |. 33C0 xor eax, eax
0040103B |. C74424 10 00010000 mov dword ptr ss:[local.65], 100
00401043 |> 8BB424 1C010000 /mov esi, ss:[arg.1]
0040104A |. 8A0F |mov cl, ds:[edi]
0040104C |. 8A1C30 |mov bl, ds:[esi+eax]
0040104F |. 02D9 |add bl, cl
00401051 |. 02D3 |add dl, bl
00401053 |. 40 |inc eax
00401054 |. 885424 14 |mov ss:[local.64], dl
00401058 |. 8B7424 14 |mov esi, ss:[local.64]
0040105C |. 81E6 FF000000 |and esi, 000000FF
00401062 |. 3BC5 |cmp eax, ebp
00401064 |. 8A5C34 18 |mov bl, ss:[esi+esp+18]
00401068 |. 8D7434 18 |lea esi, [esi+esp+18]
0040106C |. 881F |mov ds:[edi], bl
0040106E |. 880E |mov ds:[esi], cl
00401070 |. 75 02 |jne short 00401074
00401072 |. 33C0 |xor eax, eax
00401074 |> 8B4C24 10 |mov ecx, ss:[local.65]
00401078 |. 47 |inc edi
00401079 |. 49 |dec ecx
0040107A |. 894C24 10 |mov ss:[local.65], ecx
0040107E |.^ 75 C3 \jnz short 00401043
00401080 |. 33C0 xor eax, eax
00401082 |. 8D8C24 17010000 lea ecx, [local.0+3]
00401089 |> 8A5404 18 /mov dl, ss:[eax+esp+18]
0040108D |. 8A19 |mov bl, ds:[ecx]
0040108F |. 02D3 |add dl, bl
00401091 |. 8A98 30604000 |mov bl, ds:[eax+406030]
00401097 |. 32DA |xor bl, dl
00401099 |. 8898 30604000 |mov ds:[eax+406030], bl
0040109F |. 40 |inc eax
004010A0 |. 49 |dec ecx
004010A1 |. 3D 80000000 |cmp eax, 80
004010A6 |.^ 7C E1 \jl short 00401089
004010A8 |. 5F pop edi
004010A9 |. 5E pop esi
004010AA |. 5D pop ebp
004010AB |. 5B pop ebx
004010AC |. 81C4 08010000 add esp, 108
004010B2 \. C3 retn
004010C0 /$ 56 push esi ; //求和校验
004010C1 |. 57 push edi
004010C2 |. 33FF xor edi, edi
004010C4 |. 33F6 xor esi, esi
004010C6 |. 33C9 xor ecx, ecx
004010C8 |> 33C0 /xor eax, eax
004010CA |. 8A81 30604000 |mov al, ds:[ecx+406030]
004010D0 |. 99 |cdq
004010D1 |. 03F8 |add edi, eax
004010D3 |. 13F2 |adc esi, edx
004010D5 |. 41 |inc ecx
004010D6 |. 81F9 80000000 |cmp ecx, 80
004010DC |.^ 7C EA \jl short 004010C8
004010DE |. 81FF 79290000 cmp edi, 2979 ; //求和必须为0x2979
004010E4 |. 75 0C jne short 004010F2
004010E6 |. 85F6 test esi, esi
004010E8 |. 75 08 jnz short 004010F2
004010EA |. 5F pop edi
004010EB |. B8 01000000 mov eax, 1
004010F0 |. 5E pop esi
004010F1 |. C3 retn
004010F2 |> 5F pop edi
004010F3 |. 33C0 xor eax, eax
004010F5 |. 5E pop esi
004010F6 \. C3 retn
根据对上面的解码函数和校验函数分析,写出下面的代码暴力破解,从'000000'到'999999'扫描:
bool keyGen()
{
BYTE buf1[0x80]={
0xF4,0x12,0x9D,0x60,0x45,0xF8,0x20,0x6A,0x6F,0x67,0x04,0x71,0xC0,0x9B,0x0C,0x5A
,0x1D,0x18,0x6C,0x96,0x69,0x01,0x1C,0xF4,0x7F,0x28,0x5A,0xFB,0x29,0x07,0x40,0x8B
,0xD3,0xE1,0xB1,0x12,0xFB,0xCA,0x7C,0x89,0xB9,0x5A,0x30,0x70,0x9D,0x95,0x2B,0x95
,0x3C,0x8D,0x2E,0x45,0xEF,0x70,0xC6,0xA3,0xB9,0xB2,0x5A,0x63,0x5F,0x03,0x33,0xB8
,0x64,0x4A,0x8F,0xBC,0xF7,0x91,0x69,0x6A,0x56,0x2E,0xD4,0x6E,0x82,0x93,0xE9,0x76
,0xDC,0xA3,0x6C,0x5E,0x6B,0x72,0x64,0x37,0xE7,0x15,0x17,0xAC,0x64,0x78,0xD5,0x4A
,0x60,0x2D,0xF0,0x54,0xA6,0xF3,0xE8,0xE0,0xE0,0xB9,0x8F,0x85,0x90,0xE4,0xEA,0xD6
,0xBB,0xB7,0x15,0x9E,0x2A,0x44,0xE7,0x31,0x63,0xAC,0x80,0x6C,0x34,0x82,0xE9,0xCF
};
DWORD magic = 0x2979;
DWORD sum;
BYTE buf2[0x100];
int idx;
char sSN[7];
int sn;
for(sn = 0 ; sn < 1000000 ; sn++){
sprintf(sSN, "%06d", sn);
for(idx = 0 ; idx < 0x100 ; idx++){
buf2[idx] = idx;
}
BYTE c = 0;
for(idx = 0 ; idx < 0x100 ; idx++){
BYTE c2 = buf2[idx];
c += (BYTE)sSN[idx % 6] + c2;
buf2[idx] = buf2[c];
buf2[c] = c2;
}
sum = 0;
for(idx = 0 ; idx < 0x80 ; idx++){
c = (buf2[idx] + buf2[0xff - idx]) ^ buf1[idx];
sum += c;
if(sum > magic){ //大于就退出,不再浪费时间
break;
}
}
if(sum == magic){ //等于,找到
OutputDebugString(sSN);
break;
}
}
if(sn >= 1000000){
OutputDebugString("未找到!");
return false;
}
return true;
}
很快能计算出结果:771535
0040112B |. 66:81BC24 2C010000 EA cmp word ptr ss:[arg.3], 3EA ; 事例 111 (WM_COMMAND) of switch CrackMe.40110A
00401135 |. 0F85 5B010000 jne 00401296
0040113B |. 884C24 20 mov ss:[local.63], cl
0040113F |. B9 3F000000 mov ecx, 3F
00401144 |. 33C0 xor eax, eax
00401146 |. 8D7C24 21 lea edi, [local.63+1]
0040114A |. F3:AB rep stos dword ptr es:[edi]
0040114C |. 8BB424 24010000 mov esi, ss:[arg.1]
00401153 |. 8B1D A0504000 mov ebx, ds:[<&USER32.GetDlgItem>]
00401159 |. 66:AB stos word ptr es:[edi]
0040115B |. 8D4424 20 lea eax, [local.63]
0040115F |. BF 01000000 mov edi, 1
00401164 |. 50 push eax ; /lParam => offset LOCAL.63
00401165 |. 68 FF000000 push 0FF ; |wParam = 255.
0040116A |. 6A 0D push 0D ; |Msg = WM_GETTEXT
0040116C |. 68 E9030000 push 3E9 ; |/ItemID = 1001.
00401171 |. 56 push esi ; ||hDialog => [ARG.1]
00401172 |. FFD3 call ebx ; |\USER32.GetDlgItem
00401174 |. 8B2D A4504000 mov ebp, ds:[<&USER32.SendMessageA>] ; |
0040117A |. 50 push eax ; |hWnd
0040117B |. FFD5 call ebp ; \USER32.SendMessageA
0040117D |. 33C9 xor ecx, ecx
0040117F |. 85C0 test eax, eax
00401181 |. 76 17 jbe short 0040119A
00401183 |> 8A540C 20 /mov dl, ss:[ecx+esp+20]
00401187 |. 80FA 30 |cmp dl, 30 ; //注册码全是数字
0040118A |. 7C 0C |jl short 00401198
0040118C |. 80FA 39 |cmp dl, 39
0040118F |. 7F 07 |jg short 00401198
00401191 |. 41 |inc ecx
00401192 |. 3BC8 |cmp ecx, eax
00401194 |.^ 72 ED \jb short 00401183
00401196 |. EB 02 jmp short 0040119A
00401198 |> 33FF xor edi, edi
0040119A |> 83F8 06 cmp eax, 6 ; //长度必须是6
0040119D |. 75 56 jne short 004011F5
0040119F |. 85FF test edi, edi
004011A1 |. 74 52 jz short 004011F5
004011A3 |. 8D4C24 20 lea ecx, [local.63]
004011A7 |. 50 push eax ; /Arg2
004011A8 |. 51 push ecx ; |Arg1 => offset LOCAL.63
004011A9 |. E8 52FEFFFF call 00401000 ; \CrackMe.00401000, //调用解码函数,对00406030的代码解码
004011AE |. 83C4 08 add esp, 8
004011B1 |. E8 0AFFFFFF call 004010C0 ; //调用函数对解码后的内容进行和校验,正确返回1
004011B6 |. 85C0 test eax, eax
004011B8 |. 74 2C jz short 004011E6
004011BA |. 6A 00 push 0 ; //校验正确,调用解码后的函数提示成功
004011BC |. 68 E9030000 push 3E9
004011C1 |. 56 push esi
004011C2 |. FFD3 call ebx
004011C4 |. 8B3D A8504000 mov edi, ds:[<&USER32.EnableWindow>]
004011CA |. 50 push eax ; |hWnd
004011CB |. FFD7 call edi ; \USER32.EnableWindow
004011CD |. 6A 00 push 0
004011CF |. 68 EA030000 push 3EA
004011D4 |. 56 push esi
004011D5 |. FFD3 call ebx
004011D7 |. 50 push eax
004011D8 |. FFD7 call edi
004011DA |. 55 push ebp
004011DB |. 56 push esi
004011DC |. BA 30604000 mov edx, offset 00406030 ; 入口点
004011E1 |. FFD2 call edx
004011E3 |. 83C4 08 add esp, 8
004011E6 |> 8D4424 20 lea eax, [arg.8]
004011EA |. 6A 06 push 6 ; /Arg2 = 6
004011EC |. 50 push eax ; |Arg1
004011ED |. E8 0EFEFFFF call 00401000 ; \CrackMe.00401000, //再次调用解码函数恢复原来的数据
004011F2 |. 83C4 08 add esp, 8
004011F5 |> 5F pop edi ; 默认情况下 of switch CrackMe.40110A
004011F6 |. 5E pop esi
004011F7 |. 5D pop ebp
004011F8 |. 33C0 xor eax, eax
004011FA |. 5B pop ebx
004011FB |. 81C4 10010000 add esp, 110
00401201 |. C2 1000 retn 10
00401000 /$ 81EC 08010000 sub esp, 108 ; //解码函数
00401006 |. 53 push ebx
00401007 |. 55 push ebp
00401008 |. 56 push esi
00401009 |. 57 push edi
0040100A |. 33D2 xor edx, edx
0040100C |. B9 3F000000 mov ecx, 3F
00401011 |. 33C0 xor eax, eax
00401013 |. 8D7C24 19 lea edi, [local.63+1]
00401017 |. 885424 18 mov ss:[local.63], dl
0040101B |. F3:AB rep stos dword ptr es:[edi]
0040101D |. 66:AB stos word ptr es:[edi]
0040101F |. AA stos byte ptr es:[edi]
00401020 |. 8D7C24 18 lea edi, [local.63]
00401024 |. 33C0 xor eax, eax
00401026 |> 884404 18 /mov ss:[eax+esp+18], al
0040102A |. 40 |inc eax
0040102B |. 3D 00010000 |cmp eax, 100
00401030 |.^ 7C F4 \jl short 00401026
00401032 |. 8BAC24 20010000 mov ebp, ss:[arg.2]
00401039 |. 33C0 xor eax, eax
0040103B |. C74424 10 00010000 mov dword ptr ss:[local.65], 100
00401043 |> 8BB424 1C010000 /mov esi, ss:[arg.1]
0040104A |. 8A0F |mov cl, ds:[edi]
0040104C |. 8A1C30 |mov bl, ds:[esi+eax]
0040104F |. 02D9 |add bl, cl
00401051 |. 02D3 |add dl, bl
00401053 |. 40 |inc eax
00401054 |. 885424 14 |mov ss:[local.64], dl
00401058 |. 8B7424 14 |mov esi, ss:[local.64]
0040105C |. 81E6 FF000000 |and esi, 000000FF
00401062 |. 3BC5 |cmp eax, ebp
00401064 |. 8A5C34 18 |mov bl, ss:[esi+esp+18]
00401068 |. 8D7434 18 |lea esi, [esi+esp+18]
0040106C |. 881F |mov ds:[edi], bl
0040106E |. 880E |mov ds:[esi], cl
00401070 |. 75 02 |jne short 00401074
00401072 |. 33C0 |xor eax, eax
00401074 |> 8B4C24 10 |mov ecx, ss:[local.65]
00401078 |. 47 |inc edi
00401079 |. 49 |dec ecx
0040107A |. 894C24 10 |mov ss:[local.65], ecx
0040107E |.^ 75 C3 \jnz short 00401043
00401080 |. 33C0 xor eax, eax
00401082 |. 8D8C24 17010000 lea ecx, [local.0+3]
00401089 |> 8A5404 18 /mov dl, ss:[eax+esp+18]
0040108D |. 8A19 |mov bl, ds:[ecx]
0040108F |. 02D3 |add dl, bl
00401091 |. 8A98 30604000 |mov bl, ds:[eax+406030]
00401097 |. 32DA |xor bl, dl
00401099 |. 8898 30604000 |mov ds:[eax+406030], bl
0040109F |. 40 |inc eax
004010A0 |. 49 |dec ecx
004010A1 |. 3D 80000000 |cmp eax, 80
004010A6 |.^ 7C E1 \jl short 00401089
004010A8 |. 5F pop edi
004010A9 |. 5E pop esi
004010AA |. 5D pop ebp
004010AB |. 5B pop ebx
004010AC |. 81C4 08010000 add esp, 108
004010B2 \. C3 retn
004010C0 /$ 56 push esi ; //求和校验
004010C1 |. 57 push edi
004010C2 |. 33FF xor edi, edi
004010C4 |. 33F6 xor esi, esi
004010C6 |. 33C9 xor ecx, ecx
004010C8 |> 33C0 /xor eax, eax
004010CA |. 8A81 30604000 |mov al, ds:[ecx+406030]
004010D0 |. 99 |cdq
004010D1 |. 03F8 |add edi, eax
004010D3 |. 13F2 |adc esi, edx
004010D5 |. 41 |inc ecx
004010D6 |. 81F9 80000000 |cmp ecx, 80
004010DC |.^ 7C EA \jl short 004010C8
004010DE |. 81FF 79290000 cmp edi, 2979 ; //求和必须为0x2979
004010E4 |. 75 0C jne short 004010F2
004010E6 |. 85F6 test esi, esi
004010E8 |. 75 08 jnz short 004010F2
004010EA |. 5F pop edi
004010EB |. B8 01000000 mov eax, 1
004010F0 |. 5E pop esi
004010F1 |. C3 retn
004010F2 |> 5F pop edi
004010F3 |. 33C0 xor eax, eax
004010F5 |. 5E pop esi
004010F6 \. C3 retn
根据对上面的解码函数和校验函数分析,写出下面的代码暴力破解,从'000000'到'999999'扫描:
bool keyGen()
{
BYTE buf1[0x80]={
0xF4,0x12,0x9D,0x60,0x45,0xF8,0x20,0x6A,0x6F,0x67,0x04,0x71,0xC0,0x9B,0x0C,0x5A
,0x1D,0x18,0x6C,0x96,0x69,0x01,0x1C,0xF4,0x7F,0x28,0x5A,0xFB,0x29,0x07,0x40,0x8B
,0xD3,0xE1,0xB1,0x12,0xFB,0xCA,0x7C,0x89,0xB9,0x5A,0x30,0x70,0x9D,0x95,0x2B,0x95
,0x3C,0x8D,0x2E,0x45,0xEF,0x70,0xC6,0xA3,0xB9,0xB2,0x5A,0x63,0x5F,0x03,0x33,0xB8
,0x64,0x4A,0x8F,0xBC,0xF7,0x91,0x69,0x6A,0x56,0x2E,0xD4,0x6E,0x82,0x93,0xE9,0x76
,0xDC,0xA3,0x6C,0x5E,0x6B,0x72,0x64,0x37,0xE7,0x15,0x17,0xAC,0x64,0x78,0xD5,0x4A
,0x60,0x2D,0xF0,0x54,0xA6,0xF3,0xE8,0xE0,0xE0,0xB9,0x8F,0x85,0x90,0xE4,0xEA,0xD6
,0xBB,0xB7,0x15,0x9E,0x2A,0x44,0xE7,0x31,0x63,0xAC,0x80,0x6C,0x34,0x82,0xE9,0xCF
};
DWORD magic = 0x2979;
DWORD sum;
BYTE buf2[0x100];
int idx;
char sSN[7];
int sn;
for(sn = 0 ; sn < 1000000 ; sn++){
sprintf(sSN, "%06d", sn);
for(idx = 0 ; idx < 0x100 ; idx++){
buf2[idx] = idx;
}
BYTE c = 0;
for(idx = 0 ; idx < 0x100 ; idx++){
BYTE c2 = buf2[idx];
c += (BYTE)sSN[idx % 6] + c2;
buf2[idx] = buf2[c];
buf2[c] = c2;
}
sum = 0;
for(idx = 0 ; idx < 0x80 ; idx++){
c = (buf2[idx] + buf2[0xff - idx]) ^ buf1[idx];
sum += c;
if(sum > magic){ //大于就退出,不再浪费时间
break;
}
}
if(sum == magic){ //等于,找到
OutputDebugString(sSN);
break;
}
}
if(sn >= 1000000){
OutputDebugString("未找到!");
return false;
}
return true;
}
很快能计算出结果:771535
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
他的文章
看原图
赞赏
雪币:
留言: