原本想在win10环境中通过Ring3程序调用火绒剑驱动实现关闭进程的实验,但以失败告终,火绒剑在驱动的安全保护上确实下了功夫,对驱动打开时的进程进行了验证。虽未成功实现调用驱动关闭进程的功能,但在逆向中还是学到了很多知识,总结以下,供大家批评指正。
1、ZwTerminateProcess
在Ring0层关闭进程的API是ZwTerminateProcess,逆向就从这里开始。查看官方文档,调用ZwTerminateProcess函数需要两个参数,一个是进程句柄ProcessHandle,另一个是退出状态码ExitStatus。IDA中打开驱动sysdiag_win10.sys,并在导入表Imports中查找ZwTerminateProcess。 使用交叉引用查看调用该api的情况。
2、定位用于终止进程的函数
定位到TerminateProcessById(sub_140029870)函数,功能是通过进程ID来终止进程。 继续交叉引用查看,直到找到处理DeviceIoControl的函数。 定位sub_14000C460->DispatchDeviceControl#3、驱动的派遣函数DispatchDeviceControl(sub_14000D0C0)函数是一个Windows内核驱动程序的派遣函数(Dispatch Routine),用于处理来自不同设备对象的IRP(I/O请求包)。其主要目的是根据传入的设备对象和IRP的主功能代码(MajorFunction)进行路由,执行相应的操作,如进程监控、设备控制、数据读写等,并最终完成IRP请求。Ring0与Ring3层的交互方式,一般用DeviceIoControl来控制,所以该函数就是处理驱动IO关键函数。 通过sub_14000C460可以逆向出调用终止进程功能的IO控制码为0x2200B8,驱动名称为“\.\HR::ActMon” 编写如下程序测试调用驱动,结果发现打开驱动失败。
BOOL TerminateProcessByPid(DWORD targetPid) {
wchar_t logMsg[128];
_snwprintf_s(logMsg, _countof(logMsg), _TRUNCATE, L"Attempting to terminate process with PID: %lu", targetPid);
WriteLog(logMsg);
// Correct device symbolic link (from reverse engineering)
LPCWSTR devicePath = L"\\\\.\\HR::ActMon";
HANDLE hDevice = CreateFileW(
devicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
NULL);
if (hDevice == INVALID_HANDLE_VALUE) {
DWORD err = GetLastError();
_snwprintf_s(logMsg, _countof(logMsg), _TRUNCATE, L"Failed to open device, error code: %lu", err);
WriteLog(logMsg);
return FALSE;
WriteLog(L"Device opened successfully");
// Prepare buffer (16 bytes)
DWORD64 pid64 = (DWORD64)targetPid;
memcpy(buffer, &pid64, sizeof(pid64)); // First 8 bytes for PID
DWORD bytesReturned;
BOOL result = DeviceIoControl(
hDevice,
SYSDIAG_IOCTL_TERMINATE_PROCESS,
buffer, sizeof(buffer),
buffer, sizeof(buffer),
&bytesReturned,
NULL);
if (!result) {
DWORD err = GetLastError();
_snwprintf_s(logMsg, _countof(logMsg), _TRUNCATE, L"DeviceIoControl failed, error code: %lu", err);
WriteLog(logMsg);
CloseHandle(hDevice);
return FALSE;
WriteLog(L"DeviceIoControl called successfully");
// Read return value (offset 8)
NTSTATUS status = *(DWORD*)(buffer + 8);
_snwprintf_s(logMsg, _countof(logMsg), _TRUNCATE, L"DeviceIoControl returned NTSTATUS: 0x%08lX", status);
WriteLog(logMsg);
CloseHandle(hDevice);
WriteLog(L"Device handle closed");
BOOL finalResult = result && (status == 0);
if (finalResult) {
WriteLog(L"Termination operation successful (result TRUE and status 0)");
} else {
WriteLog(L"Termination operation failed");
return finalResult;
失败的原因出在用CreateFileW打开“\.\HR::ActMon”时,驱动程序内部进行了判断。 程序通过函数FindAndReferenceNodeByKey(sub_1400297A0)查询数据,返回的结构体V10+1360的位置必须为0,否则就会返回错误码STATUS_ACCESS_DENIED(0xC0000022),所以接下来的逆向思路就是如何找到修改该地址存储数据的代码。
4、追踪结构体
驱动中结构体偏移1360(0x550)何时为0,可以通过IDA搜索立即数(Immediate value)的方式来定位。 虽然调用该偏
...(已截断)
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-290306.htm
[原创]火绒剑驱动逆向
251 浏览
3 回复
感谢分享思路.
这是在干啥ya
分析了半天才发现 无法绕过它的打开句柄验证