Peb.Ldr,PEB_LDR_DATA
NtQuerySystemInformation,ZwQueryInformationProcess,
CreateToolhelp32Snapshot,EnumProcesses,EnumProcessModules
ReadProcessMemory,NtReadProcessMemory
kernel32.dll,psapi.dll,ntdll.dll
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
TCB
线程
控制块
RT-Thread中每个
线程
的信息用
线程
控制块(Thread Control-Block,缩写为TCB)表示,它是定义在rtdef.h中的struct结构体,用来描述一个
线程
所有必要信息;
线程
的优先级别用非负整数(即无符号整数)表示。数值越小,优先级越高;
系统的
线程
优先级的数目固定,最多支持256级;
系统中的
线程
数目不做任何限制,
线程
的数目仅受限于系统RAM的大小。
线程
控制块存储的数据结构为
链表
;
线程
创建
在RT-Thread中分为静态创建和动态创建,二者实现
前言 Yarden Shafir 分享了两篇非常通俗易懂的,关于 windbg 新引入的调试数据模型的文章。原文链接如下:part1:https://medium.com/@yardenshafir2/windbg-the-fun-way-part-1-2e4978791f9bpart2:https://medium.com/@yardenshafir2/windbg-the-fun-way-pa...
在RT-Thread中,获取已就绪最高优先级
线程
索引会使用此函数。而此函数所包含的算法为bitmap算法。
为什么使用此函数获取已就绪最高优先级
线程
索引?为什么使用bitmap算法?目的在于提升索引值获取的执行效率,以及保证系统的稳定执行。
通常,为了获取已就绪最高优先级
线程
,最简单的方法就是
遍历
当前
线程
列表中的每一个
线程
状态及优先级,通过比较最后获取。而这种方法会随着最大支持
线程
数的增加而增加时间复杂度,且执行时间非恒定,影响系统的稳定。
此函数在RT-Thread中实现如下,
const rt_ui.
RT-Thread(Real Time-Thread),是一个嵌入式实时操作系统,基本属性之一是支持多任务,在rtt系统中,任务通过
线程
实现名词解释——rttread特点:是一个高度可伸缩组件完整丰富、简易开发、超低功耗、高安全性的物联网操作系统高度可伸缩——可以根据MCU资源情况裁剪或添加组件,最小仅需(NANO版本——极简版内核)。实时内核的实现包括:☐ 对象管理(Object Management)
代码示例了如何使用API
枚举
指定
进程
中指定
模块
创建的
线程
, 注意该方案存在一定局限性, 就是
模块
的起始地址和
线程
起始地址之间的关系无法保证, 可能存在漏掉的.
前言第一次看到改
进程
名是在PChunter上,当时虽然觉得挺牛皮的,但是没深入去研究。最近看到病毒通过
进程
名来检测沙箱的一些文章,就打算用改
进程
名的方式来绕过检测。刚开始是打算研究任务管理器获取
进程
的方式,然后中间动手脚来修改
进程
名。后面搞的差不多后突然想到,一般这种病毒都是利用CreateToolhelp32Snapshot,
Process
32First和
Process
32Next这一套函数来实...
1. 引言
在诸多的场景中(例如软件测试,软件安全研究等领域)经常需要分析在目标
进程
中具体加载了哪些
模块
(DLL),以及所加载的
模块
的信息(如
模块
基地址,映射文件大小等)。获取这windows
进程
加载的
模块
信息,曾经有一个行之有效又很便捷的方法,使用windows提供PSAPI(psapi.dll,windows
进程
状态信息接口)提供的相关的接口就可以快捷的获取
进程
及
进程
加载的
模块
信息。有关PSAPI接口可以参考psapi.h或者微软的官方文档Psapi.h header - Win32 ...
R3抹掉加载的DLL
原理类似于获取Kernel32.dll加载地址,知道这个东西也是在看获取Kernel32.dll地址的时候在网上搜索学习资料,无意中看到的这个东西。这个挺有用,结合着HiJack的话效果会不错。思路是这样:
FS--->TEB--->
PEB
--->
PEB
_LDR_DATA.InInitialzationOrderModuleList
(细节偏...
线程
所属的父
进程
_E
PROCESS
结构体中的 ThreadListHead 成员是当前
进程
中所有
线程
的双向
链表
头,该成员有两个,分别在 0x50 和 0x190 处。我们可以通过该
线程
链表
头进行
线程
遍历
,也可以通过直接
遍历
_ETHREAD 结构体中的 ThreadListEntry 成员实现
遍历
进程
中的所有
线程
,ThreadListEntry 分别位于 0x1b0 和 0x22c 处。
我们可以通过 _ETHREAD 的 ThreadListEntry 断链实现
线程
隐藏。需要注意的是,Threa
那么对于CFS会发生什么呢?用户A可使用的CPU时间越来越少。这显然是不公平的
对于服务器中,我们希望这两个用户可以平均的分配CPU时间,所以这在调度颗粒为
进程
的CFS是很难做到的,拥有
进程
数量多的用户将被分配比较多的CPU资源,因此,我们引入组调度(Group Scheduling )的概念。
关于获取Ldr的方法,网上有大量的博客作了介绍,但可能因为这些博客写的比较早,所以其中一些类似于“fs[30]指向
PEB
,
PEB
+0x0C即为Ldr指针”的观点虽然在当时非常适用,但在如今则显得不尽严谨,因为x86和x64下TEB、
PEB
、
PEB
_LDR_DATA等结构体的成员大小是不同的,使用的部分寄存器也有差异,例如x64下通过gs[0x60...
为了避免自己的某个dll
模块
被别人检测出来,有时候希望在自己加载一个dll之后,或者将dll注入到他人
进程
之后避免被检查出来。这就需要想办法抹掉这个dll的
模块
信息,使得Toolhelp、psapi等
枚举
模块
的API无法
枚举
它。我们可以先简单看看Windows
枚举
进程
内
模块
的办法吧:首先是BOOL Enum
Process
Modules( HANDLE h
Process
, HMODULE
尽管操作
PEB
BLOCK现在已经没什么价值了,但是
PEB
BLOCK作为内核的一个重要结构,这里还是提一下:
x64 E
PROCESS
结构
+0x000 Pcb : _K
PROCESS
+0x160
Process
Lock : _EX_PUSH_LOCK
+0x168 CreateTime : _LARGE_INTEGER