进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM

2023-05-16

有人投到黑防去了,不过黑防不厚道,竟然没给完整的代码,自己整理一份备用吧,驱网、DebugMan、邪八的那群人直接飘过吧。
这种方法的关键在于给线程的ETHREAD.CrossThreadFlags设置PS_CROSS_THREAD_FLAGS_SYSTEM值,这样其它进程就无法结束它了,包括IceSword、RkU。至于原理,那就先看看wrk里结束进程的那几个内核函数源码,NtTerminateProcess、PsTerminateProcess、PspTerminateProcess最终都是调用PspTerminateThreadByPointer来将每个线程杀死,而在PspTerminateThreadByPointer里,如果线程是被其它进程强x结束的,就会有个这样的判断:
 
  1. if (IS_SYSTEM_THREAD (Thread ) ) {
  2.     return STATUS_ACCESS_DENIED;
  3. }

Thread类型是PETHREAD,IS_SYSTEM_THREAD是个宏,如下:

  1. #define IS_SYSTEM_THREAD (Thread )   ( ( (Thread ) - >CrossThreadFlags &PS_CROSS_THREAD_FLAGS_SYSTEM ) ! = 0 )

也就是说当线程的ETHREAD.CrossThreadFlags包含PS_CROSS_THREAD_FLAGS_SYSTEM位时,就直接返回拒绝访问,这样线程就不会被结束了。具体参考代码请看wrk 1.2里的文件base\ntos\ps\psdelete.c。
好,现在只要给我们的进程里的每个线程都设置PS_CROSS_THREAD_FLAGS_SYSTEM,进程就不会被结束掉了。但是ETHREAD的结构没有文档化,所以还得自己找到CrossThreadFlags成员在ETHREAD结构里的偏移。可以通过在已导出的相关函数中找一些特征来定位CrossThreadFlags,黑防中是在PsIsSystemThread里找,但是这个函数在Windows 2000里没有,所以我们换个,换成PsTerminateSystemThread,先看下PsTerminateSystemThread的源码:

  1. NTSTATUS
  2. PsTerminateSystemThread (
  3.     __in NTSTATUS ExitStatus
  4.     )
  5. {
  6.     PETHREAD Thread = PsGetCurrentThread ( );
  7.  
  8.     if ( !IS_SYSTEM_THREAD (Thread ) ) {
  9.         return STATUS_INVALID_PARAMETER;
  10.     }
  11.  
  12.     return PspTerminateThreadByPointer (Thread, ExitStatus, TRUE );
  13. }

这里也用到了IS_SYSTEM_THREAD,那么也一定会有定位CrossThreadFlags的代码,如下:

  1. kd> u PsTerminateSystemThread
  2. nt!PsTerminateSystemThread :
  3. 805c89f8 8bff             mov     edi , edi
  4. 805c89fa 55               push     ebp
  5. 805c89fb 8bec             mov     ebp , esp
  6. 805c89fd 64a124010000     mov     eax , dword ptr fs : [ 00000124h ]
  7. 805c8a03 f6804802000010   test     byte ptr [ eax + 248h ] , 10h
  8. 805c8a0a 7507             jne     nt!PsTerminateSystemThread + 0x1b (805c8a13 )
  9. 805c8a0c b80d0000c0       mov     eax , 0C000000Dh
  10. 805c8a11 eb09             jmp     nt!PsTerminateSystemThread + 0x24 (805c8a1c )
  11. 805c8a13 ff7508           push     dword ptr [ ebp + 8 ]
  12. 805c8a16 50               push     eax
  13. 805c8a17 e828fcffff       call    nt!PspTerminateThreadByPointer (805c8644 )
  14. 805c8a1c 5d               pop     ebp
  15. 805c8a1d c20400           ret     4
很明显test    byte ptr [eax+248h],10h中的248h就是CrossThreadFlags在ETHREAD里的偏移了,test    byte ptr [eax+xxxxxxxx],10h的16进制是f680xxxxxxxx10,现在只要先获得PsTerminateSystemThread的地址,然后向后搜索0x80f6,搜索到后再后面的4个字节就是CrossThreadFlags在ETHREAD里的偏移了。

得到了偏移,下面就是写代码了,驱动部分:

  1. #include <ntifs. h >
  2. #include <ntddk. h >
  3.  
  4. #define PS_CROSS_THREAD_FLAGS_SYSTEM 0x00000010UL   //form wrk 1.2 base\ntos\inc\ps.h
  5. #define IOCTL_THREAD_PROTECT CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
  6.  
  7. VOID DriverUnload (PDRIVER_OBJECT pDriverObject )
  8. {
  9.   UNICODE_STRING usSymLink;
  10.   RtlInitUnicodeString ( &usSymLink, L "\\??\\ThreadProtect" );
  11.   IoDeleteSymbolicLink ( &usSymLink );
  12.   IoDeleteDevice (pDriverObject - >DeviceObject );
  13. }
  14.  
  15. NTSTATUS DispatchCreateClose (PDEVICE_OBJECT pDeviceObject, PIRP pIrp )
  16. {
  17.   pIrp - >IoStatus. Status = STATUS_SUCCESS;
  18.   pIrp - >IoStatus. Information = 0;
  19.   IoCompleteRequest (pIrp, IO_NO_INCREMENT );
  20.  
  21.   return STATUS_SUCCESS;
  22. }
  23.  
  24. NTSTATUS DispatchControl (PDEVICE_OBJECT pDeviceObject, PIRP pIrp )
  25. {
  26.   NTSTATUS nRet = STATUS_UNSUCCESSFUL;
  27.   ULONG_PTR uInf = 0;
  28.   PIO_STACK_LOCATION pIoStack = IoGetCurrentIrpStackLocation (pIrp );
  29.   PVOID pSysBuff = pIrp - >AssociatedIrp. SystemBuffer;
  30.  
  31.   switch (pIoStack - >Parameters. DeviceIoControl. IoControlCode )
  32.   {
  33.   case IOCTL_THREAD_PROTECT :
  34.     PETHREAD pEThread;
  35.     PsLookupThreadByThreadId (HANDLE ( * (PULONG )pSysBuff ), &pEThread );
  36.     UNICODE_STRING usName;
  37.     RtlInitUnicodeString ( &usName, L "PsTerminateSystemThread" );
  38.     PUSHORT pOffset = (PUSHORT )MmGetSystemRoutineAddress ( &usName );
  39.  
  40.     //search "test byte ptr [eax+xxxxxxxx],10h",hex:f680xxxxxxxx10
  41.     while ( *pOffset ! = 0x80f6 )
  42.       pOffset = PUSHORT ( (PUCHAR )pOffset + 1 );
  43.     PULONG pFlags = PULONG ( (PUCHAR )pEThread + * (PULONG ) (pOffset + 1 ) );
  44.     DbgPrint ( "pOffset:%08x, CrossFlagOffset:%08x\r\n", pOffset, * (PULONG ) (pOffset + 1 ) );
  45.     *pFlags |= PS_CROSS_THREAD_FLAGS_SYSTEM;   //set PS_CROSS_THREAD_FLAGS_SYSTEM bit
  46.     nRet = STATUS_SUCCESS;
  47.     uInf = 0;
  48.     break;
  49.   }
  50.  
  51.   pIrp - >IoStatus. Status = nRet;
  52.   pIrp - >IoStatus. Information = uInf;
  53.   IoCompleteRequest (pIrp, IO_NO_INCREMENT );
  54.   return nRet;
  55. }
  56.  
  57. extern "C" NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath )
  58. {
  59.   pDriverObject - >DriverUnload = DriverUnload;
  60.   pDriverObject - >MajorFunction [IRP_MJ_CREATE ] = DispatchCreateClose;
  61.   pDriverObject - >MajorFunction [IRP_MJ_CLOSE ] = DispatchCreateClose;
  62.   pDriverObject - >MajorFunction [IRP_MJ_DEVICE_CONTROL ] = DispatchControl;
  63.  
  64.   UNICODE_STRING usDeviceName;
  65.   RtlInitUnicodeString ( &usDeviceName, L "\\Device\\ThreadProtect" );
  66.  
  67.   NTSTATUS nRet;
  68.   PDEVICE_OBJECT pDeviceObject;
  69.   nRet = IoCreateDevice (pDriverObject, 0, &usDeviceName, FILE_DEVICE_UNKNOWN,
  70.     FILE_DEVICE_SECURE_OPEN, FALSE, &pDeviceObject );
  71.   if ( !NT_SUCCESS (nRet ) )
  72.     return nRet;
  73.  
  74.   UNICODE_STRING usSymLink;
  75.   RtlInitUnicodeString ( &usSymLink, L "\\??\\ThreadProtect" );
  76.   nRet = IoCreateSymbolicLink ( &usSymLink, &usDeviceName );
  77.   if ( !NT_SUCCESS (nRet ) )
  78.   {
  79.     IoDeleteDevice (pDeviceObject );
  80.     return nRet;
  81.   }
  82.   return STATUS_SUCCESS;
  83. }

这段代码要解释的都在上面了。EXE部分的代码就不用帖了,只要将每个线程的ID通过DeviceIoControl传入驱动即可:
 

  1. #define IOCTL_THREAD_PROTECT CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS )
  2.  
  3. DeviceIoControl (hDevice, IOCTL_THREAD_PROTECT, &nThreadId, sizeof (nThreadId ), 0, 0, &nByteRet, 0 );

 


点击这里下载文件: ThreadProtect.rar
运行后果自行负责,运行不了自行想办法到注册表里删除先前的ThreadProtect键值。

最后,怎么结束用这种方法保护的进程?方法大大的有,插入APC,然后PspExitThread就不会经过PspTerminateThreadByPointer了。


加粗 (Ctrl+B)斜体 (Ctrl+I)下划线 (Ctrl+U)字体颜色超链接 (Ctrl+L)取消超链接表情关于 xhEditor
 


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM 的相关文章

  • 使用 system() 命令运行多个 R 脚本

    我在 Windows 7 中运行 RStudio 我编写了一个主脚本 该脚本生成 57 个新的 R 脚本 每个脚本都包含根据两个参数运行函数的命令 vector1 lt c 1 19 vector2 lt c 1 3 首先 主脚本使用两个
  • 在 Perl 中启动非等待后台进程

    我有一个 Perl 脚本 需要在后台启动另一个进程并退出 而不等待其他脚本完成 StackOverflow 上有很多线程介绍如何在 Perl 中等待或如何不等待其他编程语言 但我似乎找不到 Perl 的正确答案 我已经阅读了相当多的内容 并
  • 超过 2^32 的枚举标志

    我在我的应用程序中使用枚举标志 枚举可以有大约 50 多个值 因此值最多为 2 50 我只是想知道我可以使用Math Pow 2 variable 来计算这些 当我尝试这样做时 我得到了恒定值编译时错误 除了手动计算 2 的幂并将其代入之外
  • 系统(“暂停”)澄清

    当我使用系统 暂停 时 屏幕上会显示一行 按任意键继续 这很令人恼火 并且使得读取输出变得相当麻烦 有什么办法可以阻止这种情况的发生吗 您的意思是想按任意键继续 但不想在屏幕上显示 按任意键继续 尝试这个getchar 这将捕获从键盘输入的
  • 如何在perl系统函数中同时使用管道并防止shell扩展?

    如果将多个参数传递给 perl 的系统函数 则 shell 扩展将不起作用 COMMAND perl e my s system echo s RESULT 如果该命令作为一个参数传递 则扩展将起作用 COMMAND perl e my s
  • LocalSystem vs. System vs. Local System Windows 系统帐户 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我对 Windows 内置帐户的 MS 文档感到完全困惑 SQL Server 2008 R2 在线文档 设置 Windows 服务帐户
  • 如何隐藏system()输出

    我正在 Windows XP 上工作 我可以通过调用自动执行 ssh 会话的 TCL 脚本 通过浏览器成功运行 system 命令 我还从脚本返回一个值 但是我的问题是脚本将整个 ssh 会话转储到浏览器中 我的 php 脚本如下所示 la
  • 使用数据库(MySql)的生产者/消费者系统,这可行吗?

    我需要使用某物协调我的系统与多个消费者 生产者 每个消费者 生产者在具有不同操作系统的不同机器上运行 我一直在研究使用 MySql 来做到这一点 但这似乎非常困难 我的要求很简单 我希望能够随时添加或删除消费者 生产者 因此他们根本不应该相
  • Delphi:系统菜单打开了吗?

    在 Delphi 中 我需要一个函数来确定系统菜单 分别是窗口菜 单 单击图标时出现的菜单 是否打开 原因是我正在编写一个反键盘记录器功能 它将垃圾发送到当前活动的编辑控件 这也阻止了键盘记录器读取 WinAPI 消息来读取内容 但是 如果
  • 如何在 OS X C 代码中创建异步计时器?

    所以这个问题实际上是 为什么 time h 在 OS X 和 Linux 上不一样 但是 我已经接受了这些分歧 为了在 Unix 系统上创建计时器 我遵循了本教程http www helsinki fi atk unix dec manua
  • 如何检测系统日期回滚?

    如何检测用户何时回滚系统日期 使用情况是为了防止规避许可 程序需要检测在未运行时发生的回滚 好吧 您可以在程序中使用嵌入式数据库 其中每隔一段时间就会插 入一个加密的系统日期 如果您发现 较新 的日期早于之前的某个日期 则可以看出有人更改了
  • 登录和会话 PHP

    我在检查会话时遇到一些问题 要访问页面 我需要激活会话 登录流程 Connect to mysql server require reservation connect php Function to sanitize values rec
  • POSIX 风格的操作系统中的命令行选项应该是下划线风格吗? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 POSIX 风格操作系统中程序的命令行选项名称是否应该是下划线风格 例如 cure world hunger 或者也许是其他风格 curewor
  • python pandas 标记如果列中每个值有多个唯一行

    在下面的数据框中 我有三列 Code Category Count X A 89734 X A 239487 Y B 298787 Z B 87980 W C 098454 我需要添加一列 如果一个类别有多个唯一代码 如上例中的 B 它会获
  • qt 读取就绪信号

    我正在尝试与运行 1996 年处理器的设备建立串行连接 这意味着数据传输回我可能需要几秒钟的时间 我知道readyRead每次有新数据可用时都会生成信号 但我的问题是生成多长时间 这也是我可以测试就绪读取是否较低的一种方法 因为如果当它们不
  • 将系统命令的结果绑定到 Haskell 中的变量

    如何在 Haskell 中运行系统命令and将其结果 即标准输出 绑定到变量 在伪 Haskell 中 我正在寻找类似以下内容的内容 import System Process main do output lt callCommand e
  • 如何使用 System.out.println 以十六进制打印字节?

    我已经声明了一个字节数组 我使用的是 Java byte test new byte 3 test 0 0x0A test 1 0xFF test 2 0x01 如何打印数组中存储的不同值 如果我使用 System out println
  • Haskell 类型系统的细微差别

    我一直在深入了解 haskell 类型系统的本质 并试图了解类型类的要点 我已经学到了很多东西 但我在下面的代码片段上遇到了困难 使用这些类和实例定义 class Show a gt C a where f Int gt a instanc
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • C# 枚举 - 根据掩码检查标志

    我有以下枚举标志 Flags private enum MemoryProtection uint None 0x000 NoAccess 0x001 ReadOnly 0x002 ReadWrite 0x004 WriteCopy 0x0

随机推荐

  • 图像配准代码(包含matlab/opencv C++)

    1 论文链接 https ieeexplore ieee org abstract document 7769090 2 gitHub源代码链接 https github com wenzelian Image Registration
  • SLAM-ch3-实践Eigen

    1 eigenMatrix cpp include lt iostream gt include lt ctime gt include lt eigen3 Eigen Core gt include lt eigen3 Eigen Den
  • ubuntu中使用VsCode+Eigen创建Eiegn应用程序

    Visual studio code是微软发布的一个运行于 Mac OS X Windows和 Linux 之上的 xff0c 针对于编写现代 Web 和云应用的跨平台源代码编辑器 1 VsCode安装 VScode官网下载 deb文件 网
  • ubuntu+VsCode+Cmake+eigen 开发eigen应用

    以下内容参见官方文档 xff1a https code visualstudio com docs cpp cmake linux 1 安装Cmake工具 点击左侧的Extensions 搜索Cmake tools 这里已经安装 2 安装C
  • 树莓派 Ubuntu mate 18.04 下开启vncserver

    1 安装 vncserver sudo apt get y install vnc4server 2 启动 vncserver xff08 首次启动需要设置密码 xff09 vncserver Ubuntu mate里面是 mate des
  • 树莓派 Ubuntu mate 18.04 修改为清华源

    1 备份源 cp etc apt sources list etc apt sources list bck 2 root身份打开 etc apt sources list 将每个 http ports ubuntu com 都替换为 ht
  • 动手学深度深度学习-pycharm中配置mxnet开发环境

    1 文件准备 1 下载包含本书全部代码的压缩包 我们可以在浏览器的地址栏中输https zh d2l ai d2l zh 1 0 zip 下载后解压 2 由于近来 2019 05 05 国内conda源被迫关闭 xff0c 因此通过cond
  • dbm和db的关系与区别

    db是无量纲单位 xff0c 它表示两个信号之间的幅度差 dbm是有量纲单位 xff0c 它表示以1毫瓦为基准时的计量单位 1 dbm dbm是一个考征功率绝对值的值 xff0c 计算公式为 xff1a 10lg10 xff08 P 1mw
  • linux.和stm32驱动的区别

    linux下的驱动和stm32驱动的区别 xff1f stm32的驱动分为2部分 xff0c 初始化和发送接收数据 xff0c 这个理论概括了spi xff0c iic xff0c uart xff0c sdio xff0c usb 在li
  • SUMO入门(四) - 需求建模 车辆和路线的定义

    SUMO入门 四 需求建模 车辆和路线的定义 Demand Introduction to demand modelling in SUMO 在生成网络之后 xff0c 可以使用SUMO GUI来查看它 xff0c 但是没有汽车可以行驶 人
  • 图像处理特征可视化方法总结(特征图、卷积核、类可视化CAM)(附代码)

    一 前言 众所周知 xff0c 深度学习是一个 34 黑盒 34 系统 它通过 end to end 的方式来工作 xff0c 输入数据例如RGB图像 xff0c 输出目标例如类别标签 回归值等 xff0c 中间过程不可得知 如何才能打开
  • deian10 安装aptitude

    debian10系统不会默认安装aptitude xff0c 导致需要处理大量依赖关系的软件安装变得很麻烦 常规的apt源可以安装aptitude xff0c 但是需要手动处理大量的依赖包安装 可以通过如下apt源使用apt get来安装a
  • DJI OSDK开发笔记(N3飞控)(1)——开发工作流程

    DJI OSDK开发笔记 xff08 N3飞控 xff09 xff08 1 xff09 开发工作流程 API层次结构硬件设置一般设置数据串口 连接器引脚排列连接到记载计算机 软件环境设置所有平台下载SDK和所需工具更新固件启用OSDK AP
  • Windows Vista 交互式服务编程

    Windows Vista 对快速用户切换 xff0c 用户账户权限 xff0c 以及服务程序所运行的会话空间都作了很大的改动 xff0c 致使一些原本可以工作的程序不再能够正常工作了 xff0c 我们不得不进行一些改进以跟上 Vista
  • Windows2000 服务器端应用程序开发设计指南-信任成员的管理

    Microsoft的开发者已经完成Microsoft Windows 2000安全性特色的设计工作 xff0c 这些安全性特色比大多数人所习惯的环境更复杂且更有弹性 事实上 xff0c 若加上适当的管理和软件开发 xff0c Windows
  • NoDriveTypeAutoRun键值的作用

    常见的Autorun inf文件格式大致如下 xff1a AutoRun 表示AutoRun部分开始 xff0c 必须输入 icon 61 C ixigua ico 指定给C盘一个个性化的盘符图标C ico open 61 C ixigua
  • Windows系统调用架构分析—也谈KiFastCallEntry函数地址的获取 .

    为什么要写这篇文章 1 因为最近在学习 软件调试 这本书 xff0c 看到书中的某个调试历程中讲了Windows 的系统调用的实现机制 xff0c 其中讲到了从Ring3 跳转到Ring0 之后直接进入了KiFastCallEntry 这个
  • ubuntu rc.local不能正常运行

    查了下rc local有时不能正常运行的原因 xff1a Ubuntu默认将 bin sh链接到 bin dash xff0c 而 etc rc local脚本中用的正是 bin sh xff0c 导致出错 将默认的shell改成bash的
  • 关于建设symbol store的建议

    xfeff xfeff 一 symbol store的需求分析 xff1a 1 我们现在的调试环境严重依赖开发人员自己使用的开发环境 xff0c 缺点在于其他人要进行调试要么搭建一个同样的环境 xff0c 严重地占去大家不必要花费的工作时间
  • 进程防结束之PS_CROSS_THREAD_FLAGS_SYSTEM

    有人投到黑防去了 xff0c 不过黑防不厚道 xff0c 竟然没给完整的代码 xff0c 自己整理一份备用吧 xff0c 驱网 DebugMan 邪八的那群人直接飘过吧 这种方法的关键在于给线程的ETHREAD CrossThreadFla