首页
论坛
课程
招聘
[分享]WinLicense SDK 应用实例分析
2012-12-24 17:30 31702

[分享]WinLicense SDK 应用实例分析

2012-12-24 17:30
31702
工具:原版OllyDbg v1.10 + StrongOD + ODBGScript + "Oreans UnVirtualizer ODBG Plug-in v1.5"
声明:JFF(JUST for FUN);转载请注明出处!

实例程序来自帖子“这家伙那么恐怖吗?才下1次,没人接单指点吗?
楼主的标题确实够吸引眼球,“电击率”也算不错。程序本身已经失效,大概是人家把漏子堵上了,所以才会有这篇文章。

if 只想使用目标程序 goto :EOF else goto Label_请继续往下看


后来铁打英雄的帖子“GetDuxiuStr破解 ---WL/TMD加密”也提到这个东西,不过他是有Key的,用"Bypass HWID"方法;而我没有,只能Keygen了。

不管用那种方法,按说过了WinLicense的"License System",就应该出现用户界面了,但是程序却莫名其妙地退出了。看来作者在用户代码中还设有“机关”。

WinLicense的"许可系统"就不用再关心它了,我们从用户代码开始找。起点当然是目标的OEP。

一.寻找OEP
本例是CISC虚拟机,除注明外,以下讨论只针对CISC VM。

直接跑LCF-AT的脚本"Themida - Winlicense 1.x - 2.x Multi PRO Edition 1.2",得到:"VM OEP ADDRESS is 5C88A7"
005C88A7   68 68E57B13           PUSH    137BE568               ; VM OEP by LCF-AT
005C88AC   E9 4B6FE5FF           JMP     0041F7FC

可见,OEP被虚拟化了,所以称为"VM OEP"。稍后可以看到"Entry Point Virtualization"的值,也就是说OEP处有多少条指令被虚拟化。
"VM OEP"处为一个典型的PUSH/JMP序列:PUSH KEY/JMP VM_ENTRY。

在一个TMD/WL保护的应用中,如果虚拟机的处理器类型选择CISC,一定有3~4个VMs。Themida是3个,WinLicense是4个。
按其出现的地址顺序,将它们依次命名为VM1、VM2、VM3、VM4:
    a) VM1是主控,包括三个重要DLL(KERNEL32.dll,USER32.dll,ADVAPI32.dll)的处理;WL中HWID的生成及处理;及部分Anti Checks。
    b) VM2 & VM3 基本就是打酱油的,主要是一些Anti Checks。
    c) VM4是WL才有的,负责处理"License System"相关的东西。VM4是WinLicense中Bypass或Keygen的关键。
cektop、quosego等等那些文章中著名的CmpEcxEaxAddress就是VM4中一个Handler的有效关键指令地址,明白了道理就不用满世界去找它。

查找这些个VMs的入口/出口地址、CONTEXT地址/大小、Handlers个数等等,可以用手工或脚本,本文不再深入。虚拟机的基本信息对写脚本、或正确理解使用插件工具非常重要。

在一个CISC虚拟机中,无论以何种方式,当来到VM_ENTRY时,栈上的第一个DWORD总是KEY。我把它称为"VM CALL",对每个"VM CALL"用VM#_KEY的格式来标识,它有可能只是一个过程,也可能是一个子程序被多次调用。
比如这里,"VM OEP"跳向VM1,用VM1_137BE568来表示。

好了,VM1_137BE568究竟干了些什么?显然需要弄清楚两件事:
     i) 模拟执行了哪些被虚拟的指令,也就是人们常说的"Stolen Code"——被偷的代码;
    ii) 没有不醒的梦——总要从虚拟回到现实的:这些代码执行完后,它一定会回到用户代码段(对EXE基本上是0x401000段)继续执行接下来的代码——返回地址。

第一点在Unpacking简单保护的Themida目标时很重要——“还原OEP”,在不清楚或不愿意碰虚拟机这个“黑匣子”的情况下,人们使用“类比法”来还原,即找目标的相同编程语言、编译连接版本等入口特征信息。
在WinLicense或保护得较好的Themida目标中,“还原OEP”已显得毫无意义,特别是虚拟机处理器为RISC时,情况会更加复杂,还涉及跨区段。所以返回地址对我们更加重要。
第二点取得返回地址,很简单,拦在VM1_EXIT处。

在这里我们可以避开“黑匣子”,但是在其他地方我们却不得不面对它。要打开它,如果不借助适当的工具是很困难的——不是说不可能。
事实上,我在逆向WL中那个用来自LicenseHash的“四小天鹅”(4 DWORDs)解密LicenseFileKey[0]~[2F]的算法时,只用到了脚本;而在使用下面提到的工具时,它崩溃了。
工具不是万能的,但是确实能为我们提供极大的便利,特别是当你理解并掌握了它。

要用到的工具就是"Oreans UnVirtualizer ODBG Plug-in",来自“伟大的Deathway”——请原谅我模仿一下“建翔体”。相信很多人是知道这个工具的,但大多数人是把这柄宝剑珍藏在箱底,连取出来舞弄一下的机会都没有。
这把利剑经过数年的磨砾,不能说有多完美,但已足够“神器”。如果不会用就放弃,可惜哦!总不能永远停留在“牛B”的阶段(NB = newbie?)吧。

我们在VM1_137BE568上小试“牛刀”:
        ...                                                     ; 此处省略数十行
@Label_005C8331
        005C8331        PUSH DWORD PTR [ESP]
        005C834D        MOV EBP,DWORD PTR [ESP]
        005C836E        ADD ESP,0x4
        005C8397        ADD ESP,0x4
        005C83F4        PUSH DWORD PTR [ESP]
        005C840A        MOV EAX,DWORD PTR [ESP]
        005C8426        ADD ESP,0x4
        005C846D        ADD ESP,0x4
        005C8488        MOV EBX,DWORD PTR [ESP]
        005C849E        PUSH ECX
        005C84A5        MOV ECX,ESP
        005C84B4        ADD ECX,0x4
        005C84CE        ADD ECX,0x4
        005C8518        PUSH DWORD PTR [ESP]
        005C851F        MOV DWORD PTR [ESP],ECX
        005C8582        POP ECX
        005C85AC        POP ESP                                 ; <-***
        005C85B4        PUSH EBP                                ; emulating OEP of MFC started here
        005C85BD        MOV EBP,ESP
        005C85D3        PUSH 0xff
        005C85D8        PUSH 0x411670
        005C8603        PUSH 0x40dfec                           ; SE handler installation
        005C863A        MOV EAX,DWORD PTR FS:[0x0]
        005C86AA        PUSH EAX
        005C86BD        MOV DWORD PTR FS:[0x0],ESP
        005C86CC        SUB ESP,0x68
        005C8732        PUSH EBX
        005C8747        PUSH ESI
        005C8755        PUSH EDI
        005C8768        MOV DWORD PTR [EBP+0xffffffe8],ESP      ; [EBP-18]
        005C8798        XOR EBX,EBX
        005C87F8        MOV DWORD PTR [EBP+0xfffffffc],EBX      ; [EBP-04]
        005C8867        JMP 0x40de8a                            ; back to the real world

以上复制自"Oreans UnVirtualizer"生成的"Cisc_Uv_Dump.txt"文件。
首先,本段反汇编的地址不是现实世界的地址,而是虚拟机的取指指针ESI。其次,地址不是连续的,除了虚拟机本身 (1字节指令代码) + (0/1/2/4字节操作码) 的因素外,还有大量垃圾指令的影响。
从005C85B4到005C87F8,随便找个MFC应用的OEP对比一下,看到它的神奇了吧。
005C8867处返回到用户代码0x40de8a处:

顺便说一下,OllyDBG的SFX功能或手工查找栈上的"SEH Record"也可以找到0040DE8A处,它是现实世界中执行的第一条用户程序指令。

二.用户代码跟踪
本段代码列表显示了从MFC入口跟踪到我们所关注代码处的过程,期间含有大量的"VM CALL",其中代码的虚实转换非常有意思,可以观察到SecureEngine是怎么把他们组合到一起的。你可以跳过本节直接到第三节。
0040DE8A   6A 02                 PUSH    2
0040DE8C   E8 EB747F77           CALL    msvcrt.__set_app_type
0040DE91   90                    NOP
0040DE92   59                    POP     ECX
...
0040DF80   6A 0A                 PUSH    0A
0040DF82   58                    POP     EAX
0040DF83   50                    PUSH    EAX
0040DF84   56                    PUSH    ESI
0040DF85   53                    PUSH    EBX
0040DF86   53                    PUSH    EBX
0040DF87   E8 33650900           CALL    004A44BF
0040DF8C   90                    NOP
0040DF8D   50                    PUSH    EAX
0040DF8E   E8 91000000           CALL    0040E024               ; <-***
0040DF93   8945 98               MOV     [EBP-68], EAX
0040DF96   50                    PUSH    EAX
0040DF97   90                    NOP
0040DF98   E8 E1BE7F77           CALL    msvcrt.exit
...
0040E024   FF7424 10             PUSH    DWORD PTR [ESP+10]     ; 0000000A
0040E028   FF7424 10             PUSH    DWORD PTR [ESP+10]     ; 00152371
0040E02C   FF7424 10             PUSH    DWORD PTR [ESP+10]     ; 00000000
0040E030   FF7424 10             PUSH    DWORD PTR [ESP+10]     ; 00400000
0040E034   E8 43000000           CALL    0040E07C
0040E039   C2 1000               RETN    10
...
0040E07C   E9 AAEE9273           JMP     mfc42.#1576
...
73D3CF2B > 8BFF                  MOV     EDI, EDI               ; in mfc42.dll
...
73D3CF71   FF50 58               CALL    NEAR [EAX+58]          ; back to 004013D0
...
004013D0   55                    PUSH    EBP
004013D1   8BEC                  MOV     EBP, ESP
004013D3   6A FF                 PUSH    -1
004013D5   68 F3E04000           PUSH    0040E0F3
004013DA   64:A1 00000000        MOV     EAX, FS:[0]
004013E0   50                    PUSH    EAX
004013E1   64:8925 00000000      MOV     FS:[0], ESP
004013E8   81EC C4010000         SUB     ESP, 1C4
004013EE   53                    PUSH    EBX
004013EF   56                    PUSH    ESI
004013F0   57                    PUSH    EDI
004013F1   8BF1                  MOV     ESI, ECX
004013F3   E8 D2C70000           CALL    0040DBCA
004013F8   E9 57081E00           JMP     005E1C54
...
005E1C54   68 2D5B7D13           PUSH    137D5B2D               ; VM1_137D5B2D
005E1C59   E9 9EDBE3FF           JMP     0041F7FC               ; VM1_EXIT back to 004044E0
...
004044E0   6A FF                 PUSH    -1
004044E2   68 20E94000           PUSH    0040E920
004044E7   64:A1 00000000        MOV     EAX, FS:[0]
...
004045A2   64:890D 00000000      MOV     FS:[0], ECX
004045A9   81C4 1C010000         ADD     ESP, 11C
004045AF   C3                    RETN                           ; return to 005DCA83
...
005DCA83   68 5B957D13           PUSH    137D955B               ; 以下"VM CALL"依次执行
005DCA88   E9 6F2DE4FF           JMP     0041F7FC
005DCA8D   68 36977D13           PUSH    137D9736
005DCA92   E9 652DE4FF           JMP     0041F7FC
005DCA97   68 F1987D13           PUSH    137D98F1
005DCA9C   E9 5B2DE4FF           JMP     0041F7FC
005DCAA1   68 A69A7D13           PUSH    137D9AA6
005DCAA6   E9 512DE4FF           JMP     0041F7FC
005DCAAB   68 E79B7D13           PUSH    137D9BE7
005DCAB0   E9 472DE4FF           JMP     0041F7FC
005DCAB5   68 2B9D7D13           PUSH    137D9D2B
005DCABA   E9 3D2DE4FF           JMP     0041F7FC
005DCABF   68 C99D7D13           PUSH    137D9DC9
005DCAC4   E9 332DE4FF           JMP     0041F7FC
005DCAC9   68 F19E7D13           PUSH    137D9EF1
005DCACE   E9 292DE4FF           JMP     0041F7FC
005DCAD3   68 80A07D13           PUSH    137DA080
005DCAD8   E9 1F2DE4FF           JMP     0041F7FC
005DCADD   68 98A17D13           PUSH    137DA198
005DCAE2   E9 152DE4FF           JMP     0041F7FC
005DCAE7   68 95A27D13           PUSH    137DA295
005DCAEC   E9 0B2DE4FF           JMP     0041F7FC
005DCAF1   68 50A37D13           PUSH    137DA350
005DCAF6   E9 012DE4FF           JMP     0041F7FC
005DCAFB   68 A2A47D13           PUSH    137DA4A2
005DCB00   E9 F72CE4FF           JMP     0041F7FC
005DCB05   68 6DA67D13           PUSH    137DA66D
005DCB0A   E9 ED2CE4FF           JMP     0041F7FC
005DCB0F   68 05A77D13           PUSH    137DA705
005DCB14   E9 E32CE4FF           JMP     0041F7FC
005DCB19   68 42A87D13           PUSH    137DA842
005DCB1E   E9 D92CE4FF           JMP     0041F7FC
005DCB23   68 63A97D13           PUSH    137DA963
005DCB28   E9 CF2CE4FF           JMP     0041F7FC
005DCB2D   68 FFA97D13           PUSH    137DA9FF
005DCB32   E9 C52CE4FF           JMP     0041F7FC
005DCB37   68 28AB7D13           PUSH    137DAB28
005DCB3C   E9 BB2CE4FF           JMP     0041F7FC               ; VM1_EXIT to 00401541
...
00401541   E9 C93A1E00           JMP     005E500F
...
005E500F   68 6FAC7D13           PUSH    137DAC6F
005E5014   E9 E3A7E3FF           JMP     0041F7FC               ; VM1_EXIT to 00404C10
...
00404C10   55                    PUSH    EBP
00404C11   8BEC                  MOV     EBP, ESP
00404C13   6A FF                 PUSH    -1
00404C15   68 90EA4000           PUSH    0040EA90
00404C1A   64:A1 00000000        MOV     EAX, FS:[0]
00404C20   50                    PUSH    EAX
00404C21   64:8925 00000000      MOV     FS:[0], ESP
00404C28   81EC 28070000         SUB     ESP, 728
00404C2E   53                    PUSH    EBX
00404C2F   56                    PUSH    ESI
00404C30   57                    PUSH    EDI
00404C31   E9 78E22000           JMP     00612EAE               ; <-***
...
00612EAE   68 D22D8013           PUSH    13802DD2               ; <-***
00612EB3   E9 44C9E0FF           JMP     0041F7FC



三.用户代码中的校验分析
00404C31处的JMP指向"VM CALL":VM1_13802DD2。“机关”就在这个里面,再次祭出"Oreans UnVirtualizer"进行UnVirtualizing。
处理CISC虚拟机VM1的Handlers:

反虚拟化真实地址:

反虚拟化完成:


“反虚拟化”后(以下全部为正确流程,否则就去msvcrt.exit了):
00404C31  /EB 10                 JMP     SHORT 00404C43
00404C33  |90                    NOP
00404C34  |90                    NOP
00404C35  |90                    NOP
00404C36  |90                    NOP
00404C37  |90                    NOP
00404C38  |90                    NOP
00404C39  |90                    NOP
00404C3A  |90                    NOP
00404C3B  |90                    NOP
00404C3C  |90                    NOP
00404C3D  |90                    NOP
00404C3E  |90                    NOP
00404C3F  |90                    NOP
00404C40  |90                    NOP
00404C41  |90                    NOP
00404C42  |90                    NOP
00404C43  \8D45 DC               LEA     EAX, [EBP-24]
00404C46   50                    PUSH    EAX
00404C47   E8 94F8FFFF           CALL    004044E0               ; Get CurrentFolder to [EBP-24], "C:\Temp"
00404C4C   83C4 04               ADD     ESP, 4
00404C4F   68 E8444100           PUSH    004144E8               ; ASCII "\regkey.dat"
00404C54   8D4D D8               LEA     ECX, [EBP-28]
00404C57   50                    PUSH    EAX
00404C58   51                    PUSH    ECX
00404C59   C745 FC 00000000      MOV     DWORD PTR [EBP-4], 0
00404C60   E8 5F8F0000           CALL    0040DBC4               ; mfc42.#924, string cat, "C:\Temp\regkey.dat"
00404C65   8B00                  MOV     EAX, [EAX]
00404C67   50                    PUSH    EAX
00404C68   FF15 34004100         CALL    NEAR [410034]          ; [00410034]=02B30000, kernel32.GetFileAttributesW, ret EAX=00000020
00404C6E   83CF FF               OR      EDI, FFFFFFFF
00404C71   8D4D D8               LEA     ECX, [EBP-28]
00404C74   39F8                  CMP     EAX, EDI
00404C76   0F94C3                SETE    BL
00404C79   E8 028E0000           CALL    0040DA80
00404C7E   8D4D DC               LEA     ECX, [EBP-24]
00404C81   897D FC               MOV     [EBP-4], EDI
00404C84   E8 F78D0000           CALL    0040DA80
00404C89   84DB                  TEST    BL, BL
00404C8B  /74 1C                 JE      SHORT 00404CA9
00404C8D  |8B55 08               MOV     EDX, [EBP+8]           ; 0012FEAC, [0012FEAC]=001605F0
00404C90  |5F                    POP     EDI
00404C91  |5E                    POP     ESI
00404C92  |31C0                  XOR     EAX, EAX
00404C94  |C702 91010000         MOV     DWORD PTR [EDX], 191
00404C9A  |5B                    POP     EBX
00404C9B  |8B4D F4               MOV     ECX, [EBP-C]
00404C9E  |64:890D 00000000      MOV     FS:[0], ECX
00404CA5  |89EC                  MOV     ESP, EBP
00404CA7  |5D                    POP     EBP
00404CA8  |C3                    RETN
00404CA9  \E8 70930000           CALL    0040E01E               ; VM1_137B4E2A, ret eax=00000001

调用0040E01E实际上就是虚拟化后的SDK函数:bool WLRegCheckMachineLocked(void);
The WLRegCheckMachineLocked function determines if the current license is locked to a specific machine.
If the current license key is locked to a specific machine, the return value is True.
If the application is not licensed or the current license is not locked to a specific machine, the return value is False.


函数WLRegCheckMachineLocked用来检查当前许可证是否锁定到特定机器。是返回true,否则返回false。
00404CAE   84C0                  TEST    AL, AL                 ; Is locked to a specific machine?
00404CB0  /75 1C                 JNZ     SHORT 00404CCE         ; Yes
00404CB2  |8B45 08               MOV     EAX, [EBP+8]
00404CB5  |5F                    POP     EDI
00404CB6  |5E                    POP     ESI
00404CB7  |5B                    POP     EBX
00404CB8  |C700 92010000         MOV     DWORD PTR [EAX], 192
00404CBE  |31C0                  XOR     EAX, EAX
00404CC0  |8B4D F4               MOV     ECX, [EBP-C]
00404CC3  |64:890D 00000000      MOV     FS:[0], ECX
00404CCA  |89EC                  MOV     ESP, EBP
00404CCC  |5D                    POP     EBP
00404CCD  |C3                    RETN
00404CCE  \8D8D CCF8FFFF         LEA     ECX, [EBP-734]         ; 0012F5B0, pCustomData
00404CD4   8D95 CCFCFFFF         LEA     EDX, [EBP-334]         ; 0012F9B0, pCompanyName
00404CDA   51                    PUSH    ECX
00404CDB   8D85 CCFDFFFF         LEA     EAX, [EBP-234]         ; 0012FAB0, pName
00404CE1   52                    PUSH    EDX
00404CE2   50                    PUSH    EAX
00404CE3   E8 18930000           CALL    0040E000               ; VM1_137A376D, ret eax=00000001

调用0040E000为虚拟化后的SDK函数:bool WLRegGetLicenseInfo(char* pName, char* pCompanyName, char* pCustomData);
The WLRegGetLicenseInfo function retrieves the registration information for the current license.
If the function succeeds, the return value is True.
If the function fails, the return value is False.


函数WLRegGetLicenseInfo用来获取当前许可证的注册信息:用户名称、组织名称及用户自定义数据。成功返回true,失败返回false。
00404CE8   84C0                  TEST    AL, AL                 ; Is succeeded?
00404CEA  /75 1C                 JNZ     SHORT 00404D08         ; Yes
00404CEC  |8B4D 08               MOV     ECX, [EBP+8]
00404CEF  |5F                    POP     EDI
00404CF0  |5E                    POP     ESI
00404CF1  |31C0                  XOR     EAX, EAX
00404CF3  |C701 93010000         MOV     DWORD PTR [ECX], 193
00404CF9  |5B                    POP     EBX
00404CFA  |8B4D F4               MOV     ECX, [EBP-C]
00404CFD  |64:890D 00000000      MOV     FS:[0], ECX
00404D04  |89EC                  MOV     ESP, EBP
00404D06  |5D                    POP     EBP
00404D07  |C3                    RETN
00404D08  \8D95 CCFDFFFF         LEA     EDX, [EBP-234]         ; pName
00404D0E   8D4D E8               LEA     ECX, [EBP-18]          ; 0012FCCC
00404D11   52                    PUSH    EDX
00404D12   E8 898E0000           CALL    0040DBA0               ; mfc42.#537, copy to [EBP-18]
00404D17   8D85 CCF8FFFF         LEA     EAX, [EBP-734]         ; pCustomData
00404D1D   8D4D F0               LEA     ECX, [EBP-10]
00404D20   50                    PUSH    EAX
00404D21   C745 FC 01000000      MOV     DWORD PTR [EBP-4], 1
00404D28   E8 738E0000           CALL    0040DBA0               ; mfc42.#537, copy to [EBP-10]
00404D2D   8B4D E8               MOV     ECX, [EBP-18]
00404D30   C645 FC 02            MOV     BYTE PTR [EBP-4], 2
00404D34   8B41 F8               MOV     EAX, [ECX-8]           ; length of Name
00404D37   83F8 02               CMP     EAX, 2
00404D3A   0F8C D7020000         JL      00405017
00404D40   83F8 0A               CMP     EAX, 0A                ; 0x02 <= length of Name <= 0x0A
00404D43   0F8F CE020000         JG      00405017

用户名字符串长度限制:大于等于2,小于等于10。
00404D49   8B55 F0               MOV     EDX, [EBP-10]
00404D4C   8B42 F8               MOV     EAX, [EDX-8]           ; length of CustomData
00404D4F   83F8 31               CMP     EAX, 31
00404D52   0F8F B4020000         JG      0040500C
00404D58   83F8 27               CMP     EAX, 27
00404D5B   0F8C AB020000         JL      0040500C               ; 0x27 <= length of CustomData <= 0x31

自定义字符串长度限制:大于等于39,小于等于49。
00404D61   68 E4444100           PUSH    004144E4               ; pointer to delimiter char: 0x7C('|')
00404D66   8D4D F0               LEA     ECX, [EBP-10]
00404D69   E8 4C8F0000           CALL    0040DCBA               ; mfc42.#2764, search '|' in CustomData string

查找自定义字符串中的分隔符'|'。
00404D6E   50                    PUSH    EAX
00404D6F   8D45 E0               LEA     EAX, [EBP-20]
00404D72   50                    PUSH    EAX
00404D73   8D4D F0               LEA     ECX, [EBP-10]
00404D76   E8 1F8E0000           CALL    0040DB9A               ; mfc42.#4129, get Name string in CustomData to [EBP-20]
00404D7B   8B4D F0               MOV     ECX, [EBP-10]
00404D7E   68 E4444100           PUSH    004144E4
00404D83   C645 FC 03            MOV     BYTE PTR [EBP-4], 3
00404D87   8B71 F8               MOV     ESI, [ECX-8]
00404D8A   8D4D F0               LEA     ECX, [EBP-10]
00404D8D   E8 288F0000           CALL    0040DCBA
00404D92   29C6                  SUB     ESI, EAX
00404D94   8D55 EC               LEA     EDX, [EBP-14]
00404D97   4E                    DEC     ESI
00404D98   8D4D F0               LEA     ECX, [EBP-10]
00404D9B   56                    PUSH    ESI
00404D9C   52                    PUSH    EDX
00404D9D   E8 488F0000           CALL    0040DCEA               ; mfc42.#5710, RString(ecx, esi) to [EBP-10]: get Hardware ID sting in CustomData
00404DA2   8B4D E0               MOV     ECX, [EBP-20]          ; pName
00404DA5   C645 FC 04            MOV     BYTE PTR [EBP-4], 4
00404DA9   8B41 F8               MOV     EAX, [ECX-8]           ; length of Name
00404DAC   83F8 02               CMP     EAX, 2
00404DAF   0F8C 34020000         JL      00404FE9
00404DB5   83F8 14               CMP     EAX, 14
00404DB8   0F8F 2B020000         JG      00404FE9               ; 2<= length of Name <=0x14
00404DBE   8B45 E8               MOV     EAX, [EBP-18]
00404DC1   50                    PUSH    EAX                    ; EAX 003853D8 ASCII "MistHill", get by function WLRegGetLicenseInfo
00404DC2   51                    PUSH    ECX                    ; ECX 00385428 ASCII "MistHill", from CustomData
00404DC3   FF15 D8024100         CALL    NEAR [4102D8]          ; msvcrt._mbsicmp, if Name matches ret eax=0, else eax=FFFFFFFF

比较许可证里的用户名和自定义字符串中的用户名。
00404DC9   83C4 08               ADD     ESP, 8
00404DCC   85C0                  TEST    EAX, EAX
00404DCE  /74 0E                 JE      SHORT 00404DDE
00404DD0  |8B4D 08               MOV     ECX, [EBP+8]
00404DD3  |C701 97010000         MOV     DWORD PTR [ECX], 197
00404DD9  |E9 14020000           JMP     00404FF2
00404DDE  \8B55 EC               MOV     EDX, [EBP-14]          ; EDX 003854C8 ASCII "105A-EB11-45C1-403E-20D2-290C-7855-509D"
00404DE1   837A F8 27            CMP     DWORD PTR [EDX-8], 27  ; Hardware ID string length MUST==0x27 (39)
00404DE5  /74 0E                 JE      SHORT 00404DF5
00404DE7  |8B45 08               MOV     EAX, [EBP+8]
00404DEA  |C700 98010000         MOV     DWORD PTR [EAX], 198
00404DF0  |E9 FD010000           JMP     00404FF2
00404DF5  \8A0D 3C4E4100         MOV     CL, [414E3C]           ; DS:[00414E3C]=00
00404DFB   31C0                  XOR     EAX, EAX
00404DFD   888D CCFEFFFF         MOV     [EBP-134], CL
00404E03   B9 3F000000           MOV     ECX, 3F
00404E08   8DBD CDFEFFFF         LEA     EDI, [EBP-133]
00404E0E   8D95 CCFEFFFF         LEA     EDX, [EBP-134]
00404E14   F3:AB                 REP     STOS DWORD PTR ES:[EDI]
00404E16   66:AB                 STOS    WORD PTR ES:[EDI]
00404E18   52                    PUSH    EDX                    ; pHardwareId: 0012FBB0
00404E19   AA                    STOS    BYTE PTR ES:[EDI]
00404E1A   E8 F9910000           CALL    0040E018               ; VM1_1379FCB3, ret eax=00000001

调用0040E018为虚拟化后的SDK函数:bool WLRegGetLicenseHardwareID (char* pHardwareId);
The WLRegGetLicenseHardwareID retrieves the hardware ID in the current license key.
If the function succeeds, the return value is True.
If the function fails, the return value is False.


函数WLRegGetLicenseHardwareID取得当前许可证里的HWID。成功返回true,失败返回false。
00404E1F   8D85 CCFEFFFF         LEA     EAX, [EBP-134]         ; EAX 0012FBB0 ASCII "105A-EB11-45C1-403E-20D2-290C-7855-509D"
00404E25   8D4D E4               LEA     ECX, [EBP-1C]
00404E28   50                    PUSH    EAX
00404E29   E8 728D0000           CALL    0040DBA0               ; mfc42.#537, copy string to [EBP-1C]
00404E2E   8D4D D4               LEA     ECX, [EBP-2C]
00404E31   6A 04                 PUSH    4
00404E33   B3 05                 MOV     BL, 5
00404E35   51                    PUSH    ECX
00404E36   8D4D E4               LEA     ECX, [EBP-1C]
00404E39   885D FC               MOV     [EBP-4], BL
00404E3C   E8 A98E0000           CALL    0040DCEA               ; mfc42.#5710, RString(ecx, 4) to [EBP-2C], "509D"
00404E41   89C6                  MOV     ESI, EAX
00404E43   8D55 D8               LEA     EDX, [EBP-28]          ; [0012FCBC]=pCustomData
00404E46   6A 19                 PUSH    19
00404E48   52                    PUSH    EDX
00404E49   8D4D E4               LEA     ECX, [EBP-1C]
00404E4C   C645 FC 06            MOV     BYTE PTR [EBP-4], 6
00404E50   E8 458D0000           CALL    0040DB9A               ; mfc42.#4129, get 0x19 (25) chars "105A-EB11-45C1-403E-20D2-" to [EBP-28]
00404E55   56                    PUSH    ESI
00404E56   50                    PUSH    EAX
00404E57   8D45 DC               LEA     EAX, [EBP-24]
00404E5A   C645 FC 07            MOV     BYTE PTR [EBP-4], 7
00404E5E   50                    PUSH    EAX
00404E5F   E8 F88E0000           CALL    0040DD5C               ; mfc42.#922, cat to [EBP-24], "105A-EB11-45C1-403E-20D2-509D"
00404E64   50                    PUSH    EAX
00404E65   8D4D E4               LEA     ECX, [EBP-1C]
00404E68   C645 FC 08            MOV     BYTE PTR [EBP-4], 8
00404E6C   E8 238D0000           CALL    0040DB94               ; mfc42.#858, copy to [EBP-1C], "105A-EB11-45C1-403E-20D2-509D"
00404E71   8D4D DC               LEA     ECX, [EBP-24]
00404E74   C645 FC 07            MOV     BYTE PTR [EBP-4], 7
00404E78   E8 038C0000           CALL    0040DA80               ; mfc42.#800, free string
00404E7D   8D4D D8               LEA     ECX, [EBP-28]
00404E80   C645 FC 06            MOV     BYTE PTR [EBP-4], 6
00404E84   E8 F78B0000           CALL    0040DA80
00404E89   8D4D D4               LEA     ECX, [EBP-2C]
00404E8C   885D FC               MOV     [EBP-4], BL
00404E8F   E8 EC8B0000           CALL    0040DA80
00404E94   8D4D D0               LEA     ECX, [EBP-30]
00404E97   6A 04                 PUSH    4
00404E99   51                    PUSH    ECX
00404E9A   8D4D EC               LEA     ECX, [EBP-14]
00404E9D   E8 488E0000           CALL    0040DCEA               ; mfc42.#5710, RString(HardwareID, 4) to [EBP-30], "509D"
00404EA2   89C6                  MOV     ESI, EAX
00404EA4   8D55 CC               LEA     EDX, [EBP-34]
00404EA7   6A 19                 PUSH    19
00404EA9   52                    PUSH    EDX
00404EAA   8D4D EC               LEA     ECX, [EBP-14]
00404EAD   C645 FC 09            MOV     BYTE PTR [EBP-4], 9
00404EB1   E8 E48C0000           CALL    0040DB9A               ; mfc42.#4129, get 0x19 (25) chars "105A-EB11-45C1-403E-20D2-" to [EBP-34]
00404EB6   56                    PUSH    ESI
00404EB7   50                    PUSH    EAX
00404EB8   8D45 D4               LEA     EAX, [EBP-2C]
00404EBB   C645 FC 0A            MOV     BYTE PTR [EBP-4], 0A
00404EBF   50                    PUSH    EAX
00404EC0   E8 978E0000           CALL    0040DD5C               ; mfc42.#922, cat to [EBP-2C], "105A-EB11-45C1-403E-20D2-509D"
00404EC5   50                    PUSH    EAX
00404EC6   8D4D EC               LEA     ECX, [EBP-14]
00404EC9   C645 FC 0B            MOV     BYTE PTR [EBP-4], 0B
00404ECD   E8 C28C0000           CALL    0040DB94               ; mfc42.#858, copy to [EBP-14], "105A-EB11-45C1-403E-20D2-509D"
00404ED2   8D4D D4               LEA     ECX, [EBP-2C]
00404ED5   C645 FC 0A            MOV     BYTE PTR [EBP-4], 0A
00404ED9   E8 A28B0000           CALL    0040DA80
00404EDE   C645 FC 09            MOV     BYTE PTR [EBP-4], 9
00404EE2   8D4D CC               LEA     ECX, [EBP-34]
00404EE5   E8 968B0000           CALL    0040DA80
00404EEA   8D4D D0               LEA     ECX, [EBP-30]
00404EED   885D FC               MOV     [EBP-4], BL
00404EF0   E8 8B8B0000           CALL    0040DA80
00404EF5   8B4D EC               MOV     ECX, [EBP-14]
00404EF8   8B55 E4               MOV     EDX, [EBP-1C]
00404EFB   51                    PUSH    ECX                    ; ECX 00385518 ASCII "105A-EB11-45C1-403E-20D2-509D"
00404EFC   52                    PUSH    EDX                    ; EDX 00385608 ASCII "105A-EB11-45C1-403E-20D2-509D"
00404EFD   FF15 D4024100         CALL    NEAR [4102D4]          ; msvcrt._mbscmp

比较许可证里的HWID和自定义字符串中的HWID。注意到它只是部分比较。
00404F03   83C4 08               ADD     ESP, 8
00404F06   85C0                  TEST    EAX, EAX               ; if cmp fine ret eax=00000000
00404F08  /74 0B                 JE      SHORT 00404F15
00404F0A  |8B45 08               MOV     EAX, [EBP+8]
00404F0D  |C700 99010000         MOV     DWORD PTR [EAX], 199
00404F13  |EB 28                 JMP     SHORT 00404F3D
00404F15  \E8 F8900000           CALL    0040E012               ; This VM1_137B128D ret eax=FFFFFFFF(wlPermKey)/the number of days left

调用0040E012为虚拟化后的SDK函数:int WLRegDaysLeft(void);
The WLRegDaysLeft function retrieves the number of days left in the current license key.
If the license key is a permanent key the return value is wlPermKey(-1).
If a license key has not been installed, the return value is wlNoKey(-2).


函数WLRegDaysLeft取得当前许可证里的剩余天数。如果是永久KEY,返回wlPermKey(-1);无许可证返回wlNoKey(-2)。
00404F1A   83F8 01               CMP     EAX, 1                 ; don't allow a permanent key: if ret eax=FFFFFFFF(wlPermKey)
00404F1D  /7D 0B                 JGE     SHORT 00404F2A
00404F1F  |8B4D 08               MOV     ECX, [EBP+8]
00404F22  |C701 9B010000         MOV     DWORD PTR [ECX], 19B
00404F28  |EB 13                 JMP     SHORT 00404F3D
00404F2A  \E8 DD900000           CALL    0040E00C               ; This VM1_137AF0B7 ret eax=00000000 if "License Restrictions: Date Expiration" not set

调用0040E00C为虚拟化后的SDK函数:int WLRegDateDaysLeft(void);
The WLRegDateDaysLeft function retrieves the number of days left in the current license when the license has Date Expiration.
The return value is the number of days left in the current license key.


函数WLRegDateDaysLeft在有"失效日期"设置的情况下返回当前许可证的剩余天数。注意它和函数WLRegDaysLeft的区别,它是按"失效日期"和当前日期计算出来的。
00404F2F   83F8 01               CMP     EAX, 1
00404F32  /7D 45                 JGE     SHORT 00404F79
00404F34  |8B55 08               MOV     EDX, [EBP+8]
00404F37  |C702 9C010000         MOV     DWORD PTR [EDX], 19C
00404F3D  |8D4D E4               LEA     ECX, [EBP-1C]
00404F40  |C645 FC 04            MOV     BYTE PTR [EBP-4], 4
00404F44  |E8 378B0000           CALL    0040DA80
00404F49  |8D4D EC               LEA     ECX, [EBP-14]
00404F4C  |C645 FC 03            MOV     BYTE PTR [EBP-4], 3
00404F50  |E8 2B8B0000           CALL    0040DA80
00404F55  |8D4D E0               LEA     ECX, [EBP-20]
00404F58  |C645 FC 02            MOV     BYTE PTR [EBP-4], 2
00404F5C  |E8 1F8B0000           CALL    0040DA80
00404F61  |8D4D F0               LEA     ECX, [EBP-10]
00404F64  |C645 FC 01            MOV     BYTE PTR [EBP-4], 1
00404F68  |E8 138B0000           CALL    0040DA80
00404F6D  |C745 FC FFFFFFFF      MOV     DWORD PTR [EBP-4], -1
00404F74  |E9 B6000000           JMP     0040502F
00404F79  \8B45 08               MOV     EAX, [EBP+8]
00404F7C   C700 9A010000         MOV     DWORD PTR [EAX], 19A
00404F82  /EB 10                 JMP     SHORT 00404F94
00404F84  |90                    NOP
00404F85  |90                    NOP
00404F86  |90                    NOP
00404F87  |90                    NOP
00404F88  |90                    NOP
00404F89  |90                    NOP
00404F8A  |90                    NOP
00404F8B  |90                    NOP
00404F8C  |90                    NOP
00404F8D  |90                    NOP
00404F8E  |90                    NOP
00404F8F  |90                    NOP
00404F90  |90                    NOP
00404F91  |90                    NOP
00404F92  |90                    NOP
00404F93  |90                    NOP
00404F94  \8D4D E4               LEA     ECX, [EBP-1C]          ; clean up
00404F97   C645 FC 04            MOV     BYTE PTR [EBP-4], 4
00404F9B   E8 E08A0000           CALL    0040DA80
00404FA0   8D4D EC               LEA     ECX, [EBP-14]
00404FA3   C645 FC 03            MOV     BYTE PTR [EBP-4], 3
00404FA7   E8 D48A0000           CALL    0040DA80
00404FAC   8D4D E0               LEA     ECX, [EBP-20]
00404FAF   C645 FC 02            MOV     BYTE PTR [EBP-4], 2
00404FB3   E8 C88A0000           CALL    0040DA80
00404FB8   8D4D F0               LEA     ECX, [EBP-10]
00404FBB   C645 FC 01            MOV     BYTE PTR [EBP-4], 1
00404FBF   E8 BC8A0000           CALL    0040DA80
00404FC4   8D4D E8               LEA     ECX, [EBP-18]
00404FC7   C745 FC FFFFFFFF      MOV     DWORD PTR [EBP-4], -1
00404FCE   E8 AD8A0000           CALL    0040DA80
00404FD3   5F                    POP     EDI
00404FD4   5E                    POP     ESI
00404FD5   B8 01000000           MOV     EAX, 1                 ; return true
00404FDA   5B                    POP     EBX
00404FDB   8B4D F4               MOV     ECX, [EBP-C]           ; 0012FEC0
00404FDE   64:890D 00000000      MOV     FS:[0], ECX            ; reset SE Handler
00404FE5   8BE5                  MOV     ESP, EBP
00404FE7   5D                    POP     EBP
00404FE8   C3                    RETN                           ; return to 005E1C79
00404FE9   8B4D 08               MOV     ECX, [EBP+8]
00404FEC   C701 96010000         MOV     DWORD PTR [ECX], 196
00404FF2   8D4D EC               LEA     ECX, [EBP-14]
00404FF5   C645 FC 03            MOV     BYTE PTR [EBP-4], 3
00404FF9   E8 828A0000           CALL    0040DA80
00404FFE   8D4D E0               LEA     ECX, [EBP-20]
00405001   C645 FC 02            MOV     BYTE PTR [EBP-4], 2
00405005   E8 768A0000           CALL    0040DA80
0040500A   EB 14                 JMP     SHORT 00405020
0040500C   8B55 08               MOV     EDX, [EBP+8]
0040500F   C702 95010000         MOV     DWORD PTR [EDX], 195
00405015   EB 09                 JMP     SHORT 00405020
00405017   8B45 08               MOV     EAX, [EBP+8]
0040501A   C700 94010000         MOV     DWORD PTR [EAX], 194
00405020   8D4D F0               LEA     ECX, [EBP-10]
00405023   C645 FC 01            MOV     BYTE PTR [EBP-4], 1
00405027   E8 548A0000           CALL    0040DA80
0040502C   897D FC               MOV     [EBP-4], EDI
0040502F   8D4D E8               LEA     ECX, [EBP-18]
00405032   E8 498A0000           CALL    0040DA80
00405037   8B4D F4               MOV     ECX, [EBP-C]
0040503A   5F                    POP     EDI
0040503B   5E                    POP     ESI
0040503C   33C0                  XOR     EAX, EAX               ; return false
0040503E   5B                    POP     EBX
0040503F   64:890D 00000000      MOV     FS:[0], ECX
00405046   8BE5                  MOV     ESP, EBP
00405048   5D                    POP     EBP
00405049   C3                    RETN


总结一下,“机关”用MACRO把细节保护起来,配合几个Winlicense SDK函数再次验证许可证的有效性。
采用在用户自定义数据里写入与许可证相同的用户名及HWID的方式进行判断,而且在"License Restrictions"里面必须同时设置"Days Expiration"和"Date Expiration",否则程序将不能运行。
无疑增加了Keygen的难度,下图为最终Keygen时的设置,当然这个过程重复了几次,逐步接近真相。Keygen程序为Oreans在"WinLicense 2.2.1.0 demo"中“免费”提供的。


附件GetDuxiuStr.RePacked.by.MistHill.with.Key.7z为原目标替换两个RSAPublicKey后重新打包,带一个我调试虚拟机上的有效许可证。

http://bbs.pediy.com/attachment.php?attachmentid=74389&d=1355298773

看雪侠者千人榜,看看你上榜了吗?

上传的附件:
收藏
点赞0
打赏
分享
最新回复 (19)
雪    币: 1834
活跃值: 活跃值 (15)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
yingyue 活跃值 2012-12-24 19:22
2
0
来跟 LZ 学习的
雪    币: 1853
活跃值: 活跃值 (3794)
能力值: (RANK:350 )
在线值:
发帖
回帖
粉丝
kanxue 活跃值 8 2012-12-24 20:35
3
0
圣诞节快乐!
雪    币: 74
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
Yslf枫 活跃值 2012-12-24 21:00
4
0
圣诞快乐!学习
雪    币: 947
活跃值: 活跃值 (25)
能力值: ( LV12,RANK:440 )
在线值:
发帖
回帖
粉丝
loongzyd 活跃值 10 2012-12-24 21:13
5
0
圣诞节快乐!
雪    币: 3379
活跃值: 活跃值 (276)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
email123 活跃值 2012-12-24 21:15
6
0
只能围观
雪    币: 589
活跃值: 活跃值 (278)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
MistHill 活跃值 6 2012-12-24 21:26
7
0
祝各位平安夜快乐!
雪    币: 215
活跃值: 活跃值 (110)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
lhglhg 活跃值 1 2012-12-25 14:26
8
0
好帖,文中工具能一起提供?
雪    币: 0
活跃值: 活跃值 (22)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
tihty 活跃值 2 2012-12-25 16:51
9
0
雪    币: 281
活跃值: 活跃值 (15)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
evilor 活跃值 2012-12-26 16:35
10
0
怒mark aaa buzi
雪    币: 1223
活跃值: 活跃值 (46)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
yijun8354 活跃值 12 2012-12-26 21:50
11
0
想当详细,跟到学学
雪    币: 589
活跃值: 活跃值 (278)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
MistHill 活跃值 6 2012-12-27 09:08
12
0
文中截图是我自己对"Oreans UnVirtualizer ODBG Plug-in v1.5"的“汉化”,目前CISC部分已经完成。
前两天,"Oreans UnVirtualizer v1.6"已新鲜出炉,你可以搜索一下。
雪    币: 156
活跃值: 活跃值 (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
NearGray 活跃值 2012-12-27 09:55
13
0
楼主强大!赞一个!
雪    币: 1022
活跃值: 活跃值 (283)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
小调调 活跃值 2012-12-27 14:17
14
0
在第三步骤中,   这个地址饭虚拟化要输入这个地址: 0060e473  这个具体找到的原理是什么 或者Cisc_Uv_Dump.txt下来的内容,有什么具体的原理之类的,我看原作者的视频,也没解释过,只是操作而已~
雪    币: 589
活跃值: 活跃值 (278)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
MistHill 活跃值 6 2012-12-27 18:27
15
0
Deathway在"Oreans UnVirtualizer 1.1 Sample"的文档"Sample Info.txt"中讲:

这个地址在WL中99.9%的机率会紧接着以下指令后面:
POP ESP
MOV ESP, DWORD PTR SS:[ESP]
ADD ESP,4


原理实际上还是保持堆栈平衡。实际运用中需要经验的积累。

00404C31处的"Cisc_Uv_Dump.txt"文件:
...
@Label_0060E006
        0060E006        MOV EBP,DWORD PTR [ESP]
        0060E03B        PUSH EDI
        0060E048        MOV DWORD PTR [ESP],EAX
        0060E0C9        MOV EAX,ESP
        0060E0EE        ADD EAX,0x4
        0060E148        ADD EAX,0x4
        0060E19D        PUSH DWORD PTR [ESP]
        0060E1AE        MOV DWORD PTR [ESP],EAX
        0060E222        POP EAX
        0060E235        POP ESP
        0060E23D        MOV EAX,DWORD PTR [ESP]
        0060E274        PUSH EAX
        0060E29F        MOV EAX,ESP
        0060E2B6        PUSH EBX
        0060E2E5        MOV EBX,0x4
        0060E32B        ADD EAX,EBX
        0060E382        POP EBX
        0060E390        ADD EAX,0x4
        0060E3D3        PUSH DWORD PTR [ESP]
        0060E3DD        MOV DWORD PTR [ESP],EAX
        0060E451        POP EAX
        0060E472        POP ESP                                 ; <-***
        0060E473        LEA EAX,DWORD PTR [EBP+0xffffffdc]      ; Fill in the EditBox with this address
        0060E4A6        PUSH EAX
        0060E4B8        CALL 0x4044e0
...


事实上,研究它生成的Cisc_Vm_XXXXXXXX.txt文件更有意义,当前虚拟机所有Handlers的信息全在里面。
雪    币: 51
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
fresharp 活跃值 2013-9-23 20:16
16
0
绝世经典好文,就只有几个人回复吗
雪    币: 4182
活跃值: 活跃值 (182)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bacool 活跃值 2014-2-9 10:26
18
0
对M大知识的广度和深度,只能膜拜!
雪    币: 132
活跃值: 活跃值 (14)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
fatecaster 活跃值 1 2014-4-7 17:36
19
0
我只记得有大神在写过帖子,但是不记得名字了,一下就搜到了,学习脚本,学习keygen跟踪代码的思路,刚看了一下qqmcc写的低版本的简单例子感觉IAT的处理不难,好像就是简单的加密壳做的一样。
绝世经典好文
顶一下
雪    币: 0
活跃值: 活跃值 (38)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
商品国际 活跃值 2017-4-11 15:13
20
0
太给力了啊
雪    币: 202
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
luolinlove 活跃值 2017-6-15 04:31
21
0
好文,就是没有新版的.
游客
登录 | 注册 方可回帖
返回