Detours学习8 - D3D虚函数表

前言

关于Direct X的拦截一般情况下才用类的虚表来完成,这种方法更通用,不区别所使用的操作系统。还有一种方法则是找出类其中一个函数的地址,然后通过IDA等工具来找出其它函数的偏移量来完成,依据所查找的资料得出不同的操作系统可能会存在偏移量不一致的情况,最终会导致拦截失败。

在VS中的导出虚函数表

DirectX SDK中的相关例子中,打开对应的工程按如下方式操作:

  1. 打开项目属性页,配置属性|C/C++|命令行|其它选项(D)

  2. 例如:/d1 reportSingleClassLayoutIDirect3DDevice9可以导出IDirect3DDevice9的继承和虚函数表信息

关于DirectX 8/9

这两种版本是通过Direct3DCreate8Direct3DCreate9来创建一个IDirect3D8*IDirect3D9*的实例,然后通过创建的实例调用CreateDevice函数来创建IDirect3DDevice8*IDirect3DDevice9*的实例,最后通过这个创建的实例的各个成员方法来完成绘制,其中将数据最终输出是通过EndScense函数来完成,所以在这两个版本中完成目标进程的写屏则就是对EndScense函数的拦截。

  1. 通过/d1 reportSingleClassLayoutIDirect3DDevice9导出的IDirect3DDevice9的虚表信息如下:

    IDirect3DDevice9::$vftable@:
    | &IDirect3DDevice9_meta
    | 0
    0 | &IDirect3DDevice9::QueryInterface
    1 | &IDirect3DDevice9::AddRef
    2 | &IDirect3DDevice9::Release
    3 | &IDirect3DDevice9::TestCooperativeLevel
    4 | &IDirect3DDevice9::GetAvailableTextureMem
    5 | &IDirect3DDevice9::EvictManagedResources
    6 | &IDirect3DDevice9::GetDirect3D
    7 | &IDirect3DDevice9::GetDeviceCaps
    8 | &IDirect3DDevice9::GetDisplayMode
    9 | &IDirect3DDevice9::GetCreationParameters
    10 | &IDirect3DDevice9::SetCursorProperties
    11 | &IDirect3DDevice9::SetCursorPosition
    12 | &IDirect3DDevice9::ShowCursor
    13 | &IDirect3DDevice9::CreateAdditionalSwapChain
    14 | &IDirect3DDevice9::GetSwapChain
    15 | &IDirect3DDevice9::GetNumberOfSwapChains
    16 | &IDirect3DDevice9::Reset
    17 | &IDirect3DDevice9::Present
    18 | &IDirect3DDevice9::GetBackBuffer
    19 | &IDirect3DDevice9::GetRasterStatus
    20 | &IDirect3DDevice9::SetDialogBoxMode
    21 | &IDirect3DDevice9::SetGammaRamp
    22 | &IDirect3DDevice9::GetGammaRamp
    23 | &IDirect3DDevice9::CreateTexture
    24 | &IDirect3DDevice9::CreateVolumeTexture
    25 | &IDirect3DDevice9::CreateCubeTexture
    26 | &IDirect3DDevice9::CreateVertexBuffer
    27 | &IDirect3DDevice9::CreateIndexBuffer
    28 | &IDirect3DDevice9::CreateRenderTarget
    29 | &IDirect3DDevice9::CreateDepthStencilSurface
    30 | &IDirect3DDevice9::UpdateSurface
    31 | &IDirect3DDevice9::UpdateTexture
    32 | &IDirect3DDevice9::GetRenderTargetData
    33 | &IDirect3DDevice9::GetFrontBufferData
    34 | &IDirect3DDevice9::StretchRect
    35 | &IDirect3DDevice9::ColorFill
    36 | &IDirect3DDevice9::CreateOffscreenPlainSurface
    37 | &IDirect3DDevice9::SetRenderTarget
    38 | &IDirect3DDevice9::GetRenderTarget
    39 | &IDirect3DDevice9::SetDepthStencilSurface
    40 | &IDirect3DDevice9::GetDepthStencilSurface
    41 | &IDirect3DDevice9::BeginScene
    42 | &IDirect3DDevice9::EndScene
    43 | &IDirect3DDevice9::Clear
    44 | &IDirect3DDevice9::SetTransform
    45 | &IDirect3DDevice9::GetTransform
    46 | &IDirect3DDevice9::MultiplyTransform
    47 | &IDirect3DDevice9::SetViewport
    48 | &IDirect3DDevice9::GetViewport
    49 | &IDirect3DDevice9::SetMaterial
    50 | &IDirect3DDevice9::GetMaterial
    51 | &IDirect3DDevice9::SetLight
    52 | &IDirect3DDevice9::GetLight
    53 | &IDirect3DDevice9::LightEnable
    54 | &IDirect3DDevice9::GetLightEnable
    55 | &IDirect3DDevice9::SetClipPlane
    56 | &IDirect3DDevice9::GetClipPlane
    57 | &IDirect3DDevice9::SetRenderState
    58 | &IDirect3DDevice9::GetRenderState
    59 | &IDirect3DDevice9::CreateStateBlock
    60 | &IDirect3DDevice9::BeginStateBlock
    61 | &IDirect3DDevice9::EndStateBlock
    62 | &IDirect3DDevice9::SetClipStatus
    63 | &IDirect3DDevice9::GetClipStatus
    64 | &IDirect3DDevice9::GetTexture
    65 | &IDirect3DDevice9::SetTexture
    66 | &IDirect3DDevice9::GetTextureStageState
    67 | &IDirect3DDevice9::SetTextureStageState
    68 | &IDirect3DDevice9::GetSamplerState
    69 | &IDirect3DDevice9::SetSamplerState
    70 | &IDirect3DDevice9::ValidateDevice
    71 | &IDirect3DDevice9::SetPaletteEntries
    72 | &IDirect3DDevice9::GetPaletteEntries
    73 | &IDirect3DDevice9::SetCurrentTexturePalette
    74 | &IDirect3DDevice9::GetCurrentTexturePalette
    75 | &IDirect3DDevice9::SetScissorRect
    76 | &IDirect3DDevice9::GetScissorRect
    77 | &IDirect3DDevice9::SetSoftwareVertexProcessing
    78 | &IDirect3DDevice9::GetSoftwareVertexProcessing
    79 | &IDirect3DDevice9::SetNPatchMode
    80 | &IDirect3DDevice9::GetNPatchMode
    81 | &IDirect3DDevice9::DrawPrimitive
    82 | &IDirect3DDevice9::DrawIndexedPrimitive
    83 | &IDirect3DDevice9::DrawPrimitiveUP
    84 | &IDirect3DDevice9::DrawIndexedPrimitiveUP
    85 | &IDirect3DDevice9::ProcessVertices
    86 | &IDirect3DDevice9::CreateVertexDeclaration
    87 | &IDirect3DDevice9::SetVertexDeclaration
    88 | &IDirect3DDevice9::GetVertexDeclaration
    89 | &IDirect3DDevice9::SetFVF
    90 | &IDirect3DDevice9::GetFVF
    91 | &IDirect3DDevice9::CreateVertexShader
    92 | &IDirect3DDevice9::SetVertexShader
    93 | &IDirect3DDevice9::GetVertexShader
    94 | &IDirect3DDevice9::SetVertexShaderConstantF
    95 | &IDirect3DDevice9::GetVertexShaderConstantF
    96 | &IDirect3DDevice9::SetVertexShaderConstantI
    97 | &IDirect3DDevice9::GetVertexShaderConstantI
    98 | &IDirect3DDevice9::SetVertexShaderConstantB
    99 | &IDirect3DDevice9::GetVertexShaderConstantB
    100 | &IDirect3DDevice9::SetStreamSource
    101 | &IDirect3DDevice9::GetStreamSource
    102 | &IDirect3DDevice9::SetStreamSourceFreq
    103 | &IDirect3DDevice9::GetStreamSourceFreq
    104 | &IDirect3DDevice9::SetIndices
    105 | &IDirect3DDevice9::GetIndices
    106 | &IDirect3DDevice9::CreatePixelShader
    107 | &IDirect3DDevice9::SetPixelShader
    108 | &IDirect3DDevice9::GetPixelShader
    109 | &IDirect3DDevice9::SetPixelShaderConstantF
    110 | &IDirect3DDevice9::GetPixelShaderConstantF
    111 | &IDirect3DDevice9::SetPixelShaderConstantI
    112 | &IDirect3DDevice9::GetPixelShaderConstantI
    113 | &IDirect3DDevice9::SetPixelShaderConstantB
    114 | &IDirect3DDevice9::GetPixelShaderConstantB
    115 | &IDirect3DDevice9::DrawRectPatch
    116 | &IDirect3DDevice9::DrawTriPatch
    117 | &IDirect3DDevice9::DeletePatch
    118 | &IDirect3DDevice9::CreateQuery
  2. 从导出的虚表可以找到我们感兴趣的函数EndScense的索引是42,可以根据IDirect3DDevice*指向的首地址做偏移到得EndScense的地址

    void** pVtbl = *reinterpret_cast<void***>(pDevice);
    TureEndScense = (TEndScense)pVtbl[42];

关于DirectX 10/11

这两个版本中引入了IDXGISwapChain的对象,最终输出是在此对象中的Present函数中完成的,那么要完成目标进程的写屏则是对它进行拦截

  1. 通过/d1 reportSingleClassLayoutIDXGISwapChain导出的IDXGISwapChain的虚函数表的信息如下:

    class IDXGISwapChain size(4) :
    > +-- -
    | +-- - (base class IDXGIDeviceSubObject)
    | | +-- - (base class IDXGIObject)
    | | | +-- - (base class IUnknown)
    | | | | {vfptr}
    | | | +-- -
    | | +-- -
    | +-- -
    +-- -
    IDXGISwapChain::$vftable@:
    | &IDXGISwapChain_meta
    | 0
    0 | &IUnknown::QueryInterface
    1 | &IUnknown::AddRef
    2 | &IUnknown::Release
    3 | &IDXGIObject::SetPrivateData
    4 | &IDXGIObject::SetPrivateDataInterface
    5 | &IDXGIObject::GetPrivateData
    6 | &IDXGIObject::GetParent
    7 | &IDXGIDeviceSubObject::GetDevice
    8 | &IDXGISwapChain::Present
    9 | &IDXGISwapChain::GetBuffer
    10 | &IDXGISwapChain::SetFullscreenState
    11 | &IDXGISwapChain::GetFullscreenState
    12 | &IDXGISwapChain::GetDesc
    13 | &IDXGISwapChain::ResizeBuffers
    14 | &IDXGISwapChain::ResizeTarget
    15 | &IDXGISwapChain::GetContainingOutput
    16 | &IDXGISwapChain::GetFrameStatistics
    17 | &IDXGISwapChain::GetLastPresentCount
  2. 通过导出的虚表我们可以找出Present的索引为8,Dx10、Dx11在这个类上面没有区别,所以可以通过偏移得到此函数的地址:

    void** pSwapChainVtbl = *reinterpret_cast<void***>(swapChain);
    TruePresent = (PF_Present)pSwapChainVtbl[8];
  3. 通过上面的导出命令同时会导出ID3D11DeviceContext的虚表,它和ID3D10DeviceContext是有一些区别的,拦截它们之中的函数则能对目标进程做更丰富的二次绘制处理,下面列出ID3D11DeviceContext的虚表:

    class ID3D11DeviceContext size(4):
    +---
    | +--- (base class ID3D11DeviceChild)
    | | +--- (base class IUnknown)
    | | | {vfptr}
    | | +---
    | +---
    +---
    ID3D11DeviceContext::$vftable@:
    | &ID3D11DeviceContext_meta
    | 0
    0 | &IUnknown::QueryInterface
    1 | &IUnknown::AddRef
    2 | &IUnknown::Release
    3 | &ID3D11DeviceChild::GetDevice
    4 | &ID3D11DeviceChild::GetPrivateData
    5 | &ID3D11DeviceChild::SetPrivateData
    6 | &ID3D11DeviceChild::SetPrivateDataInterface
    7 | &ID3D11DeviceContext::VSSetConstantBuffers
    8 | &ID3D11DeviceContext::PSSetShaderResources
    9 | &ID3D11DeviceContext::PSSetShader
    10 | &ID3D11DeviceContext::PSSetSamplers
    11 | &ID3D11DeviceContext::VSSetShader
    12 | &ID3D11DeviceContext::DrawIndexed
    13 | &ID3D11DeviceContext::Draw
    14 | &ID3D11DeviceContext::Map
    15 | &ID3D11DeviceContext::Unmap
    16 | &ID3D11DeviceContext::PSSetConstantBuffers
    17 | &ID3D11DeviceContext::IASetInputLayout
    18 | &ID3D11DeviceContext::IASetVertexBuffers
    19 | &ID3D11DeviceContext::IASetIndexBuffer
    20 | &ID3D11DeviceContext::DrawIndexedInstanced
    21 | &ID3D11DeviceContext::DrawInstanced
    22 | &ID3D11DeviceContext::GSSetConstantBuffers
    23 | &ID3D11DeviceContext::GSSetShader
    24 | &ID3D11DeviceContext::IASetPrimitiveTopology
    25 | &ID3D11DeviceContext::VSSetShaderResources
    26 | &ID3D11DeviceContext::VSSetSamplers
    27 | &ID3D11DeviceContext::Begin
    28 | &ID3D11DeviceContext::End
    29 | &ID3D11DeviceContext::GetData
    30 | &ID3D11DeviceContext::SetPredication
    31 | &ID3D11DeviceContext::GSSetShaderResources
    32 | &ID3D11DeviceContext::GSSetSamplers
    33 | &ID3D11DeviceContext::OMSetRenderTargets
    34 | &ID3D11DeviceContext::OMSetRenderTargetsAndUnorderedAccessViews
    35 | &ID3D11DeviceContext::OMSetBlendState
    36 | &ID3D11DeviceContext::OMSetDepthStencilState
    37 | &ID3D11DeviceContext::SOSetTargets
    38 | &ID3D11DeviceContext::DrawAuto
    39 | &ID3D11DeviceContext::DrawIndexedInstancedIndirect
    40 | &ID3D11DeviceContext::DrawInstancedIndirect
    41 | &ID3D11DeviceContext::Dispatch
    42 | &ID3D11DeviceContext::DispatchIndirect
    43 | &ID3D11DeviceContext::RSSetState
    44 | &ID3D11DeviceContext::RSSetViewports
    45 | &ID3D11DeviceContext::RSSetScissorRects
    46 | &ID3D11DeviceContext::CopySubresourceRegion
    47 | &ID3D11DeviceContext::CopyResource
    48 | &ID3D11DeviceContext::UpdateSubresource
    49 | &ID3D11DeviceContext::CopyStructureCount
    50 | &ID3D11DeviceContext::ClearRenderTargetView
    51 | &ID3D11DeviceContext::ClearUnorderedAccessViewUint
    52 | &ID3D11DeviceContext::ClearUnorderedAccessViewFloat
    53 | &ID3D11DeviceContext::ClearDepthStencilView
    54 | &ID3D11DeviceContext::GenerateMips
    55 | &ID3D11DeviceContext::SetResourceMinLOD
    56 | &ID3D11DeviceContext::GetResourceMinLOD
    57 | &ID3D11DeviceContext::ResolveSubresource
    58 | &ID3D11DeviceContext::ExecuteCommandList
    59 | &ID3D11DeviceContext::HSSetShaderResources
    60 | &ID3D11DeviceContext::HSSetShader
    61 | &ID3D11DeviceContext::HSSetSamplers
    62 | &ID3D11DeviceContext::HSSetConstantBuffers
    63 | &ID3D11DeviceContext::DSSetShaderResources
    64 | &ID3D11DeviceContext::DSSetShader
    65 | &ID3D11DeviceContext::DSSetSamplers
    66 | &ID3D11DeviceContext::DSSetConstantBuffers
    67 | &ID3D11DeviceContext::CSSetShaderResources
    68 | &ID3D11DeviceContext::CSSetUnorderedAccessViews
    69 | &ID3D11DeviceContext::CSSetShader
    70 | &ID3D11DeviceContext::CSSetSamplers
    71 | &ID3D11DeviceContext::CSSetConstantBuffers
    72 | &ID3D11DeviceContext::VSGetConstantBuffers
    73 | &ID3D11DeviceContext::PSGetShaderResources
    74 | &ID3D11DeviceContext::PSGetShader
    75 | &ID3D11DeviceContext::PSGetSamplers
    76 | &ID3D11DeviceContext::VSGetShader
    77 | &ID3D11DeviceContext::PSGetConstantBuffers
    78 | &ID3D11DeviceContext::IAGetInputLayout
    79 | &ID3D11DeviceContext::IAGetVertexBuffers
    80 | &ID3D11DeviceContext::IAGetIndexBuffer
    81 | &ID3D11DeviceContext::GSGetConstantBuffers
    82 | &ID3D11DeviceContext::GSGetShader
    83 | &ID3D11DeviceContext::IAGetPrimitiveTopology
    84 | &ID3D11DeviceContext::VSGetShaderResources
    85 | &ID3D11DeviceContext::VSGetSamplers
    86 | &ID3D11DeviceContext::GetPredication
    87 | &ID3D11DeviceContext::GSGetShaderResources
    88 | &ID3D11DeviceContext::GSGetSamplers
    89 | &ID3D11DeviceContext::OMGetRenderTargets
    90 | &ID3D11DeviceContext::OMGetRenderTargetsAndUnorderedAccessViews
    91 | &ID3D11DeviceContext::OMGetBlendState
    92 | &ID3D11DeviceContext::OMGetDepthStencilState
    93 | &ID3D11DeviceContext::SOGetTargets
    94 | &ID3D11DeviceContext::RSGetState
    95 | &ID3D11DeviceContext::RSGetViewports
    96 | &ID3D11DeviceContext::RSGetScissorRects
    97 | &ID3D11DeviceContext::HSGetShaderResources
    98 | &ID3D11DeviceContext::HSGetShader
    99 | &ID3D11DeviceContext::HSGetSamplers
    100 | &ID3D11DeviceContext::HSGetConstantBuffers
    101 | &ID3D11DeviceContext::DSGetShaderResources
    102 | &ID3D11DeviceContext::DSGetShader
    103 | &ID3D11DeviceContext::DSGetSamplers
    104 | &ID3D11DeviceContext::DSGetConstantBuffers
    105 | &ID3D11DeviceContext::CSGetShaderResources
    106 | &ID3D11DeviceContext::CSGetUnorderedAccessViews
    107 | &ID3D11DeviceContext::CSGetShader
    108 | &ID3D11DeviceContext::CSGetSamplers
    109 | &ID3D11DeviceContext::CSGetConstantBuffers
    110 | &ID3D11DeviceContext::ClearState
    111 | &ID3D11DeviceContext::Flush
    112 | &ID3D11DeviceContext::GetType
    113 | &ID3D11DeviceContext::GetContextFlags
    114 | &ID3D11DeviceContext::FinishCommandList
posted @   非法关键字  阅读(1103)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
点击右上角即可分享
微信分享提示