VxKex icon indicating copy to clipboard operation
VxKex copied to clipboard

Author, read this. This is not another "it doesn't work for me...". You haven't implemented NtFlushBuffersFileEx.

Open Alex-ASF opened this issue 6 months ago • 2 comments

Since no hook on NtFlushBuffersFileEx is implemented (or is implemented with an error), then dbms may not work and do not work (for example, postgres 17), but you never know where it may appear. Below is an example of a hook. minHook_134 was used, but of course it can be done differently.

//
// hookNtFlush.cpp
// cl /LD hookNtF.cpp "minhook\build\Release\MinHook.x64.lib" /link /OUT:hook.dll /NODEFAULTLIB:MSVCRT
//

#include <windows.h>
#include "minHook\include\minhook.h"

#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)

typedef struct _IO_STATUS_BLOCK {
    union { NTSTATUS Status; PVOID Pointer; };
    ULONG_PTR Information;
} * PIO_STATUS_BLOCK;

typedef NTSTATUS 
    (NTAPI *NtFlushBuffersFileEx_t)
    (HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParameterSize, PIO_STATUS_BLOCK IoStatusBlock);

static NtFlushBuffersFileEx_t real_NtFlushBuffersFileEx = NULL;
 
NTSTATUS NTAPI hook_NtFlushBuffersFileEx(HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParameterSize,
    PIO_STATUS_BLOCK IoStatusBlock)
{
    BOOL result = FlushFileBuffers(FileHandle);
    NTSTATUS status = result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;

    if (IoStatusBlock)
    {
        IoStatusBlock->Status = status;
        IoStatusBlock->Information = 0;
    }
    return status;
}

static FARPROC (WINAPI *real_GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = NULL;

FARPROC WINAPI hook_GetProcAddress(HMODULE hModule, LPCSTR lpProcName)
{
    if (lpProcName && strcmp(lpProcName, "NtFlushBuffersFileEx") == 0)
    {
        return (FARPROC)hook_NtFlushBuffersFileEx;
    }
    return real_GetProcAddress(hModule, lpProcName);
}

BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, LPVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH)
    {
        char procPath[MAX_PATH]; char dllPath[MAX_PATH];
        GetModuleFileNameA(NULL, procPath, MAX_PATH); GetModuleFileNameA(hinst, dllPath, MAX_PATH);
        char procLongPath[MAX_PATH]; char dllLongPath[MAX_PATH];
        GetLongPathNameA(procPath, procLongPath, MAX_PATH); GetLongPathNameA(dllPath, dllLongPath, MAX_PATH);
        char* procDirEnd = strrchr(procLongPath, '\\'); char* dllDirEnd = strrchr(dllLongPath, '\\');
        if (procDirEnd && dllDirEnd)
        {
            *dllDirEnd = '\0';
            *procDirEnd = '\0';
            if (_stricmp(procLongPath, dllLongPath) != 0) return FALSE;
        }
        DisableThreadLibraryCalls(hinst);
        MH_Initialize();

        HMODULE kernel32 = GetModuleHandleA("kernel32.dll");
        real_GetProcAddress = (FARPROC (WINAPI *)(HMODULE, LPCSTR))GetProcAddress(kernel32, "GetProcAddress");

        MH_CreateHook((LPVOID)real_GetProcAddress, hook_GetProcAddress, (LPVOID*)&real_GetProcAddress);
        MH_EnableHook(MH_ALL_HOOKS);

    } else if (reason == DLL_PROCESS_DETACH)
    {
        MH_DisableHook(MH_ALL_HOOKS);
        MH_Uninitialize();
    }
    return TRUE;
}

For everyone. You can compile this hook and put the dll in the folder with your non-working application. And then in [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows] add a link to this dll like... "AppInit_DLLs"="C:\\PROGRA~1\\POSTGR~2\\BIN\\HOOK.DLL" Short names are required.

Alex-ASF avatar Jun 25 '25 02:06 Alex-ASF

What software use this API?

YuZhouRen86 avatar Jul 02 '25 08:07 YuZhouRen86

for example, postgres 17

CommonLoon102 avatar Jul 03 '25 14:07 CommonLoon102