首页
社区
课程
招聘
[原创] 逆向并提取QQ截图--基本功能
发表于: 2022-1-19 19:23 39027

[原创] 逆向并提取QQ截图--基本功能

2022-1-19 19:23
39027

QQ截图是我用过的最好用的截图工具, 由于基本不在电脑上登QQ了, 于是就想将其提取出独立版
目前除了屏幕录制功能其他都逆出来了, 在此分享一下, 源码见附件, 成品太大了放网盘了
链接:https://pan.baidu.com/s/1yENiFF3KDdZTDfqig6X98A
提取码:oa7c

(其他功能的效果展示请移步下一个帖子 逆向并提取QQ截图--OCR和其他功能)

版本: QQ 9.5.4.28063

网上搜一搜就知道QQ历年版本的截图功能都放在了Camera.dll里, IDA打开Camera.dll看一下导出表:
Camera_Export
(图 2-1)
大概率是通过COM组件的方式去调用截图功能, 那么必然会去调用CoCreateInstance获取类的实例, 但是在CoCreateInstance下断是断不下来的, 后面可以知道QQ在Common.dll中自己实现了CoCreateInstance函数, 也就是无注册表的COM调用
CoCreateInstance的内部实现是这样的:

无论如何都会调用DllGetClassObject获取类厂指针

于是在Camera的DllGetClassObject下断看一下调用栈:

callstack1
(图2-2)

显然截图的命令是被asynctask异步分发过来的, 那么appframework模块可能就是调用源头了

基址:camera=67CA0000, common=71860000, appframework=6BE40000

看到common.7183713那个调用栈函数, IDA分析一下:
CoCreateInstanceWithDllname
(图 3-1)
动态调试一下就是知道这个函数就是QQ自己实现的CoCreateInstance

common.719DB0A9:
sc_call
(图 3-2)

一直分析到appframework.68EEE54A:
call_source
(图 3-3)

所以直接call (AppFramework+AE46D)函数(也就是图3-3), 就可以调用截图了, 当然应该也可以去调图3-2中的v33(v21, v25, v4, v20), 但是调appframework的话, 一些初始化啊, 析构的方法就不需要我们去操心再模拟调用了
我采用的方式是模拟整个(AppFramework+AE46D)函数, 当然直接call应该也可以, 但是我一开始直接call的时候发现sub_5081B982(&v17)那个函数总是返回NULL, 下面自然也就不会执行了, 后来才发现需要初始化PlatformCore

在逆向过程中经常会发现程序会去调用类似下图的代码:
getplatformcore
(图 4-1)
看一下Common.dll的导出表:
common_platform
(图 4-2)

因为几乎所有函数的调用栈都会经HummerEngine.dll所以去这个dll里看了看, 还真就发现了初始化过程:
hummer_init
(图 4-3)
直接仿着反编译结果写一份!:

这样跑其实还是会崩溃, 调试一下发现需要SetMainAndLogicThreadId, 还是模拟一下:

其实还是直接仿着(AppFramework+AE46D)函数的反编译结果写一份就好了, 贴一下部分代码:

保存图片的时候会崩溃掉, 逆向调试一下发现, 是在保存的时候:
save_crash
大概是v50+1388那里, 猜测一下这个函数是用来写入上次保存文件路径的, 直接patch掉好了
还有程序退出的时候也会崩溃, 我进行了这样的处理:

就是让调用Util::CoreCenter::IsStopped()的时候返回TRUE

demo

这个markdown的图片都是用提取出来QQScreenShot截图的, 也没发现内存泄漏

 
CoCreateInstance(....)
{
    //.......
    IClassFactory *pClassFactory=NULL;
    //↓内部调用DllGetClassObject
    CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
    pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
    pClassFactory->Release();
    //........
}
CoCreateInstance(....)
{
    //.......
    IClassFactory *pClassFactory=NULL;
    //↓内部调用DllGetClassObject
    CoGetClassObject(CLSID_Object, CLSCTX_INPROC_SERVER, NULL, IID_IClassFactory, (void **)&pClassFactory);
    pClassFactory->CreateInstance(NULL, IID_IUnknown, (void**)&pUnk);
    pClassFactory->Release();
    //........
}
 
 
 
 
 
 
 
 
typedef long (WINAPI *LPFN_Util_Com_CreateObjectFromDllFile)(wchar_t const *, struct _GUID const &, struct _GUID const &, void * *, struct IUnknown *);
typedef int (__cdecl *LPFN_Util_CoreCenter_InitPlatform)(wchar_t *);
typedef int (__cdecl *LPFN_Util_Boot_InitPlatformI18NConfig)(void);
 
HRESULT res = 0;
LPFN_Util_Com_CreateObjectFromDllFile lpfnCreateObjectFromDllFile = (LPFN_Util_Com_CreateObjectFromDllFile)CommonMgr.GetFuncAddr("?CreateObjectFromDllFile@Com@Util@@YGJPB_WABU_GUID@@1PAPAXPAUIUnknown@@@Z");
res = lpfnCreateObjectFromDllFile(L"Common.dll", CLSID_Common_Init, IID_ICommon_Init, (void**)(&testPtr), NULL);
 
LPFN_Util_Boot_InitPlatformI18NConfig lpfnInitPlatformI18NConfig = (LPFN_Util_Boot_InitPlatformI18NConfig)CommonMgr.GetFuncAddr("?InitPlatformI18NConfig@Boot@Util@@YAHXZ");
res = lpfnInitPlatformI18NConfig();
 
LPFN_Util_Boot_InitPlatformFileSystem lpfnInitPlatformFileSystem = (LPFN_Util_Boot_InitPlatformFileSystem)CommonMgr.GetFuncAddr("?InitPlatformFileSystem@Boot@Util@@YAHXZ");
res = lpfnInitPlatformFileSystem();
//...
//完整代码见附件
typedef long (WINAPI *LPFN_Util_Com_CreateObjectFromDllFile)(wchar_t const *, struct _GUID const &, struct _GUID const &, void * *, struct IUnknown *);
typedef int (__cdecl *LPFN_Util_CoreCenter_InitPlatform)(wchar_t *);
typedef int (__cdecl *LPFN_Util_Boot_InitPlatformI18NConfig)(void);
 
HRESULT res = 0;
LPFN_Util_Com_CreateObjectFromDllFile lpfnCreateObjectFromDllFile = (LPFN_Util_Com_CreateObjectFromDllFile)CommonMgr.GetFuncAddr("?CreateObjectFromDllFile@Com@Util@@YGJPB_WABU_GUID@@1PAPAXPAUIUnknown@@@Z");
res = lpfnCreateObjectFromDllFile(L"Common.dll", CLSID_Common_Init, IID_ICommon_Init, (void**)(&testPtr), NULL);
 
LPFN_Util_Boot_InitPlatformI18NConfig lpfnInitPlatformI18NConfig = (LPFN_Util_Boot_InitPlatformI18NConfig)CommonMgr.GetFuncAddr("?InitPlatformI18NConfig@Boot@Util@@YAHXZ");
res = lpfnInitPlatformI18NConfig();
 
LPFN_Util_Boot_InitPlatformFileSystem lpfnInitPlatformFileSystem = (LPFN_Util_Boot_InitPlatformFileSystem)CommonMgr.GetFuncAddr("?InitPlatformFileSystem@Boot@Util@@YAHXZ");
res = lpfnInitPlatformFileSystem();
//...
//完整代码见附件
/**
 * @brief 设置主线程和逻辑线程ID
 */
void InitMainAndLogicThreadId()
{
    LPFN_Util_Misc_SetMainAndLogicThreadId
    lpfnSetMainAndLogicThreadId = (LPFN_Util_Misc_SetMainAndLogicThreadId)CommonMgr.GetFuncAddr("?SetMainAndLogicThreadId@Misc@Util@@YAXKK@Z");
    lpfnSetMainAndLogicThreadId(GetCurrentThreadId(), 0);
}
/**
 * @brief 设置主线程和逻辑线程ID
 */
void InitMainAndLogicThreadId()
{
    LPFN_Util_Misc_SetMainAndLogicThreadId
    lpfnSetMainAndLogicThreadId = (LPFN_Util_Misc_SetMainAndLogicThreadId)CommonMgr.GetFuncAddr("?SetMainAndLogicThreadId@Misc@Util@@YAXKK@Z");

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

最后于 2022-4-17 18:11 被0xEEEE编辑 ,原因: 修改介绍
上传的附件:
收藏
免费 22
支持
分享
最新回复 (23)
雪    币: 106
活跃值: (739)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
大佬牛逼,我选择 snipaste
2022-1-19 19:50
0
雪    币: 2286
活跃值: (6663)
能力值: ( LV7,RANK:102 )
在线值:
发帖
回帖
粉丝
3
能把QQ的图片OCR识别提取出来吗
2022-1-19 20:17
0
雪    币: 4318
活跃值: (2667)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
666
2022-1-20 09:37
0
雪    币: 4493
活跃值: (4244)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
5
fjqisba 能把QQ的图片OCR识别提取出来吗[em_6]
那怕不是有点困难哦,服务端那边肯定会有校验的
2022-1-20 09:55
0
雪    币: 8213
活跃值: (4166)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
大佬,NB,要是能逆OCR就更好了
2022-1-20 10:36
0
雪    币: 3760
活跃值: (5921)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
7
还有就是本来还想把屏幕录制功能逆出来的, 但是调用截图的时候那个截图背景会把整个屏幕遮住, 这时候调试器也就被挡住了, 即使断下来也没法调试
可以尝试下使用desktops.exe工具(是微软Sysinternals套件中提供的一款工具,可以虚拟创建出来四个屏幕),qq程序以及录制视频程序放到第一个屏幕上,windbg放到第二个屏幕上,通过alt+1 alt+2 3 4可以切换不同的桌面。
2022-1-20 10:40
0
雪    币: 4493
活跃值: (4244)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
8
0346954 还有就是本来还想把屏幕录制功能逆出来的, 但是调用截图的时候那个截图背景会把整个屏幕遮住, 这时候调试器也就被挡住了, 即使断下来也没法调试 可以尝试下使用desktops.exe工具(是微软Sys ...
好主意哦!, 有空试试
2022-1-20 11:13
0
雪    币: 6270
活跃值: (3335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
snipaste最好用,没有之一,其他都是屎
2022-1-20 11:16
0
雪    币: 5189
活跃值: (9712)
能力值: ( LV9,RANK:181 )
在线值:
发帖
回帖
粉丝
10
0xEEEE 那怕不是有点困难哦,服务端那边肯定会有校验的[em_47]
这东西都不需要逆向,直接对QQ发起的连接进行分析就会发现,它调用了服务端,同时带了QQ的身份信息,单独扣出来没用。
2022-1-20 11:18
0
雪    币: 707
活跃值: (1301)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
11
用双显示器调试
2022-1-20 15:33
0
雪    币: 14855
活跃值: (6083)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
Rectangle rect = new Rectangle(0, 0, 100, 100);
        Bitmap bmp = new Bitmap(rect.Width, rect.Height, PixelFormat.Format32bppArgb);
        Graphics g = Graphics.FromImage(bmp);
        g.CopyFromScreen(rect.Left, rect.Top, 0, 0, bmp.Size, CopyPixelOperation.SourceCopy);
        bmp.Save(fileName, ImageFormat.Jpeg);
2022-1-20 16:31
0
雪    币: 35739
活跃值: (7155)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
支持老大,2千年时最早用Hypersnap/Snagit32/后来用FsCapture
2022-1-20 16:45
0
雪    币: 112
活跃值: (1531)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
楼主不知道腾讯收购搜狗之后,给搜狗拼音提供了独立的截图工具吗?
screencapture (exe+cupf) 仅1.66MB,除了没有①和长图功能,其它都一样,系统兼容良好。
2022-1-29 20:06
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15
一直在用QQ的截屏工具,为老大点赞,试用了,矩形等工具不会默认取上次的选项(如边框粗细,颜色等),每次得重新选择,希望能优化解决,感觉
2022-4-17 17:00
0
雪    币: 227
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
楼主太给力了,听我说谢谢你,因为有你,温暖了四季!
2022-9-7 21:14
1
雪    币: 433
活跃值: (1910)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
17
tDasm Rectangle rect = new Rectangle(0, 0, 100, 100); Bitmap bmp = new Bitmap(rect.Width, rect.He ...
直接用CIMAGE更快
2022-9-7 23:19
0
雪    币: 171
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18
代码写内嵌汇编的人好帅
2022-9-27 10:11
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
win11不能使用,打开闪退,电脑使用的是华为笔记本matebook13
2022-11-2 11:17
1
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
真难取 楼主不知道腾讯收购搜狗之后,给搜狗拼音提供了独立的截图工具吗? screencapture (exe+cupf) 仅1.66MB,除了没有①和长图功能,其它都一样,系统兼容良好。
你这个是独立的吗,必须要使用搜狗的输入法,才能使用吧
2022-11-2 11:21
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
楼主,百度OCR可以将默认的“通用文字识别(标准版)”换成“高精度版”吗?两个版本的识别率相差实在是太远了。QQ文字识别在百度OCR(高精度版)面前也只能算是弟弟,分别试下非草手写体和竖版文字立马见分晓。百度OCR(高精度版)也有每月1000次免费的,个人放心用。
2023-1-4 21:56
0
雪    币: 112
活跃值: (1531)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
DINGDING8 你这个是独立的吗,必须要使用搜狗的输入法,才能使用吧
独立组件!下载最新版搜狗拼音,用7z打开直接提取这两个文件即可使用。
2023-1-13 14:21
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23
QQ附近人大佬有吗
2023-8-31 21:06
0
雪    币: 112
活跃值: (1531)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24

xsnip 就是依照QQ截图功能来全新开发的,仅有460KB,完全一样的功能!

上传的附件:
2023-9-4 19:56
0
游客
登录 | 注册 方可回帖
返回
//