登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 187|回复: 0

WindowsX86内核11.操作进程内存

[复制链接]

90

主题

9

回帖

407

积分

管理员

积分
407
发表于 2024-12-12 12:06:43 | 显示全部楼层 |阅读模式
我们研究内存管理最终目的是操作进程内存和代码注入
操作进程内存
●在3环里面操作进程的函数是 ReadPricessMemory WriteProcessMemory但是用这些函数很容易被检测出来,但是如果通过操作物理内存的方式,那么就不容易检测
●因此我们要知道如何操作对方的物理内存,如我们能得到对方进程的页目录表就可以了,他的地址是物理地址
●页目录表是由操作系统管理,从数据结构来讲他属于进程中的一个属性,每个进程有一个页目录表,所以我们要知道每个进程的页目录表,我们要知道操作系统如何管理进程的
●如果逆向分析,我们可以通过加载符号来搜索相关 Swap 线程的函数
1663748644791-80158de9-268a-417e-b04a-0c89439a789b.jpg
1663748528208-68a37173-8b71-4170-9e5b-dc9895477877.jpg
●切进程就是该CR3的值,那么CR3怎么来的呢 CR3应该是是放到一个结构体 + 18偏移的位置,可以逆向追踪,可以知道来自PROCESS 结构体
●PROCESS 来自于于全局变量
●微软开源了一份内核源码 WRK,可以编译可以用,可用于2个系统(Windows Research Kernel),可以用于Windows2003 和 xp 64位 2个系统,这份源码可以帮助我们研究内核,但是不是完整的,大部分核心代码都有,没有代码的他提供了obj ,下载链接 https://github.com/9176324/WRK.git ,这份源码只能做参考,因为不同的系统源码是不一样的
● 可以通过 sourceinsight 快速的查看源码
Source Insights使用教程
1新建工程
1663752312170-41411f08-b00f-47f3-a491-9f4a03f37a00.jpg
2选择源文件
1663752430290-d3902d77-5907-454d-a6f8-2848ae91fc57.jpg
3添加文件
1663752507989-1731445e-b1f4-4825-a1a7-d97dc9407b46.jpg
1663752780917-7c5933ef-01b9-4508-994f-38285a8333f2.jpg
  • 弄好了之后保存工程在查看符号,这样就可以搜索查看函数源码了
1663752917205-4c521fe5-590e-497b-bd5f-1313a0dd8492.jpg
●例如查看 函数 MilsAddressValid
1663753202985-fffa78d6-af65-451e-8e5e-df2ee4852c5c.jpg
1663753221029-bdf11c1d-1db6-43b9-8daa-d846f259769e.jpg
1663753232090-5923b8ed-881a-4603-b1f8-873d533a6a34.jpg
重要节结构体
结构体不同的版本是不一样的,因为这个结构体是非公开的,在windbg 中可以通过 dt _eprocess 来查看结构体信息,新版本包含老版本的结构体
进程对象 EPROCESS (执行层)
内核分为核心层和执行层
  1. <span class="hljs-keyword" style="box-sizing: border-box; display: inline; overflow: visible; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border: 0px; word-break: normal; line-height: inherit; overflow-wrap: normal;">typedef</span><span style="box-sizing: border-box; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border-style: initial; border-color: initial; border-image: initial; line-height: inherit; overflow-wrap: normal;"> </span><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">EPROCESS</span>
  2. {</span>
  3.     KPROCESS Pcb;
  4.     EX_PUSH_LOCK ProcessLock;      <span class="hljs-comment" style="box-sizing: border-box;">//EPROCESS成员保护锁(推锁)</span>
  5.     LARGE_INTEGER CreateTime;      <span class="hljs-comment" style="box-sizing: border-box;">//进程创建时间</span>
  6.     LARGE_INTEGER ExitTime;        <span class="hljs-comment" style="box-sizing: border-box;">//进程退出时间</span>
  7.     EX_RUNDOWN_REF RundownProtect; <span class="hljs-comment" style="box-sizing: border-box;">//进程结束保护锁</span>
  8.     HANDLE UniqueProcessId;        <span class="hljs-comment" style="box-sizing: border-box;">//进程ID</span>
  9.     LIST_ENTRY ActiveProcessLinks; <span class="hljs-comment" style="box-sizing: border-box;">//系统所有进程链表,可遍历所有进程</span>
  10.     SIZE_T QuotaUsage[PsQuotaTypes];  <span class="hljs-comment" style="box-sizing: border-box;">//进程内存使用量(数组:分页内存池,非分页内存池,文件内存)</span>
  11.     SIZE_T QuotaPeak[PsQuotaTypes];   <span class="hljs-comment" style="box-sizing: border-box;">//进程内存巅峰使用量(数组:分页内存池,非分页内存池,文件内存)</span>
  12.     SIZE_T CommitCharge;              <span class="hljs-comment" style="box-sizing: border-box;">//虚拟内存已提交的页面数量</span>
  13.     SIZE_T PeakVirtualSize;           <span class="hljs-comment" style="box-sizing: border-box;">//进程虚拟内存大小巅峰值</span>
  14.     SIZE_T VirtualSize;               <span class="hljs-comment" style="box-sizing: border-box;">//进程虚拟内存大小</span>
  15.     LIST_ENTRY SessionProcessLinks;
  16.     PVOID DebugPort;                 <span class="hljs-comment" style="box-sizing: border-box;">//调试端口</span>
  17.     PVOID ExceptionPort;             <span class="hljs-comment" style="box-sizing: border-box;">//异常端口 </span>
  18.     PHANDLE_TABLE ObjectTable;       <span class="hljs-comment" style="box-sizing: border-box;">//进程所有对象句柄表</span>
  19.     EX_FAST_REF Token;               <span class="hljs-comment" style="box-sizing: border-box;">//令牌(病毒,漏洞)</span>
  20.     PFN_NUMBER WorkingSetPage;       <span class="hljs-comment" style="box-sizing: border-box;">//进程工作集页面</span>
  21.     KGUARDED_MUTEX AddressCreationLock;
  22.     KSPIN_LOCK HyperSpaceLock;
  23.     <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">ETHREAD</span> *<span class="hljs-title" style="box-sizing: border-box;">ForkInProgress</span>;</span>  <span class="hljs-comment" style="box-sizing: border-box;">//正在复制物理地址空间的哪个线程</span>
  24.     ULONG_PTR HardwareTrigger;        <span class="hljs-comment" style="box-sizing: border-box;">//记录硬件错误分析次数</span>
  25.     PMM_AVL_TABLE PhysicalVadRoot;   <span class="hljs-comment" style="box-sizing: border-box;">//进程物理VAD树的根节点 </span>
  26.     PVOID CloneRoot;
  27.     PFN_NUMBER NumberOfPrivatePages;  <span class="hljs-comment" style="box-sizing: border-box;">//进程私有页数量</span>
  28.     PFN_NUMBER NumberOfLockedPages;   <span class="hljs-comment" style="box-sizing: border-box;">//进程被锁住的页面数量</span>
  29.     PVOID Win32Process;               <span class="hljs-comment" style="box-sizing: border-box;">//指示是否GUI进程</span>
  30.     <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">EJOB</span> *<span class="hljs-title" style="box-sizing: border-box;">Job</span>;</span>
  31.     PVOID SectionObject;             <span class="hljs-comment" style="box-sizing: border-box;">//进程内存区对象</span>
  32.     PVOID SectionBaseAddress;        <span class="hljs-comment" style="box-sizing: border-box;">//内存区对象基地址</span>
  33.     PEPROCESS_QUOTA_BLOCK QuotaBlock;
  34.     PPAGEFAULT_HISTORY WorkingSetWatch;  <span class="hljs-comment" style="box-sizing: border-box;">//监控进程页面错误</span>
  35.     HANDLE Win32WindowStation;
  36.     HANDLE InheritedFromUniqueProcessId;
  37.     PVOID LdtInformation;               <span class="hljs-comment" style="box-sizing: border-box;">//进程局部描述符</span>
  38.     PVOID VadFreeHint;
  39.     PVOID VdmObjects;
  40.     PVOID DeviceMap;
  41.     PVOID Spare0[<span class="hljs-number" style="box-sizing: border-box;">3</span>];                   <span class="hljs-comment" style="box-sizing: border-box;">//WRK未使用</span>
  42.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  43.         HARDWARE_PTE PageDirectoryPte;  <span class="hljs-comment" style="box-sizing: border-box;">//页目录的页表项</span>
  44.         ULONGLONG Filler;
  45.     };
  46.     PVOID Session;
  47.     UCHAR ImageFileName[ <span class="hljs-number" style="box-sizing: border-box;">16</span> ];          <span class="hljs-comment" style="box-sizing: border-box;">//进程名称</span>
  48.     LIST_ENTRY JobLinks;
  49.     PVOID LockedPagesList;
  50.     LIST_ENTRY ThreadListHead;          <span class="hljs-comment" style="box-sizing: border-box;">//进程的所有线程</span>
  51.     PVOID SecurityPort;                 <span class="hljs-comment" style="box-sizing: border-box;">//与lsass进程跨进程通讯端口</span>
  52.     PVOID PaeTop;                       <span class="hljs-comment" style="box-sizing: border-box;">//用于支持PAE内存访问机制</span>
  53.     ULONG ActiveThreads;                <span class="hljs-comment" style="box-sizing: border-box;">//进程有多少个活动线程</span>
  54.     ACCESS_MASK GrantedAccess;          <span class="hljs-comment" style="box-sizing: border-box;">//进程访问权限</span>
  55.     ULONG DefaultHardErrorProcessing;   <span class="hljs-comment" style="box-sizing: border-box;">//默认的硬件错误处理</span>
  56.     NTSTATUS LastThreadExitStatus;      <span class="hljs-comment" style="box-sizing: border-box;">//最后一个线程的退出状态</span>
  57.     PPEB Peb;                           <span class="hljs-comment" style="box-sizing: border-box;">//进程环境块</span>
  58.     EX_FAST_REF PrefetchTrace;
  59.     LARGE_INTEGER ReadOperationCount;
  60.     LARGE_INTEGER WriteOperationCount;
  61.     LARGE_INTEGER OtherOperationCount;
  62.     LARGE_INTEGER ReadTransferCount;
  63.     LARGE_INTEGER WriteTransferCount;
  64.     LARGE_INTEGER OtherTransferCount;
  65.     SIZE_T CommitChargeLimit;
  66.     SIZE_T CommitChargePeak;
  67.     PVOID AweInfo;
  68.     SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo;  <span class="hljs-comment" style="box-sizing: border-box;">//进程映像全路径名</span>
  69.     MMSUPPORT Vm;
  70.     ULONG Spares[<span class="hljs-number" style="box-sizing: border-box;">2</span>];
  71.     ULONG ModifiedPageCount;   <span class="hljs-comment" style="box-sizing: border-box;">//进程已修改页面的数量</span>
  72.     ULONG JobStatus;
  73.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  74.         ULONG Flags;
  75.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  76.             ULONG CreateReported            : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  77.             ULONG NoDebugInherit            : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  78.             ULONG ProcessExiting            : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  79.             ULONG ProcessDelete             : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  80.             ULONG Wow64SplitPages           : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  81.             ULONG VmDeleted                 : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  82.             ULONG OutswapEnabled            : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  83.             ULONG Outswapped                : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  84.             ULONG ForkFailed                : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  85.             ULONG Wow64VaSpace4Gb           : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  86.             ULONG AddressSpaceInitialized   : <span class="hljs-number" style="box-sizing: border-box;">2</span>;
  87.             ULONG SetTimerResolution        : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  88.             ULONG BreakOnTermination        : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  89.             ULONG SessionCreationUnderway   : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  90.             ULONG WriteWatch                : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  91.             ULONG ProcessInSession          : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  92.             ULONG OverrideAddressSpace      : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  93.             ULONG HasAddressSpace           : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  94.             ULONG LaunchPrefetched          : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  95.             ULONG InjectInpageErrors        : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  96.             ULONG VmTopDown                 : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  97.             ULONG ImageNotifyDone           : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  98.             ULONG PdeUpdateNeeded           : <span class="hljs-number" style="box-sizing: border-box;">1</span>;    <span class="hljs-comment" style="box-sizing: border-box;">// NT32 only</span>
  99.             ULONG VdmAllowed                : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  100.             ULONG SmapAllowed               : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  101.             ULONG CreateFailed              : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  102.             ULONG DefaultIoPriority         : <span class="hljs-number" style="box-sizing: border-box;">3</span>;
  103.             ULONG Spare1                    : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  104.             ULONG Spare2                    : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  105.         };
  106.     };
  107.     NTSTATUS ExitStatus;
  108.     USHORT NextPageColor;
  109.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  110.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  111.             UCHAR SubSystemMinorVersion;   <span class="hljs-comment" style="box-sizing: border-box;">//系统主版本号</span>
  112.             UCHAR SubSystemMajorVersion;   <span class="hljs-comment" style="box-sizing: border-box;">//系统次版本号</span>
  113.         };
  114.         USHORT SubSystemVersion;
  115.     };
  116.     UCHAR PriorityClass;
  117.     MM_AVL_TABLE VadRoot;    <span class="hljs-comment" style="box-sizing: border-box;">//用于管理该进程的虚拟地址空间(平衡二叉树)</span>
  118.     ULONG Cookie;
  119. } EPROCESS, *PEPROCESS;
复制代码



  • 我们申请内存(malloc 或者 virtualAlloc),系统怎么知道哪块内存可以分配呢,内存的地址很大(4个G),怎么快速知道哪个页被分配了,哪个页没被分配,于是微软系统就做了一棵平衡二叉树,就是把所有页的分配情况做成一棵平衡二叉树,,这颗平衡二叉树里面记录了所有被分配的页,所以要分配页的时候,只要查这棵二叉树就可以快速知道存不存在,因此,我们主要遍历这个二叉树,就可以知道这个进程所有使用的内存
    • dt _eprocess
  • 1663757764443-2cc57afe-bfcb-4d1c-85e3-8ee56b5ca009-1714486640390-75.png
    • dt _MM_AVL_TABLE
    • 1663758136479-98ff77c3-fbf0-4ce1-9123-2f796d0d2c6d-1714486640390-76.png
    • dt _MMADDRESS_NODE
    • 1663758182259-06a99c84-763d-453d-8703-b164912a4213-1714486640390-77.png
  • 遍历计算器进程的内存使用情况
    • 先遍历所有进程,找到计算机的进程 !process 0 0
    • 1663758534406-215408a0-9ae7-46ec-9ac9-aa1af60cfae6-1714486640390-78.png
    • 获取计算器的进程信息,获取 VadRoot偏移 dt _eprocess 87b9ad40
    • 1663758632299-5b92dd48-3c3b-4d2d-9caf-64c036c8e1ab-1714486640390-79.png
    • 遍历二叉树 !vad 87b9ad40+0x278
    • 1663758791626-cbaa73d7-55c7-4142-a7af-8400a6e9c8b1-1714486640390-80.png
    • 1663758872119-b820e369-2ea7-4ae4-8c90-c93f865c77f9-1714486640390-81.png
    • 遍历这棵树,可以找到所有隐藏的模块 Mapped 表示文件映射 private 都是 virtulAlloc申请的

进程对象 KPROCESS (核心层)
  1. <span class="hljs-keyword" style="box-sizing: border-box; display: inline; overflow: visible; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border: 0px; word-break: normal; line-height: inherit; overflow-wrap: normal;">typedef</span><span style="box-sizing: border-box; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border-style: initial; border-color: initial; border-image: initial; line-height: inherit; overflow-wrap: normal;"> </span><span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">KPROCESS</span>
  2. {</span>
  3.     DISPATCHER_HEADER Header;     <span class="hljs-comment" style="box-sizing: border-box;">//表明为分发器对象(同步机制)</span>
  4.     LIST_ENTRY ProfileListHead;       <span class="hljs-comment" style="box-sizing: border-box;">//用于参与性能分析</span>
  5.     ULONG_PTR DirectoryTableBase[<span class="hljs-number" style="box-sizing: border-box;">2</span>];  <span class="hljs-comment" style="box-sizing: border-box;">//数组,[0]为进程页目录表地址,[1]为超空间的页目录表地址</span>
  6.     KGDTENTRY LdtDescriptor;         <span class="hljs-comment" style="box-sizing: border-box;">//局部描述符表 </span>
  7.     KIDTENTRY Int21Descriptor;        <span class="hljs-comment" style="box-sizing: border-box;">//为了兼容dos程序, 通过int21调用dos系统功能</span>
  8.     USHORT IopmOffset;               <span class="hljs-comment" style="box-sizing: border-box;">//制定IOPM位置,控制用户模式的IO权限</span>
  9.     UCHAR Iopl;                       <span class="hljs-comment" style="box-sizing: border-box;">//进程的I/O优先级</span>
  10.     BOOLEAN Unused;                   <span class="hljs-comment" style="box-sizing: border-box;">//未使用</span>
  11.     <span class="hljs-keyword" style="box-sizing: border-box;">volatile</span> KAFFINITY ActiveProcessors;  <span class="hljs-comment" style="box-sizing: border-box;">//当前进程在哪些处理上运行</span>
  12.     ULONG KernelTime;                   <span class="hljs-comment" style="box-sizing: border-box;">//内核模式运行时间(有线程结束更新时间)</span>
  13.     ULONG UserTime;                     <span class="hljs-comment" style="box-sizing: border-box;">//用户模式运行时间(有线程结束更新时间)</span>
  14.     LIST_ENTRY ReadyListHead;          <span class="hljs-comment" style="box-sizing: border-box;">//记录了就绪但未加入全局就绪表的线程(双向链表)</span>
  15.     SINGLE_LIST_ENTRY SwapListEntry;      <span class="hljs-comment" style="box-sizing: border-box;">//进程被换出内存使用</span>
  16.     PVOID VdmTrapcHandler;                <span class="hljs-comment" style="box-sizing: border-box;">//指向ctrl + c中断的函数(用于虚拟dos机)</span>
  17.     LIST_ENTRY ThreadListHead;            <span class="hljs-comment" style="box-sizing: border-box;">//当前进程的所有线程(双向循环链表)</span>
  18.     KSPIN_LOCK ProcessLock;               <span class="hljs-comment" style="box-sizing: border-box;">//自选锁对象,保护数据成员</span>
  19.     KAFFINITY Affinity;                   <span class="hljs-comment" style="box-sizing: border-box;">//指定进程可以在那些处理器上运行</span>
  20.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  21.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  22.             LONG AutoAlignment : <span class="hljs-number" style="box-sizing: border-box;">1</span>;      <span class="hljs-comment" style="box-sizing: border-box;">//内存对其检查标志</span>
  23.             LONG DisableBoost : <span class="hljs-number" style="box-sizing: border-box;">1</span>;       <span class="hljs-comment" style="box-sizing: border-box;">//线程优先级的提升和时限有关</span>
  24.             LONG DisableQuantum : <span class="hljs-number" style="box-sizing: border-box;">1</span>;     <span class="hljs-comment" style="box-sizing: border-box;">//线程优先级的提升和时限有关</span>
  25.             LONG ReservedFlags : <span class="hljs-number" style="box-sizing: border-box;">29</span>;     <span class="hljs-comment" style="box-sizing: border-box;">//保留</span>
  26.         };
  27.         
  28.         LONG ProcessFlags;
  29.     };
  30.     SCHAR BasePriority;                 <span class="hljs-comment" style="box-sizing: border-box;">//所有线程的基本优先级</span>
  31.     SCHAR QuantumReset;                 <span class="hljs-comment" style="box-sizing: border-box;">//所有线程的时限 (时间片)</span>
  32.     UCHAR State;                        <span class="hljs-comment" style="box-sizing: border-box;">//进程是否在内存中</span>
  33.     UCHAR ThreadSeed;                   <span class="hljs-comment" style="box-sizing: border-box;">//每个线程以此作为理想处理器</span>
  34.     UCHAR PowerState;                   <span class="hljs-comment" style="box-sizing: border-box;">//电源状态</span>
  35.     UCHAR IdealNode;                    <span class="hljs-comment" style="box-sizing: border-box;">//为一个进程选择优先的处理器节点</span>
  36.     BOOLEAN Visited;                    <span class="hljs-comment" style="box-sizing: border-box;">//WRK未使用</span>
  37.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  38.         KEXECUTE_OPTIONS Flags;
  39.         UCHAR ExecuteOptions;          <span class="hljs-comment" style="box-sizing: border-box;">//设置进程内存的执行选项</span>
  40.     };
  41.     ULONG_PTR StackCount;              <span class="hljs-comment" style="box-sizing: border-box;">//多少个线程的栈在内存中</span>
  42.     LIST_ENTRY ProcessListEntry;       <span class="hljs-comment" style="box-sizing: border-box;">//系统中所有具有活动线程的进程链表</span>
  43. } KPROCESS, *PKPROCESS, *PRKPROCESS;
复制代码



线程对象 ETHREAD (执行层)
  1. <span class="hljs-keyword" style="box-sizing: border-box;">typedef</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">ETHREAD</span> {</span>
  2.     KTHREAD Tcb;
  3.     LARGE_INTEGER CreateTime;      <span class="hljs-comment" style="box-sizing: border-box;">//线程创建时间</span>
  4.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  5.         LARGE_INTEGER ExitTime;    <span class="hljs-comment" style="box-sizing: border-box;">//线程退出时间</span>
  6.         LIST_ENTRY LpcReplyChain;
  7.         LIST_ENTRY KeyedWaitChain;
  8.     };
  9.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  10.         NTSTATUS ExitStatus;    <span class="hljs-comment" style="box-sizing: border-box;">//线程退出状态</span>
  11.         PVOID OfsChain;         <span class="hljs-comment" style="box-sizing: border-box;">//WRK未使用</span>
  12.     };
  13.     LIST_ENTRY PostBlockList;
  14.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  15.         PTERMINATION_PORT TerminationPort;
  16.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">ETHREAD</span> *<span class="hljs-title" style="box-sizing: border-box;">ReaperLink</span>;</span>
  17.         PVOID KeyedWaitValue;
  18.     };
  19.     KSPIN_LOCK ActiveTimerListLock;
  20.     LIST_ENTRY ActiveTimerListHead;   <span class="hljs-comment" style="box-sizing: border-box;">//当前线程的所有定时器</span>
  21.     CLIENT_ID Cid;                    <span class="hljs-comment" style="box-sizing: border-box;">//线程ID</span>
  22.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  23.         KSEMAPHORE LpcReplySemaphore;
  24.         KSEMAPHORE KeyedWaitSemaphore;
  25.     };
  26.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  27.         PVOID LpcReplyMessage;          <span class="hljs-comment" style="box-sizing: border-box;">// -> Message that contains the reply</span>
  28.         PVOID LpcWaitingOnPort;
  29.     };
  30.     PPS_IMPERSONATION_INFORMATION ImpersonationInfo;
  31.     LIST_ENTRY IrpList;
  32.     ULONG_PTR TopLevelIrp;  <span class="hljs-comment" style="box-sizing: border-box;">// either NULL, an Irp or a flag defined in FsRtl.h</span>
  33.     <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">DEVICE_OBJECT</span> *<span class="hljs-title" style="box-sizing: border-box;">DeviceToVerify</span>;</span>
  34.     PEPROCESS ThreadsProcess;        <span class="hljs-comment" style="box-sizing: border-box;">//当前线程所属进程</span>
  35.     PVOID StartAddress;              <span class="hljs-comment" style="box-sizing: border-box;">//系统dll的启动地址(来自Context的EIP)</span>
  36.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  37.         PVOID Win32StartAddress;     <span class="hljs-comment" style="box-sizing: border-box;">//线程回调函数地址(来自context的EAX)</span>
  38.         ULONG LpcReceivedMessageId;
  39.     };
  40.     LIST_ENTRY ThreadListEntry;
  41.     EX_RUNDOWN_REF RundownProtect;   <span class="hljs-comment" style="box-sizing: border-box;">//线程停止保护锁</span>
  42.     EX_PUSH_LOCK ThreadLock;         <span class="hljs-comment" style="box-sizing: border-box;">//保护线程的数据成员</span>
  43.     ULONG LpcReplyMessageId;         <span class="hljs-comment" style="box-sizing: border-box;">//当前正等待对一个消息的应答</span>
  44.     ULONG ReadClusterSize;           <span class="hljs-comment" style="box-sizing: border-box;">//在一次I/O操作读取了多少个页面</span>
  45.     ACCESS_MASK GrantedAccess;       <span class="hljs-comment" style="box-sizing: border-box;">//线程的访问权限</span>
  46.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {

  47.         ULONG CrossThreadFlags;            <span class="hljs-comment" style="box-sizing: border-box;">//针对跨线程访问的标志</span>
  48.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  49.             ULONG Terminated              : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//线程已执行中止操作</span>
  50.             ULONG DeadThread              : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//创建失败</span>
  51.             ULONG HideFromDebugger        : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//该线程对于调试器不可见</span>
  52.             ULONG ActiveImpersonationInfo : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  53.             ULONG SystemThread            : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//是一个系统线程</span>
  54.             ULONG HardErrorsAreDisabled   : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//对于该现场,硬件错误无效</span>
  55.             ULONG BreakOnTermination      : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//调试器在线程中止时停下该线程</span>
  56.             ULONG SkipCreationMsg         : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//不向调试器发送创建线程消息(可以用于反调试)</span>
  57.             ULONG SkipTerminationMsg      : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//不向调试器发送线程中止消息(可以用于反调试)</span>
  58.         };
  59.     };
  60.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  61.         ULONG SameThreadPassiveFlags;
  62.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  63.             ULONG ActiveExWorker : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  64.             ULONG ExWorkerCanWaitUser : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  65.             ULONG MemoryMaker : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  66.             ULONG KeyedEventInUse : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  67.         };
  68.     };
  69.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  70.         ULONG SameThreadApcFlags;
  71.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  72.             BOOLEAN LpcReceivedMsgIdValid : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  73.             BOOLEAN LpcExitThreadCalled   : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  74.             BOOLEAN AddressSpaceOwner     : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  75.             BOOLEAN OwnsProcessWorkingSetExclusive  : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  76.             BOOLEAN OwnsProcessWorkingSetShared     : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  77.             BOOLEAN OwnsSystemWorkingSetExclusive   : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  78.             BOOLEAN OwnsSystemWorkingSetShared      : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  79.             BOOLEAN OwnsSessionWorkingSetExclusive  : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  80.             BOOLEAN OwnsSessionWorkingSetShared     : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  81.             BOOLEAN ApcNeeded                       : <span class="hljs-number" style="box-sizing: border-box;">1</span>;
  82.         };
  83.     };
  84.     BOOLEAN ForwardClusterOnly;
  85.     BOOLEAN DisablePageFaultClustering;
  86.     UCHAR ActiveFaultCount;
  87. <span class="hljs-meta" style="box-sizing: border-box;">#<span class="hljs-meta-keyword" style="box-sizing: border-box;">if</span> defined (PERF_DATA)</span>
  88.     ULONG PerformanceCountLow;
  89.     LONG PerformanceCountHigh;
  90. <span class="hljs-meta" style="box-sizing: border-box;">#<span class="hljs-meta-keyword" style="box-sizing: border-box;">endif</span></span>
  91. } ETHREAD, *PETHREAD;
复制代码



线程对象 ETHREAD (核心层)
  1. <span class="hljs-keyword" style="box-sizing: border-box;">typedef</span> <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> _<span class="hljs-title" style="box-sizing: border-box;">KTHREAD</span>
  2. {</span>
  3.     DISPATCHER_HEADER Header;       <span class="hljs-comment" style="box-sizing: border-box;">//分发器对象</span>
  4.     LIST_ENTRY MutantListHead;      <span class="hljs-comment" style="box-sizing: border-box;">//指向该线程的互斥体对象链表</span>
  5.     PVOID InitialStack;             <span class="hljs-comment" style="box-sizing: border-box;">//内核原始栈的位置</span>
  6.     PVOID StackLimit;               <span class="hljs-comment" style="box-sizing: border-box;">//内核栈界限</span>
  7.     PVOID KernelStack;              <span class="hljs-comment" style="box-sizing: border-box;">//内核栈的开始位置</span>
  8.     KSPIN_LOCK ThreadLock;          <span class="hljs-comment" style="box-sizing: border-box;">//自旋锁,保护线程数据成员</span>
  9.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  10.         KAPC_STATE ApcState;        <span class="hljs-comment" style="box-sizing: border-box;">//指向APC信息(异步过程调用,有一个队列,记录了所有的注册函数)</span>
  11.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  12.             UCHAR ApcStateFill[KAPC_STATE_ACTUAL_LENGTH];
  13.             BOOLEAN ApcQueueable;             <span class="hljs-comment" style="box-sizing: border-box;">//是否可以插入APC</span>
  14.             <span class="hljs-keyword" style="box-sizing: border-box;">volatile</span> UCHAR NextProcessor;     <span class="hljs-comment" style="box-sizing: border-box;">//关于线程调度器的选择</span>
  15.             <span class="hljs-keyword" style="box-sizing: border-box;">volatile</span> UCHAR DeferredProcessor; <span class="hljs-comment" style="box-sizing: border-box;">//关于线程调度器的选择</span>
  16.             UCHAR AdjustReason;               <span class="hljs-comment" style="box-sizing: border-box;">//优先级调整原因</span>
  17.             SCHAR AdjustIncrement;            <span class="hljs-comment" style="box-sizing: border-box;">//优先级调整量</span>
  18.         };
  19.     };
  20.     KSPIN_LOCK ApcQueueLock;     <span class="hljs-comment" style="box-sizing: border-box;">//自旋锁,保护APC队列</span>
  21.     ULONG ContextSwitches;       <span class="hljs-comment" style="box-sizing: border-box;">//线程进行了多少次环境切换</span>
  22.     <span class="hljs-keyword" style="box-sizing: border-box;">volatile</span> UCHAR State;        <span class="hljs-comment" style="box-sizing: border-box;">//线程状态</span>
  23.     UCHAR NpxState;              <span class="hljs-comment" style="box-sizing: border-box;">//浮点寄存器状态</span>
  24.     BOOLEAN Alertable;           <span class="hljs-comment" style="box-sizing: border-box;">//说明一个线程是否可以被唤醒</span>
  25.     BOOLEAN WaitNext;            <span class="hljs-comment" style="box-sizing: border-box;">//线程马上要调用一个内核等待函数</span>
  26.     UCHAR WaitReason;            <span class="hljs-comment" style="box-sizing: border-box;">//线程等待理由</span>
  27.     SCHAR Priority;              <span class="hljs-comment" style="box-sizing: border-box;">//该线程动态优先级</span>
  28.     UCHAR EnableStackSwap;       <span class="hljs-comment" style="box-sizing: border-box;">//本线程栈是否允许换到外存中</span>
  29.     <span class="hljs-keyword" style="box-sizing: border-box;">volatile</span> UCHAR SwapBusy;     <span class="hljs-comment" style="box-sizing: border-box;">//当前线程是否在切换环境中</span>
  30.     BOOLEAN Alerted[MaximumMode];
  31.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  32.         LIST_ENTRY WaitListEntry;
  33.         SINGLE_LIST_ENTRY SwapListEntry;
  34.     };
  35.     PRKQUEUE Queue;      <span class="hljs-comment" style="box-sizing: border-box;">//队列分发器对象</span>
  36.     PVOID Teb;           <span class="hljs-comment" style="box-sizing: border-box;">//指向TEB,这就是3环的Teb</span>
  37.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  38.         KTIMER Timer;   <span class="hljs-comment" style="box-sizing: border-box;">//线程上的定时器(超时等待)</span>
  39.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  40.             UCHAR TimerFill[KTIMER_ACTUAL_LENGTH];
  41.             <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  42.                 <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  43.                     LONG AutoAlignment : <span class="hljs-number" style="box-sizing: border-box;">1</span>;   <span class="hljs-comment" style="box-sizing: border-box;">//参考KPROCESS</span>
  44.                     LONG DisableBoost : <span class="hljs-number" style="box-sizing: border-box;">1</span>;     <span class="hljs-comment" style="box-sizing: border-box;">//参考KPROCESS</span>
  45.                     LONG ReservedFlags : <span class="hljs-number" style="box-sizing: border-box;">30</span>;
  46.                 };
  47.                 LONG ThreadFlags;
  48.             };
  49.         };
  50.     };
  51.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  52.         KWAIT_BLOCK WaitBlock[THREAD_WAIT_OBJECTS + <span class="hljs-number" style="box-sizing: border-box;">1</span>];  <span class="hljs-comment" style="box-sizing: border-box;">//第4项用于可等待的定时器对象</span>
  53.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  54.             UCHAR WaitBlockFill0[KWAIT_BLOCK_OFFSET_TO_BYTE0];
  55.             BOOLEAN SystemAffinityActive;
  56.         };
  57.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  58.             UCHAR WaitBlockFill1[KWAIT_BLOCK_OFFSET_TO_BYTE1];
  59.             CCHAR PreviousMode;
  60.         };
  61.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  62.             UCHAR WaitBlockFill2[KWAIT_BLOCK_OFFSET_TO_BYTE2];
  63.             UCHAR ResourceIndex;
  64.         };
  65.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  66.             UCHAR WaitBlockFill3[KWAIT_BLOCK_OFFSET_TO_BYTE3];
  67.             UCHAR LargeStack;
  68.         };
  69.     };
  70.     LIST_ENTRY QueueListEntry;
  71.     PKTRAP_FRAME TrapFrame;     <span class="hljs-comment" style="box-sizing: border-box;">//切换线程,保存寄存器环境用</span>
  72.     PVOID CallbackStack;
  73.     PVOID ServiceTable;         <span class="hljs-comment" style="box-sizing: border-box;">//该线程使用的SSDT表</span>
  74.     UCHAR ApcStateIndex;
  75.     UCHAR IdealProcessor;       <span class="hljs-comment" style="box-sizing: border-box;">//该线程的理想处理器</span>
  76.     BOOLEAN Preempted;          <span class="hljs-comment" style="box-sizing: border-box;">//该线程是否被高优先级的线程抢占了</span>
  77.     BOOLEAN ProcessReadyQueue;
  78.     BOOLEAN KernelStackResident;
  79.     SCHAR BasePriority;
  80.     SCHAR PriorityDecrement;
  81.     CHAR Saturation;
  82.     KAFFINITY UserAffinity;
  83.     PKPROCESS <span class="hljs-built_in" style="box-sizing: border-box;">Process</span>;
  84.     KAFFINITY Affinity;          <span class="hljs-comment" style="box-sizing: border-box;">//掩码,指定线程在哪一核上运行</span>
  85.     PKAPC_STATE ApcStatePointer[<span class="hljs-number" style="box-sizing: border-box;">2</span>];
  86.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  87.         KAPC_STATE SavedApcState;
  88.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  89.             UCHAR SavedApcStateFill[KAPC_STATE_ACTUAL_LENGTH];
  90.             CCHAR FreezeCount;
  91.             CCHAR SuspendCount;
  92.             UCHAR UserIdealProcessor;
  93.             UCHAR CalloutActive;
  94.             UCHAR OtherPlatformFill;
  95.         };
  96.     };
  97.     PVOID Win32Thread;
  98.     PVOID StackBase;
  99.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  100.         KAPC SuspendApc;
  101.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  102.             UCHAR SuspendApcFill0[KAPC_OFFSET_TO_SPARE_BYTE0];
  103.             SCHAR Quantum;
  104.         };
  105.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  106.             UCHAR SuspendApcFill1[KAPC_OFFSET_TO_SPARE_BYTE1];
  107.             UCHAR QuantumReset;
  108.         };
  109.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  110.             UCHAR SuspendApcFill2[KAPC_OFFSET_TO_SPARE_LONG];
  111.             ULONG KernelTime;
  112.         };
  113.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  114.             UCHAR SuspendApcFill3[KAPC_OFFSET_TO_SYSTEMARGUMENT1];
  115.             PVOID TlsArray;
  116.         };
  117.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  118.             UCHAR SuspendApcFill4[KAPC_OFFSET_TO_SYSTEMARGUMENT2];
  119.             PVOID BBTData;
  120.         };
  121.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  122.             UCHAR SuspendApcFill5[KAPC_ACTUAL_LENGTH];
  123.             UCHAR PowerState;
  124.             ULONG UserTime;
  125.         };
  126.     };
  127.     <span class="hljs-keyword" style="box-sizing: border-box;">union</span> {
  128.         KSEMAPHORE SuspendSemaphore;
  129.         <span class="hljs-class" style="box-sizing: border-box;"><span class="hljs-keyword" style="box-sizing: border-box;">struct</span> {</span>
  130.             UCHAR SuspendSemaphorefill[KSEMAPHORE_ACTUAL_LENGTH];
  131.             ULONG SListFaultCount;
  132.         };
  133.     };
  134.     LIST_ENTRY ThreadListEntry;
  135.     PVOID SListFaultAddress;
  136. } KTHREAD, *PKTHREAD, *PRKTHREAD;
复制代码



1663759855440-67c5c82b-50be-4bf3-9e1c-fb4d3d1f5171-1714486689878-96.png
1663759924908-0534b2b4-15fe-46dc-98cd-bd99e9e88c51-1714486689878-97.png
对源码进行编译调试编译
  1. <font color="rgba(0, 0, 0, 0.8)" face="SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"><span style="box-sizing: border-box; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border-style: initial; border-color: initial; border-image: initial; line-height: inherit; overflow-wrap: normal;">path G:\wrk-v1</span></font><span class="hljs-number" style="box-sizing: border-box;">.2</span>\tools\x86;%path%

  2. cl.exe

  3. cd G:\wrk-v1<span class="hljs-number" style="box-sizing: border-box;">.2</span>\base\ntos

  4. g:

  5. nmake -nologo x86=
复制代码



1663765371823-2dbfccb4-b023-4a3c-8388-abce2f09968e-1714486703967-102.png
1663765416799-43319702-ddd9-4ea9-a638-86abcbdd2cfa-1714486703967-103.png
1663765454973-a4953545-78d0-4dff-85c9-a85c9c3e0b55-1714486703967-104.png
这个就等于 NTKernel.exe
用法
先把文件拷到虚拟机里面,我们要把当前系统的内核替换掉,但是不能把系统原来的内核删了,因此只能在 boot.ini里面加一个开机选项
​ 1. 把 wrkx86.exe 复制到/WINDOWS/system32/目录下
​ 把 ..\wrk-v1.2\ws03sp1hals\x86\halacpim目录下的 halacpim.dll 复制到/WINDOWS/system32/目录下
​ 2.编辑BOOT.ini
/kernel=wrkx86.exe /hal=halacpim.dll multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="Windows Server 2003, Enterprise" /fastdetect /NoExecute=OptOut    multi(0)disk(0)rdisk(0)partition(1)/WINDOWS="WRK 1.2" /fastdetect /NoExecute=OptOut /kernel=wrkx86.exe /hal=halmacpi.dll  /debugport=com1 /baudrate=115200

​ 3.配置双机调试
​ 4.用windbg去连接 ,连接后记得 lm 看一下符号加载没有
​ 5.要调试什么函数都可以可以 .例如我们要调 NtCreateProcess
1663766460269-9190bb95-69d1-42ba-a53b-16b340e7aceb-1714486730155-111.png
1663766525690-7f90297e-6900-4d95-9959-534895cb6e0e-1714486730155-112.png
然后在文件里面搜索你要调试的函数,下断点 F9就可以了 ,或者通过命令 BP NtCreateProcess 也可以
  • WRK源码还是有缺陷的,比如一些计算器,画图等3环软件就没有源码,而且它的源码不是很全,微软是不会提供的
    • 可以自己逆向获取,但是工作量太大了;可以下载ReatOS,用它和WRK结合起来分析

参考书籍
Windows内核原理和实现 潘爱民
Windows内核情景分析 毛德操
获取所有进程的页目录表地址
  • 我们主需要获取一个进程的进程对象,就可以遍历所有进程
  • 可以通过API PsGetCurrentProcess 获取当前的进程对象
  • 我们可以通过 wrk 查看 该函数的实现
#define _PsGetCurrentProcess() (CONTAINING_RECORD(((KeGetCurrentThread())->ApcState.Process),EPROCESS,Pcb))拿到当前的一个线程,通过线程的 ApcState 拿到进程
  1. <span style="box-sizing: border-box; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border-style: initial; border-color: initial; border-image: initial; line-height: inherit; overflow-wrap: normal;">
  2. </span><span class="hljs-function" style="box-sizing: border-box;">NTAPI <span class="hljs-title" style="box-sizing: border-box;">KeGetCurrentThread</span> <span class="hljs-params" style="box-sizing: border-box;">(VOID)</span>
  3. </span>{
  4. <span class="hljs-meta" style="box-sizing: border-box;">#<span class="hljs-meta-keyword" style="box-sizing: border-box;">if</span> (_MSC_FULL_VER >= 13012035)</span>
  5.     <span class="hljs-keyword" style="box-sizing: border-box;">return</span> (struct _KTHREAD *) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, PrcbData.CurrentThread));
  6. <span class="hljs-meta" style="box-sizing: border-box;">#<span class="hljs-meta-keyword" style="box-sizing: border-box;">else</span></span>
  7.     __asm {  mov eax, fs:[<span class="hljs-number" style="box-sizing: border-box;">0</span>] KPCR.PrcbData.CurrentThread }
  8. <span class="hljs-meta" style="box-sizing: border-box;">#<span class="hljs-meta-keyword" style="box-sizing: border-box;">endif</span></span>
  9. }
复制代码

可以看到这里涉及到一个KPCR结构体也就是CPU控制块CPU控制块: 操作系统需要实时交给CPU很多表信息,因此需要快速的去查一下表,因此微软做了一个KPCR结构体,里面放了CPU用到的所有表,这个表地址 放到了 fs:[0]  或者直接在WinDbg里u一下这个函数的实现
  1. kd> u PsGetCurrentProcess
  2. nt!PsGetCurrentProcess:
  3.         mov     eax,dword ptr fs:[<span class="hljs-number" style="box-sizing: border-box;">00000124</span>h];等价于_KPRCB结构体再+<span class="hljs-number" style="box-sizing: border-box;">4</span>的位置也就是当前线程
  4.         mov     eax,dword ptr [eax+<span class="hljs-number" style="box-sizing: border-box;">50</span>h];拿到当前线程对象后再加<span class="hljs-number" style="box-sizing: border-box;">50</span>h就得到了进程对象结构体
  5.         ret
复制代码

也就是fs:[124]在_KPCR结构体最后一项还要加4的位置,0x120 PrcbData : _KPRCB(还要+4)也就是_KPRCB结构体里的+0x004 CurrentThread    : Ptr32 _KTHREAD 成员然后再+50h就是_KTHREAD里的+0x040 ApcState : _KAPC_STATE;这个结构体里再+10的位置最终在_KAPC_STATE结构体里+10的位置得到了+0x010 Process : Ptr32 _KPROCESS这里测试系统用的是Win732位.XP的话是eax+44h

  • KPCR结构体的部分成员 可以通过指令 dt KPCR 查看
  • KPCR这个结构体基本上想拿什么东西都可以从这里拿
  1. kd> dt _KPCR
  2.    
  3. ntdll!_KPCR
  4. +0x000 NtTib            : _NT_TIB ;记录了内核的栈信息
  5. ;........成员省略..........................
  6. +0x020 Prcb             : Ptr32 _KPRCB;   最重要的成员 KPCRB结构体
  7. ;........成员省略..........................
  8. +0x03c GDT              : Ptr32 _KGDTENTRY ;CPU要给GDTR的地址就从这里拿出来给过去
  9. ;........成员省略..........................
  10. +0x120 PrcbData         : _KPRCB   
复制代码



    • KPCRB结构体 可以通过指令 dt KPCR 查看
  • 这个结构体很大,结构体套结构体,所以只展示部分重要字段
    1. <font color="rgba(0, 0, 0, 0.8)" face="SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace"><span style="box-sizing: border-box; background-image: initial; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; text-size-adjust: none; border-radius: 6px; border-style: initial; border-color: initial; border-image: initial; line-height: inherit; overflow-wrap: normal;">kd> dt _KPRCB
    2.    
    3. ntdll!_KPRCB
    4. +</span></font><span class="hljs-number" style="box-sizing: border-box;">0x000</span> MinorVersion     : Uint2B
    5. +<span class="hljs-number" style="box-sizing: border-box;">0x002</span> MajorVersion     : Uint2B
    6. +<span class="hljs-number" style="box-sizing: border-box;">0x004</span> CurrentThread    : Ptr32 _KTHREAD    保存了当前线程,指向一个_KTHREAD结构体也就等价
    7.                                             于指向_ETHREAD结构体
    8. +<span class="hljs-number" style="box-sizing: border-box;">0x008</span> NextThread       : Ptr32 _KTHREAD;   指向下一个会被切换的线程
    9. +<span class="hljs-number" style="box-sizing: border-box;">0x00c</span> IdleThread       : Ptr32 _KTHREAD;   指向空闲的线程(如果没有下一个就走这个空闲的)
    复制代码



  • 以XP为例,遍历所有进程
  • 1663770532796-a3845596-0000-4f7f-a48f-fe28b47d8303-1714486811366-117.png
  • 可以看到 fs的地址不是0 ,所以 _KPCR 结构体的首地址在 ffdff000
    1. kd> dt _KPCR
    2. nt!_KPCR
    3.    +0x000 NtTib            : _NT_TIB
    4.    +0x01c SelfPcr          : Ptr32 _KPCR
    5.    +0x020 Prcb             : Ptr32 _KPRCB
    6.    +0x024 Irql             : UChar
    7.    +0x028 IRR              : Uint4B
    8.    +0x02c IrrActive        : Uint4B
    9.    +0x030 IDR              : Uint4B
    10.    +0x034 KdVersionBlock   : Ptr32 Void
    11.    +0x038 IDT              : Ptr32 _KIDTENTRY
    12.    +0x03c GDT              : Ptr32 _KGDTENTRY
    13.    +0x040 TSS              : Ptr32 _KTSS
    14.    +0x044 MajorVersion     : Uint2B
    15.    +0x046 MinorVersion     : Uint2B
    16.    +0x048 SetMember        : Uint4B
    17.    +0x04c StallScaleFactor : Uint4B
    18.    +0x050 DebugActive      : UChar
    19.    +0x051 Number           : UChar
    20.    +0x052 Spare0           : UChar
    21.    +0x053 SecondLevelCacheAssociativity : UChar
    22.    +0x054 VdmAlert         : Uint4B
    23.    +0x058 KernelReserved   : [14] Uint4B
    24.    +0x090 SecondLevelCacheSize : Uint4B
    25.    +0x094 HalReserved      : [16] Uint4B
    26.    +0x0d4 InterruptMode    : Uint4B
    27.    +0x0d8 Spare1           : UChar
    28.    +0x0dc KernelReserved2  : [17] Uint4B
    29.    +0x120 PrcbData         : _KPRCB


    30. kd> dt _eprocess
    31. ntdll!_EPROCESS
    32.    +0x000 Pcb              : _KPROCESS
    33.    +0x06c ProcessLock      : _EX_PUSH_LOCK
    34.    +0x070 CreateTime       : _LARGE_INTEGER
    35.    +0x078 ExitTime         : _LARGE_INTEGER
    36.    +0x080 RundownProtect   : _EX_RUNDOWN_REF
    37.    +0x084 UniqueProcessId  : Ptr32 Void
    38.    +0x088 ActiveProcessLinks : _LIST_ENTRY
    39.    +0x090 QuotaUsage       : [3] Uint4B
    40.    +0x09c QuotaPeak        : [3] Uint4B
    41.    +0x0a8 CommitCharge     : Uint4B
    42.    +0x0ac PeakVirtualSize  : Uint4B
    43.    +0x0b0 VirtualSize      : Uint4B
    44.    +0x0b4 SessionProcessLinks : _LIST_ENTRY
    45.    +0x0bc DebugPort        : Ptr32 Void
    46.    +0x0c0 ExceptionPort    : Ptr32 Void
    47.    +0x0c4 ObjectTable      : Ptr32 _HANDLE_TABLE
    48.    +0x0c8 Token            : _EX_FAST_REF
    49.    +0x0cc WorkingSetLock   : _FAST_MUTEX
    50.    +0x0ec WorkingSetPage   : Uint4B
    51.    +0x0f0 AddressCreationLock : _FAST_MUTEX
    52.    +0x110 HyperSpaceLock   : Uint4B
    53.    +0x114 ForkInProgress   : Ptr32 _ETHREAD
    54.    +0x118 HardwareTrigger  : Uint4B
    55.    +0x11c VadRoot          : Ptr32 Void
    56.    +0x120 VadHint          : Ptr32 Void
    57.    +0x124 CloneRoot        : Ptr32 Void
    58.    +0x128 NumberOfPrivatePages : Uint4B
    59.    +0x12c NumberOfLockedPages : Uint4B
    60.    +0x130 Win32Process     : Ptr32 Void
    61.    +0x134 Job              : Ptr32 _EJOB
    62.    +0x138 SectionObject    : Ptr32 Void
    63.    +0x13c SectionBaseAddress : Ptr32 Void
    64.    +0x140 QuotaBlock       : Ptr32 _EPROCESS_QUOTA_BLOCK
    65.    +0x144 WorkingSetWatch  : Ptr32 _PAGEFAULT_HISTORY
    66.    +0x148 Win32WindowStation : Ptr32 Void
    67.    +0x14c InheritedFromUniqueProcessId : Ptr32 Void
    68.    +0x150 LdtInformation   : Ptr32 Void
    69.    +0x154 VadFreeHint      : Ptr32 Void
    70.    +0x158 VdmObjects       : Ptr32 Void
    71.    +0x15c DeviceMap        : Ptr32 Void
    72.    +0x160 PhysicalVadList  : _LIST_ENTRY
    73.    +0x168 PageDirectoryPte : _HARDWARE_PTE_X86
    74.    +0x168 Filler           : Uint8B
    75.    +0x170 Session          : Ptr32 Void
    76.    +0x174 ImageFileName    : [16] UChar
    77.    +0x184 JobLinks         : _LIST_ENTRY
    78.    +0x18c LockedPagesList  : Ptr32 Void
    79.    +0x190 ThreadListHead   : _LIST_ENTRY
    80.    +0x198 SecurityPort     : Ptr32 Void
    81.    +0x19c PaeTop           : Ptr32 Void
    82.    +0x1a0 ActiveThreads    : Uint4B
    83.    +0x1a4 GrantedAccess    : Uint4B
    84.    +0x1a8 DefaultHardErrorProcessing : Uint4B
    85.    +0x1ac LastThreadExitStatus : Int4B
    86.    +0x1b0 Peb              : Ptr32 _PEB
    87.    +0x1b4 PrefetchTrace    : _EX_FAST_REF
    88.    +0x1b8 ReadOperationCount : _LARGE_INTEGER
    89.    +0x1c0 WriteOperationCount : _LARGE_INTEGER
    90.    +0x1c8 OtherOperationCount : _LARGE_INTEGER
    91.    +0x1d0 ReadTransferCount : _LARGE_INTEGER
    92.    +0x1d8 WriteTransferCount : _LARGE_INTEGER
    93.    +0x1e0 OtherTransferCount : _LARGE_INTEGER
    94.    +0x1e8 CommitChargeLimit : Uint4B
    95.    +0x1ec CommitChargePeak : Uint4B
    96.    +0x1f0 AweInfo          : Ptr32 Void
    97.    +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO
    98.    +0x1f8 Vm               : _MMSUPPORT
    99.    +0x238 LastFaultCount   : Uint4B
    100.    +0x23c ModifiedPageCount : Uint4B
    101.    +0x240 NumberOfVads     : Uint4B
    102.    +0x244 JobStatus        : Uint4B
    103.    +0x248 Flags            : Uint4B
    104.    +0x248 CreateReported   : Pos 0, 1 Bit
    105.    +0x248 NoDebugInherit   : Pos 1, 1 Bit
    106.    +0x248 ProcessExiting   : Pos 2, 1 Bit
    107.    +0x248 ProcessDelete    : Pos 3, 1 Bit
    108.    +0x248 Wow64SplitPages  : Pos 4, 1 Bit
    109.    +0x248 VmDeleted        : Pos 5, 1 Bit
    110.    +0x248 OutswapEnabled   : Pos 6, 1 Bit
    111.    +0x248 Outswapped       : Pos 7, 1 Bit
    112.    +0x248 ForkFailed       : Pos 8, 1 Bit
    113.    +0x248 HasPhysicalVad   : Pos 9, 1 Bit
    114.    +0x248 AddressSpaceInitialized : Pos 10, 2 Bits
    115.    +0x248 SetTimerResolution : Pos 12, 1 Bit
    116.    +0x248 BreakOnTermination : Pos 13, 1 Bit
    117.    +0x248 SessionCreationUnderway : Pos 14, 1 Bit
    118.    +0x248 WriteWatch       : Pos 15, 1 Bit
    119.    +0x248 ProcessInSession : Pos 16, 1 Bit
    120.    +0x248 OverrideAddressSpace : Pos 17, 1 Bit
    121.    +0x248 HasAddressSpace  : Pos 18, 1 Bit
    122.    +0x248 LaunchPrefetched : Pos 19, 1 Bit
    123.    +0x248 InjectInpageErrors : Pos 20, 1 Bit
    124.    +0x248 VmTopDown        : Pos 21, 1 Bit
    125.    +0x248 Unused3          : Pos 22, 1 Bit
    126.    +0x248 Unused4          : Pos 23, 1 Bit
    127.    +0x248 VdmAllowed       : Pos 24, 1 Bit
    128.    +0x248 Unused           : Pos 25, 5 Bits
    129.    +0x248 Unused1          : Pos 30, 1 Bit
    130.    +0x248 Unused2          : Pos 31, 1 Bit
    131.    +0x24c ExitStatus       : Int4B
    132.    +0x250 NextPageColor    : Uint2B
    133.    +0x252 SubSystemMinorVersion : UChar
    134.    +0x253 SubSystemMajorVersion : UChar
    135.    +0x252 SubSystemVersion : Uint2B
    136.    +0x254 PriorityClass    : UChar
    137.    +0x255 WorkingSetAcquiredUnsafe : UChar
    138.    +0x258 Cookie           : Uint4B
    复制代码



  • //枚举进程页目录表
    1. void EnumProcessDir() {
    2.     PEPROCESS Porcess = NULL;
    3.     //获取进程对象
    4.     __asm {
    5.         mov eax, fs:[124h]    //ETHREAD; 先获取当前线程对象
    6.         mov eax, [eax + 44h]  //EPROCESS;进程对象 在XP里是+44h (34+10)
    7.         mov Porcess, eax;     //进程对象保存一下.
    8.     }

    9.     //链表在EPROCESS结构体偏移88的位置
    10.     _LIST_ENTRY* head = (_LIST_ENTRY*)((char*)Porcess + 0x88);//链表头;
    11.         //这样就得到了第一个进程的结构体指针.
    12.     _LIST_ENTRY* tail = head;//由于是双向循环链表所以再保存一下,相当于保存一下遍历的终点

    13.     //如果头不等于尾就一直循环.
    14.     do {
    15.         Porcess = (PEPROCESS)((char*)head - 0x88); //获取到进程对象
    16.         //进程ID在偏移0x84的位置
    17.         ULONG UniqueProcessId = *(ULONG*)((char*)Porcess + 0x84);
    18.         //进程名在偏移0x174的位置
    19.         CHAR* ImageFileName = (char*)Porcess + 0x174;
    20.         //获取页目录表的地址
    21.         PVOID DirectoryTableBase = *(PVOID*)((char*)Porcess + 0x18);
    22.         KdPrint(("UniqueProcessId:%d  ImageFileName:%s DirectoryTableBase:%p
    23.                          \r\n", UniqueProcessId, ImageFileName, DirectoryTableBase));

    24.         //下一个链表
    25.         head = head->Blink; //当前节点等于它的后继节点
    26.     } while (head != tail);

    27.     /*
    28.         得到一个进程的页目录表地址, 要操作它的进程就简单了...
    29.         知道某个进程的页目录表地址,就可以查它的表了,就能知道对方的线性地址映射到那个物理地址
    30.         这样就能在自己线程里操作这个物理地址,等价于操作对方的进程
    31.         流程就是:
    32.         读写进程内存 => 虚拟地址  =>  页目录表地址 =>  物理地址  =>  当前进程操作物理地址

    33.         操作物理地址的话可以把物理地址映射到自己的进程里,等价于强制和别的进程内存共享...
    34.     */
    35. }
    复制代码



  • 遍历的时候我们可以发现有一个无效的进程ID,因为他有头结点,头结点就是一个空的节点,一般都是全局变量
  • 1663773022003-d4b2909f-a014-4193-9d08-fd310b88e30d.jpg
  • 1663773418135-24793d7d-a043-4ed4-bd25-81224216ff3d.jpg

获取所有进程的页目录表地址
  • 只需要获取到一个进程的进程对象,就可以遍历所有进程了
  • 通过API可以获取到当前的进程对象PsGetCurrentProcess

可以用WRK或者ReatOS看一下这个函数是如何实现的,就能知道进程结构体中的链表放在那里了WRK版本        #define PsGetCurrentProcess() _PsGetCurrentProcess()        #define _PsGetCurrentProcess() (CONTAINING_RECORD(((KeGetCurrentThread())        ->ApcState.Process),EPROCESS,Pcb))可以看到这里是先拿到当前线程,然后通过线程的APC状态拿到进程这个线程来自于fs:[0]
  1. NTAPI KeGetCurrentThread (VOID)
  2. {
  3. #if (_MSC_FULL_VER >= 13012035)
  4.     return (struct _KTHREAD *) (ULONG_PTR) __readfsdword (FIELD_OFFSET (KPCR, PrcbData.CurrentThread));
  5. #else
  6.     __asm {  mov eax, fs:[0] KPCR.PrcbData.CurrentThread }
  7. #endif
  8. }
复制代码

可以看到这里涉及到一个KPCR结构体也就是CPU控制块或者直接在WinDbg里u一下这个函数的实现
  1. kd> u PsGetCurrentProcess
  2. nt!PsGetCurrentProcess:
  3.         mov     eax,dword ptr fs:[00000124h];等价于_KPRCB结构体再+4的位置也就是当前线程
  4.         mov     eax,dword ptr [eax+50h];拿到当前线程对象后再加50h就得到了进程对象结构体
  5.         ret
复制代码

也就是fs:[124]在_KPCR结构体最后一项还要加4的位置,0x120 PrcbData : _KPRCB(还要+4)也就是_KPRCB结构体里的+0x004 CurrentThread    : Ptr32 _KTHREAD 成员然后再+50h就是_KTHREAD里的+0x040 ApcState : _KAPC_STATE;这个结构体里再+10的位置最终在_KAPC_STATE结构体里+10的位置得到了+0x010 Process : Ptr32 _KPROCESS这里测试系统用的是Win732位.XP的话是eax+44h

KPCR-->CPU控制块
操作系统作者要时时刻刻交给CPU很多表的信息. 动不动就切换进程切换线程就要快速的去查一些表,所以微软就做了一个KPCR结构体,里面放了CPU要用到的所有表 而这个表地址被放到fs里了 所以要想访问这个表就直接fs:[0]就可以访问了
    • KPCR结构体的部分成员
  • kd> dt _KPCR ntdll!_KPCR +0x000 NtTib : _NT_TIB ;记录了内核的栈信息 ;........成员省略.......................... +0x020 Prcb : Ptr32 _KPRCB;KPCRB结构体 ;........成员省略.......................... +0x03c GDT : Ptr32 _KGDTENTRY ;CPU要给GDTR的地址就从这里拿出来给过去 ;........成员省略.......................... +0x120 PrcbData : _KPRCB
      • KPCRB结构体
    • 这个结构体很大,结构体套结构体,所以只展示部分重要字段 kd> dt _KPRCB ntdll!_KPRCB +0x000 MinorVersion : Uint2B +0x002 MajorVersion : Uint2B ;保存了当前线程,指向一个_KTHREAD结构体也就等价于指向_ETHREAD结构体 +0x004 CurrentThread : Ptr32 _KTHREAD +0x008 NextThread : Ptr32 _KTHREAD;指向下一个会被切换的线程 +0x00c IdleThread : Ptr32 _KTHREAD;指向空闲的线程(如果没有下一个就走这个空闲的)
      • KPCR这个结构体基本上想拿什么东西都可以从这里拿
      • 代码示例
    • //枚举进程页目录表
      1. void EnumProcessDir() {
      2.     PEPROCESS Porcess = NULL;
      3.     //获取进程对象
      4.     __asm {
      5.         mov eax, fs:[124h] //先获取当前线程对象
      6.         mov eax, [eax + 44h] //EPROCESS;进程对象 在XP里是+44h
      7.         mov Porcess, eax; //进程对象保存一下.
      8.     }

      9.     //链表在EPROCESS结构体偏移88的位置
      10.     _LIST_ENTRY* head = (_LIST_ENTRY*)((char*)Porcess + 0x88);//链表头;
      11.         //这样就得到了第一个进程的结构体指针.
      12.     _LIST_ENTRY* tail = head;//由于是双向循环链表所以再保存一下,相当于保存一下尾部吧

      13.     //如果头不等于尾就一直循环.
      14.     do {
      15.         Porcess = (PEPROCESS)((char*)head - 0x88); //获取到进程对象
      16.         //进程ID再0x84的位置
      17.         ULONG UniqueProcessId = *(ULONG*)((char*)Porcess + 0x84);
      18.         //进程名在174的位置
      19.         CHAR* ImageFileName = (char*)Porcess + 0x174;
      20.         //获取页目录表的地址
      21.         PVOID DirectoryTableBase = *(PVOID*)((char*)Porcess + 0x18);
      22.         KdPrint(("UniqueProcessId:%d  ImageFileName:%s DirectoryTableBase:%p
      23.                          \r\n", UniqueProcessId, ImageFileName, DirectoryTableBase));

      24.         //下一个链表
      25.         head = head->Blink; //当前节点等于它的后继节点
      26.     } while (head != tail);

      27.     /*
      28.         得到一个进程的页目录表地址, 要操作它的进程就简单了...
      29.         知道某个进程的页目录表地址,就可以查它的表了,就能知道对方的线性地址映射到那个物理地址
      30.         这样就能在自己线程里操作这个物理地址,等价于操作对方的进程
      31.         流程就是:
      32.         读写进程内存 => 虚拟地址  =>  页目录表地址 =>  物理地址  =>  当前进程操作物理地址

      33.         操作物理地址的话可以把物理地址映射到自己的进程里,等价于强制和别的进程内存共享...
      34.     */
      35. }
      复制代码






您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-1-18 15:48 , Processed in 0.128041 second(s), 32 queries .

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

快速回复 返回顶部 返回列表