请问如何在d3d窗口显示文字

HSxuguangxing 2008-08-18 04:46:52
我能够钩住DirectXCreate8,但是由于本人对directX不熟,所以不知道该如何利用这个函数在一个不断刷新的d3d窗口显示我自己的文字?貌似是要钩住他的Render()函数,不过还比较迷茫,希望有人指点一下!
...全文
427 16 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
HSxuguangxing 2008-08-20
  • 打赏
  • 举报
回复
哦,谢谢了!
rageliu 2008-08-20
  • 打赏
  • 举报
回复
w_anthony的代码,第4点可以修改下:

挂EndScere,在这里直接写字,然后Present,不“在HWND上画字”
HSxuguangxing 2008-08-20
  • 打赏
  • 举报
回复
太感谢了,太感动了,多谢大侠!不介意的话我会以身相许的!
w_anthony 2008-08-20
  • 打赏
  • 举报
回复
对了,第二个步骤其实不用asm,应该参数本来就有,直接取就可以了,呵呵,晕头了。
如果要用asm,就要把int addr放远一点,免得他改变了esp的值。
w_anthony 2008-08-20
  • 打赏
  • 举报
回复
有意思,不过有些麻烦,要钩的话,只能钩IDirect3DDevice8::Present,不过这是个虚函数,不是导出函数,无法轻易的得到其地址,只能通过虚函数表来找到它。

既然你可以钩住DirectXCreate8,其返回值是一个IDirect3D8*,然后再由IDirect3D8::CreateDevice得到IDirect3DDevice8*,最后才是IDirect3DDevice8::Present。根据这个原理:
1、先通过IDirect3D8*,找到CreateDevice的地址:

DECLARE_INTERFACE_(IDirect3D8, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;

/*** IDirect3D8 methods ***/
STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE;
STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE;
STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier) PURE;
STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter) PURE;
STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed) PURE;
STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE;
STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType) PURE;
STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE;
STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps) PURE;
STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE;
STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE;
};

CreateDevice是第16个虚函数,假设IDirect3D8* pD3d,那么CreateDevice的地址应该是*(((int*)(INT_PTR)*(int*)pD3d) + 16)。

2、挂钩这个CreateDevice,它的原形前面也看到了,最后一个参数是IDirect3DDevice8**,由于压栈顺序是从右往左,而且是个_stdcall,也就是说此函数执行完毕时,栈顶减4的地方就是IDirect3DDevice8**,可以这样读取:

int addr;
_asm mov eax, [esp - 4];
_asm mov addr, [eax];

这样就得到了IDirect3DDevice8*指针。

3、最后通过IDirect3DDevice8*,找到Present的地址。

DECLARE_INTERFACE_(IDirect3DDevice8, IUnknown)
{
/*** IUnknown methods ***/
STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;

/*** IDirect3DDevice8 methods ***/
STDMETHOD(TestCooperativeLevel)(THIS) PURE;
STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE;
STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE;
STDMETHOD(GetDirect3D)(THIS_ IDirect3D8** ppD3D8) PURE;
STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8* pCaps) PURE;
STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE;
STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE;
STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface8* pCursorBitmap) PURE;
STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE;
STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE;
STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain8** pSwapChain) PURE;
STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE;
STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE;
……
};

可以看到Present也是第16个函数,假设IDirect3DDevice8* pD3Device,那么Present的地址就是*(((int*)(INT_PTR)*(int*)pD3Device) + 16)。

4、找到Present就好办,钩一下,每次Present执行完毕后,再在HWND上画字就OK了。

HSxuguangxing 2008-08-20
  • 打赏
  • 举报
回复
谁有些实例能够小弟参考一下啊?
superdiablo 2008-08-20
  • 打赏
  • 举报
回复
HSxuguangxing 2008-08-19
  • 打赏
  • 举报
回复
可是钩不着啊!
rageliu 2008-08-19
  • 打赏
  • 举报
回复
d3d是使用Present来刷新的,开始是BeginScene后结束EndScene
HSxuguangxing 2008-08-19
  • 打赏
  • 举报
回复
怎么又没人了啊?来人帮忙啊!
Amuro1987218 2008-08-19
  • 打赏
  • 举报
回复
COM HOOK
HSxuguangxing 2008-08-19
  • 打赏
  • 举报
回复
我用的是inline hook,用GetProcAddress得不到你说的那个函数啊!
rageliu 2008-08-19
  • 打赏
  • 举报
回复
com hook,怎么个钩不着
HSxuguangxing 2008-08-19
  • 打赏
  • 举报
回复
来人啊!
HSxuguangxing 2008-08-18
  • 打赏
  • 举报
回复
LS就一个render是个啥意思啊?说明白点啥!
rageliu 2008-08-18
  • 打赏
  • 举报
回复
render

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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