【问题标题】:Get loaded module from another process从另一个进程获取加载的模块
【发布时间】:2016-09-11 21:41:29
【问题描述】:

我想从另一个进程中获取所有模块。但它返回荒谬的值。程序停留在 do-while 循环中一次。之后退出 do-while 循环。

我找不到错误所在 - 我该如何解决这个问题?我知道该程序必须多次处于 do-while 循环中,但事实并非如此。

NTSTATUS Status;
PROCESS_BASIC_INFORMATION pbi;
ULONG ReturnLength;
Status = NtQueryInformationProcess(
    INJECTOR_INFO.process.processHandle,
    ProcessBasicInformation,
    &pbi,
    sizeof(PROCESS_BASIC_INFORMATION),
    &ReturnLength);
if (!NT_SUCCESS(Status)) {
    printf("NtQueryInformationProcess failed.(pbi)\n");
    return;
}
else {
    PLIST_ENTRY  HeadEntry = pbi.PebBaseAddress->LoaderData->InMemoryOrderModuleList.Flink;
    PLIST_ENTRY nextEntry = pbi.PebBaseAddress->LoaderData->InMemoryOrderModuleList.Blink;


    DWORD dwBytesRead = 0;
    PLDR_MODULE pLdrModule = nullptr;
    LDR_MODULE LdrModule;
    do
    {
        LDR_DATA_TABLE_ENTRY LdrEntry;
        PLDR_DATA_TABLE_ENTRY Base = CONTAINING_RECORD(HeadEntry, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);

        if (NT_SUCCESS(Status = NtReadVirtualMemory(INJECTOR_INFO.process.processHandle, Base, &LdrEntry, sizeof(LdrEntry), &dwBytesRead)))
        {
            if (dwBytesRead != sizeof(LdrEntry)) {
                printf("length doesn't match");
                return;
            }
            char* pLdrModuleOffset = reinterpret_cast<char*>(HeadEntry) - sizeof(LIST_ENTRY);
            if (!NT_SUCCESS(Status = NtReadVirtualMemory(INJECTOR_INFO.process.processHandle, pLdrModuleOffset, &pLdrModule, sizeof(pLdrModule), &dwBytesRead))) { 
                printf("pLdrModuleOffset doesn't read"); return;
            }else if (dwBytesRead != sizeof(pLdrModule)) { printf("pLdrModule length doesn't match"); return; }
            if (!NT_SUCCESS(Status = NtReadVirtualMemory(INJECTOR_INFO.process.processHandle, pLdrModule, &LdrModule, sizeof(LdrModule), &dwBytesRead))) { 
                printf("pLdrModule doesn't read"); return;
            }else if (dwBytesRead != sizeof(LdrModule)) { printf("LdrModule length doesn't match"); return; }

            if (LdrEntry.DllBase)
            {
                printf("BaseAddress:     %p\n", LdrModule.BaseAddress);
                printf("Reference Count: %d\n", LdrModule.LoadCount);
            }

            HeadEntry = LdrEntry.InMemoryOrderLinks.Flink;
        }
        else { printf("LDR_DATA_TABLE_ENTRY doesn't read"); return; }
    } while (HeadEntry != nextEntry);
}

我在变量值的 NtQueryInformationProcess 之后在 !NT_SUCCESS(Status) 上设置了断点:

Values after NtQueryInformationProcess

第一个循环结束时 do while 中变量值的另一个断点:

Values for the end of the first cycle

【问题讨论】:

标签: c++ visual-c++ struct process inject


【解决方案1】:

您正在查询远程进程的PROCESS_BASIC_INFORMATION,但随后您继续按照自己进程中的指针进行操作:

PLIST_ENTRY HeadEntry = pbi.PebBaseAddress-&gt;LoaderData-&gt;InMemoryOrderModuleList.Flink;

为此,请从远程进程(来自pbi.PebBaseAddress)读取PEB, 然后从远程进程(PEB.LoaderData)读取LoaderData。 然后,跟随InMemoryOrderModuleList(再次,从远程进程读取数据)。

此时,您可以通过从远程进程读取每个条目来遍历整个列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    • 2016-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多