Я хочу получить все модули из другого процесса. Но это возвращает абсурдные ценности. Программа остается в цикле 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);
}
Я ставлю точку останова на !NT_SUCCESS(Status)
после NtQueryInformationProcess для значений переменных:
Значения после NtQueryInformationProcess
Еще одна точка останова для значений переменных в do while для конца первого цикла:
Вы запрашиваете удаленный процесс для его PROCESS_BASIC_INFORMATION
, но затем вы продолжаете следовать указателям в своем собственном процессе:
PLIST_ENTRY HeadEntry = pbi.PebBaseAddress->LoaderData->InMemoryOrderModuleList.Flink;
Чтобы это работало, прочитайте PEB
из удаленного процесса (из pbi.PebBaseAddress
),
затем прочитайте LoaderData
из удаленного процесса (PEB.LoaderData
).
Затем следуйте InMemoryOrderModuleList
(еще раз, прочитайте данные из удаленного процесса).
На этом этапе вы можете перебирать весь список, читая каждую запись из удаленного процесса.
Других решений пока нет …