[作者]aalloverred
[工具]Ollydbg
[目标]KGM1Tal.exe
[介绍]
1. Bypass debugger checks.
2. Write a keygenerator.
3. Submit keygen and tutorial.
[闲话]看到这两天这里挺热闹,我也来凑凑热闹,学习学习,望各位多多指点...
[开始]
1. Bypass debugger checks.
程序入口附近看到:
00401210 |. 6A 00 PUSH 0 ; /lParam = NULL
00401212 |. 68 30124000 PUSH KGM1Tal.00401230 ; |DlgProc = KGM1Tal.00401230
00401217 |. 6A 00 PUSH 0 ; |hOwner = NULL
00401219 |. 56 PUSH ESI ; |pTemplate
0040121A |. FF35 50324000 PUSH DWORD PTR DS:[403250] ; |hInst = 00400000
00401220 |. E8 6B030000 CALL <JMP.&user32.DialogBoxIndirectParam>; \DialogBoxIndirectParamA
所以过去看看DlgProc = KGM1Tal.00401230
00401230 /. 55 PUSH EBP
00401231 |. 8BEC MOV EBP,ESP
00401233 |. 817D 0C 100100>CMP DWORD PTR SS:[EBP+C],110 ; WM_INITDIALOG
0040123A |. 75 1E JNZ SHORT KGM1Tal.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 SS:[EBP+8] ; |hWnd
00401253 |. E8 56030000 CALL <JMP.&user32.SendMessageA> ; \SendMessageA
00401258 |. EB 36 JMP SHORT KGM1Tal.00401290
0040125A |> 817D 0C 110100>CMP DWORD PTR SS:[EBP+C],111
00401261 |. 75 1D JNZ SHORT KGM1Tal.00401280
00401263 |. 817D 10 E90300>CMP DWORD PTR SS:[EBP+10],3E9
0040126A |. 75 24 JNZ SHORT KGM1Tal.00401290
0040126C |. E8 A8020000 CALL KGM1Tal.00401519 ; 检测401296是否有断点(keygen过程
)
00401271 |. E8 33020000 CALL KGM1Tal.004014A9 ; 检测getdlgitemtext上是否有断点
00401276 |. FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401279 |. E8 18000000 CALL KGM1Tal.00401296 ;keygen 过程
0040127E |. EB 10 JMP SHORT KGM1Tal.00401290
00401280 |> 837D 0C 10 CMP DWORD PTR SS:[EBP+C],10
00401284 |. 75 0A JNZ SHORT KGM1Tal.00401290
00401286 |. 6A 00 PUSH 0 ; /Result = 0
00401288 |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040128B |. E8 06030000 CALL <JMP.&user32.EndDialog> ; \EndDialog
00401290 |> 33C0 XOR EAX,EAX
00401292 |. C9 LEAVE
00401293 \. C2 1000 RETN 10
代码看起来很短,所以几个call我就一一跟进了,首先是0040126C处的call:
00401519 $ BF 96124000 MOV EDI,KGM1Tal.00401296 ; Entry address
0040151E . B9 00010000 MOV ECX,100
00401523 . B0 99 MOV AL,99
00401525 . 34 55 XOR AL,55 ; al=CC(int 3)
00401527 . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; 测试有没有在代码检查过程中设置
断点
00401529 . 85C9 TEST ECX,ECX
0040152B . 74 06 JE SHORT KGM1Tal.00401533
0040152D . 5E POP ESI
0040152E . 33F6 XOR ESI,ESI
00401530 . 57 PUSH EDI
00401531 .^EB C2 JMP SHORT KGM1Tal.004014F5 ; 有断点,检测到CC(int3),出错
00401533 > C3 RETN
然后是00401271处的call:
004014A9 $ BE 9C154000 MOV ESI,<JMP.&user32.GetDlgItemTextA> ; Entry address
004014AE . 8B7E 02 MOV EDI,DWORD PTR DS:[ESI+2] ;指向GetDlgItemTextA地址的指针
004014B1 . 8B3F MOV EDI,DWORD PTR DS:[EDI] ;GetDlgItemTextA
004014B3 . B9 06000000 MOV ECX,6
004014B8 . B0 CC MOV AL,0CC
004014BA . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ;有没有断点?
004014BC . 85C9 TEST ECX,ECX
004014BE . 74 06 JE SHORT KGM1Tal.004014C6
004014C0 . 5E POP ESI
004014C1 . 33F6 XOR ESI,ESI
004014C3 . 57 PUSH EDI
004014C4 . EB 2F JMP SHORT KGM1Tal.004014F5 ; 有就byebye了
004014C6 > C3 RETN
最后我们终于到了00401279处的keygen过程:
00401296 $ 55 PUSH EBP
00401297 . 8BEC MOV EBP,ESP
00401299 . 60 PUSHAD
0040129A . BE FE124000 MOV ESI,KGM1Tal.004012FE
0040129F . 56 PUSH ESI
004012A0 . 64:FF35 0000000>PUSH DWORD PTR FS:[0]
004012A7 . 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
004012AE . FF35 3C304000 PUSH DWORD PTR DS:[40303C] ; /Count = 1E (30.)
004012B4 . 68 00304000 PUSH KGM1Tal.00403000 ; |Buffer = KGM1Tal.00403000
004012B9 . 68 EC030000 PUSH 3EC ; |ControlID = 3EC (1004.)
004012BE . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012C1 . E8 D6020000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004012C6 . FF35 40304000 PUSH DWORD PTR DS:[403040] ; /Count = 14 (20.)
004012CC . 68 23304000 PUSH KGM1Tal.00403023 ; |Buffer = KGM1Tal.00403023
004012D1 . 68 ED030000 PUSH 3ED ; |ControlID = 3ED (1005.)
004012D6 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012D9 . E8 BE020000 CALL <JMP.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004012DE . E8 4F000000 CALL KGM1Tal.00401332 ; 获得用户名及初步计算
004012E3 . 68 53304000 PUSH KGM1Tal.00403053 ; ASCII
"ZWATRQLCGHPSXYENVBJDFKMU"
004012E8 . E8 C9000000 CALL KGM1Tal.004013B6 ; 注册码验证
004012ED . E8 DC010000 CALL KGM1Tal.004014CE ; 显示结果
004012F2 . 6A 00 PUSH 0 ; /Result = 0
004012F4 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004012F7 . E8 9A020000 CALL <JMP.&user32.EndDialog> ; \EndDialog
先说这里:
004012DE . E8 4F000000 CALL KGM1Tal.00401332 ; 获得用户名及初步计算
===================================
00401332 $ 33C0 XOR EAX,EAX
00401334 . B9 00000000 MOV ECX,0
00401339 . BE 23304000 MOV ESI,KGM1Tal.00403023 ; ASCII "PEFWUDMPWN" 我们输
入的代码
0040133E . 8A06 MOV AL,BYTE PTR DS:[ESI]
00401340 . EB 10 JMP SHORT KGM1Tal.00401352
00401342 > 0FB6C0 MOVZX EAX,AL
00401345 . 80B8 50314000 0>CMP BYTE PTR DS:[EAX+403150],2 ; 注册码是A-Z?
0040134C . 75 0A JNZ SHORT KGM1Tal.00401358 ; 不是就设置失败标志
0040134E . 41 INC ECX
0040134F . 8A0431 MOV AL,BYTE PTR DS:[ECX+ESI]
00401352 > 3C 00 CMP AL,0
00401354 .^77 EC JA SHORT KGM1Tal.00401342
00401356 . EB 07 JMP SHORT KGM1Tal.0040135F
00401358 > C605 44304000 4>MOV BYTE PTR DS:[403044],40 ; 失败标志
0040135F > BE 00304000 MOV ESI,KGM1Tal.00403000 ; ASCII "aall"
00401364 . 33C9 XOR ECX,ECX
00401366 . B8 01000000 MOV EAX,1
0040136B . 33D2 XOR EDX,EDX
0040136D . C705 45304000 0>MOV DWORD PTR DS:[403045],0
00401377 > B9 00000000 MOV ECX,0
0040137C . 8A0C32 MOV CL,BYTE PTR DS:[EDX+ESI]
0040137F . 80F9 00 CMP CL,0
00401382 . 74 09 JE SHORT KGM1Tal.0040138D
00401384 . 42 INC EDX
00401385 . 000D 45304000 ADD BYTE PTR DS:[403045],CL
0040138B .^EB EA JMP SHORT KGM1Tal.00401377 ; 用户名字符ascii码值的和
0040138D > A1 45304000 MOV EAX,DWORD PTR DS:[403045]
00401392 . B9 18000000 MOV ECX,18
00401397 . 99 CDQ
00401398 . F7F9 IDIV ECX
0040139A . 8815 4F304000 MOV BYTE PTR DS:[40304F],DL ; 余数
004013A0 . 8A0D 44304000 MOV CL,BYTE PTR DS:[403044]
004013A6 . 80F9 40 CMP CL,40 ; 比较失败标志
004013A9 . 75 05 JNZ SHORT KGM1Tal.004013B0 ; 有失败标志就跳
004013AB . E9 45010000 JMP KGM1Tal.004014F5
004013B0 > E9 CB000000 JMP KGM1Tal.00401480 ;第二位注册码为45“E”,再次
检查断点
004013B5 . C3 RETN
到00401345这里时看到403150处的内容:
00403150 00 09 09 09 09 09 09 09 09 06 05 09 09 05 09 09 .............
00403160 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403170 06 05 05 05 09 05 05 05 05 05 04 04 05 04 05 04 .
00403180 01 01 01 01 01 01 01 01 01 01 05 05 05 05 05 05
00403190 09 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 .
004031A0 02 02 02 02 02 02 02 02 02 02 02 05 05 05 05 05
004031B0 05 03 03 03 03 03 03 03 03 03 03 03 03 03 03 03
004031C0 03 03 03 03 03 03 03 03 03 03 03 05 05 05 09 09 ..
004031D0 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
004031E0 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
004031F0 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403200 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403210 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403220 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403230 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
00403240 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 09 ................
其中403091--4030AA是02的值,与403150的差值为41-5A即"A"-"Z"
另外就是最后004013B0处的跳转:
00401480 > E8 8B000000 CALL KGM1Tal.00401510 ; 第二个字符='E'
00401485 . 33DB XOR EBX,EBX
00401487 . BF 80144000 MOV EDI,KGM1Tal.00401480
0040148C . 83EF 60 SUB EDI,60
0040148F . B8 DE000000 MOV EAX,0DE
00401494 . 83F0 12 XOR EAX,12
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 KGM1Tal.004014A8
004014A2 . 5E POP ESI
004014A3 . 33F6 XOR ESI,ESI
004014A5 . 57 PUSH EDI
004014A6 . EB 4D JMP SHORT KGM1Tal.004014F5 ; 有就失败
004014A8 > C3 RETN
接下来是真正的注册码验证,跟进004012E8的call:
004013B6 $ 55 PUSH EBP
004013B7 . 8BEC MOV EBP,ESP
004013B9 . 68 23304000 PUSH KGM1Tal.00403023 ; ASCII "PEFWUDMPWN"我的注
册码
004013BE . E8 7D010000 CALL KGM1Tal.00401540 ; 长度必须为10
004013C3 . 83F8 0A CMP EAX,0A
004013C6 . 0F85 29010000 JNZ KGM1Tal.004014F5 ; 失败跳转
004013CC . BE 23304000 MOV ESI,KGM1Tal.00403023 ; ASCII "PEFWUDMPWN"
004013D1 . B8 00000000 MOV EAX,0
004013D6 . BB 00000000 MOV EBX,0
004013DB . 33C9 XOR ECX,ECX
004013DD . EB 06 JMP SHORT KGM1Tal.004013E5
004013DF > > 8A0C30 MOV CL,BYTE PTR DS:[EAX+ESI]
004013E2 . 03D9 ADD EBX,ECX
004013E4 . 40 INC EAX
004013E5 > 83F8 09 CMP EAX,9
004013E8 .^72 F5 JB SHORT <KGM1Tal.004014CE> ; 注册码前9位的和
004013EA . 8BC3 MOV EAX,EBX
004013EC . B9 09000000 MOV ECX,9
004013F1 . 99 CDQ
004013F2 . F7F9 IDIV ECX
004013F4 . A3 4A304000 MOV DWORD PTR DS:[40304A],EAX ; 将商保存起来
004013F9 . 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8]
004013FC . 8A15 4F304000 MOV DL,BYTE PTR DS:[40304F] ; 前面的过程中保存的余数
00401402 . 8AC2 MOV AL,DL
00401404 . 3C 18 CMP AL,18
00401406 . 76 02 JBE SHORT KGM1Tal.0040140A
00401408 . 2C 18 SUB AL,18
0040140A > A2 4E304000 MOV BYTE PTR DS:[40304E],AL
0040140F . 33C0 XOR EAX,EAX
00401411 . A0 4E304000 MOV AL,BYTE PTR DS:[40304E] ; 余数〉18?余数-18:余数
00401416 . 8A2438 MOV AH,BYTE PTR DS:[EAX+EDI]
00401419 . 8A36 MOV DH,BYTE PTR DS:[ESI]
0040141B . 38F4 CMP AH,DH ; 获得索引处的常量
0040141D . 0F85 D2000000 JNZ KGM1Tal.004014F5 ; 失败跳转
00401423 . 80EE 41 SUB DH,41
00401426 . 8AF2 MOV DH,DL
00401428 . B4 00 MOV AH,0
0040142A . A2 4E304000 MOV BYTE PTR DS:[40304E],AL
0040142F . 33C0 XOR EAX,EAX
00401431 . A0 4E304000 MOV AL,BYTE PTR DS:[40304E]
00401436 . 02C2 ADD AL,DL
00401438 . 3C 18 CMP AL,18 ; 因为常量字符串的长度为18
0040143A . 76 02 JBE SHORT KGM1Tal.0040143E
0040143C . 2C 18 SUB AL,18
0040143E > B9 02000000 MOV ECX,2
00401443 . 8A2438 MOV AH,BYTE PTR DS:[EAX+EDI]
00401446 . 8A3431 MOV DH,BYTE PTR DS:[ECX+ESI] ; 注册码第三位
00401449 . 38F4 CMP AH,DH
0040144B 0F85 A4000000 JNZ KGM1Tal.004014F5
00401451 . EB 24 JMP SHORT KGM1Tal.00401477
00401453 > A2 4E304000 MOV BYTE PTR DS:[40304E],AL
00401458 . 33C0 XOR EAX,EAX
0040145A . A0 4E304000 MOV AL,BYTE PTR DS:[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 KGM1Tal.0040146D
0040146B . 2C 18 SUB AL,18
0040146D > 8A2438 MOV AH,BYTE PTR DS:[EAX+EDI]
00401470 . 8A3431 MOV DH,BYTE PTR DS:[ECX+ESI]
00401473 . 38F4 CMP AH,DH
00401475 75 7E JNZ SHORT KGM1Tal.004014F5 ; 失败跳转
00401477 > 83F9 08 CMP ECX,8 ; 比较第3-9位的注册码
0040147A .^72 D7 JB SHORT KGM1Tal.00401453
0040147C . C9 LEAVE
0040147D . C2 0400 RETN 4
马上就要完工了,就差这里了,跟进:
004012ED . E8 DC010000 CALL KGM1Tal.004014CE ; 显示结果
=========================
004014CE /$ BE 23304000 MOV ESI,KGM1Tal.00403023 ; 我们的注册码
004014D3 |. A1 4A304000 MOV EAX,DWORD PTR DS:[40304A] ; 我们注册码前9位和除以9的
商,见004013F4
004014D8 |. 8A5E 09 MOV BL,BYTE PTR DS:[ESI+9]
004014DB |. 38D8 CMP AL,BL
004014DD |. 75 16 JNZ SHORT KGM1Tal.004014F5
004014DF |. B8 6C304000 MOV EAX,KGM1Tal.0040306C ; ASCII "Great Job!"
004014E4 |. 8BD8 MOV EBX,EAX
004014E6 |. 83C3 0B ADD EBX,0B
004014E9 |. 6A 00 PUSH 0 ; /Style =
MB_OK|MB_APPLMODAL
004014EB |. 50 PUSH EAX ; |Title => "Great Job!"
004014EC |. 53 PUSH EBX ; |Text => "You have
completed Key Gen Me #1."
004014ED |. 6A 00 PUSH 0 ; |hOwner = NULL
004014EF |. E8 B4000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
004014F4 |. C3 RETN
004014F5 |> 6A 00 PUSH 0 ; /Style =
MB_OK|MB_APPLMODAL
004014F7 |. 68 C2304000 PUSH KGM1Tal.004030C2 ; |Title = "Not this time."
004014FC |. 68 99304000 PUSH KGM1Tal.00403099 ; |Text = "Try Again,
something did not work right."
00401501 |. 6A 00 PUSH 0 ; |hOwner = NULL
00401503 |. E8 A0000000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
00401508 |. 6A 00 PUSH 0 ; /
0040150A \. E8 A5000000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
0040150F . C3 RETN
2. Write a keygenerator.
然后是注册机:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
include user32.inc
include comctl32.inc
include comdlg32.inc includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib
includelib comdlg32.lib
......
.const
IDD_DLGKEYG equ 1000
IDC_EDTNAME equ 1001
IDC_EDTKEY equ 1004
IDC_BTNKEY equ 1005
IDC_BTNABOUT equ 1006
IDC_BTNEXIT equ 1007
.data
dlgtxt db "KeyGen by aal",0
dlgabout db "keygen by aal for KGM1Tal on 05/14/2006",0
lNameLen dd 0
szError db "Error",0
szNoName db "没有名字?"
s1 dd 0
s2 dd 0
s3 dd 0
sKey db 0,'E',7 dup(0),0,0
c_1 db "ZWATRQLCGHPSXYENVBJDFKMU",0
.data?
sname db 40 dup(?)
hInstance dd ?
.code
start:
invoke InitCommonControls
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,eax,IDD_DLGKEYG,NULL,offset dlgproc,0
invoke ExitProcess,NULL
dlgproc proc hWnd:DWORD,wMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,wMsg
.if eax == WM_CLOSE
invoke EndDialog,hWnd,NULL
.elseif eax == WM_INITDIALOG
invoke InitCommonControls
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == IDC_BTNKEY
invoke RtlZeroMemory,addr sname,40
invoke GetDlgItemText,hWnd,IDC_EDTNAME,addr sname,sizeof sname
mov lNameLen,eax
cmp eax,0
jz _NoName
xor ecx,ecx
xor ebx,ebx
_SumName:
mov al,byte ptr [sname+ecx]
cmp al,0
jz exit1
add bl,al
inc ecx
;cmp ecx,dword ptr [lNameLen]
;jne _SumName
jmp _SumName
exit1:
mov byte ptr [s1],bl
mov eax,dword ptr [s1]
mov ecx,18h
cdq
idiv ecx
mov byte ptr [s2],dl
cmp dl,18h
jbe _char1
sub dl,18h
_char1:
mov byte ptr [s3],dl
movzx edx,dl
mov al,byte ptr [c_1+edx]
mov byte ptr [sKey],al
mov dl,byte ptr [s3]
mov al,dl
add al,dl
cmp al,18h
jbe _char3
sub al,18h
_char3:
mov byte ptr[s3],al
movzx eax,al
mov bl,byte ptr[c_1+eax]
mov byte ptr[sKey+2],bl
mov ecx,3
_gonxt:
mov dl,bl
sub dl,41h
add al,dl
cmp al,18h
jbe _nxtchar
sub al,18h
_nxtchar:
mov byte ptr[s3],al
movzx eax,al
mov bl,byte ptr[c_1+eax]
mov byte ptr[sKey+ecx],bl
inc ecx
cmp ecx,09h
jnz _gonxt
xor ecx,ecx
xor eax,eax
_keysum:
mov bl,byte ptr[sKey+ecx]
movzx ebx,bl
add eax,ebx
inc ecx
cmp ecx,09h
jne _keysum
;mov ecx,09h
cdq
idiv ecx
mov byte ptr[sKey+9],al
invoke SetDlgItemText,hWnd,IDC_EDTKEY,addr sKey
jmp _OK
_NoName:
invoke MessageBox,hWnd,addr szNoName,addr szError,MB_OK
_OK:
.elseif eax == IDC_BTNABOUT
invoke MessageBox,hWnd,addr dlgabout,addr dlgtxt,MB_OK
.elseif eax == IDC_BTNEXIT
invoke EndDialog,hWnd,NULL
.endif
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
dlgproc endp
end start
3......
=====================================================================
[结束]
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
上传的附件: