开始第二次尝试破解第四课例子:
首先搜关键词"未注册",发现没有,改为搜“注册”再搜寻有用信息,发现重要线索“已注册版本”,跟进去,在上指令上面一些打上断点,或者直接在这个函数头打断点也行,
然后发现能不能显示“已注册版本”,关键在于cmp byte ptr ds:[0x579F24],0x0,这句的比较,在第一次尝试破解的时候,我天真地以为只要将其结果变成不相等(将常量0x0改为了0x1),就可以了;
实际上是并不行的,首先软件开发者不太可能只在一个地方进行这个已注册未注册的验证,更理性的方式应该是分析变量的来源(就是0x579F24里面的值是什么时候被赋值的),我们查找所有常量0x579F24,给所有结果打上断点;
Ctrl+F2重新调试,点击运行,发现停在了一个断点处,
[Asm] 纯文本查看 复制代码 00541634 . 8B0485 2C9F57>mov eax,dword ptr ds:[eax*4+0x579F2C]
0054163B . E8 842FECFF call qqqf.004045C4
00541640 . 83F8 18 cmp eax,0x18
00541643 . 74 09 je short qqqf.0054164E
00541645 . 83F8 0C cmp eax,0xC
00541648 . 74 04 je short qqqf.0054164E
0054164A . 33D2 xor edx,edx
0054164C . EB 02 jmp short qqqf.00541650
0054164E > B2 01 mov dl,0x1
00541650 > 8815 249F5700 mov byte ptr ds:[0x579F24],dl
断点停在00541650,观看下上面的指令,可以大概猜出是比较一个长度是不是0x18和0xC,如果是,就将0x579F24的值赋值为1,我们F8一步步往下调,发现下面还有两个关于0x579F24的断点
不知道判断了什么又给0x579F24赋值,并且马上对0x579F24进行了比较cmp!,发生cmp 说明可能是有重要的分支要出现了,这个时候0x579F24应该必须赋值为1,才不会错过我们想要的。
[Asm] 纯文本查看 复制代码 00541695 . 40 inc eax
00541696 EB 04 jmp short qqqf.0054169C
00541698 > 33C0 xor eax,eax
0054169A . EB 02 jmp short qqqf.0054169E
0054169C > B0 01 mov al,0x1
0054169E > A2 249F5700 mov byte ptr ds:[0x579F24],al
005416A3 > 803D 249F5700>cmp byte ptr ds:[0x579F24],0x0
我直接将00541696的条件跳转改称了无条件jmp跳转,然后你发现已经成功的注册了,现在软件弹出网络验证错误
搜索"正在验证" retn掉整个函数,然后重新打开,左下角显示已注册;然后尝试功能,发现插入昵称是乱码,我们得跟进去,由于这个程序是Delphi 写的,下Delphi 按钮断点,论坛里有人分享了这个脚本,大家可以搜一下,选择插入昵称跟进去,停在一个call上,F7进入;
[Asm] 纯文本查看 复制代码 00568198 /. 55 push ebp
00568199 |. 8BEC mov ebp,esp
0056819B |. 6A 00 push 0x0
0056819D |. 6A 00 push 0x0
0056819F |. 33C0 xor eax,eax
005681A1 |. 55 push ebp
005681A2 |. 68 F4815600 push qqqf.005681F4
005681A7 |. 64:FF30 push dword ptr fs:[eax]
005681AA |. 64:8920 mov dword ptr fs:[eax],esp
005681AD |. 8D4D F8 lea ecx,[local.2]
005681B0 |. 33D2 xor edx,edx
005681B2 |. B8 20000000 mov eax,0x20
005681B7 |. E8 04ACF4FF call qqqf.004B2DC0
005681BC |. 8B55 F8 mov edx,[local.2]
005681BF |. 8D45 FC lea eax,[local.1]
005681C2 |. E8 11CAE9FF call qqqf.00404BD8
005681C7 |. 8B45 FC mov eax,[local.1]
005681CA |. 50 push eax
005681CB |. E8 9046FFFF call qqqf.0055C860
005681D0 |. 5A pop edx ; qqqf.0048B2DC
005681D1 |. E8 DAF6F8FF call qqqf.004F78B0
005681D6 |. 33C0 xor eax,eax
005681D8 |. 5A pop edx ; qqqf.0048B2DC
005681D9 |. 59 pop ecx ; qqqf.0048B2DC
005681DA |. 59 pop ecx ; qqqf.0048B2DC
005681DB |. 64:8910 mov dword ptr fs:[eax],edx
005681DE |. 68 FB815600 push qqqf.005681FB
005681E3 |> 8D45 F8 lea eax,[local.2]
005681E6 |. E8 EDC0E9FF call qqqf.004042D8
005681EB |. 8D45 FC lea eax,[local.1]
005681EE |. E8 1DC8E9FF call qqqf.00404A10
005681F3 \. C3 retn
005681F4 .^ E9 23BAE9FF jmp qqqf.00403C1C
005681F9 .^ EB E8 jmp short qqqf.005681E3
005681FB . 59 pop ecx ; qqqf.0048B2DC
005681FC . 59 pop ecx ; qqqf.0048B2DC
005681FD . 5D pop ebp ; qqqf.0048B2DC
005681FE . C3 retn
如上代码,马上映入眼前。。。我觉得这里可以采用一个BFS搜索算法的原理,先看下这6个call,发现只有第一个call 才有可能会实现一些检验等复杂的功能,我们跟进第一个call,饿,更多了call出现了;
首先我感觉可以下合理的猜测,就是检验应该是在SendMessageA这个系统API之前,因为这个是发送消息的功能部分,其实大多数在这种情况下,我们都有一种生死不自知的感觉。不过我偶然看论坛里,有人提到一个快捷方式,就是知道要进行md5校验,我们可以在和md5相关的API上下断点,更加迅速的靠近我们的目标位置,我选择GetFileSize,我准备试试,在开始之前在SendMessageA这里打上断点,想证明下上面自己的猜测对不对(如果GetFileSize在SendMessageA前面断下来了,说明我的猜测是对的);
Ctrl+G 搜索GetFileSize函数,并下断点。然后F9运行,停在了GetFileSize这里,证明我上面的这一小点推测是正确的。栈里面显call来自004B1E99,我们跳过去,发现了很多系统dll的api ,一步步F8,直到过了API CloseHandle,目标肯定在下面。
当我跟着程序走的时候,发现中途跳过了好几个call(使用retn的方式)
找到了md5比较处,虽然我怀疑,但是我反复确定 才真的确定下来(我察看了ebp-0x14发现是现在程序的md5值,脑袋里还是有昨天视频里的一点影像。。)
我发现这里的特点是将刚计算出来的文件md5值进行比较(这个md5就极大概率是保存在栈上了),md5这么长,比较起来肯定是有个小循环之类的
[Asm] 纯文本查看 复制代码 004B1F6F |. BE 10000000 mov esi,0x10
004B1F74 8D5D EC lea ebx,dword ptr ss:[ebp-0x14]
004B1F77 8D55 E8 lea edx,dword ptr ss:[ebp-0x18]
004B1F7A |. 33C0 |xor eax,eax
004B1F7C |. 8A03 |mov al,byte ptr ds:[ebx]
004B1F7E |. E8 35F1FFFF |call qqqf.004B10B8
004B1F83 |. 8B55 E8 |mov edx,[local.6]
004B1F86 |. 8BC7 |mov eax,edi
004B1F88 |. E8 3F26F5FF |call qqqf.004045CC
004B1F8D |. 43 |inc ebx
004B1F8E |. 4E |dec esi
004B1F8F |.^ 75 E6 \jnz short qqqf.004B1F77
004B1F91 |. 33C0 xor eax,eax
004B1F93 |. 5A pop edx ; 0012FCAC
查找二进制字符串 找到空白位置
最后 添加的代码为:
[Asm] 纯文本查看 复制代码 0056B0A8 BE 10000000 mov esi,0x10
0056B0AD C745 EC 11EA7>mov dword ptr ss:[ebp-0x14],0xA370EA11
0056B0B4 C745 F0 C3735>mov dword ptr ss:[ebp-0x10],0x295C73C3
0056B0BB C745 F4 B4855>mov dword ptr ss:[ebp-0xC],0x775285B4
0056B0C2 C745 F8 67564>mov dword ptr ss:[ebp-0x8],0x6A405667
0056B0C9 8D5D EC lea ebx,dword ptr ss:[ebp-0x14]
0056B0CC 8D55 E8 lea edx,dword ptr ss:[ebp-0x18]
0056B0CF 33C0 xor eax,eax
0056B0D1 8A03 mov al,byte ptr ds:[ebx]
0056B0D3 E8 E05FF4FF call qqqf.004B10B8
0056B0D8 8B55 E8 mov edx,dword ptr ss:[ebp-0x18]
0056B0DB 8BC7 mov eax,edi
0056B0DD E8 EA94E9FF call qqqf.004045CC
0056B0E2 43 inc ebx
0056B0E3 4E dec esi
0056B0E4 ^ 75 E6 jnz short qqqf.0056B0CC
0056B0E6 33C0 xor eax,eax
0056B0E8 5A pop edx ; 0012FCAC
0056B0E9 ^ E9 A66EF4FF jmp qqqf.004B1F94
原来修改的地方为
[Asm] 纯文本查看 复制代码 004B1F5F |. E8 7423F5FF call qqqf.004042D8
004B1F64 |. 8D55 EC lea edx,[local.5]
004B1F67 |. 8B45 FC mov eax,[local.1]
004B1F6A |. E8 69FEFFFF call qqqf.004B1DD8
004B1F6F E9 34910B00 jmp qqqf.0056B0A8
004B1F74 8D5D EC lea ebx,dword ptr ss:[ebp-0x14]
004B1F77 8D55 E8 lea edx,dword ptr ss:[ebp-0x18]
004B1F7A |. 33C0 |xor eax,eax
004B1F7C |. 8A03 |mov al,byte ptr ds:[ebx]
004B1F7E |. E8 35F1FFFF |call qqqf.004B10B8
004B1F83 |. 8B55 E8 |mov edx,[local.6]
004B1F86 |. 8BC7 |mov eax,edi
004B1F88 |. E8 3F26F5FF |call qqqf.004045CC
004B1F8D |. 43 |inc ebx
004B1F8E |. 4E |dec esi
004B1F8F |.^ 75 E6 \jnz short qqqf.004B1F77
004B1F91 |. 33C0 xor eax,eax
004B1F93 |. 5A pop edx ; 0012FCAC
004B1F94 |. 59 pop ecx ; 0012FCAC
004B1F95 |. 59 pop ecx ; 0012FCAC
004B1F96 |. 64:8910 mov dword ptr fs:[eax],edx
11EA70A3 C3735C29 B4855277 6756406A是qqqf.exe在我电脑上的md5值,尝试了下修改的文件 果然成功了 啊哈 吃小米饭去
|