制作这个工具(和其他工具)的原因是试图找到一份涉及逆向工程/网络安全等的工作……
与仅仅声称你知道你的东西的“空白”简历形成对比,我想,好吧,最好做一些项目和开源代码来展示它。

我决定尝试测试这个(和其他)产品的安全性,以及我是否可以绕过它的保护并可能做一个小项目。

逆向过程

寻找内存地址

当您运行 target (surfblock.exe) 时(并且每次从系统托盘中调出它),您会看到一个对话框,要求您输入密码。

您输入错误并出现提示您重试的消息框。因此,在让您进入或显示消息框之前,必须有一些功能检查密码是否有效。

目标没有打包/混淆,没有反调试技巧,没有 ASLR 等……所以不使用所有这些东西会加速逆向过程。Blumentals Surfblocker v5.x与PoiSoN的神秘火花

这也意味着所有字符串都是明文形式并且在调试器/反汇编器中可见,因此搜索“密码”关键字或类似关键字似乎是一种选择。但是有很多结果,所以尝试更具体并搜索显示在消息框中的字符串只会给你这个:

该字符串是 UNICODE,因此在MessageBoxW上设置断点并稍微回溯似乎是让您进入密码检查功能的好方法。这个技巧奏效了,在你输入错误的密码并单击“确定”后,你会在 USER32 模块内的 MessageBoxW 处中断。

从 USER32 返回后,您在这里:

但仍然没有通过检查功能。您似乎处于处理显示消息框内容的集中式功能中。

直至00509B8F → RETN 4并退出此功能。

之后向上滚动一点,您就可以看到某些功能的开始,大概是密码检查功能。

清除 MessageBoxW BP 并将其设置为008B38BC → PUSH EBP
再次输入密码,你在这个函数的开始处中断。

在堆栈/寄存器准备指令之后,该函数立即通过将输入的密码与真实密码进行比较来检查输入的密码是否正确。

008B38F4   E8 4B4AC2FF    CALL surfbloc.004D8344 ; length of typed in pass
008B38F9   8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4] ; points to typed in pass
008B38FC   8B15 C0568E00  MOV EDX,DWORD PTR DS:[8E56C0] 
008B3902   8B12           MOV EDX,DWORD PTR DS:[EDX]
008B3904   8B92 58040000  MOV EDX,DWORD PTR DS:[EDX+458] ; points to correct password
008B390A   E8 514FB5FF    CALL surfbloc.00408860 ; compare strings

解密后的密码存储在内存中,如下所示:

固定地址 → 固定地址 → 动态地址 + 0x458 = 指向正确密码的指针

所以在这种情况下,它的 0x008E56C0 → 0x0090DBB4 → dynamic_address + 0x458

密码解密

如果您查看 Windows 注册表(程序通常存储其设置的地方),您可以看到 Surfblocker 将其设置存储在那里,包括加密密码。

但是在RegQueryValueExW (和其他注册表函数)上设置 BP不起作用。我需要不同的方法。

我已经找到了存储解密密码的内存地址。但是实际的解密是如何完成的以及在哪里完成的呢?

我在调试器中重新加载目标,在第二个固定地址(在本例中为 0x0090DBB4)设置硬件写入断点 (DWORD) ,然后运行。

硬件休息后,我们现在在这里:

现在我们已经得到了写在 0x0090DBB4 处的动态内存地址,但是密码仍然没有被解密。

因此,在 dynamic_address+0x458 处设置另一个硬件写入断点 (DWORD),然后运行。

在第二次硬件休息后,我们在这里:
hwbp2

此时,我可以在 EDI 和 ESI 寄存器中看到解密的密码,但解密已经完成,这个函数看起来不像解密例程。

在执行到返回(Olly 中的 Ctrl+F9)两次之后,我们得到了一个相当长的函数。在该函数的顶部附近,我们在 0x006ECC42 处看到一个有趣的调用:

检查此调用表明 surfblock.exe 正在尝试与 Internet Protector Service (IProtectorService.exe) 通信。

在该呼叫密码被解密之后,因此看起来解密过程正在该服务内部的某处发生。

下一步是将调试器附加到该服务并检查那里发生的情况。

现在,由于在 surfblock.exe 中的RegQueryValueExW上设置 BP不起作用,我在服务模块中尝试了这种方法,认为它现在应该可以工作了,因为在解密之前,必须将加密密码加载到内存缓冲区中。

这成功了,我们现在在 IProtectorService 模块内的 RegQueryValueExW 处中断:

从通话中返回后,我们现在在这里:
正则值获取

0062FD9F   E8 C8E4FFFF    CALL IProtect.0062E26C

从函数内部可以看到,在 0x0062FD9F 处调用会进行 XOR 解密:

结论

就是这样。

我们已经完成了对这个产品的逆向并破坏了它的保护。