技术逆向IMGUI
ZEROKO14imgui开发记录
环境配置
imgui库下载
detours库下载
imgui的使用需要提前安装dx库:安装执行文件:DXSDK_jun10.exe,安装好后文件夹名称:Microsoft DirectX SDK(June 2010)
imgui环境配置
配置DX库
在配置-VC++目录-包含目录加入DX安装路径根目录的include文件夹,$(DXSDK_DIR)是表示DX安装目录的宏

配置-链接器-常规-附加库目录加入DX安装路径根目录Lib文件夹,$(PlatformTarget)是表示当前项目是x86或x64,因为Lib文件夹下分x86和x64文件夹要针对性选择库文件,因此使用该宏

配置-链接器-输入-附加依赖项中添加库的名字

项目中导入头文件#include <d3d9.h>,根据引入的d3d版本来导入头文件
配置imgui
下图可以取到对应版本的DX实例:用于实验imgui

新建项目后,将imgui-master文件夹中的所有.h和.cpp文件拖拽到项目文件夹中(可以新建一个文件夹存放),然后还要将backends文件夹中的选对应的文件(根据需要DX9还是DX10还是DX11还是DX12还是别的版本对应选下面的imgui文件)也挪到项目下

同时由于我们是在windows下使用的,因此,backends下的如下文件也要添到新项目下:

项目中添加头文件:

detours环境配置
detours库到github下载下来的是源文件,因此我们需要把他编译出来
在powershell中cd到Detours-master文件夹下的src文件夹中,输入nmake,编译。


编译后在当前目录下生成obj.x86文件夹
我们需要的是Detours-master下的include中的头文件和Detours-master下的lib.X86文件夹中的库(64位的话需要lib.X64文件夹中的库)


将上述内容放入项目中。也可以直接在包含目录和附加库目录和附加依赖项直接添加。
最后导入头文件#include "Detours.h"
detours使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void vtHook(PVOID* oldFunc,PVOID newFunc) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(oldFunc,newFunc); DetourTransactionCommit(); } void vtUnhook(PVOID* oldFunc,PVOID newFunc) { DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourDetach(oldFunc,newFunc); DetourTransactionCommit(); }
|
D3D初始化
安装目录中直接提供了D3D的初始化代码,封装在一个类似initD3D的函数中
上图后面的数字表示在虚表中的序号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
| D3DPRESENT_PARAMETERS g_present; IDirect3D9* g_Direct3D9 = NULL; IDirect3DDevice9* g_pd3dDevice =NULL; HWND g_hWnd = NULL;
DWORD* dDeviceVT =NULL;
typedef HRESULT(WINAPI* Reset_t)(LPDIRECT3DDEVICE9,D3DPRESENT_PARAMETERS*); typedef long(__stdcall* EndScene_t)(LPDIRECT3DDEVICE9); typedef LRESULT(__stdcall* WndProc_t)(const HWND,UINT,WPARAM,LPARAM); Reset_t oReset; EndScene_t oEndScene; WndProc_t oWndProc;
void myImGuiInit(LPDIRECT3DDEVICE9 pd3dDevice) { IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIo& io =ImGui::GetIO(); io.ConfigFlags = ImGuiConfigFlags_NoMouseCursorChange; io.WantSaveIniSettings=false; io.IniFilename=NULL; ImGui::StyleColorsClassic(); ImFFontConfig f_cfg; f_cfg.FontDataOwnedByAtlas = false; const ImFont* font = io.Fonts->AddFontFromMemoryTTF((void*)baidu_font_data,baidu_font_size,14.0f,&f_cfg,io.Fonts->GetGlyphRangesChineseSimplifi) ImGui_ImplWin32_Init(g_hWnd); ImGui_ImplDX9_Init(pd3dDevice); }
bool mainBeginSate=TRUE; bool checkBoxFlags_1=FALSE;
void LoadMyWin() { ImGui_ImplDX9_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); ImGui::SetNextWindowPos(ImVec2(50,50),ImGuiCond_FirstUseEver); ImGui::SetNextWindowSize(ImVec2(350,450)); ImGui::Begin(u8"测试",&mainBeginSate); if(ImGui::BeginTabBar("tab1",tab_bar_flags)) { ImGui::Text(u8"测试文本"); ImGui::SameLine(); ImGui::Text(u8"欢迎使用imgui"); if(ImGui::CheckBox(u8"打开功能",&checkBoxFlags_1)) { if(checkBoxFlags_1) { } else { } } if(checkBoxFlags_1) { ImGui::Text(u8"选中了"); } if(ImGui::Button(u8"按钮文本")) { } ImGui::BeginTabItem(u8"测试item1"); ImGui::EndTabItem(); ImGui::BeginTabItem(u8"测试item2"); ImGui::EndTabItem(); ImGui::BeginTabItem(u8"测试item3"); ImGui::EndTabItem(); ImGui::EndTabBar(); } ImGui::End(); ImGui::EndFrame(); ImGui::Render(); ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); }
extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
LRESULT __stdcall newWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { if(ImGui_ImplWin32_WndProcHandler(hWnd,msg,wParam,lParam))return TRUE; return CallWindowProc(oWndProc,hWnd,msg,wParam,lParam); }
HRESULT __stdcall newResult(LPDIRECT3DDEVICE9 pd3dDevice,D3DPRESENT_PARAMETERS* pPresentationParameters) { vtUnhook((PVOID*)(&oReset),newReset); ImGui_ImplDX9_InvalidateDeviceObjects(); HRESULT tmpReset=pd3dDevice->Reset(pPresentationParameters); ImGui_ImplDX9_CreateDeviceObjects(); vtHook((PVOID*)(&oReset),newReset); return tmpReset; }
HRESULT __stdcall newEndScene(LPDIRECT3DDEVICE9 pd3dDevice) { vtUnhook((PVOID*)(&oEndScene),newEndScene); static bool firstCall=TRUE; if(firstCall) { firstCall=!firstCall; myImGuiInit(pd3dDevice); oWndProc = (WNDPROC)SetWindowLongPtr(g_hWnd,GWL_WNDPROC,(LONG_PTR)newWndProc); } LoadMyWin(); HRESULT result=pd3dDevice->EndScene(); vtHook((PVOID*)(&oEndScene),newEndScene); return result; }
void InitD3d() { g_hWnd=FindWindowA("类名","窗口标题"); g_Direct3D9 = Direct3DCreate9(D3D_SDK_VERSION); memset(&g_present,0,sizeof(g_present)); g_present.Windowed=TRUE; g_present.SwapEffect=D3DSWAPEFFECT_DISCARD; g_present.BackBufferFormat = D3DFMT_UNKNOWN; g_present.EnableAutoDepthStencil = TRUE; g_present.AutoDepthStencilFormat = D3DFMT_D16; HRESULT result = g_Direct3D9->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_present, &g_pd3dDevice); dDeviceVT=(DWORD*)*(DWORD*)g_pd3dDevice; oReset=(Reset_t)dDeviceVT[16]; oEndScene=(EndScene_t)dDeviceVT[42]; vtHook((PVOID*)(&oReset),newReset); vtHook((PVOID*)(&oEndScene),newEndScene); }
|
更多控件写法参考下图案例(下图路径为官方提供的实例)
