【破文标题】 KeyGenMe 1 by Taliesin反调试及算法分析
【破文作者】 koala
【调试工具】 Ollydbg
【破解过程】
一、反调试分析
由于程序有反调试代码,检测程序中和GetDlgItemTextA函数是否有int3断点,故考虑下消息断点,分析如下
00401230 /. 55 push ebp
00401231 |. 8BEC mov ebp, esp
00401233 |. 817D 0C 10010>cmp dword ptr [ebp+C], 110 ; WM_INITDIALOG消息
0040123A |. 75 1E jnz short 0040125A
0040123C |. 68 057F0000 push 7F05 ; /RsrcName = IDI_WINLOGO
00401241 |. 6A 00 push 0 ; |hInst = NULL
00401243 |. E8 5A030000 call <jmp.&user32.LoadIconA> ; \LoadIconA
00401248 |. 50 push eax ; /lParam
00401249 |. 6A 01 push 1 ; |wParam = 1
0040124B |. 68 80000000 push 80 ; |Message = WM_SETICON
00401250 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
00401253 |. E8 56030000 call <jmp.&user32.SendMessageA> ; \SendMessageA
00401258 |. EB 36 jmp short 00401290
0040125A |> 817D 0C 11010>cmp dword ptr [ebp+C], 111 ; WM_COMMAND消息
00401261 |. 75 1D jnz short 00401280
00401263 |. 817D 10 E9030>cmp dword ptr [ebp+10], 3E9 ; 按钮消息
0040126A |. 75 24 jnz short 00401290
0040126C |. E8 A8020000 call 00401519 ; 检测int3断点,此处下断
{
00401519 $ BF 96124000 mov edi, 00401296 ; 入口地址
0040151E . B9 00010000 mov ecx, 100
00401523 . B0 99 mov al, 99
00401525 . 34 55 xor al, 55 ; al=CC (int3)
00401527 . F2:AE repne scas byte ptr es:[edi] ; 检测
00401529 . 85C9 test ecx, ecx
0040152B . 74 06 je short 00401533 ; ecx不为0,则有断点
0040152D . 5E pop esi
0040152E . 33F6 xor esi, esi
00401530 . 57 push edi
00401531 .^ EB C2 jmp short 004014F5 ; 跳至结束
00401533 > C3 retn
}
00401271 |. E8 33020000 call 004014A9 ; 检测int3断点
{
004014A9 $ BE 9C154000 mov esi, <jmp.&user32.GetDlgItemText>
004014AE . 8B7E 02 mov edi, [esi+2]
004014B1 . 8B3F mov edi, [edi] ; user32.GetDlgItemTextA
004014B3 . B9 06000000 mov ecx, 6
004014B8 . B0 CC mov al, 0CC ; al=CC (int3)
004014BA . F2:AE repne scas byte ptr es:[edi] ; 检测
004014BC . 85C9 test ecx, ecx
004014BE . 74 06 je short 004014C6 ; ecx不为0,则有断点
004014C0 . 5E pop esi
004014C1 . 33F6 xor esi, esi
004014C3 . 57 push edi
004014C4 . EB 2F jmp short 004014F5 ; 跳至结束
004014C6 > C3 retn
}
00401276 |. FF75 08 push dword ptr [ebp+8]
00401279 |. E8 18000000 call 00401296 ; 算法call
0040127E |. EB 10 jmp short 00401290
00401280 |> 837D 0C 10 cmp dword ptr [ebp+C], 10
00401284 |. 75 0A jnz short 00401290
00401286 |. 6A 00 push 0 ; /Result = 0
00401288 |. FF75 08 push dword ptr [ebp+8] ; |hWnd
0040128B |. E8 06030000 call <jmp.&user32.EndDialog> ; \EndDialog
00401290 |> 33C0 xor eax, eax
00401292 |. C9 leave
00401293 \. C2 1000 retn 10
二、算法分析
==================== 跟进 00401279 call 00401296 ====================
00401296 $ 55 push ebp
00401297 . 8BEC mov ebp, esp
00401299 . 60 pushad
0040129A . BE FE124000 mov esi, 004012FE
0040129F . 56 push esi
004012A0 . 64:FF35 00000>push dword ptr fs:[0]
004012A7 . 64:8925 00000>mov fs:[0], esp
004012AE . FF35 3C304000 push dword ptr [40303C] ; /Count = 1E (30.)
004012B4 . 68 00304000 push 00403000 ; |
004012B9 . 68 EC030000 push 3EC ; |ControlID = 3EC (1004.)
004012BE . FF75 08 push dword ptr [ebp+8] ; |hWnd
004012C1 . E8 D6020000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004012C6 . FF35 40304000 push dword ptr [403040] ; /Count = 14 (20.)
004012CC . 68 23304000 push 00403023 ; |
004012D1 . 68 ED030000 push 3ED ; |ControlID = 3ED (1005.)
004012D6 . FF75 08 push dword ptr [ebp+8] ; |hWnd
004012D9 . E8 BE020000 call <jmp.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004012DE . E8 4F000000 call 00401332 ; 检测验证call
004012E3 . 68 53304000 push 00403053 ; zwatrqlcghpsxyenvbjdfkmu
004012E8 . E8 C9000000 call 004013B6 ; 算法call
004012ED . E8 DC010000 call 004014CE ; 验证注册码最后一位
004012F2 . 6A 00 push 0 ; /Result = 0
004012F4 . FF75 08 push dword ptr [ebp+8] ; |hWnd
004012F7 . E8 9A020000 call <jmp.&user32.EndDialog> ; \EndDialog
==================== 跟进 004012DE call 00401332 ====================
00401332 $ 33C0 xor eax, eax
00401334 . B9 00000000 mov ecx, 0
00401339 . BE 23304000 mov esi, 00403023 ; 注册码
0040133E . 8A06 mov al, [esi] ; 依次取注册码并判断是否为大写
00401340 . EB 10 jmp short 00401352
00401342 > 0FB6C0 movzx eax, al
00401345 . 80B8 50314000>cmp byte ptr [eax+403150], 2 ; (initial cpu selection)
0040134C . 75 0A jnz short 00401358
0040134E . 41 inc ecx
0040134F . 8A0431 mov al, [ecx+esi]
00401352 > 3C 00 cmp al, 0
00401354 .^ 77 EC ja short 00401342
00401356 . EB 07 jmp short 0040135F
00401358 > C605 44304000>mov byte ptr [403044], 40 ; 若注册码不是大写,设置标志
0040135F > BE 00304000 mov esi, 00403000 ; 用户名
00401364 . 33C9 xor ecx, ecx
00401366 . B8 01000000 mov eax, 1
0040136B . 33D2 xor edx, edx
0040136D . C705 45304000>mov dword ptr [403045], 0
00401377 > B9 00000000 mov ecx, 0
0040137C . 8A0C32 mov cl, [edx+esi] ; 取用户名ASCII值
0040137F . 80F9 00 cmp cl, 0
00401382 . 74 09 je short 0040138D
00401384 . 42 inc edx
00401385 . 000D 45304000 add [403045], cl
0040138B .^ EB EA jmp short 00401377
0040138D > A1 45304000 mov eax, [403045] ; 用户名ASCII累加和sum
00401392 . B9 18000000 mov ecx, 18
00401397 . 99 cdq
00401398 . F7F9 idiv ecx
0040139A . 8815 4F304000 mov [40304F], dl ; dl=sum%18h
004013A0 . 8A0D 44304000 mov cl, [403044] ; 取标志
004013A6 . 80F9 40 cmp cl, 40
004013A9 . 75 05 jnz short 004013B0
004013AB . E9 45010000 jmp 004014F5 ; 跳至结束
004013B0 > E9 CB000000 jmp 00401480
004013B5 . C3 retn
00401480 > \E8 8B000000 call 00401510
{
00401510 $ A0 24304000 mov al, [403024] ; 取注册码第二位
00401515 . 3C 45 cmp al, 45 ; 是否为'E'
00401517 .^ 75 DC jnz short 004014F5 ; 不是,跳至结束
00401519 $ BF 96124000 mov edi, 00401296 ; 入口地址
0040151E . B9 00010000 mov ecx, 100
00401523 . B0 99 mov al, 99
00401525 . 34 55 xor al, 55 ; al=CC (int3)
00401527 . F2:AE repne scas byte ptr es:[edi] ; 检测
00401529 . 85C9 test ecx, ecx
0040152B EB 06 jmp short 00401533 ; 不相等,则有断点
0040152D . 5E pop esi
0040152E . 33F6 xor esi, esi
00401530 . 57 push edi
00401531 .^ EB C2 jmp short 004014F5 ; 跳至结束
00401533 > C3 retn
}
00401485 . 33DB xor ebx, ebx
00401487 . BF 80144000 mov edi, 00401480 ; 入口地址
0040148C . 83EF 60 sub edi, 60
0040148F . B8 DE000000 mov eax, 0DE
00401494 . 83F0 12 xor eax, 12 ; al=CC
00401497 . B9 59000000 mov ecx, 59
0040149C . F2:AE repne scas byte ptr es:[edi] ; 检测
0040149E . 85C9 test ecx, ecx
004014A0 . 74 06 je short 004014A8 ; ecx不为0,则有断点
004014A2 . 5E pop esi
004014A3 . 33F6 xor esi, esi
004014A5 . 57 push edi
004014A6 . EB 4D jmp short 004014F5 ; 跳至结束
004014A8 > C3 retn
==================== 跟进 004012E8 call 004013B6 ====================
004013B6 $ 55 push ebp
004013B7 . 8BEC mov ebp, esp
004013B9 . 68 23304000 push 00403023 ; 注册码
004013BE . E8 7D010000 call 00401540
004013C3 . 83F8 0A cmp eax, 0A ; 检测注册码长度是否为10
004013C6 . 0F85 29010000 jnz 004014F5
004013CC . BE 23304000 mov esi, 00403023 ; 注册码
004013D1 . B8 00000000 mov eax, 0
004013D6 . BB 00000000 mov ebx, 0
004013DB . 33C9 xor ecx, ecx
004013DD . EB 06 jmp short 004013E5
004013DF > 8A0C30 mov cl, [eax+esi]
004013E2 . 03D9 add ebx, ecx ; 注册码ASCII累加和
004013E4 . 40 inc eax
004013E5 > 83F8 09 cmp eax, 9
004013E8 .^ 72 F5 jb short 004013DF
004013EA . 8BC3 mov eax, ebx
004013EC . B9 09000000 mov ecx, 9
004013F1 . 99 cdq
004013F2 . F7F9 idiv ecx
004013F4 . A3 4A304000 mov [40304A], eax ; 和/9的商
004013F9 . 8B7D 08 mov edi, [ebp+8]
004013FC . 8A15 4F304000 mov dl, [40304F] ; 计算用户名的结果
00401402 . 8AC2 mov al, dl
00401404 . 3C 18 cmp al, 18
00401406 . 76 02 jbe short 0040140A
00401408 . 2C 18 sub al, 18
0040140A > A2 4E304000 mov [40304E], al
0040140F . 33C0 xor eax, eax
00401411 . A0 4E304000 mov al, [40304E]
00401416 . 8A2438 mov ah, [eax+edi]
00401419 . 8A36 mov dh, [esi]
0040141B . 38F4 cmp ah, dh ; 验证注册码第一位
0040141D . 0F85 D2000000 jnz 004014F5
00401423 . 80EE 41 sub dh, 41
00401426 . 8AF2 mov dh, dl
00401428 . B4 00 mov ah, 0
0040142A . A2 4E304000 mov [40304E], al
0040142F . 33C0 xor eax, eax
00401431 . A0 4E304000 mov al, [40304E]
00401436 . 02C2 add al, dl
00401438 . 3C 18 cmp al, 18
0040143A . 76 02 jbe short 0040143E
0040143C . 2C 18 sub al, 18
0040143E > B9 02000000 mov ecx, 2
00401443 . 8A2438 mov ah, [eax+edi]
00401446 . 8A3431 mov dh, [ecx+esi]
00401449 . 38F4 cmp ah, dh ; 验证注册码第三位
0040144B . 0F85 A4000000 jnz 004014F5
00401451 . EB 24 jmp short 00401477
00401453 > A2 4E304000 mov [40304E], al
00401458 . 33C0 xor eax, eax
0040145A . A0 4E304000 mov al, [40304E]
0040145F . 80EE 41 sub dh, 41
00401462 . 8AD6 mov dl, dh
00401464 . 41 inc ecx
00401465 . 02C2 add al, dl
00401467 . 3C 18 cmp al, 18
00401469 . 76 02 jbe short 0040146D
0040146B . 2C 18 sub al, 18
0040146D > 8A2438 mov ah, [eax+edi]
00401470 . 8A3431 mov dh, [ecx+esi]
00401473 . 38F4 cmp ah, dh ; 验证注册码其余位
00401475 90 nop
00401476 90 nop
00401477 > 83F9 08 cmp ecx, 8
0040147A .^ 72 D7 jb short 00401453
0040147C . C9 leave
0040147D . C2 0400 retn 4
【注册机源码】
.data
szTable db "ZWATRQLCGHPSXYENVBJDFKMU",0
.data?
szName db 64 dup (?)
szSerial db 64 dup (?)
.code
GetSerial proc hDlg
pushad
invoke RtlZeroMemory,addr szName,sizeof szName
invoke RtlZeroMemory,addr szSerial,sizeof szSerial
invoke GetDlgItemText,hDlg,IDC_NAME,addr szName,sizeof szName
.if eax
lea esi,szName
xor eax,eax
@@:
mov cl,[esi]
or cl,cl
je @F
add al,cl
inc esi
jmp @B
@@:
xor edx,edx
mov ecx,18h
idiv ecx
lea esi,szTable
lea edi,szSerial
mov eax,edx
cmp al,18h
jbe @F
sub al,18h
@@:
mov bl,[esi+eax]
mov [edi],bl
inc edi
mov BYTE ptr [edi],'E'
inc edi
add al,dl
cmp al,18h
jbe @F
sub al,18h
@@:
mov bl,[esi+eax]
mov [edi],bl
inc edi
mov ecx,6
@L:
sub bl,41h
add al,bl
cmp al,18h
jbe @F
sub al,18h
@@:
mov bl,[esi+eax]
mov [edi],bl
inc edi
dec ecx
jnz @L
xor eax,eax
xor ebx,ebx
lea edi,szSerial
@@:
mov bl,[edi]
or bl,bl
je @F
add eax,ebx
inc edi
jmp @B
@@:
xor edx,edx
mov ecx,9
idiv ecx
mov [edi],al
invoke SetDlgItemText,hDlg,IDC_REG,addr szSerial
.else
invoke SetDlgItemText,hDlg,IDC_REG,CTXT("Please Enter Your Name.")
.endif
popad
ret
GetSerial endp
【版权声明】 本文纯属技术交流, 转载请注明作者并保持文章的完整, 谢谢!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)