QQ堂DLL劫持
在QQ堂目录下面有个zlib1.dll
文件, 通过文件属性我们知道版本号是1.2.1, 而且刚好是开源的. 下载zlib v1.2.1版本的源码, cd
到源码根目录下运行nmake -f win32/Makefile.msc
, 会自动生成zlib.lib和zlib1.res, 我们可以用来制作dll代理. 通过运行dumpbin /EXPORTS zlib1.dll
我们得到原来的DLL导出表的成员, 输出大概是这样子:
1 0 00001000 adler32
2 1 000011E0 compress
3 2 00001130 compress2
4 3 00001200 compressBound
5 4 00001510 crc32
6 5 00001760 deflate
7 6 00001680 deflateBound
8 7 00001C60 deflateCopy
9 8 00001BA0 deflateEnd
10 9 00003050 deflateInit2_
11 A 00003280 deflateInit_
12 B 00002CC0 deflateParams
13 C 00001640 deflatePrime
14 D 00002C20 deflateReset
15 E 00001530 deflateSetDictionary
16 F 00001220 get_crc_table
17 10 00003B20 gzclearerr
18 11 000039D0 gzclose
19 12 00003DC0 gzdopen
20 13 00003930 gzeof
21 14 00003A20 gzerror
22 15 00003880 gzflush
23 16 000040B0 gzgetc
24 17 000040E0 gzgets
25 18 00003DA0 gzopen
26 19 000036C0 gzprintf
27 1A 00003740 gzputc
28 1B 00003770 gzputs
29 1C 00003E00 gzread
30 1D 000038C0 gzrewind
31 1E 00004140 gzseek
32 1F 000032B0 gzsetparams
33 20 000042E0 gztell
34 21 000035A0 gzungetc
35 22 000035F0 gzwrite
36 23 00005950 inflate
37 24 000043C0 inflateBack
38 25 00005240 inflateBackEnd
39 26 00004300 inflateBackInit_
40 27 00007060 inflateCopy
41 28 00006DB0 inflateEnd
42 29 00005740 inflateInit2_
43 2A 00005810 inflateInit_
44 2B 000056F0 inflateReset
45 2C 00006E00 inflateSetDictionary
46 2D 00006F30 inflateSync
47 2E 00007030 inflateSyncPoint
48 2F 00009050 uncompress
49 30 00009120 zError
50 31 00009110 zlibCompileFlags
51 32 00009100 zlibVersion
新建一个文件夹添加我们自己的DLL文件zlib1.c文件和感兴趣的启动代码, 复制zlib.lib
, zlib1.res
, zlib.def到我们的文件夹.
然后执行下面的指令
cl /c /nologo /O2 /MD /utf-8 zlib1.c && link /NOLOGO /RELEASE /DEF:zlib.def /DLL /IMPLIB:zdll.lib /OUT:zlib1.dll zlib1.obj zlib.lib zlib1.res User32.lib Gdi32.lib
如果zlib
没有自带zlib.def
文件的话, 我们需要对zlib1.c
做一些修改: 对于每一行导出函数我们需要添加这样一行代码到zlib1.c
#pragma comment(linker, "/export:_函数名字")
例如
#pragma comment(linker, "/export:_zlibVersion")
最后生成的zlib1.dll就是我们的外挂程序
修复版本过低和验证码闪退补丁
下载QQ游戏客户端, 然后在QQ游戏客户端文件夹里面找SSOCommon.dll, SSOPlatform.dll, 或者你也可以直接下载我提取好的. 我们可以在我们的DLL用LoadLibraryW
加载这两个DLL文件. 修改zlib1.c
然后重新生成zlib1.dll
把他和SSOCommon.dll
, SSOPlatform.dll
一起复制到QQ堂根目录下面就能解决版本过低和验证码闪退的问题.
创建窗口
我们需要创建一个新的进程用来维持一个独立的图形化界面, 具体看代码
1 | HWND FindHandleToQQTangWindow() |
下载商城资源
QQ堂的商城资源保存在服务端http://qqt-img.qq.com/item/ItemZips/<资源类别>/<资源类别><资源id>.zip
. 资源类别和资源id可以在object/itemCFG.pyc
和object/commodityCFG.pyc
中找到. 运行我写的脚本实现.
mkdir -p script
git clone https://gist.github.com/76682c7f9a065566d213bd46c849bdec.git script
conda create --no-default-packages -n QQT python=3.8.12
conda activate QQT
conda install aiohttp
cd script
python QQTResourceDownload.py
反编译pyc
pip install uncompyle6
然后运行uncompyle6
反编译pyc
文件
FOR /R %f IN (*.pyc) DO (uncompyle6 -o . --encoding gbk %f)
uncompyle6
可能会反编译注释的时候出错因为QQ堂源文件是gbk
编码的,需要修改一些uncompyle6
源码,在这一段之前添加一行docstring = docstring.decode("gbk")
. 即使反编译出来,源码不一定能直接用,需要手动修改, 需要一些的Python的知识. 例如可能会有编码的问题以及一些在最新版本的Python会出现语法不支持.
反编译QQ堂地图编辑器
安装Python2.5然后安装unpy2exe然后把把exe转换成pyc文件.反编译的主要难题是Python2.5版本太老了,安装不了pip文件,需要手动修改pip的源码,很多依赖也要手动安装,要找支持对应Python版本的依赖,有些可能根本没有或者太老了.我猜测QQ堂本身也可以被反编译的,不过可能要安装更老版的Python例如2.2版本.
参考
- API Interception via DLL Redirection
- Can we export a function made available through a static library
- creating dll with cl and linker
- /MD, /MT, /LD (Use Run-Time Library)
- Compiler options listed alphabetically
- /DEF (Specify Module-Definition File)
- c++ creating a window from a dll
- Create your Proxy DLLs automatically
- ProxiFy - Automatic Proxy DLL Generation
- SharpDllProxy
- DLL代理转发
- 火拼QQ堂穿墙功能的挖掘
- 对某游戏功能实现的逆向分析及实现变态功能
- 缘来社区 - QQ堂板块
- 网悠社区 - QQ堂板块