c - GetModuleHandle 实现不起作用

标签 c windows winapi

出于培训目的,我自己实现了 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/

相关文章:

c++ - 在不使用交换的情况下分配最大缓冲区

c - 缩放 MandelBrot 集

c# - Windows 服务与简单程序

c++ - 如何将目录符号链接(symbolic link)复制为指向目标的链接?

winapi - 空渲染器不在 graphedit 中

windows - 在最终用户系统上调试 "application configuration is incorrect"问题的好方法?

c - Hook 在终端上。我可以在终端中运行命令之前调用方法吗?

c - 在编译时连接链表

c++ - IMAGE_SECTION_HEADER的VirtualAddress和PointerToRawData的区别

c++ - 重用后 DLL 使应用程序崩溃