吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 26371|回复: 71
收起左侧

[原创] 某内存 SPD 读取和烧录软件个人注册版脱壳和注册分析、注册机实现激活!

[复制链接]
solly 发表于 2019-9-12 18:45
本帖最后由 solly 于 2019-9-18 03:50 编辑

我8月份在搬家,因此有一段时间没发贴了。


前几天录制了一个本论坛的参赛视频,针对的是一个内存 SPD 芯片的数据读取和烧录软件 Thaiphoon Burner,其版本是 16.0.0.6 Build 0818 免费版,没有注册算法,不需要注册。
这次是针对另一个老一点的版本,15.0.0.0 build 1126 个人版,这个版本需要注册激活,才可以使用烧录功能。


还是先查查壳吧:
00.png
再“Scan /t":
01.png
节的情况:
03.png
可以看出,主程序是通过 PECompact 加壳的,首先需要脱壳


用 OD 载入主程序:
11.png
可以看到,一开始就是一段通过 SEH 异常处理机制的反调试的代码,防止单步跟踪。具体代码如下:
[Asm] 纯文本查看 复制代码
00401000 >  B8 70A97300        mov     eax, 0073A970                    ; eax == 新的异常处理子例程地址
00401005    50                 push    eax                              ; 保存新的异常处理子例程地址
00401006    64:FF35 00000000   push    dword ptr fs:[0]                 ; 保存老的SEH指针
0040100D    64:8925 00000000   mov     dword ptr fs:[0], esp            ; 保存新的SEH指针
00401014    33C0               xor     eax, eax                         ; 将 eax 清 0,将导致下一行指令出现非法地址异常
00401016    8908               mov     dword ptr [eax], ecx             ; 因 eax == 0,这一行代码会产生异常


先 F8 执行第一行指令,使得 eax == 0x0073A970,这个地址就是异常处理子例程的地址。
Ctrl + G,输入 eax ,就可以跳转到这个异常处理子例程了:
12.png
上图所选的代码部分,就是整个异常处理子例程。其中第1、2、3行是对另一个子程序的入口(0x0073A993)代码进行参数修正。具体代码如下:
[Asm] 纯文本查看 复制代码
0073A970    B8 F59673F0        mov     eax, F07396F5
0073A975    8D88 9E120010      lea     ecx, dword ptr [eax+1000129E]    ; eax == 0x0073A993,是这个异常处理子全程后面的第一条指令地址
0073A97B    8941 01            mov     dword ptr [ecx+1], eax           ; 修改 mov 指令中的立即数
0073A97E    8B5424 04          mov     edx, dword ptr [esp+4]
0073A982    8B52 0C            mov     edx, dword ptr [edx+C]
0073A985    C602 E9            mov     byte ptr [edx], 0E9              ; 修正产生异常的指令
0073A988    83C2 05            add     edx, 5
0073A98B    2BCA               sub     ecx, edx
0073A98D    894A FC            mov     dword ptr [edx-4], ecx           ; 修正产生异常的指令的参数
0073A990    33C0               xor     eax, eax
0073A992    C3                 retn                                     ; 返回重新执行修改后的指令


另外的代码就是用来修正前面会产生异常的指令代码的。我们先在 0x0073A97B 处下一个断点,然后 F9 运行程序,如下图所示,会中断下来:
13.png
中断在我们刚下的断点处,开始进行代码修改,为了激活 OD 的 patch 记录功能(会使变动代码或数据变成红色),我们先把将要修改的代码改一改,如下图所示,先在数据区转移到修改处(ecx中保存的地址值):
14.png
然后随便改一下数据,再按”确定“。
15.png
这样操作后,修改处的数据会变成红色,便于区分程序改动了什么地方,如下图所示:
16.png
然后 F8 执行,可见,mov 指令的立即数参数已经修改了,如下图所示:
17.png
另一个指令的修改也一样进行操作,如下图所示,先跟随edx中的地址跳转到修改处:
18.png
数据区也跟随到这个地址,再手动在数据区随便修改一下(0x00401016 处)数据,如下图所示:
19.png
按 F8 执行,如下图,把几条修改异常指令的代码全执行完成:
20.png

再过去看一下刚才手动修改的地方,可以看到,如下图所示,指令变成了 "jmp 0x0073A993",不会再产生异常了。
21.png
上图具体代码如下:

[Asm] 纯文本查看 复制代码
00401000 >  B8 70A97300        mov     eax, 0073A970                    ; eax == 新的异常处理子例程地址
00401005    50                 push    eax                              ; 保存新的异常处理子例程地址
00401006    64:FF35 00000000   push    dword ptr fs:[0]                 ; 保存老的SEH指针
0040100D    64:8925 00000000   mov     dword ptr fs:[0], esp            ; 保存新的SEH指针
00401014    33C0               xor     eax, eax                         ; 将 eax 清 0,将导致下一行指令出现非法地址异常
00401016  - E9 78993300        jmp     0073A993                         ; 通过异常处理子例程修正为可正常执行的指令了

我们再”跟随“刚才修正的 jmp 指令,转移到下图所示位置:
22.png

我们再在 ”0x0073A99F" 处下一个断点,然后直接 “F9" 运行程序,执行到下图所示位置:
23.png
正是我们才下的断点处,到了这里后,通过 SEH 异常处理机制反调试的代码就被破除了。下面继续 F8 执行:
30.png
来到一个调用处,这个调用是 VirtualAlloc() ,是一个分配内存的调用,我们  F8 继续执行。
31.png
执行完后,数据区跟随 eax,就可以来到刚才申请的内存区,这片内存区已被初始化为全 0 了。
32.png
继续 F8 执行,当执行完上图所示的 call ecx 后,可以看到,数据区已经写入了数据,不过这还是壳的代码,并不是原始程序代码,这段代码会再对原始代码进行解码。
33.png
继续 F8 来到 0x0073AA0E call edi ,可以看到 edi 的值处在前面申请的内存的范围内,也就是去执行刚才解码的壳代码,因此这时按 F7 进入函数,来到下图所示位置:
40.png
可以看到,第1条指令是一个跳转指令,并且是跳转到两条指令的中间位置,因此,此跳转后含有花指令,只有一个字节的花指令,就是 0x25,在数据区改成 0x90 就可以正常显示了,如下图所示:
41.png
我们一路 F8 执行代码,来到下图位置:
42.png
这几条指令是修正刚才解码的代码的几个 API 调用地址,相当于 IAT 修正吧。具体代码如下:
[Asm] 纯文本查看 复制代码
00030A7A    03F2            add     esi, edx
00030A7C    8DBD 5D2F0010   lea     edi, dword ptr [ebp+10002F5D]
00030A82    AD              lods    dword ptr [esi]                          ; LoadLibraryA()
00030A83    AB              stos    dword ptr es:[edi]
00030A84    AD              lods    dword ptr [esi]                          ; GetProcAddress()
00030A85    AB              stos    dword ptr es:[edi]
00030A86    AD              lods    dword ptr [esi]                          ; VirtualAlloc()
00030A87    AB              stos    dword ptr es:[edi]
00030A88    AD              lods    dword ptr [esi]                          ; VirtualFree()
00030A89    AB              stos    dword ptr es:[edi]


共更新了4个 API 函数。
43.png
上面数据区就是刚才修改的几个 API 地址,共 4 个 API 入口地址。


接下来就是几条指令对程序的入口代码进行破坏,如下图所示,这样程序的入口代码就不正确了,也算是一种反调试或反脱壳方法吧
44.png
上图具体代码如下:
[Asm] 纯文本查看 复制代码
00030A98    B9 23000000      mov     ecx, 23
00030A9D    03F2             add     esi, edx
00030A9F    8B7B 40          mov     edi, dword ptr [ebx+40]
00030AA2    03FA             add     edi, edx
00030AA4    F3:A4            rep     movs byte ptr es:[edi], byte ptr [esi]     ; 传输 ecx == 0x23 字节, edi==0x401000,破坏启动代码




一路 F8 往下走,执行完一堆 nop 指令后,又来到一个反调试代码处,如下图所示:
45.png

这次是调用 IsDebuggerPresent() ,这条 API 是通过 PEB+02 处的标志来确定程序是否处于调试状态的。
如果返回  eax == 0x00000001,就表示程序处于调试状态,我们修改代码避开检测(也可以在函数返回后直接将 eax 置 0),如下图所示:
46.png
具体代码如下:
[Asm] 纯文本查看 复制代码
00030ACA    8B85 292F0010    mov     eax, dword ptr [ebp+10002F29]
00030AD0    85C0             test    eax, eax
00030AD2    74 07            je      short 00030ADB
00030AD4    FFD0             call    eax                                      ; call KERNELBA.IsDebuggerPresent, 检查调试状态
00030AD6    85C0             test    eax, eax                                 ; 上面调用后,需手动将 eax 清 0,或改成 xor eax, eax
00030AD8    74 01            je      short 00030ADB
00030ADA    4B               dec     ebx                                      ; 如果是处理调试状态,则 ebx 减 1,会导致后面程序出现异常。
00030ADB    8B4E 2C          mov     ecx, dword ptr [esi+2C]
00030ADE    898D 592F0010    mov     dword ptr [ebp+10002F59], ecx


test eax, eax 改成 xor eax, eax 就可以了,上图已改好了。


再次一路 F8 执行程序,来到下面位置:
50.png

又是一个调用,申请了一片内存,我们在数据区跟随到申请的内存区,也是初始化成全0状态。继续 F8 执行,来到下面位置:
51.png
具体代码如下:
[Asm] 纯文本查看 复制代码
00030ADB    8B4E 2C          mov     ecx, dword ptr [esi+2C]
00030ADE    898D 592F0010    mov     dword ptr [ebp+10002F59], ecx
00030AE4    6A 04            push    4
00030AE6    68 00100000      push    1000
00030AEB    51               push    ecx
00030AEC    6A 00            push    0
00030AEE    FF95 652F0010    call    dword ptr [ebp+10002F65]                 ; call VirtualAlloc
00030AF4    8985 552F0010    mov     dword ptr [ebp+10002F55], eax
00030AFA    56               push    esi
00030AFB    E8 F6030000      call    00030EF6                                 ; 释放程序原delphi代码
00030B00    8D8D D12D0010    lea     ecx, dword ptr [ebp+10002DD1]            ; ecx ===> "Application corrupt."
00030B06    85C0             test    eax, eax
00030B08    0F85 94000000    jnz     00030BA2


执行完上面的调用后,数据区出现了 delphi 风格的代码头。表明原始程序应该是一个 delphi 编译的程序。继续 F8 往下走,执行完几个调用后,来到下图位置:
52.png

上面是释放刚才申请的内存的调用,表明代码已经完成解码并转移到可执行节区去了。
这里是清理现场并准备退出函数了。


一路 F8 退出当前函数,来到下图所示位置:
53.png
具体代码如下:
[Asm] 纯文本查看 复制代码
0073AA10    8985 3F130010   mov     dword ptr [ebp+1000133F], eax             ; eax == OEP
0073AA16    8BF0            mov     esi, eax
0073AA18    8B4B 14         mov     ecx, dword ptr [ebx+14]
0073AA1B    5A              pop     edx
0073AA1C    EB 0C           jmp     short 0073AA2A
0073AA1E    03CA            add     ecx, edx
0073AA20    68 00800000     push    8000
0073AA25    6A 00           push    0
0073AA27    57              push    edi
0073AA28    FF11            call    dword ptr [ecx]
0073AA2A    8BC6            mov     eax, esi
0073AA2C    5A              pop     edx
0073AA2D    5E              pop     esi
0073AA2E    5F              pop     edi
0073AA2F    59              pop     ecx
0073AA30    5B              pop     ebx
0073AA31    5D              pop     ebp
0073AA32    FFE0            jmp     eax                                        ; goto OEP


可以看到,所选代码中,最后一个跳转 jmp eax 就是去 OEP 了,call edi 返回的 eax 值,就是 OEP 了。如下图所示,是壳代码最后一条指令了:
54.png
按 F8 来到 OEP,就可以开始脱壳了:
55.png
直接用 OD 的脱壳功能进行脱壳:
60.png
不修改任何内容,直接按 ”Dump" 即可,取一个名字并保存好脱壳文件。



下面,我们执行一下刚才脱壳的程序,不能正常运行,会弹出下面的错误:
61.png
这表示 API 函数导入不正确,还需要修复 IAT 才可以运行。


以“管理员身份运行 ”ImportREC"。如下图所示,选好进程,修改 OEP,并按 "IAT AutoSearch",再 ”Get Imports",但结果并不正确,如下图所示,没有取到所需的 IAT(在有些情况也可以取到IAT,就可以去后面的IAT修正步骤了)。
62.png

我们点"Clear Import“ 先清除不正确的 IAT,然后修改 OEP 为原始值 0x00001000,如下图所示,重新按 "IAT AutoSearch",再 ”Get Imports",如下图所示,取到了 IAT:
63.png
再按”Show Invalid",还是有一些无效的导入,如下图所示:
64.png
这个就是刚才执行时弹出的错误 API 导入。手动修改为 User32.dll 中的  DefWindowProcA()即可,如下图所示:
65.png
修改后仍然按“Show Invalid”,找到其它无效导入,如下图所示:

66.png
改完那个 DefWindowProcA()后,还要修改几个 combase.dll 中的几个错误导入,如上图所示的一个,改成如下图所示 Ole32.dll 中的相应函数:
67.png

还有几个如下图所示,也一并要改掉:
68.png
全部改成 Ole32.dll 中的调用:
69.png
全部改完后,就可以修复刚才导出的程序了,如下图所示,点“ Fix Dump",弹出文件对话框,选中刚才的导出文件,点"打开”即可。
70.png
会重新生成一个已修复 IAT 的新的执行文件,带有下划线“_”的那个文件。
71.png
还有一个问题,刚才在 ImportREC 中并没有修复 OEP。我们还需要手动去修复 OEP。如下图示位置,现在 OEP 还是原来的入口:0x00001000。
72.png
我们将其改成 0x001BF1D0 后才能正常运行,如下图所示就是改好 OEP 了。
73.png
现在,我们可以正常运行程序了,先来看看程序是什么编译器生成的,便于后面的分析处理。如下图所示,重新查看文件信息:
05.png

显示程序由 Delphi 编译,因此,我们先用 DeDeDark 来反编译程序,便于查看资源、函数、表单、事件入口等。
如下图所示,正在反编译:
80.png

反编译后,先看看工程文件,也就是 Delphi 编译的程序入口,即 OEP 开始的代码。
81.png
再在 OD 中看一下这段代码,可以看到,有一段生成文件名:"C:\Windows\Debug\passwd.log"。这个在后面要用到,先不管。
82.png
还有这一段,读取文件“Regdata.rkf”的内容,这个就是注册文件,注册表单中按 "Accept"就会把注册信息存于此文件中。
83.png
在 DeDeDark 看就更明显了,如下图所示,拼成了一个文件路径:
84.png

如果文件存在,则读取文件内容:
85.png
下面是注册信息判断,最后的结果检测:
86.png

有关  NAG 显示的配置读取和判断是否显示:
87.png
这里有一个判断,不为0则退出程序:
88.png
看到有对按钮的显示进行控制:
89.png
对按钮的启用和禁用状态进行设置:
90.png

一些不明标志的判断,后面可能会用到:
91.png
大概看了一下程序的启动代码,下面我们运行程序。


首先会弹出一个警告对话框,表示 BIOS 对芯片的写保护,需要到 BIOS 中去禁用写保护后方可进行烧录操作。
100.png

接着弹出注册的 NAG,不过可以通过其界面下面的 CheckBox 来禁止弹出这个 NAG。
101.png
最后,显示主界面,由于没有注册,看不到有写入的功能按钮。
102.png
退出程序。


用 OD 重新载入脱壳后的程序
110.png

根据前面的 DeDeDark 中查得信息,我们在入口代码中处理注册文件前下一个断点
111.png


还在主表单(TForm1)的 TForm1.FormCreate() 事件中也下一个断点
112.png


F9 运行,还是先弹出这个警告框:
113.png

然后中断在第1个断点处,如下图所示,由于没有输入注册码,还是继续一路猛按 F8 往下运行。
114.png
泥煤,程序直接退出了,看来还是有暗桩,不仅是脱个壳就可以了的。
115.png

按”-“回退,退回到下面代码处,就是刚才退出的即方,这就是按 F8 的好处,可以退回看哪里脱靶的。。。。
116.png
根据地址,在 DeDeDark 中找到相应位置如下图所示:
117.png
这个就是创建注册 NAG 表单的方法,这是 Delphi 内置的方法,所以只要中断 NAG 表单的 FormCreate 事件即可,因为创建表单会自动执行这个事件,基本也应该是在这个事件中跑飞了。
注册 NAG 表单是 TForm2。因此我们看一下 TForm2.FormCreate事件:
118.png
从上图可以找到该事件入口地址。


重新在 OD 载入程序,直接在 OD 中转到该入口:
119.png
在事件中下一个断点即可,如上图所示位置下一个断点。


重新运行,然后在 TForm2.FormCreate() 中断下来,再一次猛按 F8 ,不一会程序又跑飞了,然后按”-“回退到如下位置,在此位置下一个断点
120.png


再重新用 OD 载入程序并一路 F9 运行。在最后断点处(0x0050F1F9),如上图所示位置,我们按 F7 进入。


然后又一路 F8 ,又会退出。回退看到退出位置如下,再下一个断点(0x0050EF96处)。
121.png

退出的函数地址是 call 0050ED5C,我们到 DeDeDark 中看看这个函数。
122.png
如上图所示,找到了退出位置的代码了,Delphi 函数 Halt() 就是强行退出程序。具体代码如下:
[Asm] 纯文本查看 复制代码
0050ED83  |.  803D E8435C00 00     cmp     byte ptr [5C43E8], 0           ;  如果 [5C43E8] == 0x01,则退出程序,需要在这个地址(0x005C43E8)下硬件断点寻找赋值指令
0050ED8A  |.  74 05                je      short 0050ED91
0050ED8C  |.  E8 6B59EFFF          call    004046FC                       ;  System.Halt(),退出程序
0050ED91  |>  A1 D0715C00          mov     eax, dword ptr [5C71D0]


可以看出,是对一个标志进行判断,但该标志并没在此函数内赋值,所以,我们在 OD 中重新载入程序,并运行到这里(最后断点处 F7 进入,再运行到0x0050ED83处),然后在数据区转到此指令中的地址值(0x005C43E8),下一个硬件访问断点,如下图所示:
123.png
下断点后,我们还要把该标志值修改成 0x00,免得程序再次退出或其它地方退出。


跳过刚才的退出暗桩,程序继续运行,正常弹出注册对话框的 NAG:
124.png
我们输入注册信息(老版本的激活数据,并不适合当前版本,只是套用格式)
125.png
点”Accept" 按钮保存注册信息。
126_hard_interrupt.png
立即被前面的硬件访问中断下来了,也是对这个标志进行判断,如果为 0x01 则退出程序,不会保存注册信息。因为我们前面改了数据,所以现在不会退出程序。
127.png
保存完注册信息,弹出一个对话框,提示要重启才能生效,看来是一个重启验证的注册机制。
关闭对话框,又会被硬件中断下来,还是与前面一样的原因:
128.png

按 F9 续断运行,没有再中断了,弹出了主界面。如下图所示:
129.png
没有看到写入功能,表示还没有注册成功或还没进行验证。


退出程序,在 OD 中重新载入程序,检查硬件访问中断没有问题:
130.png
按 F9 运行,硬件中断了下来,是一个写入中断,在这里将 [0x005C43E8] 写入了 0x01。如下图所示:
131.png
具体代码如下:
[Asm] 纯文本查看 复制代码
0050FFDD  |.  3B0424          cmp     eax, dword ptr [esp]
0050FFE0  |.  0F92C0          setb    al                               ; 修改为 0F94C0  sete  al
0050FFE3  |.  EB 03           jmp     short 0050FFE8
0050FFE5  |>  0F9CC0          setl    al                               ; 修改为 0F94C0  sete  al
0050FFE8  |>  83C4 08         add     esp, 8
0050FFEB  |.  A2 E8435C00     mov     byte ptr [5C43E8], al            ; al == 0x01 由表示程序已脱壳


存入的是 al 的值,前面有两条指令对 al 赋值了。如下图所示,两条 set 指令:
132.png
再到 DeDeDark 中相应位置看看。可以看出,这是一个文件大小的检查,看来程序会检查文件大小,防止程序脱壳运行。
133.png

破解也很简单,如下图所示,直接修改两个 set 指令即可。
134.png

然后在文件中找到相应位置,修改脱壳后文件。
135.png
下图是改好了的:
136.png


破除了退出暗桩,下面进行注册算法的处理,在启动代码的如下位置,包含了注册算法:
140_register.png
具体代码如下:
[Asm] 纯文本查看 复制代码
; start() 注册验证部分
005BF63E   > \8D95 8CFEFFFF       lea     edx, dword ptr [ebp-174]
005BF644   .  A1 EC715C00         mov     eax, dword ptr [5C71EC]
005BF649   .  8B00                mov     eax, dword ptr [eax]
005BF64B   .  E8 C803EBFF         call    0046FA18                                            ;  GetExeName()
005BF650   .  8B85 8CFEFFFF       mov     eax, dword ptr [ebp-174]
005BF656   .  8D95 90FEFFFF       lea     edx, dword ptr [ebp-170]
005BF65C   .  E8 1FA8E4FF         call    00409E80                                            ;  ExtractFilePath()
005BF661   .  8B95 90FEFFFF       mov     edx, dword ptr [ebp-170]
005BF667   .  A1 6C715C00         mov     eax, dword ptr [5C716C]
005BF66C   .  B9 34025C00         mov     ecx, 005C0234                                       ;  ASCII "Regdata.rkf"
005BF671   .  E8 FE54E4FF         call    00404B74                                            ;  StrCat()
005BF676   .  33D2                xor     edx, edx
005BF678   .  55                  push    ebp
005BF679   .  68 95FD5B00         push    005BFD95
005BF67E   .  64:FF32             push    dword ptr fs:[edx]
005BF681   .  64:8922             mov     dword ptr fs:[edx], esp
005BF684   .  A1 6C715C00         mov     eax, dword ptr [5C716C]
005BF689   .  8B00                mov     eax, dword ptr [eax]
005BF68B   .  E8 B8A4E4FF         call    00409B48                                            ;  FileExists()
005BF690   .  84C0                test    al, al
005BF692   .  0F84 D0060000       je      005BFD68
005BF698   .  6A 40               push    40
005BF69A   .  8B0D 6C715C00       mov     ecx, dword ptr [5C716C]                             ;  dumped_b.005C99A4
005BF6A0   .  8B09                mov     ecx, dword ptr [ecx]
005BF6A2   .  B2 01               mov     dl, 1
005BF6A4   .  A1 ACA64100         mov     eax, dword ptr [41A6AC]
005BF6A9   .  E8 0A05E6FF         call    0041FBB8                                            ;  TFileStream.Create()
005BF6AE   .  8BD8                mov     ebx, eax
005BF6B0   .  BA 30A85C00         mov     edx, 005CA830                                       ;  ASCII 05,"solly"
005BF6B5   .  B9 3C010000         mov     ecx, 13C
005BF6BA   .  8BC3                mov     eax, ebx
005BF6BC   .  E8 1302E6FF         call    0041F8D4                                            ;  TStream.ReadBuffer()
005BF6C1   .  8BC3                mov     eax, ebx
005BF6C3   .  E8 D842E4FF         call    004039A0                                            ;  TObject.Free()
005BF6C8   .  B8 95A85C00         mov     eax, 005CA895                                       ;  ASCII 04,"THRK"
005BF6CD   .  BA 40025C00         mov     edx, 005C0240                                       ;  ASCII 04,"THRK"
005BF6D2   .  33C9                xor     ecx, ecx
005BF6D4   .  8A08                mov     cl, byte ptr [eax]
005BF6D6   .  41                  inc     ecx
005BF6D7   .  E8 D83AE4FF         call    004031B4                                            ;  AStrCmp(), 检测注册文件的文件头
005BF6DC   .  74 15               je      short 005BF6F3
005BF6DE   .  A1 6C715C00         mov     eax, dword ptr [5C716C]
005BF6E3   .  8B00                mov     eax, dword ptr [eax]
005BF6E5   .  E8 6AA6E4FF         call    00409D54                                            ;  DeleteFile()
005BF6EA   .  B2 01               mov     dl, 1
005BF6EC   .  B0 04               mov     al, 4
005BF6EE   .  E8 95FBF4FF         call    0050F288                                            ;  显示错误信息, eax == 4, 'The registration file has a corrupted header!'
005BF6F3   >  8D85 C4FEFFFF       lea     eax, dword ptr [ebp-13C]
005BF6F9   .  E8 5EF8F4FF         call    0050EF5C                                            ;  生成ID
005BF6FE   .  8D95 C4FEFFFF       lea     edx, dword ptr [ebp-13C]                            ;  edx ===> ID
005BF704   .  A1 2C6F5C00         mov     eax, dword ptr [5C6F2C]
005BF709   .  E8 FA39E4FF         call    00403108                                            ;  PStrCpy()
005BF70E   .  B8 9AA85C00         mov     eax, 005CA89A                                       ;  ASCII 21,"A1884D69D3C7F040-205D575B25207559"
005BF713   .  8B15 2C6F5C00       mov     edx, dword ptr [5C6F2C]                             ;  edx ===> ID
005BF719   .  33C9                xor     ecx, ecx
005BF71B   .  8A08                mov     cl, byte ptr [eax]                                  ;  取得delphi短字符串的长度, cl == 0x21
005BF71D   .  41                  inc     ecx                                                 ;  将长度字节也计算在内进行比较
005BF71E   .  E8 913AE4FF         call    004031B4                                            ;  AStrCmp(), eax, edx 指向的两个ID比较
005BF723   .  0F85 3F060000       jnz     005BFD68
005BF729   .  B8 30A85C00         mov     eax, 005CA830                                       ;  eax == 0x005CA830 ===> (ASCII 05,"solly")
005BF72E   .  E8 85FFF4FF         call    0050F6B8                                            ;  eax == 0x79, 最字符串最后一个字母(不超过48个)
005BF733   .  3A05 69A95C00       cmp     al, byte ptr [5CA969]                               ;  'y', 名字最后一个字母?或较验和
005BF739   .  0F85 24060000       jnz     005BFD63
005BF73F   .  B8 30A85C00         mov     eax, 005CA830                                       ;  ASCII 05,"solly"
005BF744   .  E8 C302F5FF         call    0050FA0C                                            ;  al == 0x73, 's'
005BF749   .  3A05 68A95C00       cmp     al, byte ptr [5CA968]                               ;  's',名字第一个字母?
005BF74F   .  0F85 13060000       jnz     005BFD68
005BF755   .  BA 48025C00         mov     edx, 005C0248
005BF75A   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF760   .  E8 A339E4FF         call    00403108                                            ;  PStrCpy(),生成delphi字符串 01,'$'
005BF765   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF76B   .  50                  push    eax
005BF76C   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF771   .  BA 01000000         mov     edx, 1                                              ;  start = 1
005BF776   .  B8 9AA85C00         mov     eax, 005CA89A                                       ;  eax == 005CA89A ===> (ASCII 21,"A1884D69D3C7F040-205D575B25207559")
005BF77B   .  E8 E431E4FF         call    00402964                                            ;  System.Copy()
005BF780   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> "A1884D69"
005BF786   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF78C   .  B1 65               mov     cl, 65
005BF78E   .  E8 4539E4FF         call    004030D8                                            ;  PStrNCat(),形成 "$A1884D69"
005BF793   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> "$A1884D69"
005BF799   .  8D85 88FEFFFF       lea     eax, dword ptr [ebp-178]
005BF79F   .  E8 2853E4FF         call    00404ACC                                            ;  LStrFromString(),生成 pchar 字符串 "$A1884D69"
005BF7A4   .  8B85 88FEFFFF       mov     eax, dword ptr [ebp-178]                            ;  EAX ===> "$A1884D69"
005BF7AA   .  E8 819FE4FF         call    00409730                                            ;  StrToInt()
005BF7AF   .  8BD8                mov     ebx, eax                                            ;  ID 第 1 部分
005BF7B1   .  BA 48025C00         mov     edx, 005C0248
005BF7B6   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF7BC   .  E8 4739E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, '$'
005BF7C1   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF7C7   .  50                  push    eax
005BF7C8   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF7CD   .  BA 1A000000         mov     edx, 1A                                             ;  start = 26
005BF7D2   .  B8 9AA85C00         mov     eax, 005CA89A                                       ;  ASCII 21,"A1884D69D3C7F040-205D575B25207559"
005BF7D7   .  E8 8831E4FF         call    00402964                                            ;  SubString(), get "25207559"
005BF7DC   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> "25207559"
005BF7E2   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF7E8   .  B1 65               mov     cl, 65
005BF7EA   .  E8 E938E4FF         call    004030D8                                            ;  PStrNCat()
005BF7EF   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$25207559"
005BF7F5   .  8D85 B4FDFFFF       lea     eax, dword ptr [ebp-24C]
005BF7FB   .  E8 CC52E4FF         call    00404ACC                                            ;  LStrFromString()
005BF800   .  8B85 B4FDFFFF       mov     eax, dword ptr [ebp-24C]                            ;  eax ===> "$25207559"
005BF806   .  E8 259FE4FF         call    00409730                                            ;  StrToInt()
005BF80B   .  33D8                xor     ebx, eax                                            ;  ID最后部分与第1部分xor运算,0xA1884D69 xor 0x25207559 == 0x84A83830,这是激活码的第1部分
005BF80D   .  BA 48025C00         mov     edx, 005C0248
005BF812   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF818   .  E8 EB38E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, '$'
005BF81D   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF823   .  50                  push    eax
005BF824   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF829   .  BA 12000000         mov     edx, 12                                             ;  start = 18
005BF82E   .  B8 9AA85C00         mov     eax, 005CA89A                                       ;  ASCII 21,"A1884D69D3C7F040-205D575B25207559"
005BF833   .  E8 2C31E4FF         call    00402964                                            ;  System.Copy(), get "205D575B"
005BF838   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "205D575B"
005BF83E   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF844   .  B1 65               mov     cl, 65
005BF846   .  E8 8D38E4FF         call    004030D8                                            ;  PStrNCat()
005BF84B   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$205D575B"
005BF851   .  8D85 B0FDFFFF       lea     eax, dword ptr [ebp-250]
005BF857   .  E8 7052E4FF         call    00404ACC                                            ;  LStrFromString()
005BF85C   .  8B85 B0FDFFFF       mov     eax, dword ptr [ebp-250]                            ;  eax ===> "$205D575B"
005BF862   .  E8 C99EE4FF         call    00409730                                            ;  StrToInt()
005BF867   .  8BF0                mov     esi, eax                                            ;  ID 第3部分,0x205D575B
005BF869   .  BA 48025C00         mov     edx, 005C0248
005BF86E   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF874   .  E8 8F38E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BF879   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF87F   .  50                  push    eax
005BF880   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF885   .  BA 09000000         mov     edx, 9                                              ;  start = 9
005BF88A   .  B8 9AA85C00         mov     eax, 005CA89A                                       ;  (ASCII 21,"A1884D69D3C7F040-205D575B25207559")
005BF88F   .  E8 D030E4FF         call    00402964                                            ;  System.Copy(), SubString(), get "D3C7F040"
005BF894   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "D3C7F040"
005BF89A   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF8A0   .  B1 65               mov     cl, 65
005BF8A2   .  E8 3138E4FF         call    004030D8                                            ;  PStrNCat()
005BF8A7   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$D3C7F040"
005BF8AD   .  8D85 ACFDFFFF       lea     eax, dword ptr [ebp-254]
005BF8B3   .  E8 1452E4FF         call    00404ACC                                            ;  LStrFromString()
005BF8B8   .  8B85 ACFDFFFF       mov     eax, dword ptr [ebp-254]                            ;  EAX ===> "$D3C7F040"
005BF8BE   .  E8 6D9EE4FF         call    00409730                                            ;  StrToInt()
005BF8C3   .  33F0                xor     esi, eax                                            ;  ID 第 3 部分与第 2 部分进行xor运算,0x205D575B xor 0xD3C7F040 == 0xF39AA71B,这是激活码的第2部分
005BF8C5   .  BA 48025C00         mov     edx, 005C0248
005BF8CA   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF8D0   .  E8 3338E4FF         call    00403108                                            ;  PStrCpy()
005BF8D5   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF8DB   .  50                  push    eax
005BF8DC   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF8E1   .  BA 01000000         mov     edx, 1                                              ;  start = 1
005BF8E6   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BF8EB   .  E8 7430E4FF         call    00402964                                            ;  System.Copy()
005BF8F0   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ==> 08, "724FBD29",激活码第1部分
005BF8F6   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF8FC   .  B1 65               mov     cl, 65
005BF8FE   .  E8 D537E4FF         call    004030D8                                            ;  PStrNCat()
005BF903   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$724FBD29"
005BF909   .  8D85 A8FDFFFF       lea     eax, dword ptr [ebp-258]
005BF90F   .  E8 B851E4FF         call    00404ACC                                            ;  LStrFromString()
005BF914   .  8B85 A8FDFFFF       mov     eax, dword ptr [ebp-258]                            ;  eax ===> "$724FBD29"
005BF91A   .  E8 119EE4FF         call    00409730                                            ;  StrToInt()
005BF91F   .  3BD8                cmp     ebx, eax                                            ;  激活码比较1,ID第1部分与第4部分的xor值
005BF921   .  0F85 41040000       jnz     005BFD68
005BF927   .  BA 48025C00         mov     edx, 005C0248
005BF92C   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF932   .  E8 D137E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BF937   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF93D   .  50                  push    eax
005BF93E   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF943   .  BA 09000000         mov     edx, 9                                              ;  start = 9
005BF948   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BF94D   .  E8 1230E4FF         call    00402964                                            ;  System.Copy(),取激活码第2部分 "057D2202"
005BF952   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "057D2202"
005BF958   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF95E   .  B1 65               mov     cl, 65
005BF960   .  E8 7337E4FF         call    004030D8                                            ;  PStrNCat()
005BF965   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$057D2202"
005BF96B   .  8D85 A4FDFFFF       lea     eax, dword ptr [ebp-25C]
005BF971   .  E8 5651E4FF         call    00404ACC                                            ;  LStrFromString()
005BF976   .  8B85 A4FDFFFF       mov     eax, dword ptr [ebp-25C]                            ;  eax ==> "$057D2202"
005BF97C   .  E8 AF9DE4FF         call    00409730                                            ;  StrToInt()
005BF981   .  3BF0                cmp     esi, eax                                            ;  激活码比较2,ID第3部分与第2部分的xor值
005BF983   .  0F85 DF030000       jnz     005BFD68
005BF989   .  BA 48025C00         mov     edx, 005C0248
005BF98E   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF994   .  E8 6F37E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BF999   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF99F   .  50                  push    eax
005BF9A0   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BF9A5   .  BA 19000000         mov     edx, 19                                             ;  start = 25
005BF9AA   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BF9AF   .  E8 B02FE4FF         call    00402964                                            ;  System.Copy(),取激活码第4部分 "07D10C72"
005BF9B4   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "07D10C72"
005BF9BA   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF9C0   .  B1 65               mov     cl, 65
005BF9C2   .  E8 1137E4FF         call    004030D8                                            ;  PStrNCat()
005BF9C7   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$07D10C72"
005BF9CD   .  8D85 A0FDFFFF       lea     eax, dword ptr [ebp-260]
005BF9D3   .  E8 F450E4FF         call    00404ACC                                            ;  LStrFromString()
005BF9D8   .  8B85 A0FDFFFF       mov     eax, dword ptr [ebp-260]                            ;  eax ===> "$07D10C72"
005BF9DE   .  E8 4D9DE4FF         call    00409730                                            ;  StrToInt()
005BF9E3   .  8BD8                mov     ebx, eax                                            ;  ebx == 0x07D10C72,激活码第4部分
005BF9E5   .  BA 48025C00         mov     edx, 005C0248
005BF9EA   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BF9F0   .  E8 1337E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BF9F5   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BF9FB   .  50                  push    eax
005BF9FC   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BFA01   .  BA 11000000         mov     edx, 11                                             ;  start = 17
005BFA06   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BFA0B   .  E8 542FE4FF         call    00402964                                            ;  System.Copy(),取激活码第3部分 "12345678"
005BFA10   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "12345678"
005BFA16   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BFA1C   .  B1 65               mov     cl, 65
005BFA1E   .  E8 B536E4FF         call    004030D8                                            ;  PStrNCat()
005BFA23   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "12345678"
005BFA29   .  8D85 9CFDFFFF       lea     eax, dword ptr [ebp-264]
005BFA2F   .  E8 9850E4FF         call    00404ACC                                            ;  LStrFromString()
005BFA34   .  8B85 9CFDFFFF       mov     eax, dword ptr [ebp-264]                            ;  eax ===> "12345678"
005BFA3A   .  E8 F19CE4FF         call    00409730                                            ;  StrToInt()
005BFA3F   .  35 45812700         xor     eax, 278145                                         ;  激活码处理3
005BFA44   .  33D8                xor     ebx, eax
005BFA46   .  3B1D 64A95C00       cmp     ebx, dword ptr [5CA964]                             ;  [0x005CA964] == 0x00000026,order_no = 38 = 0x26
005BFA4C   .  0F85 16030000       jnz     005BFD68
005BFA52   .  BB 04000000         mov     ebx, 4
005BFA57   .  BE AC6C5C00         mov     esi, 005C6CAC                                       ;  版本类型,[esi] == 0x11E768B7(个人版), [esi] xor 0x00278145 为激活码第三部分
005BFA5C   >  BA 48025C00         mov     edx, 005C0248
005BFA61   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BFA67   .  E8 9C36E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BFA6C   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BFA72   .  50                  push    eax
005BFA73   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BFA78   .  BA 11000000         mov     edx, 11                                             ;  start = 17
005BFA7D   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BFA82   .  E8 DD2EE4FF         call    00402964                                            ;  System.Copy(),取激活码第3部分 "12345678"
005BFA87   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "12345678"
005BFA8D   .  8D85 20FEFFFF       lea     eax, dword ptr [ebp-1E0]
005BFA93   .  B1 65               mov     cl, 65
005BFA95   .  E8 3E36E4FF         call    004030D8                                            ;  PStrNCat()
005BFA9A   .  8D95 20FEFFFF       lea     edx, dword ptr [ebp-1E0]                            ;  edx ===> 09, "$12345678"
005BFAA0   .  8D85 98FDFFFF       lea     eax, dword ptr [ebp-268]
005BFAA6   .  E8 2150E4FF         call    00404ACC                                            ;  LStrFromString()
005BFAAB   .  8B85 98FDFFFF       mov     eax, dword ptr [ebp-268]                            ;  eax ===> "$12345678"
005BFAB1   .  E8 7A9CE4FF         call    00409730
005BFAB6   .  35 45812700         xor     eax, 278145                                         ;  激活码处理4
005BFABB   .  99                  cdq
005BFABC   .  52                  push    edx
005BFABD   .  50                  push    eax
005BFABE   .  8B06                mov     eax, dword ptr [esi]                                ;  激活码第3部分等于 0x11E768B7 xor 0x00278145,0x11E768B7 表示个人版
005BFAC0   .  33D2                xor     edx, edx
005BFAC2   .  3B5424 04           cmp     edx, dword ptr [esp+4]
005BFAC6   .  75 03               jnz     short 005BFACB
005BFAC8   .  3B0424              cmp     eax, dword ptr [esp]
005BFACB   >  5A                  pop     edx
005BFACC   .  58                  pop     eax
005BFACD   .  0F85 84020000       jnz     005BFD57
005BFAD3   .  8D85 B8FDFFFF       lea     eax, dword ptr [ebp-248]
005BFAD9   .  50                  push    eax
005BFADA   .  B9 08000000         mov     ecx, 8                                              ;  len = 8
005BFADF   .  BA 21000000         mov     edx, 21                                             ;  start = 33
005BFAE4   .  B8 FFA85C00         mov     eax, 005CA8FF                                       ;  ASCII 28,"724FBD29057D22021234567807D10C7299022142"
005BFAE9   .  E8 762EE4FF         call    00402964                                            ;  System.Copy(),取激活码第5部分 "99022142"
005BFAEE   .  8D95 B8FDFFFF       lea     edx, dword ptr [ebp-248]                            ;  edx ===> 08, "99022142"
005BFAF4   .  B8 74AB5C00         mov     eax, 005CAB74                                       ;  ASCII 08,"99022142"
005BFAF9   .  B1 0A               mov     cl, 0A                                              ;  len = 10
005BFAFB   .  E8 1436E4FF         call    00403114                                            ;  PStrNCpy(), [005CAB74] ==> 08, "99022142"
005BFB00   .  BA 48025C00         mov     edx, 005C0248                                       ;  edx ===> 01, "$"
005BFB05   .  8D85 84FDFFFF       lea     eax, dword ptr [ebp-27C]
005BFB0B   .  E8 F835E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BFB10   .  8D85 78FDFFFF       lea     eax, dword ptr [ebp-288]
005BFB16   .  50                  push    eax
005BFB17   .  B9 04000000         mov     ecx, 4                                              ;  len == 4
005BFB1C   .  BA 01000000         mov     edx, 1                                              ;  start = 1
005BFB21   .  B8 74AB5C00         mov     eax, 005CAB74                                       ;  ASCII 08,"99022142"
005BFB26   .  E8 392EE4FF         call    00402964                                            ;  System.Copy(),从 "99022142" 中取前4个字符"9902"
005BFB2B   .  8D95 78FDFFFF       lea     edx, dword ptr [ebp-288]                            ;  edx ===> 04, "9902"
005BFB31   .  8D85 84FDFFFF       lea     eax, dword ptr [ebp-27C]
005BFB37   .  B1 0B               mov     cl, 0B
005BFB39   .  E8 9A35E4FF         call    004030D8                                            ;  PStrNCat()
005BFB3E   .  8D95 84FDFFFF       lea     edx, dword ptr [ebp-27C]                            ;  edx ===> 05, "$9902"
005BFB44   .  8D85 90FDFFFF       lea     eax, dword ptr [ebp-270]
005BFB4A   .  E8 7D4FE4FF         call    00404ACC                                            ;  LStrFromString()
005BFB4F   .  8B85 90FDFFFF       mov     eax, dword ptr [ebp-270]                            ;  eax ===> "$9902"
005BFB55   .  E8 D69BE4FF         call    00409730                                            ;  StrToInt()
005BFB5A   .  35 F6EA0000         xor     eax, 0EAF6                                          ;  激活码处理5, eax = 0x9902 xor 0xEAF6 = 0x73F4
005BFB5F   .  8D95 94FDFFFF       lea     edx, dword ptr [ebp-26C]
005BFB65   .  E8 E69AE4FF         call    00409650                                            ;  IntToStr()
005BFB6A   .  8D85 94FDFFFF       lea     eax, dword ptr [ebp-26C]                            ;  [eax] ===> "29684"
005BFB70   .  50                  push    eax
005BFB71   .  8D85 74FDFFFF       lea     eax, dword ptr [ebp-28C]
005BFB77   .  50                  push    eax
005BFB78   .  BA 48025C00         mov     edx, 005C0248                                       ;  edx ===> 01, "$"
005BFB7D   .  8D85 84FDFFFF       lea     eax, dword ptr [ebp-27C]
005BFB83   .  E8 8035E4FF         call    00403108                                            ;  PStrCpy(), 生成 01, "$"
005BFB88   .  8D85 78FDFFFF       lea     eax, dword ptr [ebp-288]
005BFB8E   .  50                  push    eax
005BFB8F   .  B9 04000000         mov     ecx, 4                                              ;  len = 4
005BFB94   .  BA 05000000         mov     edx, 5                                              ;  start = 5
005BFB99   .  B8 74AB5C00         mov     eax, 005CAB74                                       ;  ASCII 08,"99022142"
005BFB9E   .  E8 C12DE4FF         call    00402964                                            ;  System.Copy(),从 "99022142" 中取后4个字符"2142"
005BFBA3   .  8D95 78FDFFFF       lea     edx, dword ptr [ebp-288]                            ;  edx ===> 04, "2142"
005BFBA9   .  8D85 84FDFFFF       lea     eax, dword ptr [ebp-27C]
005BFBAF   .  B1 0B               mov     cl, 0B
005BFBB1   .  E8 2235E4FF         call    004030D8                                            ;  PStrNCat()
005BFBB6   .  8D95 84FDFFFF       lea     edx, dword ptr [ebp-27C]                            ;  edx ===> 05, "$2142"
005BFBBC   .  8D85 68FDFFFF       lea     eax, dword ptr [ebp-298]
005BFBC2   .  E8 054FE4FF         call    00404ACC                                            ;  LStrFromString()
005BFBC7   .  8B85 68FDFFFF       mov     eax, dword ptr [ebp-298]                            ;  eax ===> "$2142"
005BFBCD   .  E8 5E9BE4FF         call    00409730                                            ;  StrToInt()
005BFBD2   .  35 F6EA0000         xor     eax, 0EAF6                                          ;  激活码处理6, eax = 0x2142 xor 0xEAF6 = 0xCBB4
005BFBD7   .  8985 6CFDFFFF       mov     dword ptr [ebp-294], eax                            ;  低32位 == eax
005BFBDD   .  C685 70FDFFFF 00    mov     byte ptr [ebp-290], 0                               ;  高32位 == 0
005BFBE4   .  8D95 6CFDFFFF       lea     edx, dword ptr [ebp-294]
005BFBEA   .  33C9                xor     ecx, ecx
005BFBEC   .  B8 54025C00         mov     eax, 005C0254                                       ;  ASCII "%.4d"
005BFBF1   .  E8 AEABE4FF         call    0040A7A4                                            ;  Format(), 格式化为10进制数字字符串, "52148"
005BFBF6   .  8B95 74FDFFFF       mov     edx, dword ptr [ebp-28C]                            ;  edx ===> "52148"
005BFBFC   .  58                  pop     eax                                                 ;  eax ===> "29684"
005BFBFD   .  E8 2E4FE4FF         call    00404B30                                            ;  LStrCat()
005BFC02   .  8B95 94FDFFFF       mov     edx, dword ptr [ebp-26C]                            ;  edx ===> "2968452148"
005BFC08   .  8D85 C4FEFFFF       lea     eax, dword ptr [ebp-13C]
005BFC0E   .  B9 FF000000         mov     ecx, 0FF
005BFC13   .  E8 EC4EE4FF         call    00404B04                                            ;  System.@LStrToString()
005BFC18   .  8D95 C4FEFFFF       lea     edx, dword ptr [ebp-13C]                            ;  edx ===> 0A, "2968452148"
005BFC1E   .  B8 74AB5C00         mov     eax, 005CAB74                                       ;  ASCII 08,"99022142"
005BFC23   .  B1 0A               mov     cl, 0A
005BFC25   .  E8 EA34E4FF         call    00403114                                            ;  PStrNCpy()
005BFC2A   .  8D85 60FDFFFF       lea     eax, dword ptr [ebp-2A0]
005BFC30   .  BA 74AB5C00         mov     edx, 005CAB74                                       ;  ASCII 08,"99022142"
005BFC35   .  E8 924EE4FF         call    00404ACC                                            ;  LStrFromString(String;String;ShortString;ShortString);
005BFC3A   .  8B85 60FDFFFF       mov     eax, dword ptr [ebp-2A0]                            ;  eax ===> "2968452148"
005BFC40   .  8D95 64FDFFFF       lea     edx, dword ptr [ebp-29C]
005BFC46   .  E8 6588E8FF         call    004484B0                                            ;  ReverseString(),将10进制字符串反转, "2968452148" 变为 "8412548692"
005BFC4B   .  8B95 64FDFFFF       mov     edx, dword ptr [ebp-29C]                            ;  edx ===> "8412548692"
005BFC51   .  8D85 C4FEFFFF       lea     eax, dword ptr [ebp-13C]
005BFC57   .  B9 FF000000         mov     ecx, 0FF
005BFC5C   .  E8 A34EE4FF         call    00404B04                                            ;  System.LStrToString;
005BFC61   .  8D95 C4FEFFFF       lea     edx, dword ptr [ebp-13C]                            ;  edx ===> 0A, "8412548692"
005BFC67   .  B8 74AB5C00         mov     eax, 005CAB74                                       ;  全局变量[0x005CAB74], ASCII 0A, "8412548692", 长度 == 10
005BFC6C   .  B1 0A               mov     cl, 0A                                              ;  len == 10
005BFC6E   .  E8 A134E4FF         call    00403114                                            ;  PStrNCpy()
005BFC73   .  8D85 58FDFFFF       lea     eax, dword ptr [ebp-2A8]
005BFC79   .  8A15 75AB5C00       mov     dl, byte ptr [5CAB75]                               ;  第1个字符, "8"
005BFC7F   .  8850 01             mov     byte ptr [eax+1], dl
005BFC82   .  C600 01             mov     byte ptr [eax], 1                                   ;  生成delphi格式短字符串,01, "8"
005BFC85   .  8D95 58FDFFFF       lea     edx, dword ptr [ebp-2A8]
005BFC8B   .  8D85 54FDFFFF       lea     eax, dword ptr [ebp-2AC]
005BFC91   .  E8 7234E4FF         call    00403108                                            ;  PStrCpy()
005BFC96   .  8D85 50FDFFFF       lea     eax, dword ptr [ebp-2B0]
005BFC9C   .  8A15 76AB5C00       mov     dl, byte ptr [5CAB76]                               ;  第2个字符 "4"
005BFCA2   .  8850 01             mov     byte ptr [eax+1], dl
005BFCA5   .  C600 01             mov     byte ptr [eax], 1                                   ;  生成delphi格式短字符串,01, "4"
005BFCA8   .  8D95 50FDFFFF       lea     edx, dword ptr [ebp-2B0]                            ;  edx ===> 01, "4"
005BFCAE   .  8D85 54FDFFFF       lea     eax, dword ptr [ebp-2AC]                            ;  eax ===> 01, "8"
005BFCB4   .  B1 02               mov     cl, 2                                               ;  字符串个数 count = 2
005BFCB6   .  E8 1D34E4FF         call    004030D8                                            ;  PStrNCat()
005BFCBB   .  8D95 54FDFFFF       lea     edx, dword ptr [ebp-2AC]                            ;  edx ===> 02, "84"
005BFCC1   .  8D85 5CFDFFFF       lea     eax, dword ptr [ebp-2A4]
005BFCC7   .  E8 004EE4FF         call    00404ACC                                            ;  System.LStrFromString(String;String;ShortString;ShortString);
005BFCCC   .  8B85 5CFDFFFF       mov     eax, dword ptr [ebp-2A4]                            ;  eax ===> "84"
005BFCD2   .  E8 599AE4FF         call    00409730                                            ;  StrToInt()
005BFCD7   .  48                  dec     eax                                                 ;  第1,2位小于32, 取 0x1F, 31(每月天数检查,不超过31)
005BFCD8   .  83E8 1F             sub     eax, 1F
005BFCDB   .  73 6A               jnb     short 005BFD47
005BFCDD   .  8D85 58FDFFFF       lea     eax, dword ptr [ebp-2A8]
005BFCE3   .  8A15 77AB5C00       mov     dl, byte ptr [5CAB77]                               ;  第3个字符 "1"
005BFCE9   .  8850 01             mov     byte ptr [eax+1], dl
005BFCEC   .  C600 01             mov     byte ptr [eax], 1                                   ;  生成delphi格式短字符串,01, "1"
005BFCEF   .  8D95 58FDFFFF       lea     edx, dword ptr [ebp-2A8]
005BFCF5   .  8D85 54FDFFFF       lea     eax, dword ptr [ebp-2AC]
005BFCFB   .  E8 0834E4FF         call    00403108                                            ;  PStrCpy()
005BFD00   .  8D85 50FDFFFF       lea     eax, dword ptr [ebp-2B0]
005BFD06   .  8A15 78AB5C00       mov     dl, byte ptr [5CAB78]                               ;  第4个字符 "2"
005BFD0C   .  8850 01             mov     byte ptr [eax+1], dl
005BFD0F   .  C600 01             mov     byte ptr [eax], 1                                   ;  生成delphi格式短字符串,01, "2"
005BFD12   .  8D95 50FDFFFF       lea     edx, dword ptr [ebp-2B0]                            ;  edx ===> 01, "2"
005BFD18   .  8D85 54FDFFFF       lea     eax, dword ptr [ebp-2AC]                            ;  eax ===> 01, "1"
005BFD1E   .  B1 02               mov     cl, 2                                               ;  count = 2
005BFD20   .  E8 B333E4FF         call    004030D8                                            ;  PStrNCat()
005BFD25   .  8D95 54FDFFFF       lea     edx, dword ptr [ebp-2AC]                            ;  edx ===> 02, "12"
005BFD2B   .  8D85 4CFDFFFF       lea     eax, dword ptr [ebp-2B4]
005BFD31   .  E8 964DE4FF         call    00404ACC                                            ;  System.LStrFromString(String;String;ShortString;ShortString);
005BFD36   .  8B85 4CFDFFFF       mov     eax, dword ptr [ebp-2B4]                            ;  eax ===> "12"
005BFD3C   .  E8 EF99E4FF         call    00409730                                            ;  StrToInt()
005BFD41   .  48                  dec     eax                                                 ;  第3、4位小于12(月份检查,不超过12)
005BFD42   .  83E8 0C             sub     eax, 0C
005BFD45   .  72 04               jb      short 005BFD4B
005BFD47   >  33C0                xor     eax, eax
005BFD49   .  EB 02               jmp     short 005BFD4D
005BFD4B   >  B0 01               mov     al, 1                                               ;  注册成功标志 == 1
005BFD4D   >  8B15 346E5C00       mov     edx, dword ptr [5C6E34]                             ;  注册成功标志 == 1
005BFD53   .  8802                mov     byte ptr [edx], al                                  ;  注册成功标志 == 1
005BFD55   .  EB 11               jmp     short 005BFD68
005BFD57   >  83C6 04             add     esi, 4
005BFD5A   .  4B                  dec     ebx
005BFD5B   .^ 0F85 FBFCFFFF       jnz     005BFA5C
005BFD61   .  EB 05               jmp     short 005BFD68
005BFD63   >  E8 9449E4FF         call    004046FC                                            ;  System.halt0
005BFD68   >  33C0                xor     eax, eax
005BFD6A   .  5A                  pop     edx
005BFD6B   .  59                  pop     ecx
005BFD6C   .  59                  pop     ecx
005BFD6D   .  64:8910             mov     dword ptr fs:[eax], edx
005BFD70   .  68 9CFD5B00         push    005BFD9C
005BFD75   >  A1 346E5C00         mov     eax, dword ptr [5C6E34]                             ;  注册标志
005BFD7A   .  8A00                mov     al, byte ptr [eax]
005BFD7C   .  34 01               xor     al, 1                                               ;  al == 0
005BFD7E   .  8B15 A4725C00       mov     edx, dword ptr [5C72A4]                             ;  第2个注册成功标志 == 0
005BFD84   .  8802                mov     byte ptr [edx], al
005BFD86   .  8B15 346E5C00       mov     edx, dword ptr [5C6E34]                             ;  dumped_b.005C43E4
005BFD8C   .  8B15 C86E5C00       mov     edx, dword ptr [5C6EC8]                             ;  第3个注册成功标志 == 0
005BFD92   .  8802                mov     byte ptr [edx], al
005BFD94   .  C3                  retn                                                        ;  RET 用作跳转到 005BFD9C

注册算法总结如下:
1、将硬件序列号去掉中间的"-"号,分成4部分,即4个16进制32位整数,即 ID[1], ID[2], ID[3], ID[4]。
2、输入的激活码分成5部分,前面4个部分也是分成4个16进制32位整数,即 ACT[1], ACT[2], ACT[3], ACT[4],第5部分是一个时间字符串变形,表示成 ACT[5]。
3、程序中有一个版本标识,共4个版本,本程序是个人版,VERTYPE = 0x0x11E768B7,这是一个常量。
4、还有在注册界面输入的 OrderNo,这是一个32位整数。
5、然后是计算:
    (1)如果 OrderNo<430000000,则将 OrderNo 改成 38,即 OrdrerNo = 0x26,否则不变。
    (2)ACT[1] = ID[1] xor ID[4]
    (3)ACT[2] = ID[2] xor ID[3]
    (4)ACT[3] = VERTYPE xor 0x00278145
    (5)ACT[4] = ACT[3]  xor 0x00278145 xor OrderNo,其实就是 VERTYPE xor OrderNo 吧。
6、授权时间 ACT[5]:
    (1)时间数字需反序表示。
    (2)year = year xor 0xEAF6,如果 year = 9102, 是 2019年 的反序表示。
    (3)mon_day = mon_day xor 0xEAF6,如 mon_day = 9003,是09月30日反序表示。
        上面表示购买授权时间是 20190930。
    (4)ACT[5] = (year << 16) or mon_day,生成激活码第5部分。

注意,上面OrderNo的计算是在输入注册信息的表单(TForm2)中保存注册信息的“Accept”按钮事件中计算的,并且计算结果保存到注册文件中了,后面是读出来直接使用的,具体代码如下:
[Asm] 纯文本查看 复制代码
0050FCEE  |>  817D F0 8047A119      cmp     dword ptr [ebp-10], 19A14780                          ;  order_no >= 430000000
0050FCF5  |.  7D 07                 jge     short 0050FCFE
0050FCF7  |.  C745 F0 26000000      mov     dword ptr [ebp-10], 26                                ;  如果 order_no < 430000000,则将 order_no 改成 0x26




根据上面算法,计算正确的激活码,在注册界面重新输入:
141.png
可以看到,注册文件会更新,写入新的注册信息。
142.png



然后重启程序,这次又弹出一个对话框,大概是説安装版本过期,授权拒绝了:
150.png

这是另一个暗桩,大家还记得前面提到过的一个文件么:”C:\Windows\Debug\passwd.log“,就与这个文件的创建时间有关。

在注册码算法代码后,通过 F8 单步,很快确定是下面函数弹出的对话框:
151.png
具体代码如下:
[Asm] 纯文本查看 复制代码
005BFEA7   > \A1 A4725C00          mov     eax, dword ptr [5C72A4]
005BFEAC   .  8038 00              cmp     byte ptr [eax], 0
005BFEAF   .  75 11                jnz     short 005BFEC2
005BFEB1   .  A1 C86E5C00          mov     eax, dword ptr [5C6EC8]
005BFEB6   .  8038 00              cmp     byte ptr [eax], 0
005BFEB9   .  75 07                jnz     short 005BFEC2
005BFEBB   .  E8 CCEBFFFF          call    005BEA8C                       ;  程序版本过期判断
005BFEC0   .  EB 07                jmp     short 005BFEC9
005BFEC2   >  C605 BC6C5C00 01     mov     byte ptr [5C6CBC], 1
005BFEC9   >  A1 38745C00          mov     eax, dword ptr [5C7438]
005BFECE   .  8038 00              cmp     byte ptr [eax], 0
005BFED1   .  74 0C                je      short 005BFEDF


在 DeDeDark 中相应函数内可以查得就是判断上面那个文件的创建时间来判定的,并且是在程序中硬编码,这个版本的passwd.log的创建时间不能大于  2019/03/27 这个时间。
函数代码如下:
[Asm] 纯文本查看 复制代码
005BEA8C  /$  55                   push    ebp
005BEA8D  |.  8BEC                 mov     ebp, esp
005BEA8F  |.  83C4 CC              add     esp, -34
005BEA92  |.  53                   push    ebx
005BEA93  |.  33C0                 xor     eax, eax
005BEA95  |.  8945 CC              mov     dword ptr [ebp-34], eax
005BEA98  |.  8945 D0              mov     dword ptr [ebp-30], eax
005BEA9B  |.  8945 EC              mov     dword ptr [ebp-14], eax
005BEA9E  |.  8945 F0              mov     dword ptr [ebp-10], eax
005BEAA1  |.  8945 F4              mov     dword ptr [ebp-C], eax
005BEAA4  |.  33C0                 xor     eax, eax
005BEAA6  |.  55                   push    ebp
005BEAA7  |.  68 37EC5B00          push    005BEC37
005BEAAC  |.  64:FF30              push    dword ptr fs:[eax]
005BEAAF  |.  64:8920              mov     dword ptr fs:[eax], esp
005BEAB2  |.  A1 EC715C00          mov     eax, dword ptr [5C71EC]
005BEAB7  |.  8B00                 mov     eax, dword ptr [eax]
005BEAB9  |.  BA FFE99100          mov     edx, 91E9FF
005BEABE  |.  E8 B50FEBFF          call    0046FA78
005BEAC3  |.  8B1D 946E5C00        mov     ebx, dword ptr [5C6E94]        ;  Thaiphoo.005C8739
005BEAC9  |.  8A1B                 mov     bl, byte ptr [ebx]
005BEACB  |.  8D45 F4              lea     eax, dword ptr [ebp-C]
005BEACE  |.  8B15 7C6F5C00        mov     edx, dword ptr [5C6F7C]        ;  Thaiphoo.005C873C
005BEAD4  |.  8B12                 mov     edx, dword ptr [edx]
005BEAD6  |.  E8 2D5EE4FF          call    00404908
005BEADB  |.  8D55 F0              lea     edx, dword ptr [ebp-10]
005BEADE  |.  B8 4CEC5B00          mov     eax, 005BEC4C                  ;  ASCII "{-o-f"
005BEAE3  |.  E8 ECFFF4FF          call    0050EAD4
005BEAE8  |.  8B55 F0              mov     edx, dword ptr [ebp-10]
005BEAEB  |.  A1 7C6F5C00          mov     eax, dword ptr [5C6F7C]
005BEAF0  |.  E8 CF5DE4FF          call    004048C4
005BEAF5  |.  A1 946E5C00          mov     eax, dword ptr [5C6E94]
005BEAFA  |.  C600 5F              mov     byte ptr [eax], 5F
005BEAFD  |.  8D45 EC              lea     eax, dword ptr [ebp-14]
005BEB00  |.  50                   push    eax
005BEB01  |.  C745 D4 1B000000     mov     dword ptr [ebp-2C], 1B         ;  27 日    ===> 31   (0x1F)
005BEB08  |.  C645 D8 00           mov     byte ptr [ebp-28], 0
005BEB0C  |.  C745 DC 03000000     mov     dword ptr [ebp-24], 3          ;  03 月    ===> 12   (0x0C)
005BEB13  |.  C645 E0 00           mov     byte ptr [ebp-20], 0
005BEB17  |.  C745 E4 E3070000     mov     dword ptr [ebp-1C], 7E3        ;  2019 年  ===> 9999 (0x270F)
005BEB1E  |.  C645 E8 00           mov     byte ptr [ebp-18], 0
005BEB22  |.  8D55 D4              lea     edx, dword ptr [ebp-2C]
005BEB25  |.  B9 02000000          mov     ecx, 2
005BEB2A  |.  B8 5CEC5B00          mov     eax, 005BEC5C                  ;  ASCII "%d_%d_%d"
005BEB2F  |.  E8 70BCE4FF          call    0040A7A4
005BEB34  |.  8B45 EC              mov     eax, dword ptr [ebp-14]
005BEB37  |.  E8 68DEE4FF          call    0040C9A4
005BEB3C  |.  DD5D F8              fstp    qword ptr [ebp-8]
005BEB3F  |.  9B                   wait
005BEB40  |.  8D45 D0              lea     eax, dword ptr [ebp-30]
005BEB43  |.  BA 74AA5C00          mov     edx, 005CAA74                  ;  检查文件 "C:\WINDOWS\Debug\passwd.log" 的创建时间
005BEB48  |.  E8 7F5FE4FF          call    00404ACC
005BEB4D  |.  8B45 D0              mov     eax, dword ptr [ebp-30]
005BEB50  |.  E8 8BAFE4FF          call    00409AE0                       ;  SysUtils.FileAge(AnsiString):Integer;
005BEB55  |.  E8 4EB4E4FF          call    00409FA8
005BEB5A  |.  DD1D 6CA95C00        fstp    qword ptr [5CA96C]
005BEB60  |.  9B                   wait
005BEB61  |.  DD45 F8              fld     qword ptr [ebp-8]
005BEB64  |.  DC1D 6CA95C00        fcomp   qword ptr [5CA96C]
005BEB6A  |.  DFE0                 fstsw   ax
005BEB6C  |.  9E                   sahf
005BEB6D  |.  73 09                jnb     short 005BEB78                 ;  如果文件过期,则不会跳转,否则跳转去检查授权文件内的时间是否过期
005BEB6F  |.  B0 01                mov     al, 1
005BEB71  |.  E8 52FDFFFF          call    005BE8C8
005BEB76  |.  EB 7C                jmp     short 005BEBF4
005BEB78  |>  A1 346E5C00          mov     eax, dword ptr [5C6E34]
005BEB7D  |.  8038 00              cmp     byte ptr [eax], 0
005BEB80  |.  74 72                je      short 005BEBF4
005BEB82  |.  803D 74AB5C00 08     cmp     byte ptr [5CAB74], 8
005BEB89  |.  75 62                jnz     short 005BEBED
005BEB8B  |.  6A 03                push    3
005BEB8D  |.  BA 74AB5C00          mov     edx, 005CAB74                  ;  授权文件中激活码内的过期时间 (ASCII 08,"31129102"),日/月/年
005BEB92  |.  B9 0A000000          mov     ecx, 0A
005BEB97  |.  B8 68EC5B00          mov     eax, 005BEC68
005BEB9C  |.  E8 373EE4FF          call    004029D8
005BEBA1  |.  6A 06                push    6
005BEBA3  |.  BA 74AB5C00          mov     edx, 005CAB74                  ;  ASCII 08,"31129102"
005BEBA8  |.  B9 0A000000          mov     ecx, 0A
005BEBAD  |.  B8 68EC5B00          mov     eax, 005BEC68
005BEBB2  |.  E8 213EE4FF          call    004029D8
005BEBB7  |.  8D45 CC              lea     eax, dword ptr [ebp-34]
005BEBBA  |.  BA 74AB5C00          mov     edx, 005CAB74                  ;  ASCII 08,"31129102"
005BEBBF  |.  E8 085FE4FF          call    00404ACC
005BEBC4  |.  8B45 CC              mov     eax, dword ptr [ebp-34]
005BEBC7  |.  E8 D8DDE4FF          call    0040C9A4
005BEBCC  |.  DD5D F8              fstp    qword ptr [ebp-8]
005BEBCF  |.  9B                   wait
005BEBD0  |.  DD45 F8              fld     qword ptr [ebp-8]
005BEBD3  |.  D805 6CEC5B00        fadd    dword ptr [5BEC6C]
005BEBD9  |.  DC1D 6CA95C00        fcomp   qword ptr [5CA96C]
005BEBDF  |.  DFE0                 fstsw   ax
005BEBE1  |.  9E                   sahf
005BEBE2  |.  73 10                jnb     short 005BEBF4
005BEBE4  |.  B0 01                mov     al, 1
005BEBE6  |.  E8 DDFCFFFF          call    005BE8C8
005BEBEB  |.  EB 07                jmp     short 005BEBF4
005BEBED  |>  33C0                 xor     eax, eax
005BEBEF  |.  E8 D4FCFFFF          call    005BE8C8
005BEBF4  |>  C605 BC6C5C00 01     mov     byte ptr [5C6CBC], 1
005BEBFB  |.  A1 946E5C00          mov     eax, dword ptr [5C6E94]
005BEC00  |.  8818                 mov     byte ptr [eax], bl
005BEC02  |.  A1 7C6F5C00          mov     eax, dword ptr [5C6F7C]
005BEC07  |.  8B55 F4              mov     edx, dword ptr [ebp-C]
005BEC0A  |.  E8 B55CE4FF          call    004048C4
005BEC0F  |.  33C0                 xor     eax, eax
005BEC11  |.  5A                   pop     edx
005BEC12  |.  59                   pop     ecx
005BEC13  |.  59                   pop     ecx
005BEC14  |.  64:8910              mov     dword ptr fs:[eax], edx
005BEC17  |.  68 3EEC5B00          push    005BEC3E
005BEC1C  |>  8D45 CC              lea     eax, dword ptr [ebp-34]
005BEC1F  |.  BA 02000000          mov     edx, 2
005BEC24  |.  E8 6B5CE4FF          call    00404894
005BEC29  |.  8D45 EC              lea     eax, dword ptr [ebp-14]
005BEC2C  |.  BA 03000000          mov     edx, 3
005BEC31  |.  E8 5E5CE4FF          call    00404894
005BEC36  \.  C3                   retn
005BEC37   .^ E9 F854E4FF          jmp     00404134
005BEC3C   .^ EB DE                jmp     short 005BEC1C
005BEC3E   .  5B                   pop     ebx
005BEC3F   .  8BE5                 mov     esp, ebp
005BEC41   .  5D                   pop     ebp
005BEC42   .  C3                   retn


我们直接可以在程序文件中找到这个位置,如下图所示:
152.png

将上图位置的硬编码“年/月/日”修改一下即可,上面改成了 9999/12/31,够大的了。


保存修改结果,重新运行,正常进入程序,界面如下:
160.png
这次可以看到了 "Write" 按钮,并且是可用状态,注册成功了!!!


前面对时间限制的破除还有一个方法,就是修改文件”C:\Windows\Debug\passwd.log“ 的创建时间早于 2019-03-27 即可。
下面的注册机就实现了这个方法,不过需要”以管理员身份运行“注册机,不然不能修改 C:\Windows 目录下的任何文件的属性。


注册机源码如下:
[C++] 纯文本查看 复制代码
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <string.h>

/// char v[][] = {"Personal Edition", "Personal Lifetime Edition", "Professional Edition", "Engineering Edition"};
unsigned long version_type_id[4] = {0x11E768B7, 0x11E89D96, 0x11E7A00A, 0x11E8788D};


int GetSN(char * ID, unsigned long order_no);
int showFileTime(LPSTR szFile);
int modifyFileTime(LPSTR szFile, int year, int mon, int day);

int main(int argc, char** argv) {
        
        //char ID[] = "A1884D69D3C7F040-205D575B25207559";     //// 根据本机软件显示的ID修正 
        char ID[] = "8C894D69D387F000-4351525542445F5F";
        unsigned long order_no = 430000000;                  //// 32位整数, 定单号,可随意填 
        
        /// generate activation code
        GetSN(ID, order_no);
        
        LPSTR szFilePath = new char[256];
        strcpy(szFilePath, "c:\\Windows\\Debug\\PASSWD.LOG");
        
        printf("\nFile Time Check patching...\n");
        
        showFileTime(szFilePath); //// before of 2019-03-27
        //// 修改文件时间需要“以管理员身份运行”本注册程序 
        //modifyFileTime(szFilePath, 2019, 3, 28); //// 无效 
        modifyFileTime(szFilePath, 2019, 3, 26); //// before of 2019-03-27,有效 
        
        delete szFilePath;

        printf("\nFile Time Check patched.\n");
        
        return 0;
}

int GetSN(char * ID, unsigned long order_no) {
        
        char tmp[12];
        unsigned long id1, id2, id3, id4;
        unsigned long act1, act2, act3, act4, act5;
        
        char * endptr;
        
        memset(tmp, 0, 12);
        strncpy(tmp, ID, 8);
        id1 = strtoul(tmp, &endptr, 16);
        
        strncpy(tmp, &ID[8], 8);
        id2 = strtoul(tmp, &endptr, 16);

        strncpy(tmp, &ID[17], 8);
        id3 = strtoul(tmp, &endptr, 16);

        strncpy(tmp, &ID[25], 8);
        id4 = strtoul(tmp, &endptr, 16);
        
        printf(" ID: %08X%08X-%08X%08X\n", id1, id2, id3, id4);
        printf("Order Number: %u\n", order_no);
        
        act1 = id1 ^ id4;
        act2 = id2 ^ id3;
        
        if(order_no < 430000000) {
                order_no = 38;   //// 0x26
        }
        
        act3 = version_type_id[0] ^ 0x00278145; //0x11C0E9F2; /// Person Version
        act4 = act3 ^ 0x00278145 ^ order_no;
        
        //long dmy = 31129998;  /// reverse to 89992113
        unsigned long y  = 2019;  // reverse from "9102"   /// year: 9102 
        unsigned long md = 2113;  // reverse from "1231";  /// month and day

        y  ^= 0xEAF6;
        md ^= 0xEAF6;
        
        //printf("YMD: %X%X\n",y, md);
        
        act5 = (y << 16) | md;
        
        printf("Activation Code: %08X%08X%08X%08X%08X\n", act1, act2, act3, act4, act5);
        
        return 0;
}

int modifyFileTime(LPSTR szFile, int year, int mon, int day) {
        FILETIME CTime, LATime, LWTime;
        FILETIME CTime1, LATime1, LWTime1;
        SYSTEMTIME CTime2, LATime2, LWTime2;

        /// Creation Time
        CTime2.wYear   = year;
        CTime2.wMonth  = mon;
        CTime2.wDay    = day;
        CTime2.wHour   = 0;
        CTime2.wMinute = 0;
        CTime2.wSecond = 0;
        
        /// Last accessed time
        LATime2.wYear   = year;
        LATime2.wMonth  = mon;
        LATime2.wDay    = day;
        LATime2.wHour   = 0;
        LATime2.wMinute = 0;
        LATime2.wSecond = 0;
        
        /// Last modified time
        LWTime2.wYear   = year;
        LWTime2.wMonth  = mon;
        LWTime2.wDay    = day;
        LWTime2.wHour   = 0;
        LWTime2.wMinute = 0;
        LWTime2.wSecond = 0;

        //// convert to local file time        
        SystemTimeToFileTime(&CTime2, &CTime1);
        SystemTimeToFileTime(&LATime2, &LATime1);
        SystemTimeToFileTime(&LWTime2, &LWTime1);

        /// convert to file time
        LocalFileTimeToFileTime(&CTime1, &CTime);
        LocalFileTimeToFileTime(&LATime1, &LATime);
        LocalFileTimeToFileTime(&LWTime1, &LWTime);
        
        HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
        bool bSetFile = SetFileTime(hFile, &CTime, &LATime, &LWTime); //// run as administrator
        CloseHandle(hFile);
        if(bSetFile) {
                printf("Set File time successed.\n");
        } else {
                printf("Set File time failured. error code: 0x%X\n", GetLastError());
        }
}

int showFileTime(LPSTR szFile) {
    //文件时间结构
    FILETIME ftLocal;
    //系统时间结构
    SYSTEMTIME st;
    //文件属性结构
    WIN32_FILE_ATTRIBUTE_DATA wfad;

    printf("File: %s\n", szFile);
    //获取文件属性
    if(!GetFileAttributesExA(szFile, GetFileExInfoStandard, &wfad)) {
        printf("GetFileAttr Error:%d\n", GetLastError());
        return -1;
    }
    //显示相关时间
    PFILETIME lptime = &(wfad.ftCreationTime);
    //调整为系统所在时区的时间
    FileTimeToLocalFileTime(lptime, &ftLocal);
    //将文件时间转换为SYSTEMTIME格式,便于显示。
    FileTimeToSystemTime(&ftLocal, &st);
    //显示时间信息字符串
    printf("Creation Time:\t%4d-%.2d-%#02d, %.2d:%.2d:%.2d\n",
        st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

    return 0;
}



分析完毕。

本程序的最新版本为 16.0.0.8 build 0818 版,我录制了这个新版本的视频破解教程,参加本论坛的动画比赛,请各位朋友多多支持,连接如下:


https://www.52pojie.cn/thread-1021707-1-1.html

谢谢!!!


免费评分

参与人数 21威望 +1 吾爱币 +26 热心值 +20 收起 理由
lzzdyyy + 1 谢谢@Thanks!
独木桥的世界 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
shixiaoliang719 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
Hmily + 1 + 7 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
DimRacker + 1 + 1 这软件很好用!2010年的时候我做过它的注册并发布在国内某论坛供超频玩家使.
qaz003 + 1 + 1 谢谢@Thanks!
kwan8888 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
zero呆 + 1 + 1 谢谢@Thanks!
dsanke + 1 + 1 谢谢@Thanks!
52ppp000 + 1 + 1 谢谢@Thanks!
wbangmsli + 1 + 1 我很赞同!
夜陌 + 1 + 1 太长了 不看
九宫格 + 1 + 1 我很赞同!
UnrealFPS + 1 + 1 用心讨论,共获提升!
内瑟斯 + 1 + 1 我很赞同!
笙若 + 1 + 1 谢谢@Thanks!
smile5 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
xcuuwww + 1 + 1 热心回复!
zHiHz + 1 + 1 我很赞同!
fengmosir + 1 我很赞同!
3yu3 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

chen4321 发表于 2019-9-13 11:15
哇真是精彩,分析的非常好
 楼主| solly 发表于 2019-9-21 04:08
本帖最后由 solly 于 2019-9-21 22:48 编辑
dsanke 发表于 2019-9-17 22:19
感谢楼主,依葫芦画瓢处理好了

16 版的个人注册版的注册算法相比15版有了一点变化:
about.png
注册算法如下:

[C++] 纯文本查看 复制代码
#include <iostream>
#include <windows.h>
#include <stdlib.h>
#include <string.h>

/// char v[][] = {"Personal Edition", "Personal Lifetime Edition", "Professional Edition", "Engineering Edition"};
unsigned long version_type_id[4] = {0x11E768B7, 0x11E89D96, 0x11E7A00A, 0x11E8788D};
        
int GetSN(char * ID, unsigned long order_no);
int showFileTime(LPSTR szFile);
int modifyFileTime(LPSTR szFile, int year, int mon, int day);

int main(int argc, char** argv) {
        
        char ID[] = "A1884D69D3C7F040-205D575B25207559";     //// 根据本机软件显示的ID修正 
        unsigned long order_no = 450000000;                  //// 32位整数, 定单号,可随意填,但不能小于 440000000 
        
        /// generate activation code
        GetSN(ID, order_no);
        
        LPSTR szFilePath = new char[256];
        strcpy(szFilePath, "c:\\Windows\\Debug\\PASSWD.LOG");
        
        printf("\nFile Time Check patching...\n");
        
        showFileTime(szFilePath); //// before of 2020-01-30
        ////
        modifyFileTime(szFilePath, 2019, 3, 26); //// before of 2020-01-30, 版本失效日期 
        
        delete szFilePath;

        printf("\nFile Time Check patched.\n");
        
        return 0;
}

int GetSN(char * ID, unsigned long order_no) {
        
        char tmp[12];
        unsigned long id1, id2, id3, id4;
        unsigned long act1, act2, act3, act4, act5;
        
        char * endptr;
        
        memset(tmp, 0, 12);
        strncpy(tmp, ID, 8);
        id1 = strtoul(tmp, &endptr, 16);
        
        strncpy(tmp, &ID[8], 8);
        id2 = strtoul(tmp, &endptr, 16);

        strncpy(tmp, &ID[17], 8);
        id3 = strtoul(tmp, &endptr, 16);

        strncpy(tmp, &ID[25], 8);
        id4 = strtoul(tmp, &endptr, 16);

        if(order_no < 440000000) {
                order_no = 440000000;   //// OrderNo < 440000000 时,注册失效 
        }
        
        printf(" ID: %08X%08X-%08X%08X\n", id1, id2, id3, id4);
        printf("Order Number: %u\n", order_no);
        
        act1 = id1 ^ id4;
        act2 = id2 ^ id3;
        
        //act3 = version_type_id[0] ^ 0x002B884A; ///// Person Version
        act3 = version_type_id[3] ^ 0x002B884A; ///// Engineering Edition
        act4 = act3 ^ 0x2B884A ^ order_no;
        
        //long dmy = 31129998;  /// reverse to 89992113
        unsigned long y  = 9102;  // reverse from "2019"   /// year: 9102 
        unsigned long md = 9061;  // reverse from "0916";  /// month and day

        y  ^= 0xEAF6;
        md ^= 0xEAF6;
        
        //printf("YMD: %X%X\n",y, md);
        
        act5 = (y << 16) | md;
        
        printf("Activation Code: %08X%08X%08X%08X%08X\n", act1, act2, act3, act4, act5);
        
        return 0;
}

int modifyFileTime(LPSTR szFile, int year, int mon, int day) {
        FILETIME CTime, LATime, LWTime;
        FILETIME CTime1, LATime1, LWTime1;
        SYSTEMTIME CTime2, LATime2, LWTime2;

        /// Creation Time
        CTime2.wYear   = year;
        CTime2.wMonth  = mon;
        CTime2.wDay    = day;
        CTime2.wHour   = 0;
        CTime2.wMinute = 0;
        CTime2.wSecond = 0;
        
        /// Last accessed time
        LATime2.wYear   = year;
        LATime2.wMonth  = mon;
        LATime2.wDay    = day;
        LATime2.wHour   = 0;
        LATime2.wMinute = 0;
        LATime2.wSecond = 0;
        
        /// Last modified time
        LWTime2.wYear   = year;
        LWTime2.wMonth  = mon;
        LWTime2.wDay    = day;
        LWTime2.wHour   = 0;
        LWTime2.wMinute = 0;
        LWTime2.wSecond = 0;

        //// convert to local file time        
        SystemTimeToFileTime(&CTime2, &CTime1);
        SystemTimeToFileTime(&LATime2, &LATime1);
        SystemTimeToFileTime(&LWTime2, &LWTime1);

        /// convert to file time
        LocalFileTimeToFileTime(&CTime1, &CTime);
        LocalFileTimeToFileTime(&LATime1, &LATime);
        LocalFileTimeToFileTime(&LWTime1, &LWTime);
        
        HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0);
        bool bSetFile = SetFileTime(hFile, &CTime, &LATime, &LWTime); //// run as administrator
        CloseHandle(hFile);
        if(bSetFile) {
                printf("Set File time successed.\n");
        } else {
                printf("Set File time failured. error code: 0x%X\n", GetLastError());
        }
}

int showFileTime(LPSTR szFile) {
    //文件时间结构
    FILETIME ftLocal;
    //系统时间结构
    SYSTEMTIME st;
    //文件属性结构
    WIN32_FILE_ATTRIBUTE_DATA wfad;

    printf("File: %s\n", szFile);
    //获取文件属性
    if(!GetFileAttributesExA(szFile, GetFileExInfoStandard, &wfad)) {
        printf("GetFileAttr Error:%d\n", GetLastError());
        return -1;
    }
    //显示相关时间
    PFILETIME lptime = &(wfad.ftCreationTime);
    //调整为系统所在时区的时间
    FileTimeToLocalFileTime(lptime, &ftLocal);
    //将文件时间转换为SYSTEMTIME格式,便于显示。
    FileTimeToSystemTime(&ftLocal, &st);
    //显示时间信息字符串
    printf("Creation Time:\t%4d-%.2d-%#02d, %.2d:%.2d:%.2d\n",
        st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);

    return 0;
}




download url:

http://softnology.biz/files/thphn_16010_spblsk_build_0916.zip

xcuuwww 发表于 2019-9-12 19:49
IsMe9666 发表于 2019-9-12 19:51
大佬就是大佬,膜拜,顺便问一句 干嘛用的??
熊熊 发表于 2019-9-12 20:05
膜拜大神,精彩
 楼主| solly 发表于 2019-9-12 22:52
yu17863200980 发表于 2019-9-12 19:51
大佬就是大佬,膜拜,顺便问一句 干嘛用的??

查看内存 SPD 芯片信息的,并可以烧录 XMP Profile 到内存的 SPD 芯片中。
fnp902003 发表于 2019-9-13 00:24
某些奸商就是用这个工具修改内存条信息的~~~~
 楼主| solly 发表于 2019-9-13 00:38
fnp902003 发表于 2019-9-13 00:24
某些奸商就是用这个工具修改内存条信息的~~~~

JEDEC标准部分改不了,只是增加超频部分 XMP Profile 之类的。
duduhao 发表于 2019-9-13 02:54
谢谢楼主的分享
pepete 发表于 2019-9-13 05:17
学习了, 谢谢楼主分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 21:56

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表