关键字:
R3
Peb.Ldr,PEB_LDR_DATA
NtQuerySystemInformation,ZwQueryInformationProcess,
CreateToolhelp32Snapshot,EnumProcesses,EnumProcessModules
ReadProcessMemory,NtReadProcessMemory
kernel32.dll,psapi.dll,ntdll.dll
R0
PsIdleProcess
EPROCESS.Peb, EPROCESS.ActiveProcessLinks, EPROCESS.Pcb.ThreadListHead(即KPROCESS.ThreadListHead)
EPROCESS.ThreadListHead
NtQuerySystemInformation(从PsIdleProcess进程开始通过EPROCESS.ActiveProcessLinks遍历进程,通过EPROCESS.Pcb.ThreadListHead遍历线程)
NtQueryInformationProcess(通过ObReferenceObjectByHandle 得到EPORCESS再得到PEB,用于模块遍历)ObReferenceObjectByHandle(通过R3传过来的进程句柄得到EPROCESS)
NtReadProcessMemory(跨进程读PEB)
注意,如果是取自身进程的PEB地址,可以直接通过PTEB = fs:0x18,PPEB=PTEB->ProcessEnvironmentBlock或者PPEB=fs:0x30取得。无需跨进程读,也无需进内核(如GetModuleFileName就是如此)
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID Reserved4[3];
PVOID AtlThunkSListPtr;
PVOID Reserved5;
ULONG Reserved6;
PVOID Reserved7;
ULONG Reserved8;
ULONG AtlThunkSListPtr32;
PVOID Reserved9[45];
BYTE Reserved10[96];
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved11[128];
PVOID Reserved12[1];
ULONG SessionId;
} PEB, *PPEB;
typedef struct _PEB_LDR_DATA
{
DWORD Length;
UCHAR Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID EntryInProgress;
}PEB_LDR_DATA,*PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
DWORD SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
DWORD Flags;
WORD LoadCount;
WORD TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
DWORD CheckSum;
DWORD TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY;
获取所有进程信息
关键: NtQuerySystemInformation(ntdll.dll) ---> 内核通过EPROCESS.ActiveProcessLinks遍历,从PsIdleProcess开始
1. 进程枚举:
https://docs.microsoft.com/zh-cn/windows/win32/toolhelp/taking-a-snapshot-and-viewing-processes
https://docs.microsoft.com/zh-cn/windows/win32/toolhelp/traversing-the-thread-list
HANDLE CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
//th32ProcessID=0表示当前线程, CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
CreateToolhelp32Snapshot (kernel32.dll)
NtQuerySystemInformation (ntdll.dll)
------------------------------------------------------------------------------
NtQuerySystemInformation (ntoskrnl.exe) //EPROCESS.ActiveProcessLinks
ExpGetProcessInformation R0枚举所有进程(以及线程,直接通过EPROCESS.Pcb.ThreadListHead遍历线程)
PsGetNextProcess 直接通过EPROCESS.ActiveProcessLinks获取下一个进程
2. 进程id枚举:
https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-processes
BOOL EnumProcesses(
DWORD *lpidProcess,
DWORD cb,
LPDWORD lpcbNeeded
);
EnumProcesses (psapi.dll / kernle32.dll)
NtQuerySystemInformation (ntdll.dll)
------------------------------------------------------------------------------
NtQuerySystemInformation (ntoskrnl.exe) //EPROCESS.ActiveProcessLinks
3. 直接调用NtQuerySystemInformation(声明即可使用)/ZwQuerySystemInformation(GetProcAddress)
NTSTATUS NtQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
NtQuerySystemInformation(SystemProcessInformation, ...); //SystemInformationClass.SystemProcessInformation = 5
获取单个进程信息(进程模块枚举)
关键: NtQueryInformationProcess(ntdll.dll) ---> 内核Handle->EPROCESS->Peb
//ProcessInformationClass .ProcessBasicInformation = 0
//(Retrieves a pointer to a PEB structure that can be used to determine whether the specified process is being debugged, and a unique value used by the system to identify the specified process. )
1. 调用EnumProcessModules获取所有模块
https://docs.microsoft.com/en-us/windows/win32/psapi/enumerating-all-modules-for-a-process
BOOL EnumProcessModules(
HANDLE hProcess,
HMODULE *lphModule,
DWORD cb,
LPDWORD lpcbNeeded
);
EnumProcessModules(psapi.dll / kernle32.dll)
NtQueryInformationProcess (ntdll.dll) and ReadProcessMemory (kernel32.dll)
------------------------------------------------------------------------------
NtQueryInformationProcess (ntoskrnl.exe)
ObReferenceObjectByHandle (Handle->EPORCESS->Peb)
2.
https://docs.microsoft.com/zh-cn/windows/win32/toolhelp/traversing-the-module-list
//CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, dwPID );
CreateToolhelp32Snapshot --> RtlQueryProcessDebugInformation(ntdll.dll) --> RtlQueryProcessModuleInformation --> LdrQueryProcessModuleInformationEx --> LdrQueryInLoadOrderModuleList
--> LdrQueryProcessPeb and LdrReadMemory
--> ZwQueryInformationProcess and NtReadVirtualMemory
------------------------------------------------------------------------------
NtQueryInformationProcess (ntoskrnl.exe)
ObReferenceObjectByHandle (Handle->EPORCESS->Peb)
3. 直接调用ZwQueryInformationProcess(声明即可使用)/NtQueryInformationProcess(GetProcAddress)
NTSTATUS WINAPI ZwQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ PROCESSINFOCLASS ProcessInformationClass,
_Out_ PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, ProcessInformation, ...);
ReadProcessMemory(ProcessInformation, ...);
4.
BOOL GetProcessInformation(
HANDLE hProcess,
PROCESS_INFORMATION_CLASS ProcessInformationClass,
LPVOID ProcessInformation,
DWORD ProcessInformationSize
);
(>win8)???
pid handle eprocess
1、pid->handle
OBJECT_ATTRIBUTES ObjectAttributes;
CLIENT_ID clientid;
InitializeObjectAttributes(&ObjectAttributes, 0 ,OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, 0, 0);
clientid.UniqueProcess = (HANDLE)pid;
clientid.UniqueThread=0;
ZwOpenProcess(&handle, PROCESS_ALL_ACCESS, &ObjectAttributes, &clientid);
handle即为所求
2、handle->pid
PROCESS_BASIC_INFORMATION pbi;
Status = ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, (PVOID)&pbi, sizeof(ProcessBasicInformation), NULL);
pid = pbi.UniqueProcessId;
pid即为所求。
3、pid->eprocess
PEPROCESS process;
PsLookupProcessByProcessId((HANDLE)pid, &process);
ObDereferenceObject(process);
process即为所求eprocess的指针。
4、handle->eprocess
Status = ObReferenceObjectByHandle (ProcessHandle,
PROCESS_TERMINATE,
PsProcessType,
KeGetPreviousModeByThread(&Self->Tcb),
&Process,
NULL);
或
handle->pid->eprocess。
5、eprocess->pid
_EPROCESS.UniqueProcessId即为所求,虽然声明类型为HANDLE,但实际上是pid
6、eprocess->handle
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
PsProcessType,
PreviousMode,
&Handle
);
或eprocess->pid->handle
本文详细介绍了在Windows环境下,如何利用系统API和内核功能遍历所有进程及其模块信息,包括使用NtQuerySystemInformation和NtQueryInformationProcess进行进程枚举,以及通过不同方法获取进程模块列表。
742

被折叠的 条评论
为什么被折叠?



