主要原理通过PsSetCreateProcessNotifyRoutine这个玩意实现
自定义数据结构用于R3,R0交互
typedef struct _CallbackInfo
{
HANDLE hParentId;
HANDLE hProcessId;
BOOLEAN bCreate;
}CALLBACK_INFO, *PCALLBACK_INFO;
驱动部分如下:
// 自定义函数的声明
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);
}
===================================
应用层代码:
int main()
{
/*
// 获取驱动驱动程序ProcDrv.sys的完整目录
// 注意,您应该将ProcDrv工程编译产生的ProcDrv.sys文件复制到当前工程目录下
char szDriverPath[256];
char szLinkName[] = "slNTProcDrv";
char* p;
::GetFullPathName("ProcDrv.sys", 256, szDriverPath, &p);
*/
char fileName[128]; //文件名
char szDriverPath[512]; //驱动文件路径
char szLinkName[128]; //设备链接名
char cfgFile[512]; //配置文件路径
int errCode=0;
GetCurrentDirectory(sizeof(cfgFile),cfgFile);
strcat(cfgFile,"\\syscfg.ini");
HANDLE tmpFileHand=CreateFileA(cfgFile,
GENERIC_READ,
FILE_SHARE_READ,
0,
OPEN_EXISTING,
FILE_FLAG_SEQUENTIAL_SCAN,
0);
if(tmpFileHand==INVALID_HANDLE_VALUE)
{
int errCode=GetLastError();
// cout<<"Open Config File Failed,Error: "<<errCode<<endl;
printf("Open Config File Failed,Error: %d",errCode);
getch();
return errCode;
}
GetPrivateProfileString("DriverPath","FileName",NULL,fileName,sizeof(fileName),cfgFile);
GetPrivateProfileString("DriverPath","DriverName",NULL,szLinkName,sizeof(szLinkName),cfgFile);
GetPrivateProfileString("DriverPath","SysFilePath",NULL,szDriverPath,sizeof(szDriverPath),cfgFile);
CloseHandle(tmpFileHand);
// 打开SCM管理器
SC_HANDLE hSCM = ::OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if(hSCM == NULL)
{
printf("Open Server Manager Failed !\n");
return -1;
}
// 创建或打开服务
SC_HANDLE hService = ::CreateService(hSCM,
szLinkName,
szLinkName,
SERVICE_ALL_ACCESS,
SERVICE_KERNEL_DRIVER,
SERVICE_DEMAND_START,
SERVICE_ERROR_NORMAL,
szDriverPath, NULL,
0,
NULL,
NULL,
NULL);
if(hService == NULL)
{
int nError = ::GetLastError();
if(nError == ERROR_SERVICE_EXISTS || nError == ERROR_SERVICE_MARKED_FOR_DELETE)
{
hService = ::OpenService(hSCM, szLinkName, SERVICE_ALL_ACCESS);
}
}
if(hService == NULL)
{
printf("Create Server Error !\n");
return -1;
}
// 启动服务
if(!::StartService(hService, 0, NULL)) // 这里调用DriverEntry例程
{
int nError = ::GetLastError();
if(nError != ERROR_SERVICE_ALREADY_RUNNING)
{
printf("Start Server Error !%d \n", nError);
return -1;
}
}
// 打开到驱动程序所控制设备的句柄
char sz[256] = {0};
wsprintf(sz, "\\\\.\\%s", szLinkName);
HANDLE hDriver = ::CreateFile(sz,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hDriver == INVALID_HANDLE_VALUE)
{
printf("Open Device Failed !\n");
return -1;
}
// 打开事件内核对象,等待驱动程序的事件通知
HANDLE hProcessEvent = ::OpenEvent(SYNCHRONIZE, FALSE, "NTProcDrvProcessEvent");
CALLBACK_INFO callbackInfo, callbackTemp = { 0 };
while(::WaitForSingleObject(hProcessEvent, INFINITE) == WAIT_OBJECT_0)
{
// 向驱动程序发送控制代码
DWORD nBytesReturn;
BOOL bRet = ::DeviceIoControl(hDriver,
IOCTL_NTPROCDRV_GET_PROCINFO,
NULL,
0,
&callbackInfo,
sizeof(callbackInfo),
&nBytesReturn,
NULL);
if(bRet)
{
if(callbackInfo.hParentId != callbackTemp.hParentId
|| callbackInfo.hProcessId != callbackTemp.hProcessId
|| callbackInfo.bCreate != callbackTemp.bCreate)
{
if(callbackInfo.bCreate)
{
printf("Create Process PID: %d \n", callbackInfo.hProcessId);
}
else
{
printf("Kill Process PID: %d \n", callbackInfo.hProcessId);
}
callbackTemp = callbackInfo;
}
// break;
}
else
{
printf(" Get Process Information Failed !\n");
break;
}
}
::CloseHandle(hDriver);
// 等待服务完全停止运行
SERVICE_STATUS ss;
::ControlService(hService, SERVICE_CONTROL_STOP, &ss);
// 从SCM数据库中删除服务
::DeleteService(hService);
::CloseServiceHandle(hService);
::CloseServiceHandle(hSCM);
return 0;
}
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法