出于培训目的,我自己实现了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指针调整到 struct 的头部.并且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++相关问答推荐

Bison解析器转移/减少冲突

ISO_C_BINDING,从Fortran调用C

错误:在.h程序中重新定义 struct

常数函数指针优化

特定闪存扇区的内存别名

Can函数指针指向C++中具有不同参数连续性的函数

LONG_DOUBLE_T是否存在(标准C:C23)

用C宏替换strncMP函数中的参数

自定义变参数函数的C预处置宏和警告 suppress ?

将 struct 传递给函数

C中的FREE函数正在触发断点

OpenSSL:如何将吊销列表与SSL_CTX_LOAD_VERIFY_LOCATIONS一起使用?

处理EPOLL_WAIT中的接收数据和连接关闭信号

GCC奇怪的行为,有fork 和印花,有换行符和不换行符

用C++构建和使用DLL的困惑

C中的回文数字

OMP并行嵌套循环

c如何传递对 struct 数组的引用,而不是设置 struct 的副本

既然我们在 if 中将 int 的值更改为 10,为什么在第二个 fork 后,子进程及其创建的子进程都会打印 33 ?

尽管将其标记为易失性,但 gcc 是否优化了我的等待代码?