模拟PspTerminateProcess结束进程-学习笔记

来源:互联网 发布:刚开的淘宝店怎么装修 编辑:程序博客网 时间:2024/06/03 23:01


此文是阅读黑防上胡文亮大牛《模拟实现NT系统通用PspTerminateProcess》后作为学习笔记记录下来的,仅作学习记录,理解错的请勿拍砖。和通过特征暴力搜索定位PspTerminateProcess的地址的方法相比,亮点就是模拟了实现PspTerminateProcess,PspTerminateThreadByPointer等函数。

此前先看PJF大牛的一篇《进程终止的内幕》

有来信询问进程结束的有关问题,下面就这个问题简单讨论一下(下面的讨论基于2000,其他NT系统也类似)。
    首先看看一个应用程序想要强制结束另一个进程所要做的事:首先获得目标的进程ID,接着利用OpenProcess获取进程句柄(确保足够权限),最后将句柄传给TerminateProcess了结那个进程。
    1、OpenProcess通过本机系统服务接口进入核心态,随后调用ntoskrnl的NtOpenProcess。在服务函数里,系统使用 SeSinglePrivilegeCheck检查调用者是否有DEBUG权限(SeDebugPrivilege),若有,则修改 AccessState使得在后面的操作中获取允许任意进程访问操作的句柄。最后通过ObOpenObjectByName或 PsLookupProcess*** + ObOpenObjectByPointer来打开进程(创建并返回进程句柄)。
    2、TerminateProcess通过本机系统服务接口进入核心态,随后调用ntoskrnl的NtTerminateProcess。系统首先调用 ObReferenceObjectByHandle获取进程执行体块,执行体块的DebugPort指出进程是否处于调试状态,若处于调试状态且传入的 ExitStatus为DBG_TERMINATE_PROCESS则返回失败禁止结束进程。随后服务函数转入正题:
    系统利用ThreadListHead枚举进程的每一个线程,使用PspTerminateThreadByPointer来结束它们。注意并不是对每个 线程系统都会忠实地执行你的命令:若枚举到的线程是系统线程则不会继续执行而是返回STATUS_INVALID_PARAMETER。判断的方法是线程 的Teb为零或者Teb的值在内核地址空间。有人问2000下为何csrss.exe进程杀不死,很简单,打开IceSword,在进程栏利用右键菜单的 “线程信息”看一下,看到那几个Teb为零的线程没有?(注意是针对windows2000,XP下不同。另外一点就是csrss中其它非系统线程的线程 是很容易被杀死的,试图结束csrss时也可以看到在Teb为零的线程前面的线程已被杀掉,只是操作停在了Teb为零的线程这里)再看看system进 程,呵呵。IceSword也并未提供杀除这种进程的功能,因为觉得没有需求。在最后一个线程结束时,进程的生命也结束了,随着 PspExitProcess/ObKillProcess灰飞烟灭。
    另一方面,线程是怎样结束的呢。PspTerminateThreadByPointer并不是直接“杀掉”指定线程,实质上线程是“自杀”的,呵呵。系 统简单的使用KeInitializeApc/KeInsertQueueApc插入了一个核心态的APC调用,若是用户线程,会再插入用户态的APC调 用,最终线程在自己的执行环境中使用PspExitThread(...=>KeTerminateThread=> KiSwapThread)悲壮的自行了断。
    有人问起为什么IceSword有时杀不死除那三个有系统线程的进程(两个是csrss、system,而idle是个非常奇特的存在,与众不同,这里不 多废话了)外的其它进程。从上面的讨论可以找到答案。这种情况往往是目标进程的某用户态线程进入核心态后,系统出了某些问题挂死在核心态,无法返回执行 Apc例程的缘故。IceSword未强制除去它们是考虑此刻系统可能已经有某些问题,强制删除操作更有可能使系统崩溃,不过有了不少用户要求有这项功 能,所以以后有空可能会加上(已经有一大堆杂七杂八的要求了,很难有时间升级一下版本,~_~)。
    一般来说,要干掉一个进程,有了Debug权限就可以了,若别人有了保护,那就要发挥你的能力了。

    我想上面的讨论对于想要杀除进程、保护进程的人有一些启发了吧。

有了上面的了解,就可以隐约得出一个实现PspTerminateProcess的流程,就好比要干掉一个组织,你得先从茫茫人海根据该组织人员的特征去找该组织成员,然后找到一个杀一个,直到杀光后这个组织也就完了。就是枚举出目标进程的线程,然后通过PspTerminateThreadByPointer 去结束线程。 代码如下:

PS:

模拟PspTerminateProcess 一下命名为ForceTerminateProcess

ForceTerminateThread 是模拟PspTerminateThreadByPointer 阅读时注意

[cpp] view plaincopyprint?
  1. NTSTATUS ForceTerminateProcess(PEPROCESS Process)  
  2. {  
  3.     ULONG i;  
  4.     PETHREAD txtd;  
  5.     PEPROCESS txps;  
  6.     NTSTATUS st = STATUS_UNSUCCESSFUL;  
  7.     for (i=8;i<=65536;i=i+4)  
  8.     {  
  9.         st = PsLookupThreadByThreadId(i,&txtd);  
  10.         if ( NT_SUCCESS(st) )  
  11.         {  
  12.             txps=IoThreadToProcess(txtd);  
  13.             if ( txps == Process )  
  14.             {  
  15.                 ForceTerminateThread(txtd);  
  16.             }  
  17.         }  
  18.     }  
  19.     return STATUS_SUCCESS;  
  20. }  

这个自己实现的PspTerminateProcess和原来的PspTerminateProcess有点区别。原来的PspTerminateProcess是通过PEPROCESS的hreadListHead链表来获取所有线程。这里是作者用来一个认为足够大的数字(65536)来枚举出目标进程的所有线程。理论上线程ID上限为2的32次方-1,因此在不考虑极端现象,使用足够大的数字来枚举。
其过程为:循环用{ PsLookupThreadByThreadId传入线程ID获取线程结构指针,再通过IoThreadToProcess传入线程指针结构,返回线程所属的进程指针,然后对比确定该线程属于目标进程后,调用PspTerminateThreadBypointer传入该线程结构指针,日掉它}。
如果打个比喻说上面的模拟PspTerminateProcess的作用是从茫茫人海找出组织成员的话,那么杀手就是PspTerminateThreadBypointer了(这里是ForceTerminateThread)。那么这个杀手PspTerminateThreadBypointer是怎么杀死线程的呢?再回头拜读PJF的《进程终止的内幕》可知,具体模拟代码如下:

[cpp] view plaincopyprint?
  1. NTSTATUS ForceTerminateThread(PETHREAD Thread)  
  2. {  
  3.     ULONG SYS_THREAD = 0x10;  
  4.     NTSTATUS st = STATUS_UNSUCCESSFUL;  
  5.     ULONG Size = 0;  
  6.     ULONG i = 0;  
  7.     PKAPC pApc = 0;  
  8.     if ( MmIsAddressValid((PVOID)Thread) == TRUE)//判断是否有效地址  
  9.     {  
  10.         pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));//分配内存  
  11.         //Fix Thread Type To SYSTEM THREAD  
  12.         *(PULONG)((ULONG)Thread+EToffSET)=SYS_THREAD; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280 //给CrossThreadFlags赋值  
  13.         //If APC is OK  
  14.         if (pApc)  
  15.         {  
  16.             KeInitializeApc(pApc, Thread, OriginalApcEnvironment, ApcCallBack, 0, 0, KernelMode, 0);//初始化APC  
  17.             KeInsertQueueApc(pApc, pApc, 0, 2);//插入APC队列  
  18.         }  
  19.         st = STATUS_SUCCESS;  
  20.     }  
  21.     return st;    
  22. }  


其主要实现为,用KeInitializeApc初始化APC,再用KeInsertQueueApc插入线程。APC的回调过程为:

[cpp] view plaincopyprint?
  1. VOID ApcCallBack(PKAPC Apc,PKNORMAL_ROUTINE *NormalRoutine,PVOID *NormalContext,PVOID *SystemArgument1,PVOID *SystemArgument2)  
  2. {  
  3.     ExFreePool(Apc);  
  4.     PsTerminateSystemThread(STATUS_SUCCESS);  
  5. }  

这样线程是在自己的执行环境调用PsTerminateSystemThread进行自杀了。因为PsTerminateSystemThread只能结束系统线程,而且只对当前线程有效。 因此,在初始化APC之前,我们得对线程结构的CrossThreadFlags动下手脚,这个是用来判断是否为系统线程的标志。我们将其赋值为0x10(系统线程标志常量PS_CROSS_THREAD_FLAGS_SYSTEM),这样就能让PsTerminateSystemThread以为是系统线程了。
其实现为:使用线程指针+CrossThreadFlags偏移来定位CrossThreadFlags,然后赋值。
( *(PULONG)((ULONG)Thread+EToffSET)=SYS_THREAD; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280)
这里也是唯一使用硬编码的地方。不同版本的windows系统,ETHREAD结构的CrossThreadFlags偏移不同XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280这样根据不同版本的系统选择不同的偏移量就能实现通用的PspTerminateProcess了。
作者文中的附带的驱动还实现了其它的功能,为了防止他人阅读混淆,我特地精简了一下,以及对分发函数的Control Code做了一点小改变。源码属于作者。我WInXP+WinDDK

MyKiller.c

[cpp] view plaincopyprint?
  1. //#define WINVER 0x0500 //VC6.0默认编译环境为WINVER=0x0400   
  2. #include "ntddk.h"  
  3. #include <windef.h>  
  4. #include <stdlib.h>  
  5. #include "MyKiller.h"      
  6. //#include "dbghelp.h"  
  7.   
  8. //===========================================  
  9. /* 
  10. typedef struct _KAPC_STATE  
  11. { 
  12.     LIST_ENTRY ApcListHead[2]; 
  13.     PVOID Process; 
  14.     BOOLEAN KernelApcInProgress; 
  15.     BOOLEAN KernelApcPending; 
  16.     BOOLEAN UserApcPending; 
  17. }KAPC_STATE, *PKAPC_STATE; 
  18. */  
  19. typedef enum _KAPC_ENVIRONMENT  
  20. {  
  21.     OriginalApcEnvironment,  
  22.     AttachedApcEnvironment,  
  23.     CurrentApcEnvironment,  
  24.     InsertApcEnvironment  
  25. }KAPC_ENVIRONMENT;  
  26.   
  27. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);  
  28. NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  29. NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  30. VOID DriverUnload(PDRIVER_OBJECT pDriverObj);  
  31. NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);  
  32. /* 
  33. NTKERNELAPI VOID KeAttachProcess (PEPROCESS Process); 
  34. NTKERNELAPI VOID KeDetachProcess (VOID); 
  35. */  
  36. NTKERNELAPI NTSTATUS PsLookupProcessByProcessId (IN ULONG ProcessId,OUT PEPROCESS *Process);  
  37. NTKERNELAPI NTSTATUS PsLookupThreadByThreadId (IN ULONG ThreadId,OUT PETHREAD *Thread);  
  38. NTKERNELAPI PEPROCESS IoThreadToProcess(IN PETHREAD Thread);   
  39. NTKERNELAPI BOOLEAN MmIsAddressValid(IN PVOID VirtualAddress);  
  40. NTKERNELAPI NTSTATUS PsTerminateSystemThread(IN NTSTATUS ExitStatus);  
  41. NTKERNELAPI VOID KeInitializeApc(PKAPC Apc,PETHREAD Thread,KAPC_ENVIRONMENT Environment,PKKERNEL_ROUTINE KernelRoutine,PKRUNDOWN_ROUTINE RundownRoutine,PKNORMAL_ROUTINE NormalRoutine,KPROCESSOR_MODE ProcessorMode,PVOID NormalContext);  
  42. NTKERNELAPI BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArgument1,PVOID SystemArgument2,KPRIORITY Increment);  
  43. //====================  
  44. PEPROCESS   eProcess;  
  45. ULONG       processID;  
  46. ULONG       EToffSET=0x248; //default is XP  
  47. //====================  
  48.   
  49. VOID ApcCallBack(PKAPC Apc,PKNORMAL_ROUTINE *NormalRoutine,PVOID *NormalContext,PVOID *SystemArgument1,PVOID *SystemArgument2)  
  50. {  
  51.     ExFreePool(Apc);  
  52.     PsTerminateSystemThread(STATUS_SUCCESS);  
  53. }  
  54.   
  55. NTSTATUS ForceTerminateThread(PETHREAD Thread)  
  56. {  
  57.     ULONG SYS_THREAD = 0x10;  
  58.     NTSTATUS st = STATUS_UNSUCCESSFUL;  
  59.     ULONG Size = 0;  
  60.     ULONG i = 0;  
  61.     PKAPC pApc = 0;  
  62.     if ( MmIsAddressValid((PVOID)Thread) == TRUE)  
  63.     {  
  64.         pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));  
  65.         //Fix Thread Type To SYSTEM THREAD  
  66.         *(PULONG)((ULONG)Thread+EToffSET)=SYS_THREAD; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280  
  67.         //If APC is OK  
  68.         if (pApc)  
  69.         {  
  70.             KeInitializeApc(pApc, Thread, OriginalApcEnvironment, ApcCallBack, 0, 0, KernelMode, 0);  
  71.             KeInsertQueueApc(pApc, pApc, 0, 2);  
  72.         }  
  73.         st = STATUS_SUCCESS;  
  74.     }  
  75.     return st;    
  76. }  
  77.   
  78. NTSTATUS ForceTerminateProcess(PEPROCESS Process)  
  79. {  
  80.     ULONG i;  
  81.     PETHREAD txtd;  
  82.     PEPROCESS txps;  
  83.     NTSTATUS st = STATUS_UNSUCCESSFUL;  
  84.     for (i=8;i<=65536;i=i+4)  
  85.     {  
  86.         st = PsLookupThreadByThreadId(i,&txtd);  
  87.         if ( NT_SUCCESS(st) )  
  88.         {  
  89.             txps=IoThreadToProcess(txtd);  
  90.             if ( txps == Process )  
  91.             {  
  92.                 ForceTerminateThread(txtd);  
  93.             }  
  94.         }  
  95.     }  
  96.     return STATUS_SUCCESS;  
  97. }  
  98.   
  99. NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)  
  100. {  
  101.     NTSTATUS status = STATUS_SUCCESS;  
  102.     UNICODE_STRING ustrLinkName;  
  103.     UNICODE_STRING ustrDevName;      
  104.     PDEVICE_OBJECT pDevObj;  
  105.     //dprintf("[MyKiller] DriverEntry: %S\n",pRegistryString->Buffer);  
  106.     // Create dispatch points for device control, create, close.  
  107.     pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;  
  108.     pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;  
  109.     pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;  
  110.     pDriverObj->DriverUnload = DriverUnload;  
  111.     RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);  
  112.     status = IoCreateDevice(pDriverObj,   
  113.                 0,  
  114.                 &ustrDevName,   
  115.                 FILE_DEVICE_UNKNOWN,  
  116.                 0,  
  117.                 FALSE,  
  118.                 &pDevObj);  
  119.     //dprintf("[MyKiller] Device Name %S",ustrDevName.Buffer);  
  120.     if(!NT_SUCCESS(status))  
  121.     {  
  122.         //dprintf("[MyKiller] IoCreateDevice = 0x%x\n", status);  
  123.         return status;  
  124.     }  
  125.     RtlInitUnicodeString(&ustrLinkName, LINK_NAME);  
  126.     status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);    
  127.     if(!NT_SUCCESS(status))  
  128.     {  
  129.         //dprintf("[MyKiller] IoCreateSymbolicLink = 0x%x\n", status);  
  130.         IoDeleteDevice(pDevObj);    
  131.         return status;  
  132.     }  
  133.     //dprintf("[MyKiller] SymbolicLink:%S",ustrLinkName.Buffer);  
  134.     return STATUS_SUCCESS;  
  135. }  
  136.   
  137. VOID DriverUnload(PDRIVER_OBJECT pDriverObj)  
  138. {     
  139.     UNICODE_STRING strLink;  
  140.     RtlInitUnicodeString(&strLink, LINK_NAME);  
  141.     //  
  142.     // Delete the symbolic link  
  143.     //  
  144.     IoDeleteSymbolicLink(&strLink);  
  145.     //  
  146.     // Delete the device object  
  147.     //  
  148.     IoDeleteDevice(pDriverObj->DeviceObject);  
  149.     //dprintf("[MyKiller] Unloaded\n");  
  150. }  
  151.   
  152. NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)  
  153. {  
  154.     pIrp->IoStatus.Status = STATUS_SUCCESS;  
  155.     pIrp->IoStatus.Information = 0;  
  156.     //dprintf("[MyKiller] IRP_MJ_CREATE\n");  
  157.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  158.     return STATUS_SUCCESS;  
  159. }  
  160.   
  161. NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)  
  162. {  
  163.     pIrp->IoStatus.Status = STATUS_SUCCESS;  
  164.     pIrp->IoStatus.Information = 0;  
  165.     //dprintf("[MyKiller] IRP_MJ_CLOSE\n");  
  166.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  167.     return STATUS_SUCCESS;  
  168. }  
  169.   
  170. NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)  
  171. {  
  172.     NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;  
  173.     PIO_STACK_LOCATION pIrpStack;  
  174.     ULONG uIoControlCode;  
  175.     PVOID pIoBuffer;  
  176.     ULONG uInSize;  
  177.     ULONG uOutSize;  
  178.     pIrpStack = IoGetCurrentIrpStackLocation(pIrp);  
  179.     uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;  
  180.     pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;  
  181.     uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;  
  182.     uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;  
  183.     switch(uIoControlCode)  
  184.     {  
  185.         case IOCTL_ApcKps:  
  186.             {  
  187.                 __try  
  188.                 {  
  189.                     memcpy(&processID,pIoBuffer,sizeof(processID));  
  190.                     PsLookupProcessByProcessId(processID,&eProcess);  
  191.                     ForceTerminateProcess(eProcess);  
  192.                 }  
  193.                 __except(EXCEPTION_EXECUTE_HANDLER)  
  194.                 {  
  195.                     ;  
  196.                 }  
  197.                 break;                
  198.             }  
  199.         case IOCTL_OffSet:  
  200.             {  
  201.                 __try  
  202.                 {  
  203.                     memcpy(&EToffSET,pIoBuffer,sizeof(EToffSET));  
  204.                 }  
  205.                 __except(EXCEPTION_EXECUTE_HANDLER)  
  206.                 {  
  207.                     ;  
  208.                 }  
  209.                 break;                
  210.             }  
  211.     //OVER  
  212.     }  
  213.     if(status == STATUS_SUCCESS)  
  214.         pIrp->IoStatus.Information = uOutSize;  
  215.     else  
  216.         pIrp->IoStatus.Information = 0;  
  217.   
  218.     pIrp->IoStatus.Status = status;  
  219.     IoCompleteRequest(pIrp, IO_NO_INCREMENT);  
  220.   
  221.     return status;  
  222. }  


{  MyKiller.h 头文件 }

[cpp] view plaincopyprint?
  1. #include <devioctl.h>  
  2.   
  3. #ifndef _MYKILLER_H  
  4. #define _MYKILLER_H 1  
  5. //============================================  
  6. #define DEVICE_NAME L"\\Device\\devMyKiller" //Driver Name  
  7. #define LINK_NAME L"\\DosDevices\\MyKiller"  //Link Name  
  8. //============================================  
  9. #define IOCTL_BASE  0x800  
  10.   
  11. #define MY_CTL_CODE(i) \  
  12.     CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)  
  13.   
  14. #define IOCTL_ApcKps MY_CTL_CODE(1)  
  15. #define IOCTL_OffSet MY_CTL_CODE(2)  
  16. //============================================  
  17.   
  18. #endif  


附上本人driver通讯部分Delphi源码。

[delphi] view plaincopyprint?
  1. unit uMain;  
  2.   
  3. { 
  4.    MichaelJScofield 
  5. }  
  6.   
  7. interface  
  8.   
  9. uses  
  10.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  11.   Dialogs, StdCtrls, ComCtrls, ExtCtrls;  
  12.   
  13. type  
  14.   TfrmKiller = class(TForm)  
  15.     lblInfo: TLabel;  
  16.     edtOSVersion: TEdit;  
  17.     lblPid: TLabel;  
  18.     edtPID: TEdit;  
  19.     btnKill: TButton;  
  20.     btnLoad: TButton;  
  21.     btnUnload: TButton;  
  22.     lvProcessList: TListView;  
  23.     tmrRefresh: TTimer;  
  24.     procedure btnKillClick(Sender: TObject);  
  25.     procedure btnLoadClick(Sender: TObject);  
  26.     procedure btnUnloadClick(Sender: TObject);  
  27.     procedure FormCreate(Sender: TObject);  
  28.     procedure lvProcessListSelectItem(Sender: TObject; Item: TListItem;  
  29.       Selected: Boolean);  
  30.     procedure tmrRefreshTimer(Sender: TObject);  
  31.   private  
  32.     procedure GetProcessList;  
  33.   public  
  34.     { Public declarations }  
  35.   end;  
  36.   
  37. const  
  38.   Windows_2000  = 0;  
  39.   Windows_XP    = 1;  
  40.   Windows_2003  = 2;  
  41.   Windows_Vista = 3;  
  42.   Windows_7     = 4;  
  43.   
  44. var  
  45.   frmKiller: TfrmKiller;  
  46.   function GetSystemVersion:string;  
  47.   
  48.   
  49. implementation  
  50. uses  
  51.   PsAPI,  
  52.   TlHelp32,  
  53.   WinSvc,  
  54.   PsClass,  
  55.   IoCtrl;  
  56.   
  57. var  
  58. //  svrsta: SERVICE_STATUS;  
  59.   PsDrvCtrl: TDriverControl;  
  60.   
  61. {$R *.dfm}  
  62.   
  63. { Get Windows OS Version }  
  64. { 
  65.   else if Win32Platform=VER_PLATFORM_WIN32_WINDOWS then 
  66.   begin 
  67.     if AWin32Version=4.0 then 
  68.       Result := os + '95' 
  69.     else if AWin32Version=4.1 then 
  70.       Result := os + '98' 
  71.     else if AWin32Version=4.9 then 
  72.       Result := os + 'Me' 
  73.     else 
  74.       Result := os + '9x' 
  75.   end 
  76.   else if Win32Platform = VER_PLATFORM_WIN32_NT then 
  77.   begin 
  78.     if AWin32Version=3.51 then 
  79.       Result := os + 'NT 3.51' 
  80.     else if AWin32Version=4.0 then 
  81.       Result := os + 'NT 4.0' 
  82.     else if AWin32Version=5.0 then 
  83.       Result := os + '2000' 
  84.     else if AWin32Version=5.1 then 
  85.       ShowMessage('xp系统') 
  86.     else if AWin32Version=5.2 then 
  87.       Result := os + '2003' 
  88.     else if AWin32Version=6.0 then 
  89.     begin 
  90.       ShowMessage('vista系统') 
  91.     end 
  92.     else if AWin32Version=6.1 then 
  93.       Result := os + '7' 
  94.     else 
  95.       Result := os ; 
  96.   end 
  97.   else 
  98.     Result := os + '??'; 
  99.     Result:=Result + '  '+GetWIndowsVersionString; 
  100.  
  101. }  
  102.   
  103. { 获取系统版本 }  
  104. function GetSystemVersion:string;  
  105. var  
  106.   OSVerStatus: OSVERSIONINFO;  
  107. begin  
  108.   OSVerStatus.dwOSVersionInfoSize := SizeOf(OSVerStatus);  
  109.   if GetVersionEx(OSVerStatus) then  
  110.   begin  
  111.     if OSVerStatus.dwPlatformId=VER_PLATFORM_WIN32_NT then  
  112.     begin  
  113.       if OSVerStatus.dwMajorVersion=5 then // 写死了 5.0 200 5.1 XP 5.2 2003  其它版本的就放过吧  
  114.       begin  
  115.         case OSVerStatus.dwMinorVersion of  
  116.           0:Result := 'Microsoft Windows 2000';  
  117.           1:Result := 'Microsoft Windows XP';  
  118.           2:Result := 'Microsoft Windows 2003';  
  119.         end;  
  120.       end else Result := 'Other Windows Version.';  
  121.     end;  
  122.   end else Result := 'Unknow System Version.';  
  123. end;  
  124.   
  125. { 获取windows版本 }  
  126. function GetSystemVersionID:Integer;  
  127. var  
  128.   OSVerStatus: OSVERSIONINFO;  
  129. begin  
  130.   OSVerStatus.dwOSVersionInfoSize := SizeOf(OSVerStatus);  
  131.   if GetVersionEx(OSVerStatus) then  
  132.   begin  
  133.     if OSVerStatus.dwPlatformId=VER_PLATFORM_WIN32_NT then  
  134.     begin  
  135.       if OSVerStatus.dwMajorVersion=5 then // 写死了 5.0 200 5.1 XP 5.2 2003  
  136.       begin  
  137.         Result := OSVerStatus.dwMinorVersion;  
  138.       end;  
  139.       if OSVerStatus.dwMajorVersion=6 then  //6.0 Vista 6.1 Win7  
  140.       begin  
  141.         if OSVerStatus.dwMinorVersion=0 then Result := 3;  
  142.         if OSVerStatus.dwMinorVersion=1 then Result := 4;  
  143.       end;  
  144.     end;  
  145.   end;  
  146. end;  
  147.   
  148. { 传输偏移地址 Control Code }  
  149. function IOCTL_Offset: DWORD;  
  150. begin  
  151.   Result := CTL_CODE(FILE_DEVICE_UNKNOWN,$802,METHOD_BUFFERED,FILE_ANY_ACCESS);  
  152. end;  
  153.   
  154. { 传输进程PID Control Code }  
  155. function IOCTL_PID: DWORD;  
  156. begin  
  157.   Result := CTL_CODE(FILE_DEVICE_UNKNOWN,$801,METHOD_BUFFERED,FILE_ANY_ACCESS);  
  158. end;  
  159.   
  160. { 获取进程列表 }  
  161. procedure TfrmKiller.GetProcessList;  
  162. var  
  163.   hSnapshot,hProcess,hModule: THandle;  
  164.   ProcessList: PROCESSENTRY32;  
  165.   cbNeeded: DWORD;  
  166.   PsPathBuf: array[0..MAX_PATH] of Char;  
  167. begin  
  168.   hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);  
  169.   ProcessList.dwSize := SizeOf(PROCESSENTRY32);  
  170.   if Process32First(hSnapshot,ProcessList) then  
  171.   begin  
  172.     while Process32Next(hSnapshot,ProcessList) do  
  173.     begin  
  174.       hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,  
  175.                               False,  
  176.                               ProcessList.th32ProcessID);  
  177.       if hProcess<>0 then  
  178.       begin  
  179.         if EnumProcessModules(hProcess,@hModule,SizeOf(hModule),cbNeeded) then  
  180.         begin  
  181.           ZeroMemory(@PsPathBuf,MAX_PATH+1);  
  182.           GetModuleFileNameEx(hProcess,hModule,PsPathBuf,SizeOf(PsPathBuf));  
  183.           with lvProcessList.Items.Add do  
  184.           begin  
  185.             Caption := PsPathBuf;  
  186.             SubItems.Add(IntToStr(ProcessList.th32ProcessID));  
  187.           end;  
  188.         end;  
  189.       end;  
  190.     end;  
  191.   end;  
  192.   CloseHandle(hSnapshot);  
  193.   CloseHandle(hProcess);  
  194. //  CloseHandle(hModule);  
  195. end;  
  196.   
  197. { 驱动通讯 }  
  198. procedure TfrmKiller.btnKillClick(Sender: TObject);  
  199. var  
  200.    dwProcessId,dwReturn,dwOffset: DWORD;  
  201. begin  
  202.   dwProcessId := StrToInt(Trim(edtPID.Text));  
  203.   case GetSystemVersionID of  
  204.     Windows_2000  : dwOffset := $240;    //CrossThreadFlags 硬编码  
  205.     Windows_XP    : dwOffset := $248;  
  206.     Windows_2003  : dwOffset := $240;  
  207.     Windows_Vista : dwOffset := $260;  
  208.     Windows_7     : dwOffset := $280;  
  209.   end;  
  210.   PsDrvCtrl.IoControl(IOCTL_Offset,  
  211.                       @dwOffset,  
  212.                       4,  
  213.                       @dwReturn,  
  214.                       SizeOf(DWORD));  
  215.   PsDrvCtrl.IoControl(IOCTL_PID,  
  216.                       @dwProcessId,  
  217.                       4,  
  218.                       @dwReturn,  
  219.                       SizeOf(DWORD));  
  220.                       lvProcessList.Clear;  
  221.   Sleep(1500);  
  222.   Application.ProcessMessages;  
  223.   lvProcessList.Clear;  
  224.   GetProcessList;    
  225. end;  
  226.   
  227. procedure TfrmKiller.btnLoadClick(Sender: TObject);  
  228. var  
  229.    lpFilePart: PAnsiChar;  
  230.    lpDrvPath: Array [0..255of Char;  
  231. begin  
  232.   edtOSVersion.Text := GetSystemVersion;  
  233.   GetFullPathName('MyKiller.sys'256, lpDrvPath, lpFilePart);  
  234.   PsDrvCtrl := TDriverControl.Create(lpDrvPath, 'mykiller');  
  235.   if not PsDrvCtrl.IsVaild then  
  236.   begin  
  237.     PsDrvCtrl.Free;  
  238.     ShowMessage('无法加载驱动');  
  239.     Exit;  
  240.   end;  
  241.   
  242.   if not PsDrvCtrl.StartDriver then  
  243.   begin  
  244.     PsDrvCtrl.Free;  
  245.     ShowMessage('无法启动驱动');  
  246.     Exit;  
  247.   end;  
  248.   
  249.   if not PsDrvCtrl.OpenDevice then  
  250.   begin  
  251.     PsDrvCtrl.StopDriver;  
  252.     PsDrvCtrl.Free;  
  253.     ShowMessage('无法打开驱动。');  
  254.     Exit;  
  255.   end;  
  256.   
  257.   ShowMessage('驱动已经成功启动。');  
  258.   btnUnload.Enabled := True;  
  259.   btnKill.Enabled   := True;  
  260.   btnLoad.Enabled   := False;  
  261. end;  
  262.   
  263. procedure TfrmKiller.btnUnloadClick(Sender: TObject);  
  264. begin  
  265.   PsDrvCtrl.StopDriver;  
  266.   PsDrvCtrl.Free;  
  267.   ShowMessage('驱动已经卸载成功。');  
  268.   btnUnload.Enabled := False;  
  269.   btnKill.Enabled   := False;  
  270.   btnLoad.Enabled   := True;  
  271. end;  
  272.   
  273. procedure TfrmKiller.FormCreate(Sender: TObject);  
  274. begin  
  275.   GetProcessList;  
  276. end;  
  277.   
  278. procedure TfrmKiller.lvProcessListSelectItem(Sender: TObject;  
  279.   Item: TListItem; Selected: Boolean);  
  280. begin  
  281.   edtPID.Text := Item.SubItems.Text;  
  282. end;  
  283.   
  284. procedure TfrmKiller.tmrRefreshTimer(Sender: TObject);  
  285. begin  
  286.   lvProcessList.Clear;  
  287.   GetProcessList;  
  288. end;  
  289.   
  290. end.  



0 0
原创粉丝点击