诚心请教:COM HOOK问题

s_zbchen1 2012-07-16 04:50:16
我在做一个硬件加速截屏项目,在网上找到很多DirectX截图黑屏的解决方案,最后得出的解决方案是:

“通过Hook DDraw的DirectDrawCreate(RealOne用)同DirectDrawCreateEx(WMP用)
获得IDirectDraw(7)
再COM Hook CreateSurface,注意RealOne使用的是通过QueryInterface获得IDirectDraw2
WMP则是IDirectDraw7

Hook了CreateSurface后,就能获得OverlaySurface”

我在下面链接的开源代码的基础上修改,可以Hook到自己写的demo的DirectDrawCreateEx

http://www.codeguru.com/cpp/w-p/dll/hooking/article.php/c127/APIHijack--A-Library-for-Easy-DLL-Function-Hooking.htm


下面链接demo却hook不到,用ida查看了Mosquito.exe的导出接口,确认其调用了DirectDrawCreateEx
http://files.cnblogs.com/graphics/Mosquito.zip

...全文
825 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
changecode 2012-09-02
  • 打赏
  • 举报
回复
楼主能把代码共享下么?让我们学习学习,我最近也在弄个截屏,也是遇到directx硬件加速下的问题了,我对hook又不太熟悉,所以希望得到你的教育。
s_zbchen1 2012-08-17
  • 打赏
  • 举报
回复
创建离层表面时要判断数据格式
Thesea2006 2012-08-09
  • 打赏
  • 举报
回复
我想问下楼主,用lpDD7在dll里能创建OFFSCREEN么?我测试怎么一直没成功
s_zbchen1 2012-07-19
  • 打赏
  • 举报
回复
采取内存映射通知dll截图,这个问题终于解决了,非常感谢大家,特别是zhaoxy1973。

但是截到的图全是花点,那是另外一个问题了。
s_zbchen1 2012-07-19
  • 打赏
  • 举报
回复
我的所有操作还是在dll里面进行的,lpDD7没有传给exe,而且lpDD7我在data_seg里面定义的,照道理注入后还是处在同样的内存段啊。
s_zbchen1 2012-07-19
  • 打赏
  • 举报
回复
嗯,多谢zhaoxy1973提醒,问题应该出在这里了,现在我试试看。
zhaoxy1973 2012-07-19
  • 打赏
  • 举报
回复
hr = lpDD7->SetCooperativeLevel(NULL, DDSCL_NORMAL);//这里就挂掉了

你的问题,我粗略看了下,lpDD7这个指针你传给exe有啥用呢。你注入程序.exe的指针能访问注入目标的内存地址么?当然要报错。正确的作法是那一堆截屏之类的操作在dll里做,因为dll已经注入,和目标在同一进程内,能访问目标的内存地址。然后你的dll和主程序通过socket,namedpipe之类的通讯。
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
现在我的问题点不在这里,为什么我在MyDirectDrawCreateEx获取LPDIRECTDRAW7指针后,调用这个指针都会有问题呢?(因为这个时候视频还在播放,照道理进程的内存数据还在啊
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
看错了,新版本没有删掉FlipToGDISurface,
在FlipToGDISurface里面可以获取this后,再创建离线表面,再lock住离线表面,获取图像数据吧。

可是我hook不到FlipToGDISurface啊,我是用detours 去hook的,其他的函数如blt、CreateSurface我都hook到了,代码:

p=*(PROC*)(*((DWORD*)lpDDSP7)+0x28);
HookDApi(FlipToGDISurface7,p);

Saleayas 2012-07-18
  • 打赏
  • 举报
回复
你有没有自己做一个 DDraw 的程序??
难道 DDraw 出新版本把 这个函数给取消了?



DECLARE_INTERFACE_( IDirectDraw, IUnknown )
{
/*** IUnknown methods ***/
STDMETHOD(QueryInterface) (THIS_ REFIID riid, LPVOID FAR * ppvObj) PURE;
STDMETHOD_(ULONG,AddRef) (THIS) PURE;
STDMETHOD_(ULONG,Release) (THIS) PURE;
/*** IDirectDraw methods ***/
STDMETHOD(Compact)(THIS) PURE;
STDMETHOD(CreateClipper)(THIS_ DWORD, LPDIRECTDRAWCLIPPER FAR*, IUnknown FAR * ) PURE;
STDMETHOD(CreatePalette)(THIS_ DWORD, LPPALETTEENTRY, LPDIRECTDRAWPALETTE FAR*, IUnknown FAR * ) PURE;
STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC, LPDIRECTDRAWSURFACE FAR *, IUnknown FAR *) PURE;
STDMETHOD(DuplicateSurface)( THIS_ LPDIRECTDRAWSURFACE, LPDIRECTDRAWSURFACE FAR * ) PURE;
STDMETHOD(EnumDisplayModes)( THIS_ DWORD, LPDDSURFACEDESC, LPVOID, LPDDENUMMODESCALLBACK ) PURE;
STDMETHOD(EnumSurfaces)(THIS_ DWORD, LPDDSURFACEDESC, LPVOID,LPDDENUMSURFACESCALLBACK ) PURE;
STDMETHOD(FlipToGDISurface)(THIS) PURE;
STDMETHOD(GetCaps)( THIS_ LPDDCAPS, LPDDCAPS) PURE;
STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC) PURE;
STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD, LPDWORD ) PURE;
STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE FAR *) PURE;
STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD) PURE;
STDMETHOD(GetScanLine)(THIS_ LPDWORD) PURE;
STDMETHOD(GetVerticalBlankStatus)(THIS_ LPBOOL ) PURE;
STDMETHOD(Initialize)(THIS_ GUID FAR *) PURE;
STDMETHOD(RestoreDisplayMode)(THIS) PURE;
STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE;
STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD) PURE;
STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD, HANDLE ) PURE;
};
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
DIRECTDRAW7没有FlipToGDISurface函数
逸萌 2012-07-18
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 的回复:]
FlipToGDISurface的指针偏移是0x28(40=10*4)吧,没有hook到哦,还是我hook错了?
[/Quote]up
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
FlipToGDISurface的指针偏移是0x28(40=10*4)吧,没有hook到哦,还是我hook错了?
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
试试看看
Saleayas 2012-07-18
  • 打赏
  • 举报
回复
而且截取 DX 的图片应该是钩住其翻转的那一刹那。

如果是 DDraw ,应该钩住 FlipToGDISurface 那个函数。
在这个函数里,获取其使用的 IDirectDraw7 的接口,
然后创建诸如离屏表面等等。

我没有做过 DDraw。
我以前曾将有一个项目,需要在 DirectX 的游戏里,呈现我们自己的窗口。
我们不是截屏,而是在其翻转的时候,绘制我们自己的图层。
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
回Saleayas:
确认创建成功了,
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
回himulakensin:
我是要做2D的截图,你是指hook人家主表面的lock函数吗?

我现在可以hook到了blt7、Flip7、GetAttachedSurface7等函数,在blt7里面做文章咋样?
Saleayas 2012-07-18
  • 打赏
  • 举报
回复
hr = lpDD7->SetCooperativeLevel(NULL, DDSCL_NORMAL);//这里就挂掉了

检测 lpDD7 是否创建成功。
s_zbchen1 2012-07-18
  • 打赏
  • 举报
回复
回Saleayas:
钩DirectDrawCreateEx在MyDirectDrawCreateEx赋值了。
匹夫 2012-07-18
  • 打赏
  • 举报
回复
你是想截取人家的图片数据对吧,setcooper...函数肯定是不能指望成功的。
hook创建表面的函数得到人家用的表面指针,然后hook lock等函数,可以要得数据指针。
可以利用要到的指针创建自己的一个离屏的表明,去要覆盖表明的数据等等操作

我也只是hook到几个接口,没有在往下做,通过这个理解了覆盖显示调用函数的顺序和应该填什么参数
然后自己跟着实现了一下。这是在工作的机器上干的事情。后来在自己的电脑上试,发现我下载的那个hook
能吧播放器(多个播放器)弄死了,一直就没成功。

我本来的目的是想截取某个rpg游戏的视频,发现没用ddraw的接口,相当的悲剧
加载更多回复(13)

64,282

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧