模拟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 阅读时注意
- NTSTATUS ForceTerminateProcess(PEPROCESS Process)
- {
- ULONG i;
- PETHREAD txtd;
- PEPROCESS txps;
- NTSTATUS st = STATUS_UNSUCCESSFUL;
- for (i=8;i<=65536;i=i+4)
- {
- st = PsLookupThreadByThreadId(i,&txtd);
- if ( NT_SUCCESS(st) )
- {
- txps=IoThreadToProcess(txtd);
- if ( txps == Process )
- {
- ForceTerminateThread(txtd);
- }
- }
- }
- return STATUS_SUCCESS;
- }
这个自己实现的PspTerminateProcess和原来的PspTerminateProcess有点区别。原来的PspTerminateProcess是通过PEPROCESS的hreadListHead链表来获取所有线程。这里是作者用来一个认为足够大的数字(65536)来枚举出目标进程的所有线程。理论上线程ID上限为2的32次方-1,因此在不考虑极端现象,使用足够大的数字来枚举。
其过程为:循环用{ PsLookupThreadByThreadId传入线程ID获取线程结构指针,再通过IoThreadToProcess传入线程指针结构,返回线程所属的进程指针,然后对比确定该线程属于目标进程后,调用PspTerminateThreadBypointer传入该线程结构指针,日掉它}。
如果打个比喻说上面的模拟PspTerminateProcess的作用是从茫茫人海找出组织成员的话,那么杀手就是PspTerminateThreadBypointer了(这里是ForceTerminateThread)。那么这个杀手PspTerminateThreadBypointer是怎么杀死线程的呢?再回头拜读PJF的《进程终止的内幕》可知,具体模拟代码如下:
- NTSTATUS ForceTerminateThread(PETHREAD Thread)
- {
- ULONG SYS_THREAD = 0x10;
- NTSTATUS st = STATUS_UNSUCCESSFUL;
- ULONG Size = 0;
- ULONG i = 0;
- PKAPC pApc = 0;
- if ( MmIsAddressValid((PVOID)Thread) == TRUE)//判断是否有效地址
- {
- pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));//分配内存
- //Fix Thread Type To SYSTEM THREAD
- *(PULONG)((ULONG)Thread+EToffSET)=SYS_THREAD; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280 //给CrossThreadFlags赋值
- //If APC is OK
- if (pApc)
- {
- KeInitializeApc(pApc, Thread, OriginalApcEnvironment, ApcCallBack, 0, 0, KernelMode, 0);//初始化APC
- KeInsertQueueApc(pApc, pApc, 0, 2);//插入APC队列
- }
- st = STATUS_SUCCESS;
- }
- return st;
- }
其主要实现为,用KeInitializeApc初始化APC,再用KeInsertQueueApc插入线程。APC的回调过程为:
- VOID ApcCallBack(PKAPC Apc,PKNORMAL_ROUTINE *NormalRoutine,PVOID *NormalContext,PVOID *SystemArgument1,PVOID *SystemArgument2)
- {
- ExFreePool(Apc);
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
这样线程是在自己的执行环境调用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
- //#define WINVER 0x0500 //VC6.0默认编译环境为WINVER=0x0400
- #include "ntddk.h"
- #include <windef.h>
- #include <stdlib.h>
- #include "MyKiller.h"
- //#include "dbghelp.h"
- //===========================================
- /*
- typedef struct _KAPC_STATE
- {
- LIST_ENTRY ApcListHead[2];
- PVOID Process;
- BOOLEAN KernelApcInProgress;
- BOOLEAN KernelApcPending;
- BOOLEAN UserApcPending;
- }KAPC_STATE, *PKAPC_STATE;
- */
- typedef enum _KAPC_ENVIRONMENT
- {
- OriginalApcEnvironment,
- AttachedApcEnvironment,
- CurrentApcEnvironment,
- InsertApcEnvironment
- }KAPC_ENVIRONMENT;
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString);
- NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- VOID DriverUnload(PDRIVER_OBJECT pDriverObj);
- NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
- /*
- NTKERNELAPI VOID KeAttachProcess (PEPROCESS Process);
- NTKERNELAPI VOID KeDetachProcess (VOID);
- */
- NTKERNELAPI NTSTATUS PsLookupProcessByProcessId (IN ULONG ProcessId,OUT PEPROCESS *Process);
- NTKERNELAPI NTSTATUS PsLookupThreadByThreadId (IN ULONG ThreadId,OUT PETHREAD *Thread);
- NTKERNELAPI PEPROCESS IoThreadToProcess(IN PETHREAD Thread);
- NTKERNELAPI BOOLEAN MmIsAddressValid(IN PVOID VirtualAddress);
- NTKERNELAPI NTSTATUS PsTerminateSystemThread(IN NTSTATUS ExitStatus);
- NTKERNELAPI VOID KeInitializeApc(PKAPC Apc,PETHREAD Thread,KAPC_ENVIRONMENT Environment,PKKERNEL_ROUTINE KernelRoutine,PKRUNDOWN_ROUTINE RundownRoutine,PKNORMAL_ROUTINE NormalRoutine,KPROCESSOR_MODE ProcessorMode,PVOID NormalContext);
- NTKERNELAPI BOOLEAN KeInsertQueueApc(PKAPC Apc,PVOID SystemArgument1,PVOID SystemArgument2,KPRIORITY Increment);
- //====================
- PEPROCESS eProcess;
- ULONG processID;
- ULONG EToffSET=0x248; //default is XP
- //====================
- VOID ApcCallBack(PKAPC Apc,PKNORMAL_ROUTINE *NormalRoutine,PVOID *NormalContext,PVOID *SystemArgument1,PVOID *SystemArgument2)
- {
- ExFreePool(Apc);
- PsTerminateSystemThread(STATUS_SUCCESS);
- }
- NTSTATUS ForceTerminateThread(PETHREAD Thread)
- {
- ULONG SYS_THREAD = 0x10;
- NTSTATUS st = STATUS_UNSUCCESSFUL;
- ULONG Size = 0;
- ULONG i = 0;
- PKAPC pApc = 0;
- if ( MmIsAddressValid((PVOID)Thread) == TRUE)
- {
- pApc = ExAllocatePool(NonPagedPool, sizeof(KAPC));
- //Fix Thread Type To SYSTEM THREAD
- *(PULONG)((ULONG)Thread+EToffSET)=SYS_THREAD; //XP=0x248, 2K3=0x240, VISTA+2k8=0x260, Win7=0x280
- //If APC is OK
- if (pApc)
- {
- KeInitializeApc(pApc, Thread, OriginalApcEnvironment, ApcCallBack, 0, 0, KernelMode, 0);
- KeInsertQueueApc(pApc, pApc, 0, 2);
- }
- st = STATUS_SUCCESS;
- }
- return st;
- }
- NTSTATUS ForceTerminateProcess(PEPROCESS Process)
- {
- ULONG i;
- PETHREAD txtd;
- PEPROCESS txps;
- NTSTATUS st = STATUS_UNSUCCESSFUL;
- for (i=8;i<=65536;i=i+4)
- {
- st = PsLookupThreadByThreadId(i,&txtd);
- if ( NT_SUCCESS(st) )
- {
- txps=IoThreadToProcess(txtd);
- if ( txps == Process )
- {
- ForceTerminateThread(txtd);
- }
- }
- }
- return STATUS_SUCCESS;
- }
- NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
- {
- NTSTATUS status = STATUS_SUCCESS;
- UNICODE_STRING ustrLinkName;
- UNICODE_STRING ustrDevName;
- PDEVICE_OBJECT pDevObj;
- //dprintf("[MyKiller] DriverEntry: %S\n",pRegistryString->Buffer);
- // Create dispatch points for device control, create, close.
- pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
- pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
- pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
- pDriverObj->DriverUnload = DriverUnload;
- RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
- status = IoCreateDevice(pDriverObj,
- 0,
- &ustrDevName,
- FILE_DEVICE_UNKNOWN,
- 0,
- FALSE,
- &pDevObj);
- //dprintf("[MyKiller] Device Name %S",ustrDevName.Buffer);
- if(!NT_SUCCESS(status))
- {
- //dprintf("[MyKiller] IoCreateDevice = 0x%x\n", status);
- return status;
- }
- RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
- status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
- if(!NT_SUCCESS(status))
- {
- //dprintf("[MyKiller] IoCreateSymbolicLink = 0x%x\n", status);
- IoDeleteDevice(pDevObj);
- return status;
- }
- //dprintf("[MyKiller] SymbolicLink:%S",ustrLinkName.Buffer);
- return STATUS_SUCCESS;
- }
- VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
- {
- UNICODE_STRING strLink;
- RtlInitUnicodeString(&strLink, LINK_NAME);
- //
- // Delete the symbolic link
- //
- IoDeleteSymbolicLink(&strLink);
- //
- // Delete the device object
- //
- IoDeleteDevice(pDriverObj->DeviceObject);
- //dprintf("[MyKiller] Unloaded\n");
- }
- NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- //dprintf("[MyKiller] IRP_MJ_CREATE\n");
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
- {
- pIrp->IoStatus.Status = STATUS_SUCCESS;
- pIrp->IoStatus.Information = 0;
- //dprintf("[MyKiller] IRP_MJ_CLOSE\n");
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return STATUS_SUCCESS;
- }
- NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
- {
- NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
- PIO_STACK_LOCATION pIrpStack;
- ULONG uIoControlCode;
- PVOID pIoBuffer;
- ULONG uInSize;
- ULONG uOutSize;
- pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
- uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
- pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
- uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
- uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
- switch(uIoControlCode)
- {
- case IOCTL_ApcKps:
- {
- __try
- {
- memcpy(&processID,pIoBuffer,sizeof(processID));
- PsLookupProcessByProcessId(processID,&eProcess);
- ForceTerminateProcess(eProcess);
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- break;
- }
- case IOCTL_OffSet:
- {
- __try
- {
- memcpy(&EToffSET,pIoBuffer,sizeof(EToffSET));
- }
- __except(EXCEPTION_EXECUTE_HANDLER)
- {
- ;
- }
- break;
- }
- //OVER
- }
- if(status == STATUS_SUCCESS)
- pIrp->IoStatus.Information = uOutSize;
- else
- pIrp->IoStatus.Information = 0;
- pIrp->IoStatus.Status = status;
- IoCompleteRequest(pIrp, IO_NO_INCREMENT);
- return status;
- }
{ MyKiller.h 头文件 }
- #include <devioctl.h>
- #ifndef _MYKILLER_H
- #define _MYKILLER_H 1
- //============================================
- #define DEVICE_NAME L"\\Device\\devMyKiller" //Driver Name
- #define LINK_NAME L"\\DosDevices\\MyKiller" //Link Name
- //============================================
- #define IOCTL_BASE 0x800
- #define MY_CTL_CODE(i) \
- CTL_CODE(FILE_DEVICE_UNKNOWN, IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)
- #define IOCTL_ApcKps MY_CTL_CODE(1)
- #define IOCTL_OffSet MY_CTL_CODE(2)
- //============================================
- #endif
附上本人driver通讯部分Delphi源码。
- unit uMain;
- {
- MichaelJScofield
- }
- interface
- uses
- Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
- Dialogs, StdCtrls, ComCtrls, ExtCtrls;
- type
- TfrmKiller = class(TForm)
- lblInfo: TLabel;
- edtOSVersion: TEdit;
- lblPid: TLabel;
- edtPID: TEdit;
- btnKill: TButton;
- btnLoad: TButton;
- btnUnload: TButton;
- lvProcessList: TListView;
- tmrRefresh: TTimer;
- procedure btnKillClick(Sender: TObject);
- procedure btnLoadClick(Sender: TObject);
- procedure btnUnloadClick(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure lvProcessListSelectItem(Sender: TObject; Item: TListItem;
- Selected: Boolean);
- procedure tmrRefreshTimer(Sender: TObject);
- private
- procedure GetProcessList;
- public
- { Public declarations }
- end;
- const
- Windows_2000 = 0;
- Windows_XP = 1;
- Windows_2003 = 2;
- Windows_Vista = 3;
- Windows_7 = 4;
- var
- frmKiller: TfrmKiller;
- function GetSystemVersion:string;
- implementation
- uses
- PsAPI,
- TlHelp32,
- WinSvc,
- PsClass,
- IoCtrl;
- var
- // svrsta: SERVICE_STATUS;
- PsDrvCtrl: TDriverControl;
- {$R *.dfm}
- { Get Windows OS Version }
- {
- else if Win32Platform=VER_PLATFORM_WIN32_WINDOWS then
- begin
- if AWin32Version=4.0 then
- Result := os + '95'
- else if AWin32Version=4.1 then
- Result := os + '98'
- else if AWin32Version=4.9 then
- Result := os + 'Me'
- else
- Result := os + '9x'
- end
- else if Win32Platform = VER_PLATFORM_WIN32_NT then
- begin
- if AWin32Version=3.51 then
- Result := os + 'NT 3.51'
- else if AWin32Version=4.0 then
- Result := os + 'NT 4.0'
- else if AWin32Version=5.0 then
- Result := os + '2000'
- else if AWin32Version=5.1 then
- ShowMessage('xp系统')
- else if AWin32Version=5.2 then
- Result := os + '2003'
- else if AWin32Version=6.0 then
- begin
- ShowMessage('vista系统')
- end
- else if AWin32Version=6.1 then
- Result := os + '7'
- else
- Result := os ;
- end
- else
- Result := os + '??';
- Result:=Result + ' '+GetWIndowsVersionString;
- }
- { 获取系统版本 }
- function GetSystemVersion:string;
- var
- OSVerStatus: OSVERSIONINFO;
- begin
- OSVerStatus.dwOSVersionInfoSize := SizeOf(OSVerStatus);
- if GetVersionEx(OSVerStatus) then
- begin
- if OSVerStatus.dwPlatformId=VER_PLATFORM_WIN32_NT then
- begin
- if OSVerStatus.dwMajorVersion=5 then // 写死了 5.0 200 5.1 XP 5.2 2003 其它版本的就放过吧
- begin
- case OSVerStatus.dwMinorVersion of
- 0:Result := 'Microsoft Windows 2000';
- 1:Result := 'Microsoft Windows XP';
- 2:Result := 'Microsoft Windows 2003';
- end;
- end else Result := 'Other Windows Version.';
- end;
- end else Result := 'Unknow System Version.';
- end;
- { 获取windows版本 }
- function GetSystemVersionID:Integer;
- var
- OSVerStatus: OSVERSIONINFO;
- begin
- OSVerStatus.dwOSVersionInfoSize := SizeOf(OSVerStatus);
- if GetVersionEx(OSVerStatus) then
- begin
- if OSVerStatus.dwPlatformId=VER_PLATFORM_WIN32_NT then
- begin
- if OSVerStatus.dwMajorVersion=5 then // 写死了 5.0 200 5.1 XP 5.2 2003
- begin
- Result := OSVerStatus.dwMinorVersion;
- end;
- if OSVerStatus.dwMajorVersion=6 then //6.0 Vista 6.1 Win7
- begin
- if OSVerStatus.dwMinorVersion=0 then Result := 3;
- if OSVerStatus.dwMinorVersion=1 then Result := 4;
- end;
- end;
- end;
- end;
- { 传输偏移地址 Control Code }
- function IOCTL_Offset: DWORD;
- begin
- Result := CTL_CODE(FILE_DEVICE_UNKNOWN,$802,METHOD_BUFFERED,FILE_ANY_ACCESS);
- end;
- { 传输进程PID Control Code }
- function IOCTL_PID: DWORD;
- begin
- Result := CTL_CODE(FILE_DEVICE_UNKNOWN,$801,METHOD_BUFFERED,FILE_ANY_ACCESS);
- end;
- { 获取进程列表 }
- procedure TfrmKiller.GetProcessList;
- var
- hSnapshot,hProcess,hModule: THandle;
- ProcessList: PROCESSENTRY32;
- cbNeeded: DWORD;
- PsPathBuf: array[0..MAX_PATH] of Char;
- begin
- hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
- ProcessList.dwSize := SizeOf(PROCESSENTRY32);
- if Process32First(hSnapshot,ProcessList) then
- begin
- while Process32Next(hSnapshot,ProcessList) do
- begin
- hProcess := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
- False,
- ProcessList.th32ProcessID);
- if hProcess<>0 then
- begin
- if EnumProcessModules(hProcess,@hModule,SizeOf(hModule),cbNeeded) then
- begin
- ZeroMemory(@PsPathBuf,MAX_PATH+1);
- GetModuleFileNameEx(hProcess,hModule,PsPathBuf,SizeOf(PsPathBuf));
- with lvProcessList.Items.Add do
- begin
- Caption := PsPathBuf;
- SubItems.Add(IntToStr(ProcessList.th32ProcessID));
- end;
- end;
- end;
- end;
- end;
- CloseHandle(hSnapshot);
- CloseHandle(hProcess);
- // CloseHandle(hModule);
- end;
- { 驱动通讯 }
- procedure TfrmKiller.btnKillClick(Sender: TObject);
- var
- dwProcessId,dwReturn,dwOffset: DWORD;
- begin
- dwProcessId := StrToInt(Trim(edtPID.Text));
- case GetSystemVersionID of
- Windows_2000 : dwOffset := $240; //CrossThreadFlags 硬编码
- Windows_XP : dwOffset := $248;
- Windows_2003 : dwOffset := $240;
- Windows_Vista : dwOffset := $260;
- Windows_7 : dwOffset := $280;
- end;
- PsDrvCtrl.IoControl(IOCTL_Offset,
- @dwOffset,
- 4,
- @dwReturn,
- SizeOf(DWORD));
- PsDrvCtrl.IoControl(IOCTL_PID,
- @dwProcessId,
- 4,
- @dwReturn,
- SizeOf(DWORD));
- lvProcessList.Clear;
- Sleep(1500);
- Application.ProcessMessages;
- lvProcessList.Clear;
- GetProcessList;
- end;
- procedure TfrmKiller.btnLoadClick(Sender: TObject);
- var
- lpFilePart: PAnsiChar;
- lpDrvPath: Array [0..255] of Char;
- begin
- edtOSVersion.Text := GetSystemVersion;
- GetFullPathName('MyKiller.sys', 256, lpDrvPath, lpFilePart);
- PsDrvCtrl := TDriverControl.Create(lpDrvPath, 'mykiller');
- if not PsDrvCtrl.IsVaild then
- begin
- PsDrvCtrl.Free;
- ShowMessage('无法加载驱动');
- Exit;
- end;
- if not PsDrvCtrl.StartDriver then
- begin
- PsDrvCtrl.Free;
- ShowMessage('无法启动驱动');
- Exit;
- end;
- if not PsDrvCtrl.OpenDevice then
- begin
- PsDrvCtrl.StopDriver;
- PsDrvCtrl.Free;
- ShowMessage('无法打开驱动。');
- Exit;
- end;
- ShowMessage('驱动已经成功启动。');
- btnUnload.Enabled := True;
- btnKill.Enabled := True;
- btnLoad.Enabled := False;
- end;
- procedure TfrmKiller.btnUnloadClick(Sender: TObject);
- begin
- PsDrvCtrl.StopDriver;
- PsDrvCtrl.Free;
- ShowMessage('驱动已经卸载成功。');
- btnUnload.Enabled := False;
- btnKill.Enabled := False;
- btnLoad.Enabled := True;
- end;
- procedure TfrmKiller.FormCreate(Sender: TObject);
- begin
- GetProcessList;
- end;
- procedure TfrmKiller.lvProcessListSelectItem(Sender: TObject;
- Item: TListItem; Selected: Boolean);
- begin
- edtPID.Text := Item.SubItems.Text;
- end;
- procedure TfrmKiller.tmrRefreshTimer(Sender: TObject);
- begin
- lvProcessList.Clear;
- GetProcessList;
- end;
- end.
- 模拟PspTerminateProcess结束进程-学习笔记
- 模拟PspTerminateProcess结束进程-学习笔记
- PspTerminateProcess 结束冰刃进程
- PspTerminateProcess 结束冰刃进程
- windows API学习笔记 之 结束进程
- Android学习 - 如何结束进程
- JQuery学习结束笔记
- 【MFC】根据进程名结束进程学习
- 发送模拟按键&&由进程名结束进程
- 学习RING3 内存清零结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- 结束进程
- ubuntu 10.10 添加系统调用的方法
- 分布式Hadoop安装入门(2)——免密码SSH
- 022 数组初始化
- cx_oracle ImportError: DLL load failed: 找不到指定的程序
- App推广中,我是怎么铺渠道的
- 模拟PspTerminateProcess结束进程-学习笔记
- [技术讨论]可度量绩效管理模型初始化阶段实施
- HDU-圆桌会议问题
- Java和C/C++进行DES/AES密文传输
- clover分布式任务调度系统
- php中的魔术方法
- Linux 技巧:让进程在后台可靠运行的几种方法
- 转载: Linux伙伴系统(一)--伙伴系统的概述
- 教你写Android网络框架之基本架构