好友
阅读权限40
听众
最后登录1970-1-1
|
CM是什么?Crackme是什么?这是什么东西?楼主发的什么?
他们都是一些公开给别人尝试破解的小程序,制作 Crackme 的人可能是程序员,想测试一下自己的软件保护技术,也可能是一位 Cracker,想挑战一下其它 Cracker 的破解实力,也可能是一些正在学习破解的人,自己编一些小程序给自己破解,KeyGenMe是要求别人做出它的 keygen (序号产生器), ReverseMe 要求别人把它的算法做出逆向分析, UnpackMe 是要求别人把它成功脱壳,本版块禁止回复非技术无关水贴。
本帖最后由 playboysen 于 2013-12-30 22:34 编辑
本文针对以下CM:
http://www.52pojie.cn/thread-230220-1-1.html
主程序加了UPX壳、简单自校验什么的,直接下断GetFileSize即可轻松找到自校验
(或者根据异常提示也可以轻松定位自校验,这种方法仅限XP,Win7不显示错误信息)
XP上错误提示
自校验代码(以下截图均出自Win7X64,所以地址显示可能有异)
注册类型是机器码对应注册码,F9运行程序打开OD的Windows窗口看看控件ID
找到Edit框ID,在代码窗口直接搜索常量来定位相关处理代码
[AppleScript] 纯文本查看 复制代码 010216C7 . 51 PUSH ECX ; /lParam
010216C8 . 68 00010000 PUSH 0x100 ; |wParam = 0x100
010216CD . 0FB7F3 MOVZX ESI, BX ; |
010216D0 . 33C0 XOR EAX, EAX ; |
010216D2 . 6A 0D PUSH 0xD ; |Message = WM_GETTEXT
010216D4 . 895C24 34 MOV DWORD PTR SS:[ESP+0x34], EBX ; |
010216D8 . 8BD8 MOV EBX, EAX ; |
010216DA . 83C6 01 ADD ESI, 0x1 ; |
010216DD . 68 EA030000 PUSH 0x3EA ; |ControlID = 3EA (1002.)
010216E2 . 13C3 ADC EAX, EBX ; |
010216E4 . 52 PUSH EDX ; |hWnd => 0010070E ('crack me2:MK的杀手锏 by:MK',class='#32770')
010216E5 . 893D D8FA2301 MOV DWORD PTR DS:[0x123FAD8], EDI ; |
010216EB . 894424 40 MOV DWORD PTR SS:[ESP+0x40], EAX ; |
010216EF . FF15 3CB10201 CALL NEAR DWORD PTR DS:[0x102B13C] ; \SendDlgItemMessageA
010216F5 . 68 00010000 PUSH 0x100 ; 0x3EA是注册码EDIT框
......
01021774 . 8B4C24 14 MOV ECX, DWORD PTR SS:[ESP+0x14]
01021778 > 0FB6940C 6801>MOVZX EDX, BYTE PTR SS:[ESP+ECX+0x168] ; regcode[1]
01021780 . 885424 11 MOV BYTE PTR SS:[ESP+0x11], DL
01021784 . 0FB69434 7101>MOVZX EDX, BYTE PTR SS:[ESP+ESI+0x171] ; regcode[10]
0102178C . 885424 13 MOV BYTE PTR SS:[ESP+0x13], DL
01021790 . 0FB69404 7A01>MOVZX EDX, BYTE PTR SS:[ESP+EAX+0x17A] ; regcode[19]
01021798 . 885424 12 MOV BYTE PTR SS:[ESP+0x12], DL
0102179C . 0FB6943C 8301>MOVZX EDX, BYTE PTR SS:[ESP+EDI+0x183]
010217A4 . C6840C 680100>MOV BYTE PTR SS:[ESP+ECX+0x168], 0x0 ; 以上四字节置零
010217AC . C68434 710100>MOV BYTE PTR SS:[ESP+ESI+0x171], 0x0
010217B4 . C68404 7A0100>MOV BYTE PTR SS:[ESP+EAX+0x17A], 0x0
010217BC . 885424 10 MOV BYTE PTR SS:[ESP+0x10], DL
010217C0 . C6843C 830100>MOV BYTE PTR SS:[ESP+EDI+0x183], 0x0
010217C8 . 33C0 XOR EAX, EAX
010217CA . 8D8C24 680200>LEA ECX, DWORD PTR SS:[ESP+0x268]
010217D1 > 8A9404 680100>MOV DL, BYTE PTR SS:[ESP+EAX+0x168]
010217D8 . 84D2 TEST DL, DL
010217DA . 74 03 JE SHORT MKssj.010217DF
010217DC . 8811 MOV BYTE PTR DS:[ECX], DL
010217DE . 41 INC ECX
010217DF > 40 INC EAX
010217E0 . 83F8 24 CMP EAX, 0x24 ; 连接字符串 去除0x00共32位
010217E3 .^ 7C EC JL SHORT MKssj.010217D1
010217E5 . 8D8424 680200>LEA EAX, DWORD PTR SS:[ESP+0x268]
010217EC . 899C24 040100>MOV DWORD PTR SS:[ESP+0x104], EBX
010217F3 . 899C24 000100>MOV DWORD PTR SS:[ESP+0x100], EBX
010217FA . C78424 080100>MOV DWORD PTR SS:[ESP+0x108], 0x67452301 ; 这几组数字,标准的MD5函数
01021805 . C78424 0C0100>MOV DWORD PTR SS:[ESP+0x10C], 0xEFCDAB89
01021810 . C78424 100100>MOV DWORD PTR SS:[ESP+0x110], 0x98BADCFE
0102181B . C78424 140100>MOV DWORD PTR SS:[ESP+0x114], 0x10325476
01021826 . 8D48 01 LEA ECX, DWORD PTR DS:[EAX+0x1]
01021829 . 8DA424 000000>LEA ESP, DWORD PTR SS:[ESP]
01021830 > 8A10 MOV DL, BYTE PTR DS:[EAX]
01021832 . 40 INC EAX
01021833 . 84D2 TEST DL, DL
01021835 .^ 75 F9 JNZ SHORT MKssj.01021830
01021837 . 2BC1 SUB EAX, ECX
01021839 . 8D8C24 680200>LEA ECX, DWORD PTR SS:[ESP+0x268]
01021840 . 51 PUSH ECX
01021841 . 8DB424 040100>LEA ESI, DWORD PTR SS:[ESP+0x104]
01021848 . E8 83120000 CALL MKssj.01022AD0
0102184D . 8BC6 MOV EAX, ESI
0102184F . E8 8C130000 CALL MKssj.01022BE0
01021854 . 8D9424 5C0100>LEA EDX, DWORD PTR SS:[ESP+0x15C]
0102185B . 52 PUSH EDX
0102185C . B8 10000000 MOV EAX, 0x10
01021861 . 8D7424 38 LEA ESI, DWORD PTR SS:[ESP+0x38]
01021865 . 895C24 3C MOV DWORD PTR SS:[ESP+0x3C], EBX
01021869 . 895C24 38 MOV DWORD PTR SS:[ESP+0x38], EBX
0102186D . C74424 40 012>MOV DWORD PTR SS:[ESP+0x40], 0x67452301 ; 第二次MD5
01021875 . C74424 44 89A>MOV DWORD PTR SS:[ESP+0x44], 0xEFCDAB89
0102187D . C74424 48 FED>MOV DWORD PTR SS:[ESP+0x48], 0x98BADCFE
01021885 . C74424 4C 765>MOV DWORD PTR SS:[ESP+0x4C], 0x10325476
0102188D . E8 3E120000 CALL MKssj.01022AD0
01021892 . 8BC6 MOV EAX, ESI
01021894 . E8 47130000 CALL MKssj.01022BE0
01021899 . 8D8424 900000>LEA EAX, DWORD PTR SS:[ESP+0x90]
010218A0 . 50 PUSH EAX
010218A1 . B8 10000000 MOV EAX, 0x10
010218A6 . 8DB424 A40000>LEA ESI, DWORD PTR SS:[ESP+0xA4]
010218AD . 899C24 A80000>MOV DWORD PTR SS:[ESP+0xA8], EBX
010218B4 . 899C24 A40000>MOV DWORD PTR SS:[ESP+0xA4], EBX
010218BB . C78424 AC0000>MOV DWORD PTR SS:[ESP+0xAC], 0x67452301
010218C6 . C78424 B00000>MOV DWORD PTR SS:[ESP+0xB0], 0xEFCDAB89
010218D1 . C78424 B40000>MOV DWORD PTR SS:[ESP+0xB4], 0x98BADCFE
010218DC . C78424 B80000>MOV DWORD PTR SS:[ESP+0xB8], 0x10325476 ; 第三次MD5
010218E7 . E8 E4110000 CALL MKssj.01022AD0
010218EC . 8BC6 MOV EAX, ESI
010218EE . E8 ED120000 CALL MKssj.01022BE0
010218F3 . 68 00010000 PUSH 0x100
010218F8 . 8D8C24 780200>LEA ECX, DWORD PTR SS:[ESP+0x278]
010218FF . 53 PUSH EBX
01021900 . 51 PUSH ECX
01021901 . E8 BA610000 CALL MKssj.01027AC0
01021906 . 83C4 18 ADD ESP, 0x18
01021909 . 33F6 XOR ESI, ESI
0102190B . 8935 DCFA2301 MOV DWORD PTR DS:[0x123FADC], ESI
01021911 > 68 00010000 PUSH 0x100 ; 一个大循环
01021916 . 53 PUSH EBX
01021917 . 68 D8F92301 PUSH MKssj.0123F9D8 ; ASCII "%X%x"
0102191C . E8 9F610000 CALL MKssj.01027AC0
01021921 . 8A0D E0EC0201 MOV CL, BYTE PTR DS:[0x102ECE0] ; CL = 0x4A ‘J’
01021927 . 83C4 0C ADD ESP, 0xC
0102192A . 80F9 6F CMP CL, 0x6F
0102192D . 74 17 JE SHORT MKssj.01021946
0102192F . 33C0 XOR EAX, EAX
01021931 > 80F1 6F XOR CL, 0x6F ; 解码出"%x%x"
01021934 . 8888 D8F92301 MOV BYTE PTR DS:[EAX+0x123F9D8], CL
0102193A . 8A88 E1EC0201 MOV CL, BYTE PTR DS:[EAX+0x102ECE1]
01021940 . 40 INC EAX
01021941 . 80F9 6F CMP CL, 0x6F
01021944 .^ 75 EB JNZ SHORT MKssj.01021931
01021946 > 0FB68434 F000>MOVZX EAX, BYTE PTR SS:[ESP+ESI+0xF0]
0102194E . 8BD0 MOV EDX, EAX
01021950 . 81E2 0F000080 AND EDX, 0x8000000F
01021956 . 79 05 JNS SHORT MKssj.0102195D
01021958 . 4A DEC EDX
01021959 . 83CA F0 OR EDX, 0xFFFFFFF0
0102195C . 42 INC EDX
0102195D > 8B35 38B10201 MOV ESI, DWORD PTR DS:[0x102B138] ; user32.wsprintfA
01021963 . 52 PUSH EDX
01021964 . C1E8 04 SHR EAX, 0x4
01021967 . 50 PUSH EAX ; /<%d>
01021968 . 68 D8F92301 PUSH MKssj.0123F9D8 ; |Format = "%X%x"
0102196D . 68 E4FA2301 PUSH MKssj.0123FAE4 ; |s = MKssj.0123FAE4
01021972 . FFD6 CALL NEAR ESI ; \wsprintfA
01021974 . 68 00010000 PUSH 0x100
01021979 . 53 PUSH EBX
0102197A . 68 D8F92301 PUSH MKssj.0123F9D8 ; ASCII "%X%x"
0102197F . E8 3C610000 CALL MKssj.01027AC0
01021984 . 8A0D E8EC0201 MOV CL, BYTE PTR DS:[0x102ECE8]
0102198A . 83C4 1C ADD ESP, 0x1C
0102198D . 80F9 6F CMP CL, 0x6F
01021990 . 74 23 JE SHORT MKssj.010219B5
01021992 . 33C0 XOR EAX, EAX
01021994 . EB 0A JMP SHORT MKssj.010219A0
01021996 . 8DA424 000000>LEA ESP, DWORD PTR SS:[ESP]
0102199D . 8D49 00 LEA ECX, DWORD PTR DS:[ECX]
010219A0 > 80F1 6F XOR CL, 0x6F ; 解码出"%s%s"
010219A3 . 8888 D8F92301 MOV BYTE PTR DS:[EAX+0x123F9D8], CL
010219A9 . 8A88 E9EC0201 MOV CL, BYTE PTR DS:[EAX+0x102ECE9]
010219AF . 40 INC EAX
010219B0 . 80F9 6F CMP CL, 0x6F
010219B3 .^ 75 EB JNZ SHORT MKssj.010219A0
010219B5 > 68 E4FA2301 PUSH MKssj.0123FAE4
010219BA . 8D8424 6C0200>LEA EAX, DWORD PTR SS:[ESP+0x26C]
010219C1 . 50 PUSH EAX
010219C2 . 8BC8 MOV ECX, EAX
010219C4 . 68 D8F92301 PUSH MKssj.0123F9D8 ; ASCII "%X%x"
010219C9 . 51 PUSH ECX
010219CA . FFD6 CALL NEAR ESI
010219CC . 8B35 DCFA2301 MOV ESI, DWORD PTR DS:[0x123FADC]
010219D2 . 46 INC ESI
010219D3 . 83C4 10 ADD ESP, 0x10
010219D6 . 83FE 10 CMP ESI, 0x10
010219D9 . 8935 DCFA2301 MOV DWORD PTR DS:[0x123FADC], ESI
010219DF .^ 0F8C 2CFFFFFF JL MKssj.01021911
010219E5 . 8B5424 28 MOV EDX, DWORD PTR SS:[ESP+0x28]
010219E9 . 52 PUSH EDX ; /String2
010219EA . 8D8424 6C0200>LEA EAX, DWORD PTR SS:[ESP+0x26C] ; |
010219F1 . 50 PUSH EAX ; |String1
010219F2 . FF15 18B00201 CALL NEAR DWORD PTR DS:[0x102B018] ; \lstrcmpA
010219F8 . 85C0 TEST EAX, EAX
010219FA . 0F85 5E010000 JNZ MKssj.01021B5E ; 跳转失败
......
01021B34 . 05 A0F92301 ADD EAX, MKssj.0123F9A0 ; |
01021B39 . FF15 3CB10201 CALL NEAR DWORD PTR DS:[0x102B13C] ; \SendDlgItemMessageA
01021B3F . 8B0D ACF92301 MOV ECX, DWORD PTR DS:[0x123F9AC]
01021B45 . 6A 01 PUSH 0x1 ; /ShowState = SW_SHOWNORMAL
01021B47 . 68 EC030000 PUSH 0x3EC ; |/ControlID = 3EC (1004.)
01021B4C . 51 PUSH ECX ; ||hWnd => 0010070E ('crack me2:MK的杀手锏 by:MK',class='#32770')
01021B4D . FF15 40B10201 CALL NEAR DWORD PTR DS:[0x102B140] ; |\GetDlgItem
01021B53 . 50 PUSH EAX ; |hWnd
01021B54 . FF15 48B10201 CALL NEAR DWORD PTR DS:[0x102B148] ; \ShowWindow
......
01021C25 . 8BE5 MOV ESP, EBP
01021C27 . 5D POP EBP
01021C28 . C2 1400 RETN 0x14
大概流程就是SendDlgItemMessageA来获取并简单处理注册码EDIT文本,然后三次MD5加密运算得出的值与程序内置码表对应位置的值作比较
由于MD5为不可逆运算(更何况还变形后做了多次MD5),所以即使可以轻松找到内置码表(在010219E9断点查看数据窗口即可)也很难还原出注册码,逆向出注册机更不用说了(当然拼人品暴力算号不在讨论范围),有心之人在这里试一试爆破吧(提示:简单修改跳转是行不通的后面还有一些校验)
(这种MD5查表注册法N年前好像在Quick Batch File Compiler时遇到过,注册验证逻辑基本一致,不过QBFC是注册码一次MD5值查表对照,幸好QBFC爆破容易(一字节搞定)当初也并未深究
没想到几年后在这里又遇到了其加强改进版,颇有种“他乡遇故知”的感觉,进而想到了那句词“物是人非事事休,欲语泪先流”忽然有些伤感……)
这里不得不学习下@qq54007 的一个“猥琐”伎俩
程序枚举进程模块查找可疑点,如被调试等不提示不退出而是偷偷修改解码关键Key致使无论输入注册码正确与否均提示失败
[AppleScript] 纯文本查看 复制代码 0040221C 50 ||push eax
0040221D 68 D8F96100 ||push a_a.0061F9D8 ; ASCII "ollydbg.ini"
00402222 FF15 30B04000 ||call dword ptr ds:[<&kernel32.lstrcmpi>] ; kernel32.lstrcmpiA
00402228 85C0 ||test eax,eax
0040222A 75 22 ||jnz short a_a.0040224E
0040222C B9 45651352 ||mov ecx,52136545 ; 这里开始搞破坏了!!!
00402231 310D B0EC4000 ||xor dword ptr ds:[40ECB0],ecx ; [40ECB0]等等是用于注册解码的关键Key
00402237 310D B8EC4000 ||xor dword ptr ds:[40ECB8],ecx ; KEY被改的面目全非
0040223D B8 74981685 ||mov eax,85169874
00402242 3105 B4EC4000 ||xor dword ptr ds:[40ECB4],eax ; “偷偷的进村,打枪的不要!”
00402248 3105 BCEC4000 ||xor dword ptr ds:[40ECBC],eax ; 太猥琐鸟儿o_0
0040224E 8D8C24 2C1000>||lea ecx,dword ptr ss:[esp+102C]
00402255 51 ||push ecx
00402256 57 ||push edi
00402257 FF15 40B04000 ||call dword ptr ds:[<&kernel32.FindNextFileA>] ; kernel32.FindNextFileA
0040225D 85C0 ||test eax,eax
0040225F ^ 0F85 1BFFFFFF |\jnz a_a.00402180
00402265 57 |push edi
00402266 FF15 34B04000 |call dword ptr ds:[<&kernel32.FindClose>] ; kernel32.FindClose
既然无法还原注册机,能否替换机器码来实现一码多用?那首先得知道机器码在哪里计算出来的
如何快速定位机器码计算部分呢?程序运算出机器码后会在主界面显示出来,下端点SetDlgItemTextA或者代码段搜索Edit框ID均可
[AppleScript] 纯文本查看 复制代码 01021DC4 > \8B7424 14 MOV ESI, DWORD PTR SS:[ESP+0x14] ; Case 110 (WM_INITDIALOG) of switch 01021D14
01021DC8 . BF B0F92301 MOV EDI, MKssj.0123F9B0
01021DCD . 8935 ACF92301 MOV DWORD PTR DS:[0x123F9AC], ESI
01021DD3 . E8 38F7FFFF CALL MKssj.01021510
01021DD8 . 33FF XOR EDI, EDI
01021DDA . 803D B0F92301>CMP BYTE PTR DS:[0x123F9B0], 0x0
01021DE1 . 893D D8FA2301 MOV DWORD PTR DS:[0x123FAD8], EDI
01021DE7 . 0F84 5C010000 JE MKssj.01021F49
01021DED . 8B2D 4CB10201 MOV EBP, DWORD PTR DS:[0x102B14C] ; user32.GetDlgItemTextA
01021DF3 . 8B1D 24B00201 MOV EBX, DWORD PTR DS:[0x102B024] ; kernel32.lstrcatA
01021DF9 > 68 00010000 PUSH 0x100 ; 循环计算机器码
01021DFE . 6A 00 PUSH 0x0
01021E00 . 68 D8F92301 PUSH MKssj.0123F9D8 ; ASCII "%X%x"
01021E05 . C64424 20 00 MOV BYTE PTR SS:[ESP+0x20], 0x0
01021E0A . C64424 21 00 MOV BYTE PTR SS:[ESP+0x21], 0x0
01021E0F . C64424 22 00 MOV BYTE PTR SS:[ESP+0x22], 0x0
01021E14 . E8 A75C0000 CALL MKssj.01027AC0
01021E19 . 8A0D D8EC0201 MOV CL, BYTE PTR DS:[0x102ECD8]
01021E1F . 83C4 0C ADD ESP, 0xC
01021E22 . 80F9 6F CMP CL, 0x6F
01021E25 . 74 1E JE SHORT MKssj.01021E45
01021E27 . 33C0 XOR EAX, EAX
01021E29 . 8DA424 000000>LEA ESP, DWORD PTR SS:[ESP]
01021E30 > 80F1 6F XOR CL, 0x6F
01021E33 . 8888 D8F92301 MOV BYTE PTR DS:[EAX+0x123F9D8], CL
01021E39 . 8A88 D9EC0201 MOV CL, BYTE PTR DS:[EAX+0x102ECD9]
01021E3F . 40 INC EAX
01021E40 . 80F9 6F CMP CL, 0x6F
01021E43 .^ 75 EB JNZ SHORT MKssj.01021E30 ; ***begin***
01021E45 > 0FB687 B0F923>MOVZX EAX, BYTE PTR DS:[EDI+0x123F9B0] ; MD5(" WD-WMC1S4965023") 占16字节
01021E4C . 8BC8 MOV ECX, EAX
01021E4E . 81E1 0F000080 AND ECX, 0x8000000F ; 机器码计算过程见python代码
01021E54 . 79 05 JNS SHORT MKssj.01021E5B
01021E56 . 49 DEC ECX
01021E57 . 83C9 F0 OR ECX, 0xFFFFFFF0
01021E5A . 41 INC ECX
01021E5B > 8D1449 LEA EDX, DWORD PTR DS:[ECX+ECX*2] ; EDX = 3*ECX
01021E5E . 81E2 0F000080 AND EDX, 0x8000000F
01021E64 . 79 05 JNS SHORT MKssj.01021E6B
01021E66 . 4A DEC EDX
01021E67 . 83CA F0 OR EDX, 0xFFFFFFF0
01021E6A . 42 INC EDX
01021E6B > C1E8 04 SHR EAX, 0x4 ; md5_16[j]
01021E6E . 8D0440 LEA EAX, DWORD PTR DS:[EAX+EAX*2] ; EAX = 3*EAX
01021E71 . 25 0F000080 AND EAX, 0x8000000F
01021E76 . 52 PUSH EDX
01021E77 . 79 05 JNS SHORT MKssj.01021E7E
01021E79 . 48 DEC EAX
01021E7A . 83C8 F0 OR EAX, 0xFFFFFFF0
01021E7D . 40 INC EAX
01021E7E > 50 PUSH EAX ; /***end***
01021E7F . 8D4C24 1C LEA ECX, DWORD PTR SS:[ESP+0x1C] ; |
01021E83 . 68 D8F92301 PUSH MKssj.0123F9D8 ; |Format = "%X%x"
01021E88 . 51 PUSH ECX ; |s
01021E89 . FF15 38B10201 CALL NEAR DWORD PTR DS:[0x102B138] ; \wsprintfA
01021E8F . 83C4 10 ADD ESP, 0x10
01021E92 . 807C24 14 41 CMP BYTE PTR SS:[ESP+0x14], 0x41
01021E97 . 7C 05 JL SHORT MKssj.01021E9E
01021E99 . 804424 14 0A ADD BYTE PTR SS:[ESP+0x14], 0xA
01021E9E > 807C24 15 41 CMP BYTE PTR SS:[ESP+0x15], 0x41
01021EA3 . 7C 05 JL SHORT MKssj.01021EAA
01021EA5 . 804424 15 0A ADD BYTE PTR SS:[ESP+0x15], 0xA
01021EAA > 68 00010000 PUSH 0x100
01021EAF . 68 98F82301 PUSH MKssj.0123F898 ; ASCII "951768P9-0883351n-P25n33O3-9mM281"
01021EB4 . 68 E9030000 PUSH 0x3E9 ; 0x3E9是机器码EDIT框
01021EB9 . 56 PUSH ESI
01021EBA . FFD5 CALL NEAR EBP ; GetDlgItemTextA
01021EBC . 8D5424 14 LEA EDX, DWORD PTR SS:[ESP+0x14]
01021EC0 . 52 PUSH EDX
01021EC1 . 68 98F82301 PUSH MKssj.0123F898 ; ASCII "951768P9-0883351n-P25n33O3-9mM281"
01021EC6 . FFD3 CALL NEAR EBX ; lstrcatA
01021EC8 . 68 98F82301 PUSH MKssj.0123F898 ; /Text = "951768P9-0883351n-P25n33O3-9mM281"
01021ECD . 68 E9030000 PUSH 0x3E9 ; |ControlID = 3E9 (1001.)
01021ED2 . 56 PUSH ESI ; |hWnd
01021ED3 . FF15 54B10201 CALL NEAR DWORD PTR DS:[0x102B154] ; \SetDlgItemTextA
01021ED9 . 8B3D D8FA2301 MOV EDI, DWORD PTR DS:[0x123FAD8] ; 0x3E9是机器码EDIT框的ControlID
01021EDF . 8D47 01 LEA EAX, DWORD PTR DS:[EDI+0x1]
01021EE2 . 25 03000080 AND EAX, 0x80000003
01021EE7 . 79 05 JNS SHORT MKssj.01021EEE
01021EE9 . 48 DEC EAX
01021EEA . 83C8 FC OR EAX, 0xFFFFFFFC
01021EED . 40 INC EAX
01021EEE > 75 45 JNZ SHORT MKssj.01021F35
01021EF0 . 8D4F FF LEA ECX, DWORD PTR DS:[EDI-0x1]
01021EF3 . 83F9 0D CMP ECX, 0xD
01021EF6 . 77 3D JA SHORT MKssj.01021F35
01021EF8 . 68 00010000 PUSH 0x100
01021EFD . 68 98F82301 PUSH MKssj.0123F898 ; ASCII "951768P9-0883351n-P25n33O3-9mM281"
01021F02 . 68 E9030000 PUSH 0x3E9
01021F07 . 56 PUSH ESI
01021F08 . C74424 28 2D0>MOV DWORD PTR SS:[ESP+0x28], 0x2D
01021F10 . FFD5 CALL NEAR EBP
01021F12 . 8D5424 18 LEA EDX, DWORD PTR SS:[ESP+0x18]
01021F16 . 52 PUSH EDX
01021F17 . 68 98F82301 PUSH MKssj.0123F898 ; ASCII "951768P9-0883351n-P25n33O3-9mM281"
01021F1C . FFD3 CALL NEAR EBX
01021F1E . 68 98F82301 PUSH MKssj.0123F898 ; /Text = "951768P9-0883351n-P25n33O3-9mM281"
01021F23 . 68 E9030000 PUSH 0x3E9 ; |ControlID = 3E9 (1001.)
01021F28 . 56 PUSH ESI ; |hWnd
01021F29 . FF15 54B10201 CALL NEAR DWORD PTR DS:[0x102B154] ; \SetDlgItemTextA
01021F2F . 8B3D D8FA2301 MOV EDI, DWORD PTR DS:[0x123FAD8]
01021F35 > 47 INC EDI
01021F36 . 80BF B0F92301>CMP BYTE PTR DS:[EDI+0x123F9B0], 0x0
01021F3D . 893D D8FA2301 MOV DWORD PTR DS:[0x123FAD8], EDI
01021F43 .^ 0F85 B0FEFFFF JNZ MKssj.01021DF9
01021F49 > 6A 01 PUSH 0x1
01021F4B . 6A 20 PUSH 0x20
01021F4D . 68 50160201 PUSH MKssj.01021650 ; 回调函数地址
01021F52 . 68 E8030000 PUSH 0x3E8
01021F57 . 6A 64 PUSH 0x64
01021F59 . FF15 5CB10201 CALL NEAR DWORD PTR DS:[0x102B15C] ; winmm.timeSetEvent
01021F5F . B8 01000000 MOV EAX, 0x1
01021F64 . 5F POP EDI
01021F65 . 5E POP ESI
01021F66 . 5D POP EBP
01021F67 . 5B POP EBX
01021F68 . C2 1000 RETN 0x10
一个大循环逐位计算出机器码并写入Edit(具体计算过程见后面Python代码),最后timeSetEvent设置回调函数(就是上面那段注册码验证函数)
上面的计算都是基于字符串" WD-WMC1S4965023",看起来好像磁盘信息,不知道怎么计算出来的,下断点CreateFileA看看
[AppleScript] 纯文本查看 复制代码 01021345 > \53 PUSH EBX ; /<%d>
01021346 . 8D8424 3C0400>LEA EAX, DWORD PTR SS:[ESP+0x43C] ; |
0102134D . 68 D8F92301 PUSH MKssj.0123F9D8 ; |Format = "\\.\PhysicalDrive%d"
01021352 . 50 PUSH EAX ; |s
01021353 . FF15 38B10201 CALL NEAR DWORD PTR DS:[0x102B138] ; \wsprintfA
01021359 . 83C4 0C ADD ESP, 0xC
0102135C . 53 PUSH EBX ; /hTemplateFile
0102135D . 53 PUSH EBX ; |Attributes
0102135E . 6A 03 PUSH 0x3 ; |Mode = OPEN_EXISTING
01021360 . 53 PUSH EBX ; |pSecurity
01021361 . 6A 03 PUSH 0x3 ; |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
01021363 . 68 000000C0 PUSH 0xC0000000 ; |Access = GENERIC_READ|GENERIC_WRITE
01021368 . 8D8C24 500400>LEA ECX, DWORD PTR SS:[ESP+0x450] ; |
0102136F . 51 PUSH ECX ; |FileName
01021370 . FF15 00B00201 CALL NEAR DWORD PTR DS:[0x102B000] ; \CreateFileA
01021376 . 8BF0 MOV ESI, EAX
01021378 . 83FE FF CMP ESI, -0x1
0102137B . 75 07 JNZ SHORT MKssj.01021384
......
010213C9 . 53 PUSH EBX ; /pOverlapped
010213CA . 8D4424 14 LEA EAX, DWORD PTR SS:[ESP+0x14] ; |
010213CE . 50 PUSH EAX ; |pBytesReturned
010213CF . 68 13020000 PUSH 0x213 ; |OutBufferSize = 213 (531.)
010213D4 . 8D8C24 440500>LEA ECX, DWORD PTR SS:[ESP+0x544] ; |
010213DB . 51 PUSH ECX ; |OutBuffer
010213DC . 6A 23 PUSH 0x23 ; |InBufferSize = 23 (35.)
010213DE . 8D9424 280400>LEA EDX, DWORD PTR SS:[ESP+0x428] ; |
010213E5 . 52 PUSH EDX ; |InBuffer
010213E6 . 68 88C00700 PUSH 0x7C088 ; |IoControlCode = SMART_RCV_DRIVE_DATA
010213EB . 56 PUSH ESI ; |hDevice
010213EC . 889C24 380400>MOV BYTE PTR SS:[ESP+0x438], BL ; |
010213F3 . C68424 390400>MOV BYTE PTR SS:[ESP+0x439], 0x1 ; |
010213FB . 889C24 3B0400>MOV BYTE PTR SS:[ESP+0x43B], BL ; |
01021402 . 889C24 3C0400>MOV BYTE PTR SS:[ESP+0x43C], BL ; |
01021409 . C68424 3D0400>MOV BYTE PTR SS:[ESP+0x43D], 0xA0 ; |
01021411 . C68424 3E0400>MOV BYTE PTR SS:[ESP+0x43E], 0xEC ; |
01021419 . 889C24 400400>MOV BYTE PTR SS:[ESP+0x440], BL ; |
01021420 . C78424 340400>MOV DWORD PTR SS:[ESP+0x434], 0x200 ; |
0102142B . FF15 0CB00201 CALL NEAR DWORD PTR DS:[0x102B00C] ; \DeviceIoControl
01021431 . 85C0 TEST EAX, EAX
01021433 . 74 32 JE SHORT MKssj.01021467
01021435 . 33C0 XOR EAX, EAX
01021437 . EB 07 JMP SHORT MKssj.01021440
01021439 . 8DA424 000000>LEA ESP, DWORD PTR SS:[ESP]
01021440 > 0FB78C44 4805>MOVZX ECX, WORD PTR SS:[ESP+EAX*2+0x54>; Copy DeviceIoControl的OutBuffer
01021448 . 894C84 14 MOV DWORD PTR SS:[ESP+EAX*4+0x14], E>
0102144C . 40 INC EAX
0102144D . 3D 00010000 CMP EAX, 0x100
01021452 .^ 7C EC JL SHORT MKssj.01021440
01021454 . 8BC5 MOV EAX, EBP
01021456 . 8D4C24 14 LEA ECX, DWORD PTR SS:[ESP+0x14] ; Copy后的地址:Addr
0102145A . 895D 00 MOV DWORD PTR SS:[EBP], EBX
0102145D . E8 CEFBFFFF CALL MKssj.01021030 ; 加工Addr数据
01021462 . BF 01000000 MOV EDI, 0x1
01021467 > 56 PUSH ESI ; /hObject
01021468 . FF15 10B00201 CALL NEAR DWORD PTR DS:[0x102B010] ; \CloseHandle
看API也基本明了,具体API参数如下
[AppleScript] 纯文本查看 复制代码 0020DC30 01021376 /CALL 到 CreateFileA 来自 MKssj.01021370
0020DC34 0020E088 |FileName = "\\.\PhysicalDrive0"
0020DC38 C0000000 |Access = GENERIC_READ|GENERIC_WRITE
0020DC3C 00000003 |ShareMode = FILE_SHARE_READ|FILE_SHARE_WRITE
0020DC40 00000000 |pSecurity = NULL
0020DC44 00000003 |Mode = OPEN_EXISTING
0020DC48 00000000 |Attributes = 0
0020DC4C 00000000 \hTemplateFile = NULL
0061DF4C 00121431 /CALL 到 DeviceIoControl 来自 MKssj.0012142B
0061DF50 00000094 |hDevice = 00000094 (window)
0061DF54 0007C088 |IoControlCode = SMART_RCV_DRIVE_DATA
0061DF58 0061E384 |InBuffer = 0061E384
0061DF5C 00000023 |InBufferSize = 23 (35.)
0061DF60 0061E4A8 |OutBuffer = 0061E4A8
0061DF64 00000213 |OutBufferSize = 213 (531.)
0061DF68 0061DF80 |pBytesReturned = 0061DF80
0061DF6C 00000000 \pOverlapped = NULL
0102145D处对DeviceIoControl得出信息进行了加工
(这里要注意:如果在虚拟机中DeviceIoControl读取失败则将取"\\.\Scsi0:"值来计算,届时不触及下面的处理函数)
[AppleScript] 纯文本查看 复制代码 00311030 8B51 28 MOV EDX, DWORD PTR DS:[ECX+0x28] ; 以字节组合
00311033 C1EA 08 SHR EDX, 0x8
00311036 8810 MOV BYTE PTR DS:[EAX], DL
00311038 0FB651 28 MOVZX EDX, BYTE PTR DS:[ECX+0x28]
0031103C 8850 01 MOV BYTE PTR DS:[EAX+0x1], DL
......
003110BF 8B51 4C MOV EDX, DWORD PTR DS:[ECX+0x4C]
003110C2 8A49 4C MOV CL, BYTE PTR DS:[ECX+0x4C]
003110C5 C1EA 08 SHR EDX, 0x8
003110C8 8850 12 MOV BYTE PTR DS:[EAX+0x12], DL
003110CB 8848 13 MOV BYTE PTR DS:[EAX+0x13], CL ; 生成磁盘号字符串
003110CE C640 14 00 MOV BYTE PTR DS:[EAX+0x14], 0x0 ; '\x00'截断字符串
003110D2 B9 13000000 MOV ECX, 0x13
003110D7 803C01 20 /CMP BYTE PTR DS:[ECX+EAX], 0x20 ; 从字符串的最后一位依次处理
003110DB 75 09 |JNZ SHORT MKssj.003110E6 ; 简单的说就是删除字符串后面的空格
003110DD C60401 00 |MOV BYTE PTR DS:[ECX+EAX], 0x0
003110E1 49 |DEC ECX
003110E2 85C9 |TEST ECX, ECX
003110E4 ^ 7F F1 \JG SHORT MKssj.003110D7
003110E6 C3 RETN
DeviceIoControl_OutBuffer处理函数大致如下
将DeviceIoControl得出并二次处理过的磁盘号字符串MD5运算一次,值再经过一些运算和处理最终生成了机器码,代码见下
[Python] 纯文本查看 复制代码 import md5
from binascii import hexlify
from string import upper
#为方便运算,变量md5_16故意多设置了一位(首字节无意义可忽略)
md5_16 ='!' + md5.new(" WD-WMC1S4965023").digest()
tempID = {}
machineID = ''
for j in range(1,17):
tempID[j*2-1]= chr(((ord(md5_16[j]) >> 0x4)*3) & 0x8000000F)
if tempID[j*2-1]<=0:
tempID[j*2-1] = chr(ord(tempID[j*2-1]) - 1)
tempID[j*2-1] = chr(ord(tempID[j*2-1]) | 0xFFFFFFF0)
tempID[j*2-1] = chr(ord(tempID[j*2-1]) + 1)
tempID[j*2-1] = upper(hexlify(tempID[j*2-1])[1])
if ord(tempID[j*2-1])>=0x41:
tempID[j*2-1] = chr(ord(tempID[j*2-1]) + 0xA)
tempID[j*2] = chr(ord(md5_16[j]) & 0x8000000F)
if tempID[j*2]<=0:
tempID[j*2] = chr(ord(tempID[j*2]) - 1)
tempID[j*2] = chr(ord(tempID[j*2]) | 0xFFFFFFF0)
tempID[j*2] = chr(ord(tempID[j*2]) + 1)
tempID[j*2] = chr((ord(tempID[j*2]) * 3) & 0x8000000F)
if tempID[j*2]<=0:
tempID[j*2] = chr(ord(tempID[j*2]) - 1)
tempID[j*2] = chr(ord(tempID[j*2]) | 0xFFFFFFF0)
tempID[j*2] = chr(ord(tempID[j*2]) + 1)
tempID[j*2] = hexlify(tempID[j*2])[1]
if ord(tempID[j*2])>=0x41:
tempID[j*2] = chr(ord(tempID[j*2]) + 0xA)
#最终显示出的机器码共32位,使用"-"均分四段
for j in range(1,33):
if j in (9,17,25):
machineID = machineID + '-'
machineID = machineID +tempID[j]
print u'本机机器码是:%s' % machineID
在题目原帖第二页看到@xiaobai 和@qq54007 提供的一对机器码和注册码
http://www.52pojie.cn/thread-230220-2-1.html
机器码:Om503m10-L7K46494-2n44N8M0-1pO8L8M0
注册码:m5CYe7j3bnsW4NArE8kTA2Se6fbfNmNIKXV4
这下被我们抓住了小辫儿
经过前面分析DeviceIoControl_OutBuffer处理函数结尾处生成了磁盘号字符串,而在我的虚拟XP中该字符串为“00000000000000000001”,机器码恰好是Om503m10-L7K46494-2n44N8M0-1pO8L8M0
这就好办了,脱壳后SM主程序强制修改DeviceIoControl_OutBuffer处理函数来PATCH(即强制修改磁盘号字符串为“00000000000000000001”),PATCH前后对比如图
(PATCH的时机可以自己考虑,比如也可以尝试在机器码生成处(断点winmm.timeSetEvent直接定位)直接PATCH机器码)
PATCH前
PATCH后
为了防止DeviceIoControl读取失败导致程序不执行PATCH函数,再做个小修改
PATCH两处代码后无论在哪台电脑运行机器码都是固定的,成功注册——搞定!
查表注册固有缺点就是码表会增加程序体积、码表易受攻击、注册码数量有限(同码表值对应),且防窜改机制显得尤为重要!
本文采用机器码ID的PATCH攻击,而话音刚落@MistHill就放出了码表攻击思路(具体见28楼),@qq54007可以考虑查缺补漏再次加强
代码运算结果截图如下: |
免费评分
-
查看全部评分
|