I'm trying to make a small proxy dll that will be able to print out all the files that a game tries to access from disk.

I'm using a dinput8 wrapper dll as my proxy dll, from where I've managed to attach a console and print out stuff. But I think I don't understand how exactly I am supposed to hook the ReadFile function.

First of all I am not sure if this is possible at all, considering that I want to create and export a wrapper function for ReadFile, whose declaration is in a completely different dll from the one I'm wrapping.

What I'm trying right now (and its not working) is to declare a ReadFile_wrapper function, which is practically calling the original function right now:

extern "C" BOOL WINAPI ReadFile_wrapper(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
                        LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
    MessageBoxA(NULL, "Reading", "", 0);
    return ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);

Also I'm declaring a definition in the .def file, so that the export function is named like the original ReadFile function


I'm obviously missing something critical here, so any help is highly appreciated.

3 Answers 3


Why not use existing tools to do the job?

If you're just trying to monitor which files get accessed I would suggest to use Process Monitor: Process Monitor is an advanced monitoring tool for Windows that shows real-time file system, Registry and process/thread activity.

Process Monitor screenshot Process Monitor Process details screenshot

If you want to see what data is being read or written I would suggest Rohitab API Monitor: API Monitor is a free software that lets you monitor and control API calls made by applications and services. Its a powerful tool for seeing how applications and services work or for tracking down problems that you have in your own applications.

Rohitab API Monitor screenshot Rohitab ReadFile Rohitab View Buffer

Both tools are free.


I would suggest utilizing hooking.

When hooking, you patch some bytes at the start of the function you want to hook in memory to redirect to your own code. Upon completion of whatever you wanted to you, you can just return to the original implementation.

There have been various tutorials and implementations which will do this for you.

Maybe this is a good resource to start you off. Good luck.


Here is my detour function:

const void* DetourFunc(BYTE* const src, const BYTE* dest, const DWORD length)
        BYTE* jump = new BYTE[length + 5];
        for (int i = 0; i < sizeof(detourBuffer) / sizeof(void*); ++i)
            if (!detourBuffer[i])
                detourBuffer[i] = jump;

        DWORD dwVirtualProtectBackup;
        VirtualProtect(src, length, PAGE_READWRITE, &dwVirtualProtectBackup);

        memcpy(jump, src, length);
        jump += length;

        jump[0] = 0xE9;
        *(DWORD*)(jump + 1) = (DWORD)(src + length - jump) - 5;

        src[0] = 0xE9;
        *(DWORD*)(src + 1) = (DWORD)(dest - src) - 5;

        VirtualProtect(src, length, dwVirtualProtectBackup, &dwVirtualProtectBackup);

        return jump - length;

Usage: DetourFunc ((BYTE*)oFuncAddr, (BYTE*)&hkFunc, 5);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.