dump 出来,魔改,然后重新写个 DLL 加载器就好。
或者直接做成引导启动,引导后把联网的相关 API 干掉。
之前研究过这个软件,可惜帖子被黑幕了。
加载器的源码在下面:
https://pan.baidu.com/s/1_vwxkFXt30WekuzMGgUu4Q?pwd=8svb
使用的是 22.0.0.3 (2022.07.19)
版本,原版也在里面。
下面是我之前的分析部分:
作者将整个程序编译为 DLL,使用 UPX 压缩后内嵌至 EXE 文件。
主程序启动时,将该文件通过内存加载的方式启动。
我把它脱壳后写了个简单的引导程序来启动,这样就不需要回写到原来的 EXE 文件了。
启动器顺便加了个简单的屏蔽联网小功能,请注意这个没有破解功能,只是加了个引导器。
...
软件会检查是否联网并上报当前机器以及版本信息,因此启动器顺便剔除了联网相关代码;启动器的源码也在压缩包内,有兴趣可以继续加功能进去。
功能 DLL 提取、脱壳过程
首先下 VirtualAlloc
与 VirtualProtect
断点,然后正常运行;
依次查看函数的返回地址,其中有一个返回后是这样:
009718BB | 56 | push esi |
009718BC | 68 20F09A00 | push bosskey_.9AF020 |
009718C1 | E8 60FDFFFF | call bosskey_.971626 |
009718C6 | 8BF0 | mov esi,eax |
9AF020
开始的内存处就是 DLL 文件内容,直接转存这块内存区域即可;提取到这块内存区域结束即可。
注:971626
处的函数就是初始化内存加载 DLL
...
得到的这个 DLL 文件是使用 UPX 加壳的文件,但没有进行魔改。直接执行「upx -d bosskey22.0.0.3_dump.dll
」即可得到脱壳后的文件。
然后就是修改 DllMain
入口点。因为一些原因,使用 LoadLibrary
加载的 DLL 入口执行时调用 CreateThread
启动线程会产生一些奇怪的问题,因此需要手动调用这个初始化函数。
首先使用 PE-Bear
或类似的 PE 编辑器将入口点修改为 mov eax, 1; ret 04h
的地址:
...
然后就是手动执行 DLL 基址 + 0x5CA20
处的函数进行初始化即可(参见启动器代码)。
问题:
1 如果我非要使用OD调试的话(用习惯了看着舒服),问如何操作使OD能在0x5002CBB2处断下。
硬件执行断点应该可行?
2 如上图所示,从分配内存开始,它是一个PE文件,而且貌似加了UPX的文件。它是单独的一个文件吗?
如何dump出来?不知道dump出来后能不能运行。
直接转存内存即可。
转存出来的 DLL 需要特殊处理,但你可以看我以前研究过的内容。
3 申请内存空间的基址+偏移0x2CBB2就是段首,段首ret,那么写补丁时,这个判断时机是什么,如何判断呢?
如要HOOK哪个函数,正好空间已经分配,而且分配空间内已经填充了代码。如果是只是分配了空间,但是
内部还没有填充代码的话,这时写补丁,之后补丁会被填充的代码覆盖,肯定不对的。
你可以 Hook 代码内初始化 DLL 的函数下方,例如 22.0.0.3 (2022.07.19)
版的 971626
函数。调用原函数后会得到 DLL 装载后的内存地址。
4 此软件无壳,PE查壳如下:
Microsoft Visual C++ v.14.0 - 2015 (E8)
按一般正向编程思路来说,判断升级,肯定写在MFC程序的初始化函数里,但是现在这个升级
却不在初始化函数里,作者到底是如何实现的?怎么插入这个upx的单独的EXE的?如果作者自己
在MFC程序里写VirtualAlloc,里面写代码,感觉不可能的,难度不亚于写shellcode。
可能在新的线程里。DLL 加载时有调用 CreateThread
的痕迹(如果我之前的分析没有错的话)。
5 除了段首ret破解方法,是否其他破解方法,基于软件这种思路或特性。
屏蔽联网。
6 我想把补丁写成劫持补丁,经测试,msimg32.dll,version.dll,winmm.dll这三个常用劫持DLL均不加载,
请问还有其他DLL可以劫持吗?
XP 下有 lpk.dll
,这个程序的话不清楚。
不过你也可以手动更改它的导入表让它加载你的 DLL。