An ongoing project for a DirectX 9 realtime texture inspector using an injected hook dll and a WPF frontend.
(09/06/2026)
I first started out by creating the basic injectable dll. The main goal was to ensure that the hooks were setup correctly. I am using minhook to handle creating the trampoline functions between the real DirectX function calls and my
overidden ones. I created a hook for the EndScene function and setup a basic Imgui to render.
(9/06/2026)
Next I created a hook for the CreateTexture DX function. Here I can track the creation of new textures and store pointers to them. From these pointers,
I setup the imgui to draw all the loaded textures. I also at this step tested a hook for the SetTexture function. We can intercept this function to
replace the incoming texture pointer with our own one. By simply loading my own custom texture and substituting it for one of the in-game textures I can
manipulate which textures are drawn at runtime. With these ideas proven out, I next wanted to move away from using Imgui and instead create a WPF
application to preview textures and allow the user to select replacement textures.
(10/06/2026)
One of the next big challenges at this stage was handling communication between the hook library and the C# WPF application. For this I used Named
Pipes. The WPF app acts as the host, with the hook acting as the client. The server sends commands to the client and the client sends back a response.
At this stage I created two commands:
Another challenge was collecting the texture data for all the created textures. In DirectX 9 textures by default are loaded directly into VRAM leaving
few opportunities to intercept the data on the CPU. To bypass this I had to add some more hooks, specifically an UpdateTexture hook allows me
read texture data when it is copied from CPU into GPU. Depending on the game this allows me to collect a significantly more textures, however this still
does not collect all textures loaded into VRAM.
Next steps will be to expose picking a replacement texture file to the user interface and creating a command to send that information over to the
hook library. In the hook we can then create a texture and substitute it for the selected reference texture.
(12/06/2026)
Before fully tackling the texture replacement flow, I took the opportunity to tidy up the UI, expose useful information, and gave a way for the user to
write friendly names for textures making it easier to search for them later. These aren't currently saved between runs yet, but I am planning to
add a button to create/load a project folder which is where we can store information like this between sessions.
(12/06/2026)
For texture replacement, I added two new commands:
Upon receiving the SetTextureReplacement command, the hook library will read the texture hash and associate the replacement file path with it. In the DX
SetTexture hook function we then check if the texture has a replacement associated. If it is not loaded at this stage we load it into memory and
intercept the original SetTexture call with our replacement texture.
With this I have managed to prove out the core idea of the project. However I still have some challenges I want to tackle next:
(14/06/2026)
Mostly spent time on improvements to the UI and some behind the scenes work to start supporting a project framework. I also now track load state and
reference counts of images for better support of texture replacements later on. Some basic work in the hook and UI has been put in place for persisting
replacements through runs which has working in early testing.
(19/06/2026)
I spent the last couple of days continuing the work on refactoring the UI and supporting the project framework. With this work I also fixed up some of
the areas not conforming to the MVVM paradigm. Overall the project framework is now working, with the texture info saved to a file alongside any
imported textures for replacements.
The startup page for the application is now a project selection page. The other pages are locked until a project is created or loaded. The connection
state to the hook is also now tracked visually on the bottom of the window.
The textures page now has cached thumbnail previews for the textures along with some overall visual improvements.
With the project framework we can also now save previously recorded textures and edit them even if they aren't actively loaded by the hook library. For these unloaded textures we show the thumbnail preview and give a warning to the user.
Back to top