9

[原创]看雪2016 第五题 CrackMe逆向分析

HighHand 2016-11-12 11:30 1466
OD 查找SendMessageA发现通过 WM_GETTEXT 获取序列号
00401164   .  50            push    eax                              ; /lParam
00401165   .  68 FF000000   push    0FF                              ; |wParam = FF
0040116A   .  6A 0D         push    0D                               ; |Message = WM_GETTEXT
0040116C   .  68 E9030000   push    3E9                              ; |/ControlID = 3E9 (1001.)
00401171   .  56            push    esi                              ; ||hWnd
00401172   .  FFD3          call    ebx                              ; |\GetDlgItem
00401174   .  8B2D A4504000 mov     ebp, dword ptr [<&USER32.SendMes>; |user32.SendMessageA
0040117A   .  50            push    eax                              ; |hWnd
0040117B   .  FFD5          call    ebp                              ; \SendMessageA
0040117D   .  33C9          xor     ecx, ecx
0040117F   .  85C0          test    eax, eax
00401181   .  76 17         jbe     short 0040119A
00401183   >  8A540C 20     mov     dl, byte ptr [esp+ecx+20]        ;  序列号由 0-9 数字组成
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
0040119D   .  75 56         jnz     short 004011F5                   ;  序列号长度为 6 字符
0040119F   .  85FF          test    edi, edi
004011A1   .  74 52         je      short 004011F5

下面是主要调用
004011A7   .  50            push    eax
004011A8   .  51            push    ecx
004011A9   .  E8 52FEFFFF   call    00401000                                ; 变形的RC4
004011AE   .  83C4 08       add     esp, 8
004011B1   .  E8 0AFFFFFF   call    004010C0                                ; 对结果求和
004011B6   .  85C0          test    eax, eax                                ; 返回1 成功
004011B8   .  74 2C         je      short 004011E6

RC4分析如下
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, dword ptr [esp+19]
00401017  |.  885424 18     mov     byte ptr [esp+18], 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, dword ptr [esp+18]
00401024  |.  33C0          xor     eax, eax
00401026  |>  884404 18     /mov     byte ptr [esp+eax+18], al
0040102A  |.  40            |inc     eax
0040102B  |.  3D 00010000   |cmp     eax, 100
00401030  |.^ 7C F4         \jl      short 00401026
00401032  |.  8BAC24 200100>mov     ebp, dword ptr [esp+120]         ;  asiic biao
00401039  |.  33C0          xor     eax, eax
0040103B  |.  C74424 10 000>mov     dword ptr [esp+10], 100          ;  y=0
00401043  |>  8BB424 1C0100>/mov     esi, dword ptr [esp+11C]
0040104A  |.  8A0F          |mov     cl, byte ptr [edi]              ;  t[i]
0040104C  |.  8A1C30        |mov     bl, byte ptr [eax+esi]          ;  I[i]
0040104F  |.  02D9          |add     bl, cl
00401051  |.  02D3          |add     dl, bl                          ;  y += I[i]+t1[i]
00401053  |.  40            |inc     eax
00401054  |.  885424 14     |mov     byte ptr [esp+14], dl
00401058  |.  8B7424 14     |mov     esi, dword ptr [esp+14]         ;  int (y)
0040105C  |.  81E6 FF000000 |and     esi, 0FF
00401062  |.  3BC5          |cmp     eax, ebp
00401064  |.  8A5C34 18     |mov     bl, byte ptr [esp+esi+18]       ;  t[y]
00401068  |.  8D7434 18     |lea     esi, dword ptr [esp+esi+18]     ;  t= &t[y]
0040106C  |.  881F          |mov     byte ptr [edi], bl
0040106E  |.  880E          |mov     byte ptr [esi], cl              ;  swap(t[i], t[y])
00401070  |.  75 02         |jnz     short 00401074
00401072  |.  33C0          |xor     eax, eax                        ;  j > 0 : j = 0; j < len
00401074  |>  8B4C24 10     |mov     ecx, dword ptr [esp+10]
00401078  |.  47            |inc     edi
00401079  |.  49            |dec     ecx
0040107A  |.  894C24 10     |mov     dword ptr [esp+10], ecx
0040107E  |.^ 75 C3         \jnz     short 00401043
00401080  |.  33C0          xor     eax, eax                                ; 上面是RC4 key 扩展
00401082  |.  8D8C24 170100>lea     ecx, dword ptr [esp+117]
00401089  |>  8A5404 18     /mov     dl, byte ptr [esp+eax+18]
0040108D  |.  8A19          |mov     bl, byte ptr [ecx]
0040108F  |.  02D3          |add     dl, bl
00401091  |.  8A98 30604000 |mov     bl, byte ptr [eax+406030]
00401097  |.  32DA          |xor     bl, dl
00401099  |.  8898 30604000 |mov     byte ptr [eax+406030], bl
0040109F  |.  40            |inc     eax
004010A0  |.  49            |dec     ecx
004010A1  |.  3D 80000000   |cmp     eax, 80
004010A6  |.^ 7C E1         \jl      short 00401089                        ; key表 首尾相加 与 全局表异或
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

全局表 大小为 0x80
00406030  F4 12 9D 60 45 F8 20 6A 6F 67 04 71 C0 9B 0C 5A  ?漙E?jogq罌.Z
00406040  1D 18 6C 96 69 01 1C F4 7F 28 5A FB 29 07 40 8B  l杋?(Z?@?
00406050  D3 E1 B1 12 FB CA 7C 89 B9 5A 30 70 9D 95 2B 95  俞?|壒Z0p潟+?
00406060  3C 8D 2E 45 EF 70 C6 A3 B9 B2 5A 63 5F 03 33 B8  <?E飌疲共Zc_3?
00406070  64 4A 8F BC F7 91 69 6A 56 2E D4 6E 82 93 E9 76  dJ徏鲬ijV.詎倱関
00406080  DC A3 6C 5E 6B 72 64 37 E7 15 17 AC 64 78 D5 4A  埽l^krd7?琩x認
00406090  60 2D F0 54 A6 F3 E8 E0 E0 B9 8F 85 90 E4 EA D6  `-餞栲喙弲愪曛
004060A0  BB B7 15 9E 2A 44 E7 31 63 AC 80 6C 34 82 E9 CF  环?D?c瑎l4傞?

求和 函数
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, byte ptr [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                                ; 求和结果必须为 2979
004010E4  |.  75 0C         jnz     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

枚举如下:

unsigned char buf2[128] = {
	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
};
unsigned char buf3[128];

void rc4_update(const unsigned char *key, int len)
{
	int i, j, k;
	unsigned char m[256];
	unsigned char a;

	for (i = 0; i < 256; i++)
		m[i] = (unsigned char)i;

	j = k = 0;
	for (i = 0; i < 256; i++)
	{
		a = m[i];
		j = (unsigned char)(j + a + key[k]);
		m[i] = m[j]; m[j] = a;
		if (++k >= (int)len)
			k = 0;
	}

	unsigned char *y = &m[255];
	unsigned char *x = m;
	for (i = 0; i < 128; i++)
	{
		buf3[i] = buf2[i] ^ (*x+*y);
		x++; y--;
	}
}

int main(void)
{
	char buf[8] = { 0 };

	for (int i = 0; i < 999999; i++)
	{
		sprintf(buf, "%06d", i);
		rc4_update((unsigned char*)buf, 6);

		int s = 0;
		for (int j = 0; j < 128; j++)
		{
			s += buf3[j];
		}
		if (s == 0x2979)
		{
			printf("sn=%s\n", buf);
		}
	}
}


结果:
sn=771535
最新回复 (2)
blowingluo 2017-2-17 15:21
2
爆破的时候程序异常, 直接将4010C0后面的eax 判断跳转修改爆破,本以为会显示破解成功信息,但是结果却异常了,跟进去到call 6030的时候, 发现跟进去的地址变成了603x,而不是6030 ,并且正确的密码和错误的密码,call 6030 那里f7进去的时候,汇编不一样 ,
   请问作者是在这里进行了混淆么?为什么出现 call 6030的地方 f7进去却停在6032处?
算法这块好理解,跟着看懂了,也调试了,但,为什么修改跳转爆破程序异常? 能帮忙解答下么
blowingluo 2017-2-21 14:23
3
注入爆破出密码了。
返回