Sau*_*aul 1 c++ windows winapi
我有一个void *函数的指针(),我想知道这个函数属于哪个进程.我不知道采用哪种方式,但我认为通过使用某种形式的VirtualQuery技巧是可能的.任何帮助,将不胜感激.
提前致谢,
澄清: "属于进程"是指函数所处的进程.例如:假设test.exe在内存中加载了可执行文件().此可执行文件包含一个名为的函数SayHello,该函数位于内存中的0xDEADBEEF.在一个完全不同的过程中,我怎么知道0xDEADBEEF在test.exe内存空间中.
希望这能说明问题.
澄清2:我确定你熟悉"VTable挂钩",其中外部模块在单独的进程中更改VTable指针以指向不同的功能.因此,每当调用钩状构件时,它就被传递到外部模块.
为了防止这种情况(反作弊),我希望能够检查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;
}
Run Code Online (Sandbox Code Playgroud)
int*_*jay 13
每个进程都有自己的地址空间.这意味着相同的地址将包含不同进程的不同内容,因此无法按照您的要求进行操作.
如果此指针指向当前程序中的某个函数(即您当前可以调用的函数),那么答案很简单:它属于当前进程.
进一步澄清:指针本身没有意义,除非你已经知道它属于哪个进程.进程#1001可以sayHello在地址0x12345678处具有功能,而进程#1002具有sayGoodbye在地址0x12345678处的功能,并且进程#1003包含在相同地址处的一些数据.无法知道指针来自哪个进程.
| 归档时间: |
|
| 查看次数: |
2295 次 |
| 最近记录: |