标签:没有 分配 蓝屏 应该 lazy mamicode alt disable windows
NTSTATUS PsSetCreateProcessNotifyRoutineEx(
PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,
BOOLEAN Remove
);
通过PsSetCreateProcessNotifyRoutineEx注册进程通知回调函数,函数的第一个参数传入进程通知回调函数的地址,第二个参数为FALSE表示注册回调函数,为TRUE表示卸载回调函数。
void PcreateProcessNotifyRoutineEx(
PEPROCESS Process,
HANDLE ProcessId,
PPS_CREATE_NOTIFY_INFO CreateInfo
)
上面的函数是回调函数原型,当CreateInfo为NULL时表示进程正在退出,当不为NULL则表示进程正在创建。我们可以通过为最后一个参数来的CreationStatus赋值为STATUS_UNSUCCESSFUL让进程无法创建,达到拦截指定进程的目的。
NTSTATUS PsSetCreateThreadNotifyRoutine(
PSCREATETHREADNOTIFYTYPE NotifyType,
);
通过PsSetCreateThreadNotifyRoutine注册线程通知回调函数,函数的参数传入线程通知回调函数的地址。通过PsRemoteCreateThreadNotifyRoutine来卸载回调函数。
void PcreateThreadNotifyRoutine(
HANDLE ProcessId,
HANDLE ThreadId,
BOOLEAN Create
)
上面的函数为线程通知回调函数的原型,其中Create为NULL表示线程正在退出,不为NULL表示线程正在创建。
在对线程进行拦截时要注意几个问题,我们的思路是通过找到线程的ETHREAD,通过其Win32StartAddress字段得到其线程回调函数的地址,然后向线程回调函数入口写入ret指令(0xC3),从而达到使线程直接退出拦截线程的目的。
并在源程序文件中声明函数
//去除写保护
extern "C"
VOID DisableWriteProtect(PULONG pOldAttr);
//还原写保护
extern "C"
VOID EnableWriteProtect(ULONG uOldAttr);
void KeAttachProcess(
PRKPROCESS Process
);
void KeDetachProcess();
实际上我们是无法拦截进程的主线程的,因为当explorer.exe在创建进程的主线程时,在新创建进程的地址空间中windows加载器只将PE文件的文件头映射到虚拟地址空间中并为其分配物理内存,而其余的各个区段都还没有映射到虚拟地址空间中,当然也没有为其分配物理内存,此时如果直接先主线程入口点(主线程回调函数的函数入口)处写入数据因为地址是无效的,所以会直接发生异常导致蓝屏!
我们在向用户地址空间中任意地址处写入数据时都应该向判断地址的有效性防止蓝屏。
NTKERNELAPI
BOOLEAN
MmIsAddressValid (
PVOID VirtualAddress
);
NTSTATUS PsSetLoadImageNotifyRoutine(
PLOAD_IMAGE_NOTIFY_ROUTINE NotifyRoutine
);
通过PsSetLoadImageNotifyRoutine注册模块通知回调函数,我们的思路是通过修改模块初次加载时映射到进程地址空间的PE文件头来达到拦截模块的目的。
void PloadImageNotifyRoutine(
PUNICODE_STRING FullImageName,
HANDLE ProcessId,
PIMAGE_INFO ImageInfo
)
上面的函数是模块通知回调函数的原型,其中ImageInfo参数的SystemModeImage字段为1表示加载的sys模块,为0表示加载的dll模块。
如果是sys模块我们可以通过向sys模块的入口点写入shellcode,"mov eax,0xc0000022, ret"返回拒绝访问错误码让其无法加载、。
标签:没有 分配 蓝屏 应该 lazy mamicode alt disable windows
原文地址:https://www.cnblogs.com/revercc/p/14614734.html