记一次简单的逆向

本人小白,正在努力入门逆向,在此记录的是我一次次的逆向历程,而本文是一个开始。

引言

分析

随意输入用户名和序列号点击check有错误弹窗。

追踪

  • OD载入后查找字符串,定位关键代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
004010D0   .  81EC F4000000 sub esp,0xF4
004010D6 . 56 push esi ; TraceMe.<ModuleEntryPoint>
004010D7 . 57 push edi ; TraceMe.<ModuleEntryPoint>
004010D8 . B9 05000000 mov ecx,0x5
004010DD . BE 60504000 mov esi,TraceMe.00405060 ; 你输入字符要大于四个!
004010E2 . 8D7C24 18 lea edi,dword ptr ss:[esp+0x18]
004010E6 . A1 50504000 mov eax,dword ptr ds:[0x405050] ; 恭喜你!成功!
004010EB . F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
004010ED . 8B0D 54504000 mov ecx,dword ptr ds:[0x405054] ; 你!成功!
004010F3 . 8B15 58504000 mov edx,dword ptr ds:[0x405058] ; 成功!
004010F9 . 66:A5 movs word ptr es:[edi],word ptr ds:[esi]
004010FB . 894C24 0C mov dword ptr ss:[esp+0xC],ecx ; TraceMe.<ModuleEntryPoint>
004010FF . 8A0D 5E504000 mov cl,byte ptr ds:[0x40505E]
00401105 . A4 movs byte ptr es:[edi],byte ptr ds:[esi]
00401106 . 884C24 16 mov byte ptr ss:[esp+0x16],cl
0040110A . B9 05000000 mov ecx,0x5
0040110F . BE 38504000 mov esi,TraceMe.00405038 ; 序列号错误,再来一次!
00401114 . 8D7C24 30 lea edi,dword ptr ss:[esp+0x30]
00401118 . F3:A5 rep movs dword ptr es:[edi],dword ptr ds>
0040111A . 894424 08 mov dword ptr ss:[esp+0x8],eax
0040111E . 66:A1 5C50400>mov ax,word ptr ds:[0x40505C] ; !
00401124 . 66:A5 movs word ptr es:[edi],word ptr ds:[esi]
00401126 . 66:894424 14 mov word ptr ss:[esp+0x14],ax
0040112B . 8B8424 040100>mov eax,dword ptr ss:[esp+0x104]
00401132 . 83E8 10 sub eax,0x10 ; Switch (cases 10..111)
00401135 . 895424 10 mov dword ptr ss:[esp+0x10],edx ; TraceMe.<ModuleEntryPoint>
00401139 . A4 movs byte ptr es:[edi],byte ptr ds:[esi]
0040113A . 0F84 D4010000 je TraceMe.00401314
00401140 . 2D 00010000 sub eax,0x100
00401145 . 0F84 82010000 je TraceMe.004012CD
0040114B . 48 dec eax
0040114C . 0F85 6E010000 jnz TraceMe.004012C0
00401152 . 8B8424 080100>mov eax,dword ptr ss:[esp+0x108] ; Case 111 (WM_COMMAND) of switch 00401132
00401159 . 25 FFFF0000 and eax,0xFFFF
0040115E . 3D F5030000 cmp eax,0x3F5 ; Switch (cases 2..9C42)
00401163 . 0F8F 2C010000 jg TraceMe.00401295
00401169 . 74 31 je short TraceMe.0040119C
0040116B . 83E8 02 sub eax,0x2
0040116E . 74 0B je short TraceMe.0040117B
00401170 . 2D E8030000 sub eax,0x3E8
00401175 . 0F85 45010000 jnz TraceMe.004012C0
0040117B > 8B9424 000100>mov edx,dword ptr ss:[esp+0x100] ; Cases 2,3EA of switch 0040115E
00401182 . 6A 00 push 0x0 ; /lParam = 0x0
00401184 . 6A 00 push 0x0 ; |wParam = 0x0
00401186 . 6A 10 push 0x10 ; |Message = WM_CLOSE
00401188 . 52 push edx ; |hWnd = 0x4013A0
00401189 . FF15 C0404000 call dword ptr ds:[<&USER32.SendMessageA>; \SendMessageA
0040118F . 5F pop edi ; kernel32.773A62C4
00401190 . 33C0 xor eax,eax
00401192 . 5E pop esi ; kernel32.773A62C4
00401193 . 81C4 F4000000 add esp,0xF4
00401199 . C2 1000 retn 0x10
0040119C > 8BB424 000100>mov esi,dword ptr ss:[esp+0x100] ; Case 3F5 of switch 0040115E
004011A3 . 8B3D A0404000 mov edi,dword ptr ds:[<&USER32.GetDlgIte>; 勒_w
004011A9 . 53 push ebx
004011AA . 8D4424 4C lea eax,dword ptr ss:[esp+0x4C]
004011AE . 6A 51 push 0x51 ; /Count = 51 (81.)
004011B0 . 50 push eax ; |Buffer = 19D1BC69
004011B1 . 6A 6E push 0x6E ; |ControlID = 6E (110.)
004011B3 . 56 push esi ; |hWnd = 004013A0
004011B4 . FFD7 call edi ; \GetDlgItemTextA
004011B6 . 8D8C24 9C0000>lea ecx,dword ptr ss:[esp+0x9C]
004011BD . 6A 65 push 0x65 ; /Count = 65 (101.)
004011BF . 51 push ecx ; |Buffer = TraceMe.<ModuleEntryPoint>
004011C0 . 68 E8030000 push 0x3E8 ; |ControlID = 3E8 (1000.)
004011C5 . 56 push esi ; |hWnd = 004013A0
004011C6 . 8BD8 mov ebx,eax ; |
004011C8 . FFD7 call edi ; \GetDlgItemTextA
004011CA . 8A4424 4C mov al,byte ptr ss:[esp+0x4C]
004011CE . 84C0 test al,al
004011D0 . 74 76 je short TraceMe.00401248
004011D2 . 83FB 05 cmp ebx,0x5
004011D5 . 7C 71 jl short TraceMe.00401248
004011D7 . 8D5424 4C lea edx,dword ptr ss:[esp+0x4C]
004011DB . 53 push ebx
004011DC . 8D8424 A00000>lea eax,dword ptr ss:[esp+0xA0]
004011E3 . 52 push edx ; TraceMe.<ModuleEntryPoint>
004011E4 . 50 push eax
004011E5 . E8 56010000 call TraceMe.00401340 ; 关键CALL
004011EA . 8B3D BC404000 mov edi,dword ptr ds:[<&USER32.GetDlgIte>; user32.GetDlgItem
004011F0 . 83C4 0C add esp,0xC
004011F3 . 85C0 test eax,eax
004011F5 . 74 37 je short TraceMe.0040122E
004011F7 . 8D4C24 0C lea ecx,dword ptr ss:[esp+0xC]
004011FB . 51 push ecx ; /String2 = "U嬱jh蠤@"
004011FC . 68 E4544000 push TraceMe.004054E4 ; |String1 = TraceMe.004054E4
00401201 . FF15 60404000 call dword ptr ds:[<&KERNEL32.lstrcpyA>] ; \lstrcpyA
00401207 . 6A 00 push 0x0 ; /Enable = FALSE
00401209 . 6A 6E push 0x6E ; |/ControlID = 6E (110.)
0040120B . 56 push esi ; ||hWnd = 004013A0
0040120C . FFD7 call edi ; |\GetDlgItem
0040120E . 8B1D A4404000 mov ebx,dword ptr ds:[<&USER32.EnableWin>; |user32.EnableWindow
00401214 . 50 push eax ; |hWnd = 19D1BC69
00401215 . FFD3 call ebx ; \EnableWindow
00401217 . 6A 00 push 0x0 ; /Enable = FALSE
00401219 . 68 E8030000 push 0x3E8 ; |/ControlID = 3E8 (1000.)
0040121E . 56 push esi ; ||hWnd = 004013A0
0040121F . FFD7 call edi ; |\GetDlgItem
00401221 . 50 push eax ; |hWnd = 19D1BC69
00401222 . FFD3 call ebx ; \EnableWindow
00401224 . 68 E8030000 push 0x3E8 ; /ControlID = 3E8 (1000.)
00401229 . 56 push esi ; |hWnd = 004013A0
0040122A . FFD7 call edi ; \GetDlgItem
0040122C . EB 33 jmp short TraceMe.00401261
0040122E > 8D5424 34 lea edx,dword ptr ss:[esp+0x34]
00401232 . 52 push edx ; /String2 = "U嬱jh蠤@"
00401233 . 68 E4544000 push TraceMe.004054E4 ; |String1 = TraceMe.004054E4
00401238 . FF15 60404000 call dword ptr ds:[<&KERNEL32.lstrcpyA>] ; \lstrcpyA
0040123E . 68 E8030000 push 0x3E8
00401243 . 56 push esi ; TraceMe.<ModuleEntryPoint>
00401244 . FFD7 call edi ; TraceMe.<ModuleEntryPoint>
00401246 . EB 19 jmp short TraceMe.00401261
00401248 > 8D4424 1C lea eax,dword ptr ss:[esp+0x1C]
0040124C . 50 push eax ; /String2 = 19D1BC69 ???
0040124D . 68 E4544000 push TraceMe.004054E4 ; |String1 = TraceMe.004054E4
00401252 . FF15 60404000 call dword ptr ds:[<&KERNEL32.lstrcpyA>] ; \lstrcpyA
00401258 . 6A 6E push 0x6E ; /ControlID = 6E (110.)
0040125A . 56 push esi ; |hWnd = 004013A0
0040125B . FF15 BC404000 call dword ptr ds:[<&USER32.GetDlgItem>] ; \GetDlgItem
00401261 > 50 push eax ; /hWnd = 19D1BC69
00401262 . FF15 A8404000 call dword ptr ds:[<&USER32.SetFocus>] ; \SetFocus
00401268 . 6A 00 push 0x0 ; /BeepType = MB_OK
0040126A . FF15 AC404000 call dword ptr ds:[<&USER32.MessageBeep>>; \MessageBeep
00401270 . 8B0D E0544000 mov ecx,dword ptr ds:[0x4054E0]
00401276 . 6A 00 push 0x0 ; /lParam = NULL
00401278 . 68 60104000 push TraceMe.00401060 ; |DlgProc = TraceMe.00401060
0040127D . 56 push esi ; |hOwner = 004013A0
0040127E . 6A 79 push 0x79 ; |pTemplate = 0x79
00401280 . 51 push ecx ; |hInst = 004013A0
00401281 . FF15 C8404000 call dword ptr ds:[<&USER32.DialogBoxPar>; \DialogBoxParamA
00401287 . 5B pop ebx ; kernel32.773A62C4
00401288 . 5F pop edi ; kernel32.773A62C4
00401289 . 33C0 xor eax,eax
0040128B . 5E pop esi ; kernel32.773A62C4
0040128C . 81C4 F4000000 add esp,0xF4
00401292 . C2 1000 retn 0x10

两个GetDlgItemTextA以后一个CALL(4011E5),应该是把输入的用户名和注册码放到CALL中比较。
只是想知道注册码的话在4011EA处的堆栈窗口可以看到。以下分析算法。

  • 进CALL看一下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
00401340  /$  55            push ebp                                 ;  EDX 账号
00401341 |. 8B6C24 0C mov ebp,dword ptr ss:[esp+0xC] ; EAX 输入的序列号
00401345 |. 56 push esi ; EBX 账号长度
00401346 |. 57 push edi ; TraceMe.<ModuleEntryPoint>
00401347 |. 8B7C24 18 mov edi,dword ptr ss:[esp+0x18] ; edi 为账号长度
0040134B |. B9 03000000 mov ecx,0x3 ; i=3
00401350 |. 33F6 xor esi,esi ; TraceMe.<ModuleEntryPoint>
00401352 |. 33C0 xor eax,eax
00401354 |. 3BF9 cmp edi,ecx ; TraceMe.<ModuleEntryPoint>
00401356 |. 7E 21 jle short TraceMe.00401379
00401358 |. 53 push ebx
00401359 |> 83F8 07 /cmp eax,0x7
0040135C |. 7E 02 |jle short TraceMe.00401360
0040135E |. 33C0 |xor eax,eax
00401360 |> 33D2 |xor edx,edx ; TraceMe.<ModuleEntryPoint>
00401362 |. 33DB |xor ebx,ebx
00401364 |. 8A1429 |mov dl,byte ptr ds:[ecx+ebp] ; 第四位
00401367 |. 8A98 30504000 |mov bl,byte ptr ds:[eax+0x405030] ; 0C 0A 13 09 0C 0B 0A 08
0040136D |. 0FAFD3 |imul edx,ebx ; ASCII(4)*BYTE
00401370 |. 03F2 |add esi,edx ; TraceMe.<ModuleEntryPoint>
00401372 |. 41 |inc ecx ; TraceMe.<ModuleEntryPoint>
00401373 |. 40 |inc eax
00401374 |. 3BCF |cmp ecx,edi ; TraceMe.<ModuleEntryPoint>
00401376 |.^ 7C E1 \jl short TraceMe.00401359
00401378 |. 5B pop ebx ; kernel32.773A62C4
00401379 |> 56 push esi ; /<%ld> = 4013A0 (4199328.)
0040137A |. 68 78504000 push TraceMe.00405078 ; |%ld
0040137F |. 55 push ebp ; |s = 0019FF94
00401380 |. FF15 9C404000 call dword ptr ds:[<&USER32.wsprintfA>] ; \wsprintfA
00401386 |. 8B4424 1C mov eax,dword ptr ss:[esp+0x1C]
0040138A |. 83C4 0C add esp,0xC
0040138D |. 55 push ebp ; /String2 = "?"
0040138E |. 50 push eax ; |String1 = 19D1BC69 ???
0040138F |. FF15 04404000 call dword ptr ds:[<&KERNEL32.lstrcmpA>] ; \lstrcmpA
00401395 |. F7D8 neg eax
00401397 |. 1BC0 sbb eax,eax
00401399 |. 5F pop edi ; kernel32.773A62C4
0040139A |. 5E pop esi ; kernel32.773A62C4
0040139B |. 40 inc eax
0040139C |. 5D pop ebp ; kernel32.773A62C4
0040139D \. C3 retn

整个算法都在这里了。
首先用户名长度要大于4,从第4位开始到第12位结束(不到12位就提前结束),每一位的acsii码和从0x405030处开始的byte字节码做乘法,然后把所得的乘积累加,所得即为注册码。

  • 用python写个简单的注册机
1
2
3
4
5
6
7
8
9
10
11
def keygen(username):
byte405030 = [0x0C,0x0A,0x13,0x09,0x0C,0x0B,0x0A,0x08]
if len(username)<4:
return ""
start = 3
sum = 0
for i in range(0,7):
sum += ord(username[start+i])*byte405030[i]
return str(sum)

print(keygen("veritas501"))

本人新手级水平,正在努力学习中,大神勿喷