TsudaKageyu / minhook

The Minimalistic x86/x64 API Hooking Library for Windows
http://www.codeproject.com/KB/winsdk/LibMinHook.aspx
Other
4.43k stars 898 forks source link

detours vs minhook #88

Open luca2125 opened 4 years ago

luca2125 commented 4 years ago

Hi,

I have created a c++ complete project to hook GOG game and work perfectly (this add a unofficial Force Feedback support).

To to it I have found on github a custom version of d3d9.dll with with DllMain inside.

I have put in my code with detours with succefull hook the game without any problems.

Now I have used the some project to another GOG game but this time becouse there is no d3d9.dll inside I have used another github dll libogg.dll.

libogg don't have DllMain I have added it myself and my log confirm that both DLL_PROCESS_ATTACH and DLL_PROCESS_DETACH was called correcly.

Unfortunatenly I have many ussue to to hook, many times the app crash in "DetourAttach" and when work (random) the hook don't seem work correcly.

I have do the some with zlib with the some result.

At the moment I don't have a prcise idea about why this happen.

Do you think it is a good idea switch to minhook ? Or my attemp is wrong ?

Natrox commented 4 years ago

Hello Luca,

Whether you switch to MinHook or stick with Detours, there is a more flexible approach to hooking into the game than the one you are using.

What you could do instead is use "DLL Injection". The idea of it is that you force the game to call LoadLibrary to load in your own custom DLL. From there, you can resume hooking game functions.

I don't know much about Detours, but MinHook does have some functionality when it comes to finding memory space for the hook. We use MinHook constantly for virtualizing file systems, and it hasn't let us down.

There is another alternative I can think of in your case: patching the game binary. It's a bit more annoying for the end-user, but gives you a lot of flexibility. You can patch in your own LoadLibrary, or just directly patch the game functions to add force feedback. If you want these changes to be resistant to updates, I recommend you use a disassembler library and create an auto-patcher. I unfortunately have no experience with that.

Good luck!

luca2125 commented 4 years ago

Hi Sam,

Many thanks for your response !!

I I have undestand for DLL injection you mean a thing simular this:

    char path[MAX_PATH];
        GetSystemDirectoryA(path, MAX_PATH);
        strcat_s(path, "\\d3d9.dll");
        d3d9dll = LoadLibraryA(path);

        // Get function addresses
        m_pDirect3DShaderValidatorCreate9 = (Direct3DShaderValidatorCreate9Proc)GetProcAddress(d3d9dll, "Direct3DShaderValidatorCreate9");
        m_pPSGPError = (PSGPErrorProc)GetProcAddress(d3d9dll, "PSGPError");
        m_pPSGPSampleTexture = (PSGPSampleTextureProc)GetProcAddress(d3d9dll, "PSGPSampleTexture");
        m_pD3DPERF_BeginEvent = (D3DPERF_BeginEventProc)GetProcAddress(d3d9dll, "D3DPERF_BeginEvent");
        m_pD3DPERF_EndEvent = (D3DPERF_EndEventProc)GetProcAddress(d3d9dll, "D3DPERF_EndEvent");
        m_pD3DPERF_GetStatus = (D3DPERF_GetStatusProc)GetProcAddress(d3d9dll, "D3DPERF_GetStatus");
        m_pD3DPERF_QueryRepeatFrame = (D3DPERF_QueryRepeatFrameProc)GetProcAddress(d3d9dll, "D3DPERF_QueryRepeatFrame");
        m_pD3DPERF_SetMarker = (D3DPERF_SetMarkerProc)GetProcAddress(d3d9dll, "D3DPERF_SetMarker");
        m_pD3DPERF_SetOptions = (D3DPERF_SetOptionsProc)GetProcAddress(d3d9dll, "D3DPERF_SetOptions");
        m_pD3DPERF_SetRegion = (D3DPERF_SetRegionProc)GetProcAddress(d3d9dll, "D3DPERF_SetRegion");
        m_pDebugSetLevel = (DebugSetLevelProc)GetProcAddress(d3d9dll, "DebugSetLevel");
        m_pDebugSetMute = (DebugSetMuteProc)GetProcAddress(d3d9dll, "DebugSetMute");
        m_pDirect3D9EnableMaximizedWindowedModeShim = (Direct3D9EnableMaximizedWindowedModeShimProc)GetProcAddress(d3d9dll, "Direct3D9EnableMaximizedWindowedModeShim");
        m_pDirect3DCreate9 = (Direct3DCreate9Proc)GetProcAddress(d3d9dll, "Direct3DCreate9");
        m_pDirect3DCreate9Ex = (Direct3DCreate9ExProc)GetProcAddress(d3d9dll, "Direct3DCreate9Ex");

This code is present in my project that work fine and is missing in the project that not work.

In short I need to proceed in this way:

1) Locate the dll and rename it ex: zlib.dll with zlib_ori.dll 2) Create my dll clone with name "zlib.dll" and inside:

char path[MAX_PATH];
    GetSystemDirectoryA(path, MAX_PATH);
    strcat_s(path, "zlib_ori.dll");
    zlib = LoadLibraryA(path);

and functions adress.

I'am in the right way ??