我目前正在从事我的第一个D3D项目,该项目涉及为游戏创建一个覆盖图,以便向用户提供实时信息。实际的数据采集已处理,并将通过消息系统发送。目前,我有该程序可用于无边界全屏模式,并且正在调整它以使其在窗口模式下按比例缩放(以确保无论大小,一切都指向正确的位置)。该应用程序是游戏的父母,但是,当游戏进入真正的全屏模式时,一切都会崩溃。研究表明,据我所知,我需要创建一个假的.dll,并将其插入游戏的本地目录。该.dll将打开,而不是它正在寻找的实际DirectX,我可以在其中完成所需的图形。
要回答一些潜在的问题,我没有直接访问该游戏的权限,尽管对于有问题的游戏,开发人员可以这样做,但我希望它不会受到反作弊的惩罚软件。此外,我想将性能降到最低,因此目前重叠式广告的FPS相当低(〜10fps)。
在此先感谢您的帮助!
答案 0 :(得分:2)
这是我刚刚使用过的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;
}
这是我,Broihon,Traxin和A200K几个人的代码的组合