gpt4 book ai didi

c++ - 获取具体进程内存空间

转载 作者:可可西里 更新时间:2023-11-01 10:52:53 25 4
gpt4 key购买 nike

我有一个函数指针 (void *),我想知道这个函数属于哪个进程。我不知道该怎么做,但我认为可以通过使用某种形式的 VirtualQuery 技巧来实现。任何帮助将不胜感激。

提前致谢

澄清:“属于进程”是指函数所在的进程。例如:假设内存中加载了一个可执行文件 (test.exe)。该可执行文件包含一个名为 SayHello 的函数,它位于内存中的 0xDEADBEEF 处。在一个完全不同的过程中,我怎么知道 0xDEADBEEF 在 test.exe 的内存空间中。

希望事情已经解决了。

澄清 2: 我相信您熟悉“VTable Hook ”,其中外部模块在单独的进程中更改 VTable 指针以指向不同的函数。因此,无论何时调用 Hook 成员,它都会传递给外部模块。

为了防止这种情况(反作弊),我希望能够检查 VTable 的所有方法是否都指向它们所在的模块。

解决方案代码:

template<class T>
inline void **GetVTableArray(T *pClass, int *pSize)
{
void **ppVTable = *(void ***)pClass;

if(pSize)
{
*pSize = 0;

while(!IsBadReadPtr(ppVTable[*pSize], sizeof(UINT_PTR)))
(*pSize)++;
}

return ppVTable;
}

bool AllVTableMembersPointToCurrentModule(void *pClass)
{
DWORD dwOldProtect;
HANDLE hModuleSnap = INVALID_HANDLE_VALUE;
MODULEENTRY32 moduleEntry;

// Take a snapshot of all modules in the specified process
hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());
if(hModuleSnap == INVALID_HANDLE_VALUE)
return false;

// Set the size of the structure before using it
moduleEntry.dwSize = sizeof(MODULEENTRY32);

// Retrieve information about the first module (current process)
if(!Module32First(hModuleSnap, &moduleEntry))
{
CloseHandle(hModuleSnap);
return false;
}

// Grab the base address and size of our module (the address range where
// the VTable can validly point to)
UINT_PTR ulBaseAddress = reinterpret_cast<UINT_PTR>(moduleEntry.modBaseAddr);
UINT_PTR ulBaseSize = moduleEntry.modBaseSize;

// Get the VTable array and VTable member count
int nMethods;
void **ppVTable = GetVTableArray(pClass, &nMethods);

#ifdef VTABLE_FAKING
// Allow patching
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE_READWRITE, &dwOldProtect);

// Now take the next module and set the first VTable pointer to point to an
// invalid address, outside of the current module's address range
Module32Next(hModuleSnap, &moduleEntry);
ppVTable[0] = moduleEntry.modBaseAddr;
#endif

// Don't allow people to overwrite VTables (can easily be bypassed, so make
// sure you check the VirtualProtect status of the VTable regularly with
// VirtualQuery)
VirtualProtect(ppVTable, nMethods * sizeof(UINT_PTR), PAGE_EXECUTE, &dwOldProtect);

// Clean up the snapshot object
CloseHandle(hModuleSnap);

// Ensure all VTable pointers are in our current module's address range
for(int i = 0; i < nMethods; ++i)
{
// Get address of the method this VTable pointer points to
UINT_PTR ulFuncAddress = reinterpret_cast<UINT_PTR>(ppVTable[i]);

// Check the address is within our current module range
if(ulFuncAddress < ulBaseAddress || ulFuncAddress > ulBaseAddress + ulBaseSize)
return false;
}

return true;
}

最佳答案

每个进程都有自己的地址空间。这意味着同一地址将包含不同进程的不同内容,因此无法执行您的要求。

如果这个指针是指向当前程序中的函数(即你当前可以调用的函数),那么答案很简单:它属于当前进程。

进一步澄清:除非您已经知道它属于哪个进程,否则指针本身是没有意义的。进程 #1001 可能在地址 0x12345678 有一个函数 sayHello,而进程 #1002 在地址 0x12345678 有函数 sayGoodbye,进程 #1003 在同一地址包含一些数据。无法知道指针来自哪个进程。

关于c++ - 获取具体进程内存空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2705927/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com