-
-
[原创]监控进程创建结束非HOOK方式
-
发表于: 2012-5-27 11:40 6704
-
http://bbs.pediy.com/showthread.php?t=151142
这个是回答新手区一个朋友的问题,不知道是否符合要求呢·!?
主要思想用到内核中设置事件和一个进程回调函数实现
内核代码如下:
//////////////////////////////////////////////////
// ProcDrv.cpp文件
extern "C"
{
#include<ntddk.h>
#include<ntdef.h>
#include<ntstrsafe.h>
}
#include "ProcDrv.h"
// 自定义函数的声明
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
void DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate);
// 驱动内部名称、符号连接名称、事件对象名称
#define DEVICE_NAME L"\\Device\\devNTProcDrv"
#define LINK_NAME L"\\DosDevices\\slNTProcDrv"
#define EVENT_NAME L"\\BaseNamedObjects\\NTProcDrvProcessEvent"
typedef struct _DEVICE_EXTENSION // 设备对象的私有存储
{
HANDLE hProcessHandle; // 事件对象句柄
PKEVENT ProcessEvent; // 用户和内核通信的事件对象指针
HANDLE hPParentId; // 在回调函数中保存进程信息,当用户程序请求时,传递过去
HANDLE hPProcessId;
BOOLEAN bPCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
PDEVICE_OBJECT g_pDeviceObject;
// 驱动程序加载时调用DriverEntry例程
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
// 初始化各个派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
// 创建、初始化设备对象
// 设备名称
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
// 创建设备对象
PDEVICE_OBJECT pDevObj;
status = IoCreateDevice(pDriverObj,
sizeof(DEVICE_EXTENSION), // 为设备扩展结构申请空间
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status))
{
return status;
}
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 创建符号连接名称
// 符号连接名称
UNICODE_STRING ustrLinkName;
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
// 创建关联
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
// 保存到设备对象的指针,下面在进程回调函数中还要使用
g_pDeviceObject = pDevObj;
// 为了用户模式进程能够监视,创建事件对象
UNICODE_STRING uszProcessEventString;
RtlInitUnicodeString(&uszProcessEventString, EVENT_NAME);
pDevExt->ProcessEvent = IoCreateNotificationEvent(&uszProcessEventString, &pDevExt->hProcessHandle);
// 设置它为非受信状态
KeClearEvent(pDevExt->ProcessEvent);
// 设置回调例程
status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
return status;
}
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
DbgPrint("Driver Unload\n");
// 移除进程回调例程
PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
// 删除符号连接名称
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
// 删除设备对象
IoDeleteDevice(pDriverObj->DeviceObject);
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 完成此请求
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint(" ProcDrv: DispatchIoctl()... \n");
// 假设失败
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
// 取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 取得设备扩展结构指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 取得I/O控制代码
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O缓冲区指针和它的长度
PCALLBACK_INFO pCallbackInfo = (PCALLBACK_INFO)pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_NTPROCDRV_GET_PROCINFO: // 向用户程序返回有事件发生的进程的信息
{
if(uOutSize >= sizeof(CALLBACK_INFO))
{
pCallbackInfo->hParentId = pDevExt->hPParentId;
pCallbackInfo->hProcessId = pDevExt->hPProcessId;
pCallbackInfo->bCreate = pDevExt->bPCreate;
status = STATUS_SUCCESS;
}
}
break;
}
if(status == STATUS_SUCCESS)
{
pIrp->IoStatus.Information = uOutSize;
}
else
{
pIrp->IoStatus.Information = 0;
}
// 完成请求
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
// 进程回调函数
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate)
{
DbgPrint("Call ProcessCallback()\n");
// 得到设备扩展结构的指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
// 安排当前值到设备扩展结构
// 用户模式应用程序将使用DeviceIoControl调用把它取出
pDevExt->hPParentId = hParentId;
pDevExt->hPProcessId = hProcessId;
pDevExt->bPCreate = bCreate;
if(pDevExt->bPCreate)
{
DbgPrint("create: %d\n",pDevExt->hPProcessId);
}
else
{
DbgPrint("Kill: %d\n",pDevExt->hPProcessId);
}
// 触发这个事件,以便任何正在监听的用户程序知道有事情发生了。
// 用户模式下的应用程序不能重置KM事件,所以我们要在这里触发它
KeSetEvent(pDevExt->ProcessEvent, 0, FALSE);
KeClearEvent(pDevExt->ProcessEvent);
}
详细代码见附件
这个是回答新手区一个朋友的问题,不知道是否符合要求呢·!?
主要思想用到内核中设置事件和一个进程回调函数实现
内核代码如下:
//////////////////////////////////////////////////
// ProcDrv.cpp文件
extern "C"
{
#include<ntddk.h>
#include<ntdef.h>
#include<ntstrsafe.h>
}
#include "ProcDrv.h"
// 自定义函数的声明
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp);
void DriverUnload(PDRIVER_OBJECT pDriverObj);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp);
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate);
// 驱动内部名称、符号连接名称、事件对象名称
#define DEVICE_NAME L"\\Device\\devNTProcDrv"
#define LINK_NAME L"\\DosDevices\\slNTProcDrv"
#define EVENT_NAME L"\\BaseNamedObjects\\NTProcDrvProcessEvent"
typedef struct _DEVICE_EXTENSION // 设备对象的私有存储
{
HANDLE hProcessHandle; // 事件对象句柄
PKEVENT ProcessEvent; // 用户和内核通信的事件对象指针
HANDLE hPParentId; // 在回调函数中保存进程信息,当用户程序请求时,传递过去
HANDLE hPProcessId;
BOOLEAN bPCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
PDEVICE_OBJECT g_pDeviceObject;
// 驱动程序加载时调用DriverEntry例程
extern "C" NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
NTSTATUS status = STATUS_SUCCESS;
// 初始化各个派遣例程
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
// 创建、初始化设备对象
// 设备名称
UNICODE_STRING ustrDevName;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
// 创建设备对象
PDEVICE_OBJECT pDevObj;
status = IoCreateDevice(pDriverObj,
sizeof(DEVICE_EXTENSION), // 为设备扩展结构申请空间
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status))
{
return status;
}
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 创建符号连接名称
// 符号连接名称
UNICODE_STRING ustrLinkName;
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
// 创建关联
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status))
{
IoDeleteDevice(pDevObj);
return status;
}
// 保存到设备对象的指针,下面在进程回调函数中还要使用
g_pDeviceObject = pDevObj;
// 为了用户模式进程能够监视,创建事件对象
UNICODE_STRING uszProcessEventString;
RtlInitUnicodeString(&uszProcessEventString, EVENT_NAME);
pDevExt->ProcessEvent = IoCreateNotificationEvent(&uszProcessEventString, &pDevExt->hProcessHandle);
// 设置它为非受信状态
KeClearEvent(pDevExt->ProcessEvent);
// 设置回调例程
status = PsSetCreateProcessNotifyRoutine(ProcessCallback, FALSE);
return status;
}
void DriverUnload(PDRIVER_OBJECT pDriverObj)
{
DbgPrint("Driver Unload\n");
// 移除进程回调例程
PsSetCreateProcessNotifyRoutine(ProcessCallback, TRUE);
// 删除符号连接名称
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
IoDeleteSymbolicLink(&strLink);
// 删除设备对象
IoDeleteDevice(pDriverObj->DeviceObject);
}
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreateClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
// 完成此请求
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
DbgPrint(" ProcDrv: DispatchIoctl()... \n");
// 假设失败
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
// 取得此IRP(pIrp)的I/O堆栈指针
PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
// 取得设备扩展结构指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
// 取得I/O控制代码
ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
// 取得I/O缓冲区指针和它的长度
PCALLBACK_INFO pCallbackInfo = (PCALLBACK_INFO)pIrp->AssociatedIrp.SystemBuffer;
ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode)
{
case IOCTL_NTPROCDRV_GET_PROCINFO: // 向用户程序返回有事件发生的进程的信息
{
if(uOutSize >= sizeof(CALLBACK_INFO))
{
pCallbackInfo->hParentId = pDevExt->hPParentId;
pCallbackInfo->hProcessId = pDevExt->hPProcessId;
pCallbackInfo->bCreate = pDevExt->bPCreate;
status = STATUS_SUCCESS;
}
}
break;
}
if(status == STATUS_SUCCESS)
{
pIrp->IoStatus.Information = uOutSize;
}
else
{
pIrp->IoStatus.Information = 0;
}
// 完成请求
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
// 进程回调函数
VOID ProcessCallback(IN HANDLE hParentId, IN HANDLE hProcessId, IN BOOLEAN bCreate)
{
DbgPrint("Call ProcessCallback()\n");
// 得到设备扩展结构的指针
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)g_pDeviceObject->DeviceExtension;
// 安排当前值到设备扩展结构
// 用户模式应用程序将使用DeviceIoControl调用把它取出
pDevExt->hPParentId = hParentId;
pDevExt->hPProcessId = hProcessId;
pDevExt->bPCreate = bCreate;
if(pDevExt->bPCreate)
{
DbgPrint("create: %d\n",pDevExt->hPProcessId);
}
else
{
DbgPrint("Kill: %d\n",pDevExt->hPProcessId);
}
// 触发这个事件,以便任何正在监听的用户程序知道有事情发生了。
// 用户模式下的应用程序不能重置KM事件,所以我们要在这里触发它
KeSetEvent(pDevExt->ProcessEvent, 0, FALSE);
KeClearEvent(pDevExt->ProcessEvent);
}
详细代码见附件
赞赏记录
参与人
雪币
留言
时间
伟叔叔
为你点赞~
2024-5-31 04:54
心游尘世外
为你点赞~
2024-5-31 01:38
QinBeast
为你点赞~
2024-5-31 01:29
飘零丶
为你点赞~
2024-3-28 02:49
shinratensei
为你点赞~
2024-1-30 00:11
一笑人间万事
为你点赞~
2023-3-7 00:43
赞赏
他的文章
谁下载
kanxue
mudropmu
DoorKey
haoshuaioo
hchzdh
拍拖
sisess
gx_sz
woyaozhuce
蓝色光芒
lovenuo
惊电
ttstation
yjd
mowenli
lendy
heretic
小龙人
dico
owuei
yyqkxxy
tangchaogg
luohb
dwbclz
Winker
xicao
小子贼野
ycdear
creakerzgz
lhlzy
netdisk
Sacredfy
haohaook
jasonnbfan
coolwxd
zbzb
云天海
zenix
疯子
xiejienet
dahubaobao
lcc点滴
黑小杰
cmdxhz
bakurise
tfzxyinhao
stonerhes
lylxd
DENGXINSD
CuteMiyu
jnsh无锡
jordonA
leivn
zcmmwbd
correy
rst
yuxx
bathack
狐狸先生
liangdong
murrackde
shilyx
未签收
七夜血
leeone
sssccc
yeliangang
囧囧
woaisx
yunfansky
chzxp
愚公
asdfslw
xiamisun
smilediy
狂起来
tiany
cttnbcj
linziqingl
kangcin
longloo
菜鸟工程
langyashan
wuaiwu
残梦飘雪
MyBoy
小华子
guxinyi
justto
DuoLaMMeng
注册好男
porange
starrysky
艾米
feifeixiao
wwwzhigang
lovehuaibb
syh逍遥游
ConanAI
谁下载
mudropmu
cqzj70
yhtchf
卫斯理
dico
tangchaogg
luohb
Winker
vihp
Sacredfy
啤酒肚
黑色破刀
sertty
coolwxd
ficn
qqqqfcu
xiejienet
shangde
dongfangho
vipsehll
未签收
ezhimeng
狂起来
langyashan
tannaiwei
wwwzhigang
wrbcn
zhuruinan
MRHuang
Liggle
fullgamer
zyqqyz
gaollxu
pooiy
autojie
yzxdev
dkm
勾起
何健hj
usechar
rqqeq
hack残心
huntime
谢灬向
圜长
爱吃鱼
cmheia
lvbenke
吴氏小豆
AIcx
xiaoyao骏马
baileidmm
TheBlank
qqqaa
Addictions
安管平台
jameszz
北山
geeksf
xiaoxiaoxiao
月明人依楼
WAK47
看原图
赞赏
雪币:
留言: