虚拟保护大小

VirtualProtect Size

所以我在 Windows 上玩函数挂钩,一切都按预期工作。通过用 jmp 指令覆盖我的 LoadLibrary 指针指向的值和我的 Hook 函数的偏移量,我能够在每次调用 LoadLibrary 时执行我自己的代码。要覆盖内存中的字节,我显然需要更改特定内存的保护标志。尽管这工作正常,但我得到了意想不到的结果。

HMODULE APIENTRY hLoadLibrary(LPCWSTR lpFileName) {
    MessageBox(NULL, "NOT LOADING A LIBRA1RY!", "YO", MB_OK);

    return NULL;
};

BOOL APIENTRY DllMain(HANDLE hModule, DWORD  fdwReason, LPVOID lpReserved)
{
    DWORD* hookPointer = (DWORD*)&hLoadLibrary;
    DWORD* originPointer = (DWORD*)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryW");

    DWORD offset = (DWORD)hookPointer - (DWORD)originPointer - 5;

    DWORD oldProtect;
    VirtualProtect((LPVOID)originPointer, sizeof(char) * 5, PAGE_EXECUTE_READWRITE, &oldProtect);

    char* p = (char*)originPointer;
    *p = '\xE9';
    p++;
    DWORD* q = (DWORD*)p;
    *q = offset;

    VirtualProtect((LPVOID)originPointer, sizeof(char) * 5, oldProtect, &oldProtect);

    return TRUE;
}

这里

VirtualProtect((LPVOID)originPointer, sizeof(char) * 5, PAGE_EXECUTE_READWRITE, &oldProtect);

是我期望的工作

这个

VirtualProtect((LPVOID)originPointer, 0, PAGE_EXECUTE_READWRITE, &oldProtect);

明显失败

但是这个

VirtualProtect((LPVOID)originPointer, 1, PAGE_EXECUTE_READWRITE, &oldProtect);

我发现也可以工作,即使我只更改了一个字节的保护。

有人可以解释为什么这样吗?

页面保护属性的粒度必须等于页面的大小。 4096 字节。你永远不应该在你需要的大小上撒谎,如果你传递的地址恰好位于页面末尾附近,那就太糟糕了。