出于培训目的,我自己实现了 WINAPI 函数 GetModuleHandle
这是:
PVOID SelfGetModuleHandle(PCWSTR name) {
PEB* pPeb = RtlGetCurrentPeb();//getting Process Environement Bloc
PPEB_LDR_DATA pLdr = pPeb->Ldr; //https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb
LIST_ENTRY Lentry = pLdr->InMemoryOrderModuleList;//https://learn.microsoft.com/en-us/windows/win32/api/winternl/ns-winternl-peb_ldr_data
LIST_ENTRY FirstLentry = Lentry;
do
{
LDR_DATA_TABLE_ENTRY LDataTableEntry = *(LDR_DATA_TABLE_ENTRY*)Lentry.Flink;
if (StrCmpW(LDataTableEntry.FullDllName.Buffer, name) == 0) {
printf("Base foud: %p\n", LDataTableEntry.DllBase);
return (LDataTableEntry.DllBase);
}
Lentry = *Lentry.Flink;
} while (memcmp(&Lentry, &FirstLentry, sizeof(LIST_ENTRY)));
return NULL;
}
我认为我的函数非常酷并且可以工作,但是示例代码出现了段错误
typedef
double
(__stdcall* POW)( //pow from NTDLL (offset 0x151498)
double a,
double b
);
int main(){
HMODULE dllBase = (HMODULE)SelfGetModuleHandle(L"ntdll.dll");//00000000001F8000 instead of 00007FFD36FD0000
POW pow = (POW)GetProcAddress(dllBase, "pow");
printf("%f", pow(2.0,3.0));
}
我正在搜索我做错了什么,但找不到。
也许我没有在错误的表中获得正确的 dllbase,或者 PVOID 需要更大的转换才能成为 HMODULE,但我不认为是这样。
谢谢。
最佳答案
使用CONTAINING_RECORD
从LIST_ENTRY指针调整到结构体的头部。并且不需要 memcmp 来终止循环。
尝试这样的事情:
PLIST_ENTRY current = pPeb->Ldr->InMemoryOrderModuleList.Flink;
while ((current != NULL) && (current != &pPeb->Ldr->InMemoryOrderModuleList))
{
LDR_DATA_TABLE_ENTRY* module = (LDR_DATA_TABLE_ENTRY*)CONTAINING_RECORD(current, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
wprintf(L"%p %p ", module, module->DllBase);
wprintf(L"'%wZ' ", &module->FullDllName);
wprintf(L"'%wZ' ", &module->BaseDllName);
wprintf(L"\n");
current = current->Flink;
}
关于c - GetModuleHandle 实现不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76017564/