登录  | 立即注册

游客您好!登录后享受更多精彩

查看: 136|回复: 3

驱动开发与系统原理-MiProcessLoaderEntry隐藏进程

[复制链接]
回帖奖励 64 断点币 回复本帖可获得 2 断点币奖励! 每人限 1 次

94

主题

-6

回帖

126

积分

网站编辑

积分
126
发表于 2025-5-21 23:48:58 | 显示全部楼层 |阅读模式

MiProcessLoaderEntry在内核文件ntoskrnl.exe中,我们可以通过这个函数API隐藏进程,有两个参数,第一个为PLIST_ENTRY类型的结点,第二个参数为TRUE/FALSE

我们可以通过遍历驱动,找到ntoskrnl.exe,然后通过特征码搜索,找到该函数地址,再通过函数指针调用该函数

操作

1.第一步——获取特征码:

我们可以在ntoskrnl.exe找到MiProcessLoaderEntry函数,随便找两段字节码作为特征码(防止一段字节码可能不准确,另外最好往中间找,函数开始和末尾大部分为初始化操作,可能查找不准确)

CHAR szCodeFlag1[] = { 0xB1 ,0x1B ,0x88 ,0x45 ,0x0B }; CHAR szCodeFlag2[] = { 0x8B,0xCE,0xF0 ,0x0F,0xBA,0x29,0x1F }; 2.第二步——遍历查找内核文件:

NTSTATUS SearchNtosKenlAddr(PDRIVER_OBJECT pDriverObject,ULONG retNtosAddr){ PLIST_ENTRY HeadNode = NULL; PLIST_ENTRY NextNode = NULL; UNICODE_STRING usKernelFileName; PUNICODE_STRING pusTempKernelFileName; RtlInitUnicodeString(&usKernelFileName, L"ntoskrnl.exe"); HeadNode = (PLIST_ENTRY)(pDriverObject->DriverSection); NextNode = HeadNode->Flink; while (NextNode!=HeadNode) { pusTempKernelFileName = (PUNICODE_STRING)((ULONG)NextNode+0x2c); if (RtlCompareUnicodeString(pusTempKernelFileName, &usKernelFileName,TRUE)==0) { retNtosAddr = (ULONG)NextNode; return STATUS_SUCCESS; } NextNode = NextNode->Flink; } return -1; } 我们通过名字查找RtlCompareUnicodeString来遍历驱动链表,如果找到,就返回驱动文件的地址

0x2c偏移处存放的是驱动文件的名字,驱动文件的结构体是未导出的,需要我们自己定义

3.第三步——获取函数地址:

获取函数地址主要就是遍历内核文件字节码,匹配的时候返回即可,注意我们返回时需要注意减去特征码到函数首地址的偏移,这样才是真正的首地址

  NTSTATUS FindMiProcessLoaderEntryAddr(ULONG ulStartAddress,ULONG ulEndAddress,ULONG *retFunAddress){
for (size_t i = ulStartAddress; i < ulEndAddress; i++)
    {
      if (memcmp(ulStartAddress, szCodeFlag1, sizeof(szCodeFlag1)) == 0) {
        if (memcmp(((char*)ulStartAddress + 0x23), szCodeFlag2, sizeof(szCodeFlag2)) == 0)
        { 
          *retFunAddress = ulStartAddress;
          return STATUS_SUCCESS;
        }
      }
      (char*)ulStartAddress++;
    }
    return -1;
  }

0x23是两个特征码之间的偏移,两个特征码同时成立,才能算查找成功,返回的地址其实是第一个特征码的首地址,最后还需要处理

4.第四步——进程隐藏:

对于进程隐藏,其实就是对前面功能的整合

 NTSTATUS RemoveProcessListNode(PLIST_ENTRY pListNode) {
      ULONG ulNtosAddr;
      ULONG ulFunAddr;
      ULONG ulNtosStartAddr;
      ULONG ulNtosEndAddr;
      FunMiProcessLoaderEntry MyMiProcessLoaderEntry;
      SearchNtosKenlAddr(g_DriverObject, &ulNtosAddr);
      ulNtosStartAddr =*(ULONG*)(ulNtosAddr+0x18);
      ulNtosEndAddr = *(ULONG*)(ulNtosAddr + 0x20) + ulNtosStartAddr;
      FindMiProcessLoaderEntryAddr(ulNtosStartAddr, ulNtosEndAddr, &ulFunAddr);
      ulFunAddr = ulFunAddr - 0x1E;//获取函数头地址
      MyMiProcessLoaderEntry = ulFunAddr;
      MyMiProcessLoaderEntry(pListNode, FALSE);//true插入,false摘除
      return STATUS_SUCCESS;
  }

5.第五步——传入进程ID,遍历进程:

NTSTATUS HideProcess(ULONG ulProcessid) {//参数为进程ID DWORD_PTR pEprocess = NULL; ULONG ulProcessID; pEprocess = (DWORD_PTR)PsGetCurrentProcess();//获取当前进程 PLIST_ENTRY HeadNode = NULL; PLIST_ENTRY NextNode = NULL; HeadNode = (PLIST_ENTRY)(pEprocess + 0xb8);//0xb8为进程链表 NextNode = HeadNode->Flink;//指向链表下一个 while (NextNode!=HeadNode) { pEprocess = (DWORD_PTR)NextNode - 0xb8;//指向结构头 ulProcessID = ((ULONG)(pEprocess)+0xB4);//指向进程ID的指针,进行取值 if (ulProcessID= ulProcessid) { RemoveProcessListNode(NextNode);//调用RemoveProcessListNode,删除进程 } NextNode = NextNode->Flink; } return -1; } 分解成多个步骤,就比较简单

效果

我们隐藏3560进程

现在已经消失了

        #include<ntifs.h>
        #include<intrin.h>
        PDRIVER_OBJECT g_DriverObject = NULL;
        CHAR szCodeFlag1[] = { 0xB1 ,0x1B ,0x88 ,0x45 ,0x0B };
        CHAR szCodeFlag2[] = { 0x8B,0xCE,0xF0 ,0x0F,0xBA,0x29,0x1F };
        typedef VOID(*FunMiProcessLoaderEntry)(ULONG ulEntry, LOGICAL lflag);

        NTSTATUS FindMiProcessLoaderEntryAddr(ULONG ulStartAddress,ULONG ulEndAddress,ULONG *retFunAddress){

            for (size_t i = ulStartAddress; i < ulEndAddress; i++)
            {
              if (memcmp(ulStartAddress, szCodeFlag1, sizeof(szCodeFlag1)) == 0) {
                if (memcmp(((char*)ulStartAddress + 0x23), szCodeFlag2, sizeof(szCodeFlag2)) == 0)
                { 
                  *retFunAddress = ulStartAddress;
                  return STATUS_SUCCESS;
                }
              }
              (char*)ulStartAddress++;
            }
            return -1;
          }

        NTSTATUS SearchNtosKenlAddr(PDRIVER_OBJECT pDriverObject,ULONG *retNtosAddr){
          PLIST_ENTRY HeadNode = NULL;
          PLIST_ENTRY NextNode = NULL;
          UNICODE_STRING usKernelFileName;
          PUNICODE_STRING pusTempKernelFileName;
          RtlInitUnicodeString(&usKernelFileName, L"ntoskrnl.exe");
          HeadNode = (PLIST_ENTRY)(pDriverObject->DriverSection);
          NextNode = HeadNode->Flink;
          while (NextNode!=HeadNode)
          {
                pusTempKernelFileName = (PUNICODE_STRING)((ULONG)NextNode+0x2c);
                if (RtlCompareUnicodeString(pusTempKernelFileName, &usKernelFileName,TRUE)==0)
                {
                    *retNtosAddr = (ULONG)NextNode;
                    return STATUS_SUCCESS;
                }
            NextNode = NextNode->Flink;
          }
            return -1;
        }

        NTSTATUS RemoveProcessListNode(PLIST_ENTRY pListNode) {
            ULONG ulNtosAddr;
            ULONG ulFunAddr;
            ULONG ulNtosStartAddr;
            ULONG ulNtosEndAddr;
            FunMiProcessLoaderEntry MyMiProcessLoaderEntry;
            SearchNtosKenlAddr(g_DriverObject, &ulNtosAddr);
            ulNtosStartAddr =*(ULONG*)(ulNtosAddr+0x18);
            ulNtosEndAddr = *(ULONG*)(ulNtosAddr + 0x20) + ulNtosStartAddr;
            FindMiProcessLoaderEntryAddr(ulNtosStartAddr, ulNtosEndAddr, &ulFunAddr);
            ulFunAddr = ulFunAddr - 0x1E;//获取函数头地址
            MyMiProcessLoaderEntry = ulFunAddr;
            MyMiProcessLoaderEntry(pListNode, FALSE);//true插入,false摘除
            return STATUS_SUCCESS;
        }
        NTSTATUS HideProcess(ULONG ulProcessid) {
            DWORD_PTR pEprocess = NULL;
            ULONG ulProcessID;
            pEprocess = (DWORD_PTR)PsGetCurrentProcess();
            PLIST_ENTRY HeadNode = NULL;
            PLIST_ENTRY NextNode = NULL;
            HeadNode = (PLIST_ENTRY)(pEprocess + 0xb8);
            NextNode = HeadNode->Flink;
            while (NextNode!=HeadNode)
            {
                pEprocess = ((DWORD_PTR)NextNode - 0xb8);//指向结构头
                ulProcessID = *(ULONG*)(pEprocess+0xB4);
                if (ulProcessID== ulProcessid)
                {
                    RemoveProcessListNode(NextNode);
                    return STATUS_SUCCESS;
                }
                NextNode = NextNode->Flink;
            }
            return -1;
        }

        VOID DriverUnload(PDRIVER_OBJECT pDriverObject) {

          DbgPrint("Unload Driver Success! ");

        }

        NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegPath) {
          DbgPrint("Load Driver Success!");
            pDriverObject->DriverUnload = DriverUnload;
            g_DriverObject = pDriverObject;
            HideProcess(3560);
          return STATUS_SUCCESS;
          }

0

主题

106

回帖

183

积分

注册会员

积分
183
发表于 2025-5-22 16:18:57 | 显示全部楼层

回帖奖励 +2 断点币

谢谢分享
回复

使用道具 举报

0

主题

19

回帖

35

积分

新手上路

积分
35
发表于 2025-5-22 21:20:48 | 显示全部楼层

回帖奖励 +2 断点币

学到很多,感谢
回复

使用道具 举报

0

主题

236

回帖

233

积分

注册会员

积分
233
发表于 2025-5-23 09:07:51 | 显示全部楼层

回帖奖励 +2 断点币

学习学习!!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|断点社区 |网站地图

GMT+8, 2025-6-2 19:42 , Processed in 0.111372 second(s), 25 queries , Yac On.

Powered by XiunoBBS

Copyright © 2001-2025, 断点社区.

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