[ 破文标题 ] 对抗某反调试CM
[ 破文作者 ] riusksk(泉哥)
[ 作者邮箱 ] riusksk@qq.com
[ 作者主页 ] http://riusksk.blogbus.com
[ 破解工具 ] OD
[ 破解平台 ] Windows Vista
[ 软件名称 ] KGM1Tal.exe
[ 软件大小 ] 4.00 KB
[ 软件下载 ] CM.rar
[ 保护方式 ] 无壳
[ 软件简介 ] 老外写的CM
[ 破解声明 ] 纯属兴趣,无其它目的,如有错误,望指出!
[ 破解过程 ]-------------------------------------------------------------------------------------
打开CM,输入用户名:riusksk,密码:78787878,点击注册后,提示“Try Again,something did not work right.”因此用OD加载F9运行之后,利用“超级字符参考+”插件搜索字符串,双击字符串“Try Again,something did not work right.”后,向上查找,来到:
004014CE /$ BE 23304000 MOV ESI,KGM1Tal.00403023
004014D3 |. A1 4A304000 MOV EAX,DWORD PTR DS:[40304A]
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 ; 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 ; |not this time.
004014FC |. 68 99304000 PUSH KGM1Tal.00403099 ; |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 ; /ExitCode = 0
0040150A \. E8 A5000000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
由于004014CE来自004012ED,因此转到004012ED,并向上查找,来到这里:
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,获取用户名name
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,获取密码password
004012DE . E8 4F000000 CALL KGM1Tal.00401332
004012E3 . 68 53304000 PUSH KGM1Tal.00403053 ; zwatrqlcghpsxyenvbjdfkmu
004012E8 . E8 C9000000 CALL KGM1Tal.004013B6
004012ED . E8 DC010000 CALL KGM1Tal.004014CE
但在这里,如果你是对GetDlgItemTextA或者004012DE下断,均无法断下,而且仍会弹出之前失败的提示框,因此在这里我改用消息断点。
重新加载CM,F9运行,然后查看窗口:
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
窗口
句柄 标题 父窗口 WinProc ID 风格 扩展风格 线程 ClsProc 类
00160804 KeyGen1 - Taliesin Topmost 14C80844 00010100 主 75D52735 #32770
K000607F2 &Register 00160804 000003E9 50010000 00000004 主 75D568B2 Button
K000607FC Default IME 00160804 8C000000 主 75D935FC IME
IE001007D8 MSCTFIME UI 000607FC 8C000000 主 FFFF02F7 MSCTFIME UI
K000907CC 00160804 000003EC 50010000 00000204 主 75D56FEB Edit
K000B07CA 00160804 000003ED 50010000 00000204 主 75D56FEB Edit
K00130820 Name 00160804 000003EA 50000001 00000004 主 75D517F5 Static
E0015064A Password 00160804 000003EB 50000001 00000004 主 75D517F5 Static
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
这里我们对&Register按钮下消息断点,在此右击,选择“在ClassProc上设消息断点”,然后选择对“202 WM_COMMAND”下断,然后输入用户名:riusksk,密码:78787878,点击注册后,断在75D568B2,接着再查看内存映射,并在下面这一行设置内存访问断点:
-------------------------------------------------------------
地址=00401000
大小=00001000 (4096.)
属主=KGM1Tal 00400000
区段=.text
包含=代码
类型=Imag 01001002
访问=R
初始访问=RWE
------------------------------------------------------------
重新运行断下后,删除内存断点,来到这里:
00401230 /. 55 PUSH EBP
00401231 |. 8BEC MOV EBP,ESP
00401233 |. 817D 0C 10010>CMP DWORD PTR SS:[EBP+C],110 ; [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 11010>CMP DWORD PTR SS:[EBP+C],111 ; 111为WM_COMMAND
00401261 |. 75 1D JNZ SHORT KGM1Tal.00401280
00401263 |. 817D 10 E9030>CMP DWORD PTR SS:[EBP+10],3E9 ; 判断是否点击了按钮"register"
0040126A |. 75 24 JNZ SHORT KGM1Tal.00401290
0040126C |. E8 A8020000 CALL KGM1Tal.00401519 ;下断跟进
{
00401519 $ BF 96124000 MOV EDI,KGM1Tal.00401296 ; 入口地址
0040151E . B9 00010000 MOV ECX,100 ; 计数器
00401523 . B0 99 MOV AL,99 ; AL=99
00401525 . 34 55 XOR AL,55 ; AL=99^55=CC
00401527 . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; 循环检测
00401529 . 85C9 TEST ECX,ECX
0040152B . 74 06 JE SHORT KGM1Tal.00401533 ; 不存在int3断点则跳,否则弹出失败的提示框,也就是说在地址00401296—00401396之间不可下断
0040152D . 5E POP ESI
0040152E . 33F6 XOR ESI,ESI
00401530 . 57 PUSH EDI
00401531 .^ EB C2 JMP SHORT KGM1Tal.004014F5
00401533 > C3 RETN
}
00401271 |. E8 33020000 CALL KGM1Tal.004014A9 ;检测是否对GetDlgItemTextA下断
{
004014A9 > $ BE 9C154000 MOV ESI,<JMP.&user32.GetDlgItemTextA> ; 入口地址
004014AE . 8B7E 02 MOV EDI,DWORD PTR DS:[ESI+2]
004014B1 . 8B3F MOV EDI,DWORD PTR DS:[EDI]
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 ; 检测是否对GetDlgItemTextA下断,若存在int3断点则弹出失败的提示框
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
004014C6 > C3 RETN
}
00401276 |. FF75 08 PUSH DWORD PTR SS:[EBP+8]
00401279 |. E8 18000000 CALL KGM1Tal.00401296
{
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 00000>PUSH DWORD PTR FS:[0]
004012A7 . 64:8925 00000>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,获取用户名name
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,获取密码password
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 "78787878"
0040133E . 8A06 MOV AL,BYTE PTR DS:[ESI] ; 依次获取密码的各字节
00401340 . EB 10 JMP SHORT KGM1Tal.00401352
00401342 > 0FB6C0 MOVZX EAX,AL
00401345 . 80B8 50314000>CMP BYTE PTR DS:[EAX+403150],2 ; 判断是否为大写,不是则跳,2为大写,1为小写
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>MOV BYTE PTR DS:[403044],40 ; 设置大小写标志,40代表小写,也包括数字
0040135F > BE 00304000 MOV ESI,KGM1Tal.00403000 ; ASCII "riusksk"
00401364 . 33C9 XOR ECX,ECX
00401366 . B8 01000000 MOV EAX,1
0040136B . 33D2 XOR EDX,EDX
0040136D . C705 45304000>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 ; 将用户名各字节ASCII值相加
0040138B .^ EB EA JMP SHORT KGM1Tal.00401377
0040138D > A1 45304000 MOV EAX,DWORD PTR DS:[403045] ; 用户名各字节ASCII值累加和sum1
00401392 . B9 18000000 MOV ECX,18
00401397 . 99 CDQ
00401398 . F7F9 IDIV ECX ; sum1/18h
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
004013B5 . C3 RETN
}
这里我们将密码更改为“AAAAAAAA”,用OD重载继续调试.
00401480 > \E8 8B000000 CALL KGM1Tal.00401510
{
00401510 > $ A0 24304000 MOV AL,BYTE PTR DS:[403024] ; 由于全部为A,因此查看了下数据窗口,发现是取密码第二字节
00401515 . 3C 45 CMP AL,45 ; 判断是否为E
00401517 .^ 75 DC JNZ SHORT KGM1Tal.004014F5 ; 不是则跳向失败
00401519 > $ BF 96124000 MOV EDI,KGM1Tal.00401296 ; 入口地址
0040151E . B9 00010000 MOV ECX,100 ; 计数器
00401523 . B0 99 MOV AL,99 ; AL=99
00401525 . 34 55 XOR AL,55 ; AL=99^55=CC
00401527 . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; 循环检测
00401529 . 85C9 TEST ECX,ECX
0040152B . 74 06 JE SHORT KGM1Tal.00401533 ; 不存在int3断点则跳,否则弹出失败的提示框,也就是说401296-401396之间不可下断
0040152D . 5E POP ESI
0040152E . 33F6 XOR ESI,ESI
00401530 . 57 PUSH EDI
00401531 .^ EB C2 JMP SHORT KGM1Tal.004014F5
00401533 > C3 RETN
}
00401485 . 33DB XOR EBX,EBX
00401487 . BF 80144000 MOV EDI,KGM1Tal.00401480
0040148C . 83EF 60 SUB EDI,60
0040148F . B8 DE000000 MOV EAX,0DE ; EAX=DE
00401494 . 83F0 12 XOR EAX,12 ; EAX=DE^12=CC
00401497 . B9 59000000 MOV ECX,59
0040149C . F2:AE REPNE SCAS BYTE PTR ES:[EDI] ; 检测地址00401480—004014D9之间是否存在int3断点
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
}
004012E3 . 68 53304000 PUSH KGM1Tal.00403053 ; zwatrqlcghpsxyenvbjdfkmu
004012E8 . E8 C9000000 CALL KGM1Tal.004013B6 ;关键算法,F7跟进
{
004013B6 $ 55 PUSH EBP
004013B7 . 8BEC MOV EBP,ESP
004013B9 . 68 23304000 PUSH KGM1Tal.00403023 ; ASCII "AEAAAAAA"
004013BE . E8 7D010000 CALL KGM1Tal.00401540 ; 判断密码字节长度
{
00401540 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4] ; ASCII “AEAAAAAA”
00401544 |. 83E8 04 SUB EAX,4
00401547 |> 83C0 04 /ADD EAX,4
0040154A |. 8038 00 |CMP BYTE PTR DS:[EAX],0 ;依次判断到密码第几位结束
0040154D |. 74 30 |JE SHORT KGM1Tal.0040157F
0040154F |. 8078 01 00 |CMP BYTE PTR DS:[EAX+1],0
00401553 |. 74 20 |JE SHORT KGM1Tal.00401575
00401555 |. 8078 02 00 |CMP BYTE PTR DS:[EAX+2],0
00401559 |. 74 10 |JE SHORT KGM1Tal.0040156B
0040155B |. 8078 03 00 |CMP BYTE PTR DS:[EAX+3],0
0040155F |.^ 75 E6 \JNZ SHORT KGM1Tal.00401547
00401561 |. 2B4424 04 SUB EAX,DWORD PTR SS:[ESP+4]
00401565 |. 83C0 03 ADD EAX,3
00401568 |. C2 0400 RETN 4
0040156B |> 2B4424 04 SUB EAX,DWORD PTR SS:[ESP+4]
0040156F |. 83C0 02 ADD EAX,2
00401572 |. C2 0400 RETN 4
00401575 |> 2B4424 04 SUB EAX,DWORD PTR SS:[ESP+4]
00401579 |. 83C0 01 ADD EAX,1
0040157C |. C2 0400 RETN 4
0040157F |> 2B4424 04 SUB EAX,DWORD PTR SS:[ESP+4]
00401583 \. C2 0400 RETN 4
}
004013C3 . 83F8 0A CMP EAX,0A ; 密码长度不为10个字符则失败
004013C6 . 0F85 29010000 JNZ KGM1Tal.004014F5 ; 跳就玩完了
004013CC . BE 23304000 MOV ESI,KGM1Tal.00403023 ; ASCII "XEAAAAAAAA"
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 ; 密码各字节ASCII值累加
004013E4 . 40 INC EAX ; 计数器
004013E5 > 83F8 09 CMP EAX,9
004013E8 .^ 72 F5 JB SHORT KGM1Tal.004013DF
004013EA . 8BC3 MOV EAX,EBX ; 密码ASCII值累加和sum2
004013EC . B9 09000000 MOV ECX,9
004013F1 . 99 CDQ
004013F2 . F7F9 IDIV ECX ; sum2/9
004013F4 . A3 4A304000 MOV DWORD PTR DS:[40304A],EAX ; 商值
004013F9 . 8B7D 08 MOV EDI,DWORD PTR SS:[EBP+8] ; “ZWATRQLCGHPSXYENVBJDFKMU”
004013FC . 8A15 4F304000 MOV DL,BYTE PTR DS:[40304F] ; 之前用户名的计算结果
00401402 . 8AC2 MOV AL,DL
00401404 . 3C 18 CMP AL,18 ; 若用户名计算结果大于18h,则减去18h
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]
00401416 . 8A2438 MOV AH,BYTE PTR DS:[EAX+EDI] ; 取字符串“ZWATRQLCGHPSXYENVBJDFKMU”中的第EAX+1位字符
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 ; 用户名计算结果*2
00401438 . 3C 18 CMP AL,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] ; 取字符串“ZWATRQLCGHPSXYENVBJDFKMU”中的第EAX+1位字符
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 ; 用户名计算结果*2
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] ; 取字符串“ZWATRQLCGHPSXYENVBJDFKMU”中的第EAX+1位字符
00401470 . 8A3431 MOV DH,BYTE PTR DS:[ECX+ESI] ; 依次取密码第4-9位
00401473 . 38F4 CMP AH,DH
00401475 . 75 7E JNZ SHORT KGM1Tal.004014F5
00401477 > 83F9 08 CMP ECX,8
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 ; ASCII "XEAAAAAAAA"
004014D3 |. A1 4A304000 MOV EAX,DWORD PTR DS:[40304A] ;密码的计算结果
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 ; 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 ; |not this time.
004014FC |. 68 99304000 PUSH KGM1Tal.00403099 ; |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 ; /ExitCode = 0
0040150A \. E8 A5000000 CALL <JMP.&kernel32.ExitProcess> ; \ExitProcess
0040150F . C3 RETN
}
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
004012FC . EB 26 JMP SHORT KGM1Tal.00401324
004012FE . 8B6424 08 MOV ESP,DWORD PTR SS:[ESP+8]
00401302 . 64:8F05 00000>POP DWORD PTR FS:[0]
00401309 . 83C4 04 ADD ESP,4
0040130C . 61 POPAD
0040130D . 6A 00 PUSH 0 ; /Style = MB_OK|MB_APPLMODAL
0040130F . 68 D1304000 PUSH KGM1Tal.004030D1 ; |seh in assembly
00401314 . 68 E1304000 PUSH KGM1Tal.004030E1 ; |exception has been handled !!\n\npress ok
00401319 . 6A 00 PUSH 0 ; |hOwner = NULL
0040131B . E8 88020000 CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA
00401320 . EB 0C JMP SHORT KGM1Tal.0040132E
00401322 . EB 0A JMP SHORT KGM1Tal.0040132E
00401324 > 64:8F05 00000>POP DWORD PTR FS:[0]
0040132B . 83C4 24 ADD ESP,24
0040132E > C9 LEAVE
0040132F . C2 0400 RETN 4
[ 破解总结 ]
由于取用户名为riusksk后,在验证密码的时候,刚好取字符串“ZWATRQLCGHPSXYENVBJDFKMU”中的第18h+1位字符,也就是结束符对应的HEX值 00,显然这在密码中是不可行的,因为CM在取密码长度时就是依靠00来判断字符串是否结束,所以用户名为riusksk时,是没有对应密码的。大家可以动手调试一下,如有误,希望指出!我这里提供一组可行的用户名和注册码:
用户名:quange
密码:HEJTMPWUDM
测试结果:
注册机源码:
.386
.model flat, stdcall ;32 bit memory model
option casemap :none ;case sensitive
include windows.inc
include kernel32.inc
include user32.inc
includelib kernel32.lib
includelib user32.lib
DlgProc PROTO :HWND,:UINT,:WPARAM,:LPARAM
.const
IDD_DIALOG1 equ 101
IDC_STC1 equ 1001
IDC_STC2 equ 1002
IDC_NAME equ 1003
IDC_SERIAL equ 1004
IDC_KEYGEN equ 1005
IDC_EXIT equ 1006
.data?
hInstance dd ?
szName db 64 dup (?)
szSerial db 64 dup (?)
.data
szTable db "ZWATRQLCGHPSXYENVBJDFKMU",0
szAlert db '请输入用户名!',0
szError db '错误',0
szAuthor db 'quange',0
.code
start:
invoke GetModuleHandle,NULL
mov hInstance,eax
invoke DialogBoxParam,hInstance,IDD_DIALOG1,NULL,addr DlgProc,NULL
invoke ExitProcess,0
;########################################################################
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov eax,uMsg
.if eax==WM_INITDIALOG
invoke SetDlgItemText,hWin,IDC_NAME,addr szAuthor
.elseif eax==WM_COMMAND
mov eax,wParam
.if ax==IDC_KEYGEN
push hWin
call _GetSerial
.elseif ax==IDC_EXIT
invoke EndDialog,hWin,0
.endif
.elseif eax==WM_CLOSE
invoke EndDialog,hWin,0
.else
mov eax,FALSE
ret
.endif
mov eax,TRUE
ret
DlgProc endp
_GetSerial proc hWin
pushad
invoke GetDlgItemText,hWin,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,hWin,IDC_SERIAL,addr szSerial
.else
invoke MessageBox,hWin,addr szAlert,addr szError,MB_OK
.endif
popad
ret
_GetSerial endp
end start
测试结果:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!