• 断链隐藏进程及恢复(附代码)


    首先,我们知道,进程体EPROCESS是被系统维护在一个双向链表LIST_ENTRY中的,那么,我们只要把进程的EPROCESS从这个链表中摘除,就可以实现进程隐藏了,当然,这只能瞒过进程管理器和zwQuerySystemInformation,暴力枚举依旧可以发现断链隐藏的进程,因为进程体还在内存中,这个以后再说。

    要隐藏我们指定的某个进程,我们肯定需要遍历整个EPROCESS链表, 当EPROCESS对应的进程名与 我们所指定的进程的进程名一样时,我们就把该EPROCESS从链表中移除。

    这里。我们遇到两个问题,:

    1.既然要遍历链表,我们就要知道每个结构的前后结构;

    2.既然要对比进程名,我们就要知道进程名放在哪个地方;

    以上两个问题,借助Windbg,我们就可以解决

    下面我们以x86为例:

    在windbg中,我们先看一下EPROCESS的结构,输入命令dt _EPROCESS,可以发现在偏移0x88处,有一个变量ActiveProcessLinks,它的类型为LIST_ENTRY

    在输入命令dt _LIST_ENTRY,查看LIST_ENTRY的结构,可以看到变量FLink和BLink,FLink指向当前节点的后一个节点的ActiveProcessLinks地址,BLink指向当前结点的前一个节点的ActiveProcessLinks地址

    继续往下,我们可以看到在偏移0x174处,出现了ImageFileName,这里存的就是我们要找的进程名

    下面我们切入一个进程实际看一下  输入命令!process 0 0,就可以显示所有进程信息

    然后,输入命令dt  _EPROCESS  895d6da0就可以切入进程smss.exe了   

         

    smss.exe的后一个结点的 ActiveProcessLinks就放在地址0x89a6d778中,用dd 0x89a6d778命令查看地址0x89a6d778中的内容,

    注意,因为FLink指向当前节点的后一个节点的ActiveProcessLinks地址,所以后一个节点的EPROCESS地址为ActiveProcessLinks地址减去FLink偏移0x88

    然后就可以找到smss.exe的下一个进程winlogon.exe了,这就印证了上面的截图中看到smss.exe的下一个进程是winlogon.exe

    这样,我们就解决了我们所遇到的问题,对于x64,方法是一样的,读者可以自行练习。代码如下:

      1 #ifndef CXX_HIDEPROCESS_H
      2 #    include "HideProcess.h"
      3 #endif
      4 
      5 
      6 ULONG_PTR ActiveOffsetPre =  0;
      7 ULONG_PTR ActiveOffsetNext = 0;
      8 ULONG_PTR ImageName = 0; 
      9 WIN_VERSION WinVersion = WINDOWS_UNKNOW;
     10 
     11 PLIST_ENTRY Temp = NULL;
     12 PLIST_ENTRY HeadEntry = NULL;
     13 NTSTATUS
     14     DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegisterPath)
     15 {
     16 
     17 
     18     DbgPrint("DriverEntry
    ");
     19 
     20     DriverObject->DriverUnload = UnloadDriver;
     21 
     22 
     23     WinVersion = GetWindowsVersion();
     24 
     25 
     26     switch(WinVersion)
     27     {
     28     case WINDOWS_XP:   //32Bits
     29         {
     30 
     31             ActiveOffsetPre =  0x8c;
     32             ActiveOffsetNext = 0x88;
     33             ImageName = 0x174; 
     34             break;
     35         }
     36 
     37     case WINDOWS_7:   //64Bits 
     38         {
     39             ActiveOffsetPre =  0x190;
     40             ActiveOffsetNext = 0x188;
     41             ImageName = 0x2e0; 
     42             break;
     43         }
     44     }
     45     
     46 
     47     HideProcess("notepad.exe");
     48 
     49     HeadEntry = (PLIST_ENTRY)((ULONG_PTR)PsGetCurrentProcess()+ActiveOffsetNext);// 在DriverEntry中执行得到的才是System进程
     50 
     51     return STATUS_SUCCESS;
     52 
     53 }
     54 
     55 VOID HideProcess(char* ProcessName)
     56 {
     57     PEPROCESS EProcessCurrent = NULL;
     58     PEPROCESS EProcessPre = NULL;
     59 
     60 
     61     EProcessCurrent = PsGetCurrentProcess();    //System  EProcess
     62     
     63     
     64 
     65     EProcessPre = (PEPROCESS)((ULONG_PTR)(*((ULONG_PTR*)((ULONG_PTR)EProcessCurrent+ActiveOffsetPre)))-ActiveOffsetNext);
     66 
     67     //DbgPrint("EProcessCurrent: 0x%p
    ",EProcessCurrent);  
     68 
     69     //DbgPrint("EProcessNext: 0x%p
    ",EProcessNext);  
     70 
     71 
     72 
     73     while (EProcessCurrent!=EProcessPre)
     74     {
     75         //    DbgPrint("%s
    ",(char*)((ULONG_PTR)EProcessCurrent+ImageName));
     76 
     77 
     78         if(strcmp((char*)((ULONG_PTR)EProcessCurrent+ImageName),ProcessName)==0)
     79         {
     80 
     81 
     82             Temp = (PLIST_ENTRY)((ULONG_PTR)EProcessCurrent+ActiveOffsetNext);
     83 
     84             if (MmIsAddressValid(Temp))
     85             {
     86                 //    Temp->Blink->Flink = Temp->Flink;
     87                 //    Temp->Flink->Blink = Temp->Blink;   //数据结构  不稳定
     88 
     89 
     90                 RemoveEntryList(Temp);
     91 
     92 
     93             }
     94 
     95 
     96             break;
     97         }
     98 
     99         EProcessCurrent = (PEPROCESS)((ULONG_PTR)(*((ULONG_PTR*)((ULONG_PTR)EProcessCurrent+ActiveOffsetNext)))-ActiveOffsetNext);
    100 
    101 
    102     }
    103 }
    104 
    105 VOID UnloadDriver(PDRIVER_OBJECT  DriverObject)
    106 {
    107     ResumeProcess();
    108     DbgPrint("UnloadDriver
    ");
    109 }
    110 
    111 VOID ResumeProcess()
    112 {
    113     
    114     if(Temp!=NULL)
    115     {
    116         InsertHeadList(HeadEntry,Temp);
    117     }
    118     
    119 
    120 }
    121 
    122 
    123 
    124 
    125 
    126 
    127 WIN_VERSION GetWindowsVersion()
    128 {
    129     RTL_OSVERSIONINFOEXW osverInfo = {sizeof(osverInfo)}; 
    130     pfnRtlGetVersion RtlGetVersion = NULL;
    131     WIN_VERSION WinVersion;
    132     WCHAR wzRtlGetVersion[] = L"RtlGetVersion";
    133 
    134     RtlGetVersion = GetFunctionAddressByName(wzRtlGetVersion);    //Ntoskrnl.exe  导出表
    135     if (RtlGetVersion)
    136     {
    137         RtlGetVersion((PRTL_OSVERSIONINFOW)&osverInfo); 
    138     } 
    139     else 
    140     {
    141         PsGetVersion(&osverInfo.dwMajorVersion, &osverInfo.dwMinorVersion, &osverInfo.dwBuildNumber, NULL);   //Documet
    142     }
    143 
    144     DbgPrint("Build Number: %d
    ", osverInfo.dwBuildNumber);
    145 
    146     if (osverInfo.dwMajorVersion == 5 && osverInfo.dwMinorVersion == 1) 
    147     {
    148         DbgPrint("WINDOWS_XP
    ");
    149         WinVersion = WINDOWS_XP;
    150     }
    151     else if (osverInfo.dwMajorVersion == 6 && osverInfo.dwMinorVersion == 1)
    152     {
    153         DbgPrint("WINDOWS 7
    ");
    154         WinVersion = WINDOWS_7;
    155     }
    156     else if (osverInfo.dwMajorVersion == 6 && 
    157         osverInfo.dwMinorVersion == 2 &&
    158         osverInfo.dwBuildNumber == 9200)
    159     {
    160         DbgPrint("WINDOWS 8
    ");
    161         WinVersion = WINDOWS_8;
    162     }
    163     else if (osverInfo.dwMajorVersion == 6 && 
    164         osverInfo.dwMinorVersion == 3 && 
    165         osverInfo.dwBuildNumber == 9600)
    166     {
    167         DbgPrint("WINDOWS 8.1
    ");
    168         WinVersion = WINDOWS_8_1;
    169     }
    170     else
    171     {
    172         DbgPrint("WINDOWS_UNKNOW
    ");
    173         WinVersion = WINDOWS_UNKNOW;
    174     }
    175 
    176     return WinVersion;
    177 }
    178 
    179 
    180 PVOID 
    181     GetFunctionAddressByName(WCHAR *wzFunction)
    182 {
    183     UNICODE_STRING uniFunction;  
    184     PVOID AddrBase = NULL;
    185 
    186     if (wzFunction && wcslen(wzFunction) > 0)
    187     {
    188         RtlInitUnicodeString(&uniFunction, wzFunction);      //常量指针
    189         AddrBase = MmGetSystemRoutineAddress(&uniFunction);  //在System 进程  第一个模块  Ntosknrl.exe  ExportTable
    190     }
    191 
    192     return AddrBase;
    193 }
  • 相关阅读:
    数据库进阶系列之二:细说数据库范式
    ORACLE HANDBOOK系列之三:树状结构查询(Hierarchical Queries)
    Tips&Tricks系列八:Fail to convert .vsmid,.testrunconfig
    Java基础系列之四:Remote Debug入门示例
    Java基础系列之五:Spring使用入门示例
    数据库进阶系列之三:使用Logminer解析Oracle日志
    ORACLE HANDBOOK系列之四:批量SQL(BULK SQL)
    Tips&Tricks系列九:数据库外键的两个细节
    Tips&Tricks系列六:ADO.NET OracleConnection.ClearPool(conn)
    Java基础系列之六:CORBA入门示例
  • 原文地址:https://www.cnblogs.com/Gotogoo/p/5251958.html
Copyright © 2020-2023  润新知