本帖最后由 姐又寡闻了 于 2019-6-6 22:29 编辑
首先简单描述下该程序验证流程,然后主要谈下破解思路及补丁的制作。
软件KeyFile方式验证,启动时读取目录下的 wincmd.key,旧版本的Size为0x80,新版本为0x400。我们自己构造一个放于目录下。
wincmd.key 结构示意:
BLOCK0: 0x0 ~ 0x80 旧版本占位
BLOCK1: 0x80 ~ 0x100 待解密数据1
BLOCK2: 0x100 ~ 0x380 待使用
BLOCK3: 0x380 ~ 0x3F0 待解密数据2
BLOCK4: 0x3F0 ~ 0x400 哈希值MDX
wincmd.key 验证流程:
将 待解密数据1 进行解密,还原为 0x67 Byte数据,其格式为:
0x0 ~ 0x10 后0x57个数据的哈希值
0x10 ~ 0x13 订单号
0x13 ~ 0x17 用户数
0x17 ~ 0x19 区域简称
0x19 ~ End 用户名|公司|地址 字符串
这里看 v8.51a 的验证流程,这里验证 待解密数据1 用户数据的哈希值是否相同,若相同则解析用户数据并在软件中进行保存显示。
EDX 指向的地址即为Keyfile解密后的用户数据,EDX前0x10的数据为哈希值,偏移0x10处即为用户信息数据。
第一处验证:
004F5946 . 8D85 60FAFFFF LEA EAX, DWORD PTR SS:[EBP-5A0] ; 用户数据结算结果
004F594C . 8D95 70FEFFFF LEA EDX, DWORD PTR SS:[EBP-190] ; 用户数据解密后的数值
004F5952 . B9 10000000 MOV ECX, 10 ; 哈希长度0x10(MD变形算法)
004F5957 . E8 DCFD2000 CALL TOTALCMD.00705738 ; 比较用户信息的签名是否相同
004F595C . 0F84 AE000000 JE TOTALCMD.004F5A10
004F5962 . 33DB XOR EBX, EBX
004F5964 . 33D2 XOR EDX, EDX
提取特征码:B9 10 00 00 00 E8 ?? ?? ?? ?? 0F 84 ?? ?? ?? ?? 33 DB
第二处验证:
004F5E19 . 8D85 60FAFFFF LEA EAX, DWORD PTR SS:[EBP-5A0] ; 待解密数据2 计算的HASH值
004F5E1F . 8D95 60FEFFFF LEA EDX, DWORD PTR SS:[EBP-1A0] ; HASH 值
004F5E25 . B9 10000000 MOV ECX, 10
004F5E2A . E8 51F92000 CALL TOTALCMD.00705780
004F5E2F . 74 02 JE SHORT TOTALCMD.004F5E33
004F5E31 . 33DB XOR EBX, EBX ; 若失败 EBX置零
004F5E33 > 8B85 FCFEFFFF MOV EAX, DWORD PTR SS:[EBP-104]
004F5E39 . E8 1ECFF0FF CALL TOTALCMD.00402D5C
004F5E3E . 8B85 F8FEFFFF MOV EAX, DWORD PTR SS:[EBP-108]
004F5E44 . E8 13CFF0FF CALL TOTALCMD.00402D5C
004F5E49 . 8B85 F4FEFFFF MOV EAX, DWORD PTR SS:[EBP-10C]
004F5E4F . E8 08CFF0FF CALL TOTALCMD.00402D5C
004F5E54 . 881D 10407100 MOV BYTE PTR DS:[714010], BL ; 将布尔值 赋给代表程序是否注册的全局变量
004F5E5A . A1 0C407100 MOV EAX, DWORD PTR DS:[71400C]
提取特征码:B9 10 00 00 00 E8 ?? ?? ?? ?? 74 02 33 DB
我们爆破的思路就是讲解密后的 0x67 Byte数据进行替换,然后跳过第二段验证使全局变量赋值置为TRUE。
Baymax Patch Tools 通过劫持DLL加载功能模块PYG.DLL,功能模块提供异常断点功能,可以模拟OD的下断点并在断点地址修改寄存器、标志寄存器及寄存器指向的内存,我们通过该实例来演示下Baymax补丁工具的使用:
第一步,我们替换掉解密后的用户数据,我们在 004F5957 CALL 00705738 地址下硬件断点。软件无壳,所以通过特征码来直接定位地址,偏移值为5。若有壳,可以HOOK API 待解码后补丁,也可以通过RVA直接下断点。向 EDX + 0x10 的地址出写入我们构造的用户数据:订单号就是今年5.4教学的日期,用户数10000。区域FBI好了,然后是用户信息:03 B6 13 10 27 00 00 46 42 49 4E 69 73 79 7C 42 61 79 6D 61 78 20 50 61 74 63 68 20 54 6F 6F 6C 73 00
第二步,通过第一处的MDX数据校验,这里我们选择修改标志寄存器的方法:特征码偏移值为 0xA,修改 ZF 为 1
第三步,通过第二处的MDX数据校验,这里我们换一种修改方案,将寄存器EAX的数值修改为EDX,即让其比较相同的数据。当然也可以直接将EDX内存中0x10的HEX数值复制到EAX指向的内存。前两处采用默认的硬件断点(INT3断点就没有数量限制了^_^),这里我们试一下INT3的效果:
我们生成调试版的补丁,由于补丁采用的特征码动态寻址,所以直接对8.52a打补丁,我们打开 DebugView 来查看补丁执行过程的输出信息。
00000001 0.00000000 [7948] [NSDLL]version.dll Has Auto Inject ...
00000002 0.00447302 [7948] [BAYMAX] 进程加载:D:\Program Files (x86)\Total Commander\TOTALCMD.EXE
00000003 0.00614219 [7948] [BAYMAX] Proc TOTALCMD.EXE Module TOTALCMD.EXE Name TOTALCMD.EXE
00000004 0.00647143 [7948] [BAYMAX] 执行断点补丁条目
00000005 0.00654861 [7948] [BAYMAX] 执行特征码地址补丁
00000006 0.12728654 [7948] [BAYMAX] Path Rva: F5F62
00000007 0.12735879 [7948] [BAYMAX] 断点补丁地址 004F5F67 补丁数据 EDX,10:0,1,0:I,H,03 B6 13 10 27 00 00 46 42 49 4E 69 73 79 7C 42 61 79 6D 61 78 20 50 61 74 63 68 20 54 6F 6F 6C 73 00
00000008 0.12738301 [7948] [BAYMAX] 设置断点
00000009 0.12755503 [7948] [BAYMAX] 解析异常断点数据成功 ThreadId: 2624
00000010 0.12763917 [7948] [BAYMAX] 设置VEH断点回调函数成功!
00000011 0.12769952 [7948] [BAYMAX] 设置硬件断点 004F5F67 Type DR0 DR7 1
00000012 0.12778121 [7948] [BAYMAX] 获取线程硬件断点成功 004F5F67
00000013 0.12810963 [7948] [BAYMAX] 设置 NsSetUnhandledExceptionFilter OK...
00000014 0.12823197 [7948] [BAYMAX] OEP 007066EC, OPCODE 55
00000015 0.12832105 [7948] [BAYMAX] 设置硬件断点成功 DR0
00000016 0.12840521 [7948] [BAYMAX] 执行特征码地址补丁
00000017 0.15174572 [7948] [BAYMAX] Path Rva: F5F62
00000018 0.15184383 [7948] [BAYMAX] 断点补丁地址 004F5F6C 补丁数据 ZF:0,1,0:1
00000019 0.15192758 [7948] [BAYMAX] 设置断点
00000020 0.15203308 [7948] [BAYMAX] 解析异常断点数据成功 ThreadId: 2624
00000021 0.15212463 [7948] [BAYMAX] 设置硬件断点 004F5F6C Type DR1 DR7 5
00000022 0.15221822 [7948] [BAYMAX] 获取线程硬件断点成功 004F5F6C
00000023 0.15230033 [7948] [BAYMAX] 设置 NsSetUnhandledExceptionFilter OK...
00000024 0.15237996 [7948] [BAYMAX] 设置硬件断点成功 DR1
00000025 0.15246207 [7948] [BAYMAX] 执行特征码地址补丁
00000026 0.17538138 [7948] [BAYMAX] Path Rva: F6435
00000027 0.17547211 [7948] [BAYMAX] 断点补丁地址 004F643A 补丁数据 EAX:0,1,1:R,D,EDX
00000028 0.17555422 [7948] [BAYMAX] 设置断点
00000029 0.17565356 [7948] [BAYMAX] 解析异常断点数据成功 ThreadId: 2624
00000030 0.17573401 [7948] [BAYMAX] 设置INT3断点
00000031 0.17581612 [7948] [BAYMAX] 设置 NsSetUnhandledExceptionFilter OK...
00000032 0.17592737 [7948] [BAYMAX] 设置 0xCC 004F643A
00000033 0.17601359 [7948] [BAYMAX] 设置INT3断点成功 004F643A
00000034 0.17748858 [7948] [BAYMAX] End StartHook()
00000035 0.17759737 [7948] [BAYMAX] 补丁设置初始化完成,若有HOOK或下断点操作,将会在下方进行打印输出。
00000036 0.17770000 [7948] [BAYMAX] 若设置断点无输出信息,尝试将断点修改为INT3类型,OD附加查看地址数据是否仍为CC。
00000037 0.17779976 [7948] [BAYMAX] 若为CC则说明要么未执行,要么设置断点前已执行(劫持DLL加载过晚请换注入模式)。
00000038 0.18012618 [7948] [BAYMAX] Recover Oep
00000039 0.52538264 [7948] [BAYMAX] 找到 DrX 对应的 1 处断点记录
00000040 0.52546722 [7948] [BAYMAX] 触发硬件断点 ThreadId 2624 2624 Type: 0 0
00000041 0.52558911 [7948] [BAYMAX] 当前断点符合触发条件并进行处理 004F5F67
00000042 0.52569669 [7948] [BAYMAX] NS_BREAK_MEMORY 类型 ... 004F5F67
00000043 0.52584118 [7948] [BAYMAX] DealException 004F5F67
00000044 0.52595121 [7948] [BAYMAX] 找到 DrX 对应的 1 处断点记录
00000045 0.52603412 [7948] [BAYMAX] 触发硬件断点 ThreadId 2624 2624 Type: 1 1
00000046 0.52611089 [7948] [BAYMAX] 当前断点符合触发条件并进行处理 004F5F6C
00000047 0.52618766 [7948] [BAYMAX] NS_BREAK_FLAG 类型 ... 004F5F6C
00000048 0.52626276 [7948] [BAYMAX] DealException 004F5F6C
00000049 0.52948332 [7948] [BAYMAX] INT3断点 恢复当前OpCode 004F643A E8
00000050 0.52958840 [7948] [BAYMAX] 当前INT3断点 符合触发条件进行处理 004F643A
00000051 0.52967215 [7948] [BAYMAX] NS_BREAK_REG 类型 ... 004F643A
00000052 0.52975017 [7948] [BAYMAX] INT3断点 执行一次
00000053 0.52982897 [7948] [BAYMAX] DealInt3Exception 004F643A
00000054 0.52991271 [7948] [BAYMAX] ThreadId: 2624 DR0 00000000 DR1 00000000 DR2 00000000 DR3 00000000 DR7 00000005
三处补丁数据已正确执行,由于未修改程序本身,也未修改进程的代码(INT3执行后会自动恢复原指令),不会触发程序自身的校验机制。补丁方式为特征码定位关键点,在作者不修改验证代码的前提下,之前和今后的版本也均适用,安装新版本直接运行仍是注册版。点关于查看注册信息:
安装程序及补丁下载:
云盘链接:http://pan.baidu.com/s/1pLMnzJH 密码:qspl |