admin 发表于 2023-4-13 11:40:46

C,C++ 驱动开发 隐藏进程 保护进程

根据网上资料和个人总结,进程隐藏主要有如下几种方法:
1、调用RegisterServiceProcess函数
2、HOOK ZwQuerySystemInformation(通过修改内核ntoskrnl的服务表结构体KeServiceDescriptorTable,计算机出ZwQuerySystemInformation的地址,
然后替换成自己的MyZwQuerySystemInformation,然后断掉过滤要隐藏的进程名.)
3、DKOM摘链(按照进程的ID找到进程的EPROCESS然后将样隐藏的进程的EPROCESS在链表中移除)
4、用Detour Patching来修改NtQuerySystemInformation函数
5、远程线程注入,提权注入到系统服务进程
6、无驱动进入ring0,再在ring0下修改内核对象实现隐藏
7、通过驱动加载.(通过用户空间程序获的进程ID,EPROCESS块 中FLINK和 PID的偏移量 ,传送给驱动程序,驱动程序修改链表隐藏进程。)


typedef struct _IMAGE_INFO {
union {
    ULONG Properties;
    struct {
      ULONG ImageAddressingMode : 8;
      ULONG SystemModeImage : 1;
      ULONG ImageMappedToAllPids : 1;
      ULONG ExtendedInfoPresent : 1;
      ULONG MachineTypeMismatch : 1;
      ULONG ImageSignatureLevel : 4;
      ULONG ImageSignatureType : 3;
      ULONG ImagePartialMap : 1;
      ULONG Reserved : 12;
    };
};
PVOIDImageBase;
ULONGImageSelector;
SIZE_T ImageSize;
ULONGImageSectionNumber;
} IMAGE_INFO, *PIMAGE_INFO;


由于隐藏进程需要操作系统级别的权限,因此需要编写驱动程序来实现。以下是一些编写驱动程序实现隐藏进程的C++代码:#include <ntifs.h>#include <ntimage.h>
#include <ntifs.h>#include <ntimage.h>
#define DRIVER_NAME L"TestDriver.sys" //要拦截的驱动名#define DLL_NAME L"InjectDll.dll" //要拦截的DLL名
typedef struct _DLL_INFO{    HANDLE ProcessId;    PVOID pImageBase;}DLL_INFO, *PDLL_INFO; //Dll的信息,用来作为线程的参数传递
VOID DriverUnload(IN PDRIVER_OBJECT driverObject);VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo);//模块监控回调函数BOOLEAN DenyLoadDriver(PVOID pLoadImageBase); //对驱动的加载进行拦截BOOLEAN DenyLoadDll(HANDLE ProcessId, PVOID pImageBase);    //对DLL的加载进行拦截NTSTATUS MmUnmapViewOfSection(PEPROCESS Process, PVOID BaseAddr);   //未导出函数声明VOID ThreadProc(PVOID StartContext);//运行的线程函数
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject, IN PUNICODE_STRING registryPath){    NTSTATUS status = STATUS_SUCCESS;
    DbgPrint("驱动加载完成\r\n");    status = PsSetLoadImageNotifyRoutine(LoadImageNotifyRoutine);    if (!NT_SUCCESS(status))    {      DbgPrint("模块监控设置失败 0x%X\r\n", status);    }    else    {      DbgPrint("模块监控设置成功\r\n");    }exit:    driverObject->DriverUnload = DriverUnload;    return STATUS_SUCCESS;}
VOID LoadImageNotifyRoutine(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo){    PDLL_INFO pDllInfo = NULL;    HANDLE hThread = NULL;
    /*    DbgPrint("===========================================================================\r\n");    DbgPrint("检测到新加载的模块,模块信息如下:\r\n");    DbgPrint("加载该模块的进程ID:%d 模块完整名:%wZ 模块基址:0x%X 模块大小:0x%X", ProcessId, FullImageName, ImageInfo->ImageBase, ImageInfo->ImageSize);    DbgPrint("===========================================================================\r\n");    */
    // 是否是exe或者dll文件    if (ProcessId)    {      if (wcsstr(FullImageName->Buffer, DLL_NAME) != NULL)      {            pDllInfo = (PDLL_INFO)ExAllocatePool(NonPagedPool, sizeof(DLL_INFO));            if (!pDllInfo)            {                DbgPrint("ExAllocatePool Error");            }            else            {                pDllInfo->ProcessId = ProcessId;                pDllInfo->pImageBase = ImageInfo->ImageBase;                PsCreateSystemThread(&hThread, 0, NULL, NtCurrentProcess(), NULL, ThreadProc, pDllInfo);                if (hThread) ZwClose(hThread);            }      }    }    else    {      //加载的是驱动,判断是否是要拦截的驱动      if (wcsstr(FullImageName->Buffer, DRIVER_NAME) != NULL )      {            if (DenyLoadDriver(ImageInfo->ImageBase))            {                DbgPrint("成功拦截驱动%wZ的加载\r\n", FullImageName);            }      }    }}
VOID ThreadProc(PVOID StartContext){    PDLL_INFO pDllInfo = (PDLL_INFO)StartContext;    LARGE_INTEGER liTime = { 0 };
    //延时5秒    liTime.QuadPart = -50 * 1000 * 1000;    KeDelayExecutionThread(KernelMode, FALSE, &liTime);    //卸载DLL    if (DenyLoadDll(pDllInfo->ProcessId, pDllInfo->pImageBase))    {      DbgPrint("Dll卸载完成\r\n");    }
    if (pDllInfo) ExFreePool(pDllInfo);}
BOOLEAN DenyLoadDll(HANDLE ProcessId, PVOID pImageBase){    BOOLEANbRet = TRUE;    NTSTATUS status = STATUS_SUCCESS;    PEPROCESS pEprocess = NULL;//保存加载DLL的进程的EPROCESS
    //根据进程PID获取EPROCESS    status = PsLookupProcessByProcessId(ProcessId, &pEprocess);     if (!NT_SUCCESS(status))    {      DbgPrint("PsLookupProcessByProcessId Error 0x%X", status);      bRet = FALSE;      goto exit;    }
    //卸载模块    status = MmUnmapViewOfSection(pEprocess, pImageBase);    if (!NT_SUCCESS(status))    {      DbgPrint("MmUnmapViewOfSection Error 0x%X\r\n", status);      bRet = FALSE;      goto exit;    }exit:    return bRet;}
BOOLEAN DenyLoadDriver(PVOID pLoadImageBase){    BOOLEAN bRet = TRUE;    NTSTATUS status = STATUS_SUCCESS;    PVOID pVoid = NULL;    PIMAGE_DOS_HEADER pDosHead = NULL;    PIMAGE_NT_HEADERS pNtHeader = NULL;    PVOID pDriverEntry = NULL;    PMDL pMdl = NULL;    // 要写入的ShellCode,硬编码的意思是    // mov eax, 0xC0000022    // ret    UCHAR szShellCode = { 0xB8, 0x22, 0x00, 0x00, 0xC0, 0xC3};    ULONG uShellCodeLength = 6;
    pDosHead = (PIMAGE_DOS_HEADER)pLoadImageBase;    pNtHeader = (PIMAGE_NT_HEADERS)((ULONG)pLoadImageBase + pDosHead->e_lfanew);    pDriverEntry = (PVOID)((ULONG)pDosHead + pNtHeader->OptionalHeader.AddressOfEntryPoint); //获取驱动入口点位置
    //创建MDL并为内存属性添加可写属性    pMdl = MmCreateMdl(NULL, pDriverEntry, uShellCodeLength);    if (pMdl == NULL)    {      bRet = FALSE;      goto exit;    }
    //建立内存页的MDL描述    MmBuildMdlForNonPagedPool(pMdl);    //改变MDL的标记为可写    pMdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA;    //映射MDL空间    pVoid = MmMapLockedPages(pMdl, KernelMode);    //将shellcode拷到目标地址    RtlCopyMemory(pVoid, szShellCode, uShellCodeLength);    //释放MDL    MmUnmapLockedPages(pVoid, pMdl);    IoFreeMdl(pMdl);    pMdl = NULL;exit:    return bRet;}
VOID DriverUnload(IN PDRIVER_OBJECT driverObject){    NTSTATUS status = STATUS_SUCCESS;
    status = PsRemoveLoadImageNotifyRoutine(LoadImageNotifyRoutine);    if (!NT_SUCCESS(status))    {      DbgPrint("模块监控删除失败 0x%X\r\n", status);    }    else    {      DbgPrint("模块监控删除成功\r\n");    }    DbgPrint("驱动卸载完成\r\n");}
页: [1]
查看完整版本: C,C++ 驱动开发 隐藏进程 保护进程