#include <windows.h>
#include <stdio.h>
#include <winternl.h>
// Определение типа функции NtQueryInformationProcess для динамического вызова
typedef NTSTATUS (NTAPI *pNtQueryInformationProcess)(
HANDLE ProcessHandle,
PROCESSINFOCLASS ProcessInformationClass,
PVOID ProcessInformation,
ULONG ProcessInformationLength,
PULONG ReturnLength);
// Структура PROCESS_BASIC_INFORMATION для использования с NtQueryInformationProcess
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PEB* PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
int main() {
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Создание процесса в состоянии CREATE_SUSPENDED
if (!CreateProcessA(NULL, "C:\\Windows\\System32\\notepad.exe", NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
printf("CreateProcess failed (%d).\n", GetLastError());
return 0;
}
// Получаем функцию NtQueryInformationProcess из ntdll.dll
HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
pNtQueryInformationProcess NtQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hNtdll, "NtQueryInformationProcess");
PROCESS_BASIC_INFORMATION pbi;
ZeroMemory(&pbi, sizeof(PROCESS_BASIC_INFORMATION));
// Получаем базовый адрес PEB
NTSTATUS status = NtQueryInformationProcess(pi.hProcess, ProcessBasicInformation, &pbi, sizeof(PROCESS_BASIC_INFORMATION), NULL);
if (status != 0) {
printf("NtQueryInformationProcess failed (%d).\n", status);
return 0;
}
// Чтение PEB
PEB peb;
ReadProcessMemory(pi.hProcess, pbi.PebBaseAddress, &peb, sizeof(PEB), NULL);
// Чтение PEB_LDR_DATA
PEB_LDR_DATA ldr;
ReadProcessMemory(pi.hProcess, peb.Ldr, &ldr, sizeof(PEB_LDR_DATA), NULL);
// Чтение InLoadOrderModuleList
LIST_ENTRY* startListEntry = ldr.InLoadOrderModuleList.Flink;
LIST_ENTRY* listEntry = startListEntry;
do {
LDR_DATA_TABLE_ENTRY moduleEntry;
ReadProcessMemory(pi.hProcess, CONTAINING_RECORD(listEntry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks), &moduleEntry, sizeof(LDR_DATA_TABLE_ENTRY), NULL);
WCHAR moduleName[MAX_PATH];
ReadProcessMemory(pi.hProcess, moduleEntry.BaseDllName.Buffer, moduleName, moduleEntry.BaseDllName.MaximumLength, NULL);
printf("Module Name: %ws, Base Address: %p\n", moduleName, moduleEntry.DllBase);
listEntry = moduleEntry.InLoadOrderLinks.Flink;
} while (listEntry != startListEntry);
// Закрываем дескрипторы
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}