虚拟保护大小
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 字节。你永远不应该在你需要的大小上撒谎,如果你传递的地址恰好位于页面末尾附近,那就太糟糕了。
所以我在 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 字节。你永远不应该在你需要的大小上撒谎,如果你传递的地址恰好位于页面末尾附近,那就太糟糕了。