首页
社区
课程
招聘
[原创]HOOK DXGI GetBuffer实现dwm反截图 内容详细的一批
发表于: 2023-4-24 12:04 12081

[原创]HOOK DXGI GetBuffer实现dwm反截图 内容详细的一批

2023-4-24 12:04
12081


Hello啊  各位看雪的大佬们

在家天天玩游戏 无聊的一~ 在一个风和日丽的下午 我躺在床上玩手机 偶然间看到一个交流群里面 有人在收所谓的dwm反截图 于是就起来研究了一番

                                                                                                 


研究的第一件事 当然是打开从未注册过的看雪论坛 寻找一番 截图原理~ (由于看雪有太多关于构造Shellcode进dwm进行截图的帖子了  我也不清楚哪个是原创 所以没附链接


还是叙述一下原理吧 

        先这样 再内样 最后那样 就搞定啦~

  

还是不开玩笑 直接上   GitHub - lainswork/dwm-screen-shot: 将shellcode注入dwm.exe以进行屏幕截取 在这个开源项目中 你将会看到他下载了当前系统版本dxgi模块的pdb文件 并从中寻找了4个地址   


 地址都有了  第一件事情 当然是丢到ce去看看他撒嘛个情况喽



好像 4个值是一样的 ....  那我们试着下个断点  看看是啥情况   

直接说结果: 前三个地址断不下来  点击测试截图  按钮后  其中第1或2或3 的地址指向的空间会被清除    至于为什么会被清除...大家可以去那个开源项目研究研究      


嘶~  好吧  不过是 在不同版本的系统实测中  第四个地址 永远不会变  BUT...... 第四个 我发现处理第四个没啥用的  因为第四个一直被调用着  随时能断下来



大家对dwm下断 请做好卡死的准备 毕竟是处理所有窗口的程序 一旦停止了 你的画面也就无了~



那么 眼尖 又懒惰 的小伙伴    可能注意到了 前三个地址在截图时的变化   那我们是不是可以在截图的时候不绘制呢



if(IsBadHugeReadPtr(dxgi+0x14d0))
{
return;
}


欸 是不是可以利用这个思路进行反截图呢    



欸还真可以(在我的电脑上...WIN11 22H2)


然后我就兴致勃勃的发给朋友试了   欸 您猜怎么着    他的绘制会消失一会儿  但是等恢复回来的时候 就刚好被截图到了....


好吧 还是不能走歪门邪道  我们还是老老实实看看那4个地址对应的啥函数吧 ~


OK 我们直接使用dumpbin工具获取到pdb内容  



dumpbin工具 使用方法如下 :  1.打开vs   2.工具->命令行->开发者命令提示   然后出来了一个窗口 在里面输入

dumpbin /all "路径\dxgi.dll">D:\储存dump的文件.txt  注意dxgi的pdb要跟dll同目录  





ok回归正题  


在PDB文件中 找到了4个地址对应的虚函数名



第一个函数是PresentFullscreenFlip 第二个是 CDXGISwapChain::Present 第三个是PresentDWM@CDXGISwapChain 第四个是PresentMultiplaneOverlay


嘶~ 



在Bing后 在Baidu后   在Google后 再问过ChatGPT之后 我发现 这4个函数对我来说 用处不大~


于是我们退而求其次  去Bing一下 正常截图的方法 



有一种比较简单的想法能比较快速的实现DirectX11 程序运行截图。

在当前场景帧进行Present()操作之前,渲染结果存储在交换链(Swap Chain)的后缓冲区中。我们定义一个Texture2D 对象,调用IDXGISwapChain类中的GetBuffer()方法可以将当前后缓冲区的绘制结果复制到该Texture2D对象中:

HRESULT GetBuffer(

[in] UINT Buffer,

[in] REFIID riid,

[in, out] void **ppSurface

);

例子:(来源于MSDN)

ID3D11Texture2D * p_RT;

g_pSwapChain->GetBuffer(0, __uuidof(p_RT), reinterpret_cast<void**>(&p_RT));



欸嘿 这不就赚大发了吗      直接HookGetBuffer不就完了 


hook他的第一个问题 就是他的地址怎么取....  由于我的知识有限 所以我直接在pdb里面找到了..... 简单又快捷



那我们直接导入Hook库 直接开干  


MH_Initialize();
DWORD64 AddrGetBuffer =(DWORD64) DXGImoudlebase+ 0x1468; // GetBuffer
MH_CreateHook((DWORD_PTR *)AddrGetBuffer , &NewGetBuffer,(PVOID*)(&OrGetBuffer));

MH_EnableHook((DWORD_PTR *)AddrGetBuffer );

 HRESULT NewGetBuffer(IDXGISwapChain *A, UINT Buffer, GUID riid, void **ppSurface)
{
            *ppSurface = (void *)pTexture2D;
            return S_OK;
}


那么细心的观众 或者 已经去CV的观众就要问了 你给返回的pTexture2D 是啥玩意 


那我就不得不说说我这两天被折磨的路程了   


我一开始的思路是:在我还没有 绘制任何东西的时候截用GetBuffer创建一个ID3D11Texture2D *  然后到时候返回我没绘制的时候的ID3D11Texture2D *就好了  这个思路是不是很好    


当你这么想的时候你就掉进去了   我这样尝试的结果是: 即使返回一个我没绘制的时候使用GetBuffer获取到的数据(这里说数据都不严谨 微软官方说的是后台缓冲区接口的指针)也会截图到实时的画面 并且带着我的绘制....   ok 还是返回一张固定的图片方便....



ok啊 返回图片还不简单吗 ... 先这样在那样不就好了  哈哈  



读入图片需要用到d3dx11的支持库   

#include <d3d11.h>
#include"D3DX11.h"
#pragma comment(lib, "d3dx11.lib")

嗯对就是这玩意儿      什么? 你说你CV进去没有????


嘿嘿 直接上代码:

                            D3D11_TEXTURE2D_DESC dec;
                            UINT                 createDeviceFlags = 0;
                            createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
                            D3D_FEATURE_LEVEL    featureLevel;
                            ID3D11Device        *md3dDevice;
                            ID3D11DeviceContext *md3dImmediateContext;

                            HRESULT hr =
                                D3D11CreateDevice(0,                           //  默认显示适配器
                                                  D3D_DRIVER_TYPE_HARDWARE, 0, //  不使用软件设备
                                                  createDeviceFlags, 0, 0,     //  默认的特征等级数组
                                                  D3D11_SDK_VERSION, &md3dDevice, &featureLevel, &md3dImmediateContext);

                            HRESULT                result;
                            D3DX11_IMAGE_LOAD_INFO loadInfo;
                            ZeroMemory(&loadInfo, sizeof(D3DX11_IMAGE_LOAD_INFO));
                            loadInfo.BindFlags = desc.BindFlags;// ;
                            loadInfo.Format    = desc.Format;    // DXGI_FORMAT_R8G8B8A8_UNORM;
                            loadInfo.MipLevels = desc.MipLevels; // D3DX11_DEFAULT; // 这时会产生最大的mipmaps层。
                            loadInfo.MipFilter =D3DX11_FILTER_LINEAR;

                            result             = D3DX11CreateTextureFromFile(md3dDevice, "C:\\1.png", &loadInfo, NULL,
                                                                             (ID3D11Resource **)(&pTexture2D), NULL);
                            pTexture2D->GetDesc(&dec);


代码都是从我的源码里面扣出来的  难免缺斤少两 希望大家自己看得懂  有一点解释一下 上图中 desc的定义

                            D3D11_TEXTURE2D_DESC desc;
                            memset(&desc, 0x00, sizeof(desc));
                            g_back_buffer->GetDesc(&desc);

如果你连GetDesc都不知道是啥 那我也无能为力了   


最后让我们测试一下这个方法可行不可行吧           





好了 其实到这里就完结撒花了  

总结一下 GetBuffer 有更好的方法获取地址 

本篇文章不涉及太多具体代码  因为反截图本身是在对抗反作弊  本人也是仅作技术交流 才发表本文章 我怕直接发源码 一堆人拿去玩游戏 也不太好...

好啦~提前祝大家5 1 快乐~ 感谢大家的观看  




真是无语 看雪上了这么多次 一直没注册 现在想发表篇帖子 还没到24小时 



== 现在有了 发表~




转载请注明出处


[培训]《安卓高级研修班(网课)》月薪三万计划,掌 握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
点赞5
支持
分享
最新回复 (13)
雪    币: 422
活跃值: (328)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
2
补充一下  GetBuffer本身是个IDXGISwapChain的虚函数  所以第一个参数应该是IDXGISwapChain的指针
2023-4-24 12:51
1
雪    币: 5312
活跃值: (3439)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
支持
2023-4-24 13:24
0
雪    币: 228
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
如果是为了过dwm screen这个项目的截图,那么直接hook RtrlUser线程入口点拦截掉这个线程就行了,或者针对源码去做一些拦截,如果是为了搞TslGame,那么X3不只是这一个地方,他有三种Hook点的截图方案, 单纯只绕过这一个点是没啥作用的,为了防止lz被挂哥追杀,建议匿掉
2023-4-24 13:53
2
雪    币: 347
活跃值: (213702)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
tql
2023-4-24 14:03
0
雪    币: 1169
活跃值: (1694)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
Tql
2023-4-24 14:48
0
雪    币: 198
活跃值: (1168)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
Jsssss 如果是为了过dwm screen这个项目的截图,那么直接hook RtrlUser线程入口点拦截掉这个线程就行了,或者针对源码去做一些拦截,如果是为了搞TslGame,那么X3不只是这一个地方,他有三 ...
谨慎发言。不然又会出现 10万一只手的言论了
2023-4-24 15:39
0
雪    币: 1453
活跃值: (14624)
能力值: ( LV12,RANK:380 )
在线值:
发帖
回帖
粉丝
8
hackflame 谨慎发言。不然又会出现 10万一只手的言论了[em_19]
火哥我要给你生猴子
2023-4-24 16:09
0
雪    币: 889
活跃值: (1007)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
hackflame 谨慎发言。不然又会出现 10万一只手的言论了[em_19]
火哥我要给你生猴子
2023-6-27 10:19
0
雪    币: 213
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
无语了家人
2023-6-27 10:23
0
雪    币: 140
活跃值: (441)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
SSH山水画 火哥我要给你生猴子
我要给你生猴子+1
2023-7-5 21:41
0
雪    币: 19785
活跃值: (29397)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
mark
2023-7-6 11:06
1
雪    币: 1788
活跃值: (5234)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13

都欺负到你家老窝里了, 进你家里卧室偷拍摄像, 底层玩家还连屁都不敢放. 告它啊?!干它啊?!把立法权从流氓奸商手里夺回来啊.还在你电脑上挂钩子, 你怎么忍的???

最后于 2023-7-6 11:13 被PEDIY编辑 ,原因:
2023-7-6 11:11
0
雪    币: 0
活跃值: (292)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
这是注入dwm了吗
2024-5-8 07:13
0
游客
登录 | 注册 方可回帖
返回