郁金香灬老师 游戏安全  驱动 逆向调试 C/C++编程  脚本 UE4/UE5

找回密码
立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 活动 交友 discuz
发新帖
课程大纲和价格
官方联系方式2024在线课大纲QQ咨询

34万

积分

131

好友

145

主题
发表于 2023-4-13 11:40:46 | 查看: 4947| 回复: 0
根据网上资料和个人总结,进程隐藏主要有如下几种方法:
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;
    };
  };
  PVOID  ImageBase;
  ULONG  ImageSelector;
  SIZE_T ImageSize;
  ULONG  ImageSectionNumber;
} 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)
{
    BOOLEAN  bRet = 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[6] = { 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");
}
游戏安全课程 学员办理咨询联系QQ150330575 手机 139 9636 2600  免费课程 在 www.bilibili.com 搜 郁金香灬老师
您需要登录后才可以回帖 登录 | 立即注册

QQ咨询

QQ|Archiver|手机版|小黑屋|郁金香游戏技术

GMT+8, 2024-11-23 10:27 , Processed in 0.086517 second(s), 21 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表