C++ VirtualProtect PAGE_NOACCESS会导致崩溃

C++ VirtualProtect PAGE_NOACCESS causes crash

本文关键字:崩溃 NOACCESS VirtualProtect PAGE C++      更新时间:2023-10-16

美好的一天,我正在尝试以某种方式防止"dll注入"到我的程序中。这是我到目前为止所拥有的,但由于某种原因,它使我的.exe崩溃了。我正在加载此代码,并附有我的程序的.dll。

声明:

LPBYTE _LdrLoadDll = (LPBYTE)GetProcAddress(GetModuleHandle("ntdll.dll"), "LdrLoadDll");

功能:

   void HookNoAccess(LPVOID Offset, int size)
    {
        HMODULE hand = GetModuleHandle("MYPROGRAM.exe");
        DWORD OldProtect;
        VirtualProtect(Offset, size, PAGE_NOACCESS, &OldProtect);
        VirtualProtect((LPVOID)((DWORD)hand + (DWORD)0x12d1), 6, PAGE_NOACCESS, &OldProtect);
    }

称呼它:

HookNoAccess(_LdrLoadDll, 2); // tried any size...

它应该停止访问当前进程,但为什么它会崩溃......

有人可以帮我吗?

鉴于 LdrLoadDll 是一个未记录的函数,我不确定它的作用、工作原理或内部使用的位置,但我怀疑如果您能够完全阻止它,您是否会取得多大成功,因为它可能是 Windows 本身用来将 DLL 加载到您的进程中的......

除此之外,VirtualProtect会影响包含指定范围的一个或多个字节的所有页面。换句话说,它提供的保护粒度是页面的粒度。如果您不小心避免其他内存块位于同一页面上,则在尝试访问它们时会崩溃。

最后,第二次打电话给VirtualProtect是非常可疑的。您硬编码为地址偏移量的值是多少?与上面提到的问题相同:VirtualProtect提供的保护粒度是页面的粒度。页面是 4k 字节(一般来说),因此即使您只指定 6 字节的大小,您也会为至少包含部分应用程序可执行代码的整个 4k 页面设置PAGE_NOACCESS

实际上,您应该只在为自己分配了VirtualAllocVirtualAllocEx的内存块上使用VirtualProtect。其他任何事情,更改您无法控制的内存块的保护级别,都只是自找麻烦。