0 c++ directx overlay directx-11
我目前正在开发我的第一个 D3D 项目,其中涉及为游戏创建叠加层,以便向用户呈现实时信息。实际的数据采集已经处理完毕,将通过消息系统发送。目前,我的程序适用于无边框全屏模式,并且正在调整它以在窗口模式下按比例缩放(以确保所有内容都指向正确的位置,无论大小如何)。该应用程序是游戏的父级,但是,当游戏进入真正的全屏模式时,一切都会崩溃。研究表明,据我了解,我需要创建一个假的 .dll,并将其插入到游戏的本地目录中。该 .dll 将被打开,而不是它正在寻找的实际 directX DLL,我可以在那里制作所需的图形。
为了回答一些潜在的问题,我无法直接访问游戏,而且,虽然相关游戏的开发者已经同意这一点,但我宁愿它不要被反作弊软件捕获和惩罚。此外,我希望将性能影响保持在最低限度,因此目前覆盖层的 FPS 相当低(~10fps)。
预先感谢您的任何帮助!
这是我刚刚使用的 D3D11 Present x64 蹦床挂钩项目。你可以在返回之前在里面画画hkPresent(),你画的任何东西都会显示在屏幕上。
#include <Windows.h>
#include <d3d11.h>
#include <d3dcompiler.h>
#include <DirectXMath.h>
#pragma comment(lib, "d3d11.lib")
#pragma comment(lib, "d3dcompiler.lib")
#define SAFE_RELEASE(p) if (p) { p->Release(); p = nullptr; }
void* Tramp64(void* src, void* dst, int len)
{
int MinLen = 14;
if (len < MinLen) return NULL;
BYTE stub[] = {
0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, // jmp qword ptr [$+6]
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // ptr
};
void* pTrampoline = VirtualAlloc(0, len + sizeof(stub), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
DWORD dwOld = 0;
VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwOld);
uintptr_t retto = (uintptr_t)src + len;
// trampoline
memcpy(stub + 6, &retto, 8);
memcpy((void*)((uintptr_t)pTrampoline), src, len);
memcpy((void*)((uintptr_t)pTrampoline + len), stub, sizeof(stub));
// orig
memcpy(stub + 6, &dst, 8);
memcpy(src, stub, sizeof(stub));
for (int i = MinLen; i < len; i++)
{
*(BYTE*)((uintptr_t)src + i) = 0x90;
}
VirtualProtect(src, len, dwOld, &dwOld);
return (void*)((uintptr_t)pTrampoline);
}
bool GetD3D11SwapchainDeviceContext(void** pSwapchainTable, size_t Size_Swapchain, void** pDeviceTable, size_t Size_Device, void** pContextTable, size_t Size_Context)
{
WNDCLASSEX wc{ 0 };
wc.cbSize = sizeof(wc);
wc.lpfnWndProc = DefWindowProc;
wc.lpszClassName = TEXT("dummy class");
if (!RegisterClassEx(&wc))
{
return false;
}
DXGI_SWAP_CHAIN_DESC swapChainDesc{ 0 };
swapChainDesc.BufferCount = 1;
swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
swapChainDesc.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
swapChainDesc.OutputWindow = GetForegroundWindow();
swapChainDesc.SampleDesc.Count = 1;
swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapChainDesc.Windowed = TRUE;
D3D_FEATURE_LEVEL featureLevel;
IDXGISwapChain* pDummySwapChain = nullptr;
ID3D11Device* pDummyDevice = nullptr;
ID3D11DeviceContext* pDummyContext = nullptr;
HRESULT hr = D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_REFERENCE, nullptr, 0, nullptr, 0, D3D11_SDK_VERSION, &swapChainDesc, &pDummySwapChain, &pDummyDevice, &featureLevel, nullptr);
if (FAILED(hr))
{
DestroyWindow(swapChainDesc.OutputWindow);
UnregisterClass(wc.lpszClassName, GetModuleHandle(nullptr));
return false;
}
if (pSwapchainTable && pDummySwapChain)
{
memcpy(pSwapchainTable, *reinterpret_cast<void***>(pDummySwapChain), Size_Swapchain);
}
if (pDeviceTable && pDummyDevice)
{
memcpy(pDeviceTable, *reinterpret_cast<void***>(pDummyDevice), Size_Device);
}
if (pContextTable && pDummyContext)
{
memcpy(pContextTable, *reinterpret_cast<void***>(pDummyContext), Size_Context);
}
SAFE_RELEASE(pDummySwapChain);
SAFE_RELEASE(pDummyDevice);
SAFE_RELEASE(pDummyContext);
DestroyWindow(swapChainDesc.OutputWindow);
UnregisterClass(wc.lpszClassName, GetModuleHandle(nullptr));
return true;
}
void* SwapChain[18];
void* Device[40];
void* Context[108];
typedef HRESULT(__fastcall* tPresent)(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags);
tPresent oPresent = nullptr;
HRESULT __fastcall hkPresent(IDXGISwapChain* pThis, UINT SyncInterval, UINT Flags)
{
return oPresent(pThis, SyncInterval, Flags);
}
DWORD WINAPI MainThread(HMODULE hModule)
{
if (GetD3D11SwapchainDeviceContext(SwapChain, sizeof(SwapChain), Device, sizeof(Device), Context, sizeof(Context)))
{
oPresent = (tPresent)Tramp64(SwapChain[8], hkPresent, 19);
}
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)MainThread, hModule, 0, nullptr);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
Run Code Online (Sandbox Code Playgroud)
这是几个人的代码的组合:我、Broihon、Traxin 和 A200K
| 归档时间: |
|
| 查看次数: |
2786 次 |
| 最近记录: |