首页
社区
课程
招聘
[原创]看雪2016 第十八题 CrackMe逆向分析
发表于: 2016-12-8 16:05 2965

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

2016-12-8 16:05
2965
此题比16题要难,因为大部分算法都在虚拟机中运行,而且算法复杂度远远大于16题的异或,理论上必须将虚拟机9成以上指令分析出来才能完全掌握算法。虽然虚拟机还是一如既往的简陋,可以说是手动的定制化“虚拟机”。
OD中Ctrl+N 找到 GetDlgItemTextA 来到
004010AE  |.  FF15 A0804000 call    dword ptr [<&USER32.GetDlgItemTe>; \GetDlgItemTextA
004010B4  |.  3BF4          cmp     esi, esp
004010B6  |.  E8 B1310000   call    0040426C
004010BB  |.  8D4D 98       lea     ecx, dword ptr [ebp-68]
004010BE  |.  51            push    ecx
004010BF  |.  8B55 08       mov     edx, dword ptr [ebp+8]
004010C2  |.  52            push    edx
004010C3  |.  E8 58000000   call    00401120                         ;  此处为序列号操作
004010C8  |.  83C4 08       add     esp, 8
004010CB  |>  8B45 10       mov     eax, dword ptr [ebp+10]

关键函数为 call    00401120

004011AC  |.  8D05 AC114000 lea     eax, dword ptr [4011AC]
004011B2  |.  83C0 10       add     eax, 10
004011B5  |.  50            push    eax
004011B6  \.  C3            retn
该函数分为两部分,第一部分为ret跳转,跳到第二段代码,如下:
004011CA   .  8B45 F8       mov     eax, dword ptr [ebp-8]
004011CD   .  8945 E4       mov     dword ptr [ebp-1C], eax          ;  Crackme.004080C0
004011D0   .  8B45 E4       mov     eax, dword ptr [ebp-1C]
004011D3   .  8945 E0       mov     dword ptr [ebp-20], eax
004011D6   .  8B4D DC       mov     ecx, dword ptr [ebp-24]
004011D9   .  8B55 E0       mov     edx, dword ptr [ebp-20]
可疑地址为 004080C0,通过后面的分析,发现是异常处理地址表

下面是sn异或-41操作,前9个字符
0040127B   .  8955 B0       mov     dword ptr [ebp-50], edx
0040127E   >  837D B0 08    cmp     dword ptr [ebp-50], 8            ;  sn1 - sn9
00401282   .  7F 1F         jg      short 004012A3
00401284   .  8B45 0C       mov     eax, dword ptr [ebp+C]
00401287   .  0345 B0       add     eax, dword ptr [ebp-50]
0040128A   .  0FBE08        movsx   ecx, byte ptr [eax]
0040128D   .  8B55 B0       mov     edx, dword ptr [ebp-50]
00401290   .  0FBE4415 9C   movsx   eax, byte ptr [ebp+edx-64]
00401295   .  33C8          xor     ecx, eax                         ;  sn ^ t2[i]
00401297   .  83E9 41       sub     ecx, 41                          ;  - 41
0040129A   .  8B55 B0       mov     edx, dword ptr [ebp-50]
0040129D   .  894C95 B8     mov     dword ptr [ebp+edx*4-48], ecx
004012A1   .^ EB D2         jmp     short 00401275

t2 =
0019F76C  33 21 22 21 35 7C 62 65 6E 00 CC CC 01 00 00 00  3!"!5|ben.烫...

下面是对结果比较大小,共9个int类型
004012BF   .  8945 B0       mov     dword ptr [ebp-50], eax
004012C2   >  837D B0 08    cmp     dword ptr [ebp-50], 8
004012C6   .  7D 1B         jge     short 004012E3
004012C8   .  8B4D B0       mov     ecx, dword ptr [ebp-50]
004012CB   .  8B55 B0       mov     edx, dword ptr [ebp-50]
004012CE   .  8B448D B8     mov     eax, dword ptr [ebp+ecx*4-48]
004012D2   .  3B4495 BC     cmp     eax, dword ptr [ebp+edx*4-44]
004012D6   .  7C 09         jl      short 004012E1
004012D8   .  C745 AC 01000>mov     dword ptr [ebp-54], 1
004012DF   .  EB 02         jmp     short 004012E3
t1[0] > 1
t1[0] < t1[1] < t1[2] ....

对t1做乘法,结果为x
004012F9   > /8B4D B0       mov     ecx, dword ptr [ebp-50]
004012FC   . |83C1 01       add     ecx, 1
004012FF   . |894D B0       mov     dword ptr [ebp-50], ecx
00401302   > |837D B0 09    cmp     dword ptr [ebp-50], 9
00401306   . |7D 10         jge     short 00401318
00401308   . |8B55 B0       mov     edx, dword ptr [ebp-50]
0040130B   . |8B45 A8       mov     eax, dword ptr [ebp-58]
0040130E   . |0FAF4495 B8   imul    eax, dword ptr [ebp+edx*4-48]
00401313   . |8945 A8       mov     dword ptr [ebp-58], eax
00401316   .^\EB E1         jmp     short 004012F9
x= t2[0] * t2[1] ...

x = 64/(0D4C2086-x) 需要触发异常  x == 0D4C2086
00401318   > \B9 86204C0D   mov     ecx, 0D4C2086
0040131D   .  2B4D A8       sub     ecx, dword ptr [ebp-58]
00401320   .  B8 64000000   mov     eax, 64
00401325   .  99            cdq
00401326   .  F7F9          idiv    ecx
00401328   .  8945 A8       mov     dword ptr [ebp-58], eax
如果x不为0D4C2086,则不会进入  call    004013B0,MessageBox 就在这个函数中,所以...

先不管这些(逆法后面给出),直接造个除法异常,进入 004013B0 继续跟踪

初步分析004013B0是个手动构造的vm,其vm_loop如下:
00404220   .  8995 60FDFEFF mov     dword ptr [ebp+FFFEFD60], edx
00404226   .  8B45 FC       mov     eax, dword ptr [ebp-4]
00404229   .  66:8B48 04    mov     cx, word ptr [eax+4]
0040422D   .  66:83C1 01    add     cx, 1
00404231   .  8B55 FC       mov     edx, dword ptr [ebp-4]
00404234   .  66:894A 04    mov     word ptr [edx+4], cx
00404238   .  8B85 60FDFEFF mov     eax, dword ptr [ebp+FFFEFD60]
0040423E   .  FFA485 6CFEFE>jmp     dword ptr [ebp+eax*4+FFFEFE6C]

vm_code 如下:
00195701                                   01 00 02 00 03
00195711  00 96 00 20 21 0A 00 29 01 2B 01 27 F6 FF 81 14  .? !..)+'??
00195721  21 04 00 00 01 2E 12 00 80 01 63 02 09 8B 00 20  !....€c.?
00195731  21 04 00 00 01 6F 2A 01 8B 00 20 21 04 00 00 2A  !..o*? !..*
00195741  01 8B 00 20 21 04 00 00 01 6C 2A 01 8B 00 20 21  ? !..l*? !
00195751  04 00 00 01 2E 03 01 14 00 80 01 31 2A 01 8B 00  ....€1*?
00195761  20 21 04 00 00 0B 00 20 29 D0 08 45 45 1B 2A 01   !.. . )?EE*
00195771  0B 00 20 29 D0 08 45 45 1B 2A 01 0B 00 20 29 D0   . )?EE* . )?
00195781  08 45 45 1D 2D 1D 2D 1B 02 0D 0B 00 20 29 D0 41  EE--. . )蠥
00195791  64 2A 01 11 00 20 2B D0 43 0A 2D 2A 01 11 00 20  d*. +蠧.-*.
001957A1  2B D0 2D 1D 85 21 04 00 00 01 2E 03 02 14 00 80  +??....€
001957B1  2A 01 0B 00 20 29 D0 41 0A 2A 01 11 00 20 2B D0  * . )蠥.*. +?

具体的vm_hander逆向结果如下:

81 14

21 04 00 00
01 2E
12 00 80

01 63 c
02 09
8B 00 20 cmp(sn9, c)
21 04 00 00

01 6F o
2A 01
8B 00 20 cmp(sn10, o)
21 04 00 00

2A 01 o
8B 00 20 cmp(sn11, o)
21 04 00 00

01 6C l
2A 01
8B 00 20 cmp(sn12, l)
21 04 00 00
sn9 - 12 为:
cool

01 2E
03 01
14 00 80

01 31 1
2A 01
8B 00 20 cmp(sn13, 1)
21 04 00 00

0B 00 20 load(sn13)
29 D0 add(d0)
08 copy(stk)
45 mul
45 mul
1B pop_mem
2A 01 next

0B 00 20 load(sn14)
29 D0 add(d0)
08 copy(stk)
45 mul
45 mul
1B pop_mem
2A 01  next

0B 00 20 load(sn)
29 D0
08
45
45
1D push_mem
2D add_stk
1D push_mem
2D add_stk
1B pop_mem(03)
02 0D load_imm8(sn13)

0B 00 20  load(sn13)
29 D0 add(d0)
41 64 imul(64)
2A 01   next

11 00 20 load[1](sn14)
2B D0  add[1](d0)
43 0A imul[1](0A)
2D add_stk
2A 01

11 00 20  load[1](sn15)
2B D0 add[1](d0)
2D add_stk
1D push_mem
85 sub
21 04 00 00 (6f == 03)
算法为:1^3+x^3+y^3=1xy(理解为10进制)

01 2E
03 02 load[1](02)
14 00 80
2A 01

0B 00 20  load(sn16)
29 D0  add(d0)
41 0A  imul(0a)
2A 01   next

11 00 20 load[1](sn17)
2B D0 add[1](d0)
2D add_stk
1B pop_mem(03)
2A 01

11 00 20  load[1](sn18)
2B D0  add[1](d0)
43 0A imul[1](0A)
2A 01

0B 00 20   load(sn19)
29 D0   add(d0)
30 add[1](stk) v2
1E load_mem0 v1
04 copy_[0]_v
2D add_stk_v[1]

42 04 imul[0](04)v1
43 02 imul[1](02)v2
2F add[0]([1])
81 23 cmp(23)
26 12 00 jcc
82 5E cmp[0](5e)
26 0D 00 jcc
此处算法为:
sn16*0A + sn17 = v1
sn18*0A + sn19 = v2
v1 + v2 = 23
v1*4+v2*2 = 5E

01 2E
03 03  load[1](03)
14 00 80
27 04 00 00
02 00 load0(00)
01 00 load(00)
03 2E load[1](2e)
此处检查4个 2e

98 00 80
26 05 00 jcc
29 01 add(01)
2A 01

82 04  cmp0(04)
26 F4 FF jcc
81 04 cmp(04)
26 04 00 jcc
99 00 ->ok

逆向算法如下
#include "stdafx.h"

unsigned char cch[] = { "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" };
unsigned char t2[] = { 0x33, 0x21, 0x22, 0x21, 0x35, 0x7C, 0x62, 0x65, 0x6E };

int is_ch(unsigned char c)
{
	for (int i = 0; i < sizeof(cch) - 1; i++)
	{
		if (c == cch[i])
			return 1;
	}
	return 0;
}

int test(int n, int v, int k, char *ptr)
{
	if (v < 0)
		return 0;
	if (n > 8)
	{
		if (v == 1)
			printf("%s\n", ptr);
	}
	for (int i = k+1; i < 0xFF-0x40; i++)
	{
		if (v%i)
			continue;
		unsigned char ch = (i + 0x41) ^ t2[n];
		if (!is_ch(ch))
			continue;
		ptr[n] = ch;
		test(n + 1, v / i, i, ptr);
	}
	return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
	char ptr[10] = { 0 };
	test(0, 0x0D4C2086, 1, ptr);

	for (int i = 1; i < 16; i++)
	{
		for (int j = 1; j < 16; j++)
		{
			int v = i*i*i + j*j*j+1;
			if (v > 256)
				break;
			if (v / 100 == 1)
			{
				int v1 = v % 100;
				if ((v1 / 10 == i) && (v1%10 == j))
				{
					printf("%d + %d = %d\n", i, j, v);
				}
			}
		}
	}

	int v2 = (0x23 * 4 - 0x5e) / 2;
	int v1 = 0x23 - v2;
	printf("v1 = %d, v2 = %d\n", v1, v2);

	return 0;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回