Name);
// 判断是否为指定进程
if (0 == _stricmp(ProcName, "lyshark.exe"))
{
// 禁止打开
CreateInfo->CreationStatus = STATUS_UNSUCCESSFUL;
}
}
else
{
strcpy_s(ProcName, 16, PsGetProcessImageFileName(Process));
DbgPrint("[LyShark] 进程[ %s ] 退出了, 程序被关闭", ProcName);
}
}
VOID UnDriver(PDRIVER_OBJECT driver)
{
DWORD32 ref = 0;
// 注销进程回调
ref = PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)My_LyShark_Com_CreateProcessNotifyEx, TRUE);
DbgPrint("[lyshark.com] 注销进程回调: %d \n", ref);
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT Driver, PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
// 绕过签名检查
// LINKER_FLAGS=/INTEGRITYCHECK
BypassCheckSign(Driver);
DbgPrint("hello lyshark.com \n");
// 创建进程回调
// 参数1: 新进程的EProcess
// 参数2: 新进程PID
// 参数3: 新进程详细信息 (仅在创建进程时有效)
status = PsSetCreateProcessNotifyRoutineEx((PCREATE_PROCESS_NOTIFY_ROUTINE_EX)My_LyShark_Com_CreateProcessNotifyEx, FALSE);
if (!NT_SUCCESS(status))
{
DbgPrint("[lyshark.com] 创建进程回调错误");
}
Driver->DriverUnload = UnDriver;
return STATUS_SUCCESS;
}
编译并运行这个驱动程序,我们可以在ARK
工具中看到这个驱动所加载的CreateProcess
的回调事件。
当驱动加载后,如果你尝试打开lyshark.exe
那么会提示连接的设备没有发挥作用,我们则成功拦截了这次打开,当然如果在打开进程之前扫描其特征并根据特征拒绝进程打开,那么就可以实现一个简单的防恶意程序,进程监控在防恶意程序中也是用的最多的。
说完了PsSetCreateProcessNotifyRoutineEx
回调的使用方式,LyShark将继续带大家看看线程监控
如何实现,监控线程创建与监控进程差不多,检测线程需要调用PsSetCreateThreadNotifyRoutine
创建回调函数,之后就可监控系统所有线程的创建,具体实现代码如下。
// 署名权
// right to sign one's name on a piece of work
// PowerBy: LyShark
// Email: me@lyshark.com
#include <ntifs.h>
// 两个未公开函数导出
NTKERNELAPI PCHAR PsGetProcessImageFileName(PEPROCESS Process);
NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE ProcessId, PEPROCESS *Process);
NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(HANDLE ThreadId, PETHREAD *Thread);
// 绕过签名检查
BOOLEAN BypassCheckSign(PDRIVER_OBJECT pDriverObject)
{
#ifdef _WIN64
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG64 __Undefined1;
ULONG64 __Undefined2;
ULONG64 __Undefined3;
ULONG64 NonPagedDebugInfo;
ULONG64 DllBase;
ULONG64 EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
USHORT LoadCount;
USHORT __Undefined5;
ULONG64 __Undefined6;
ULONG CheckSum;
ULONG __padding1;
ULONG TimeDateStamp;
ULONG __padding2;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#else
typedef struct _KLDR_DATA_TABLE_ENTRY
{
LIST_ENTRY listEntry;
ULONG unknown1;
ULONG unknown2;
ULONG unknown3;
ULONG unknown4;
ULONG unknown5;
ULONG unknown6;
ULONG unknown7;
UNICODE_STRING path;
UNICODE_STRING name;
ULONG Flags;
} KLDR_DATA_TABLE_ENTRY, *PKLDR_DATA_TABLE_ENTRY;
#endif
PKLDR_DATA_TABLE_ENTRY pLdrData = (PKLDR_DATA_TABLE_ENTRY)pDriverObject->DriverSection;
pLdrData->Flags = pLdrData->Flags | 0x20;
return TRUE;
}
// 线程回调函数
VOID MyCreateThreadNotify(HANDLE ProcessId, HANDLE ThreadId, BOOLEAN CreateInfo)
{
PEPROCESS eprocess = NULL;
PETHREAD ethread = NULL;
UCHAR *pWin32Address = NULL;
// 通过此函数拿到程序的EPROCESS结构
PsLookupProcessByProcessId(ProcessId, &eprocess);
PsLookupThreadByThreadId(ThreadId,