• [Rootkit] 修改 peb 隐藏 dll(断链)


    原理

    PEB 中有一个成员 Ldr:

    typedef struct _PEB
    {
         UCHAR InheritedAddressSpace;
         UCHAR ReadImageFileExecOptions;
         UCHAR BeingDebugged;
         UCHAR BitField;
         ULONG ImageUsesLargePages: 1;
         ULONG IsProtectedProcess: 1;
         ULONG IsLegacyProcess: 1;
         ULONG IsImageDynamicallyRelocated: 1;
         ULONG SpareBits: 4;
         PVOID Mutant;
         PVOID ImageBaseAddress;
         PPEB_LDR_DATA Ldr;						// <----------
         PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
         PVOID SubSystemData;
         PVOID ProcessHeap;
         PRTL_CRITICAL_SECTION FastPebLock;
         PVOID AtlThunkSListPtr;
         PVOID IFEOKey;
         ULONG CrossProcessFlags;
         ULONG ProcessInJob: 1;
         ULONG ProcessInitializing: 1;
         ULONG ReservedBits0: 30;
         union
         {
              PVOID KernelCallbackTable;
              PVOID UserSharedInfoPtr;
         };
         ULONG SystemReserved[1];
         ULONG SpareUlong;
         PPEB_FREE_BLOCK FreeList;
         ULONG TlsExpansionCounter;
         PVOID TlsBitmap;
         ULONG TlsBitmapBits[2];
         PVOID ReadOnlySharedMemoryBase;
         PVOID HotpatchInformation;
         VOID * * ReadOnlyStaticServerData;
         PVOID AnsiCodePageData;
         PVOID OemCodePageData;
         PVOID UnicodeCaseTableData;
         ULONG NumberOfProcessors;
         ULONG NtGlobalFlag;
         LARGE_INTEGER CriticalSectionTimeout;
         ULONG HeapSegmentReserve;
         ULONG HeapSegmentCommit;
         ULONG HeapDeCommitTotalFreeThreshold;
         ULONG HeapDeCommitFreeBlockThreshold;
         ULONG NumberOfHeaps;
         ULONG MaximumNumberOfHeaps;
         VOID * * ProcessHeaps;
         PVOID GdiSharedHandleTable;
         PVOID ProcessStarterHelper;
         ULONG GdiDCAttributeList;
         PRTL_CRITICAL_SECTION LoaderLock;
         ULONG OSMajorVersion;
         ULONG OSMinorVersion;
         WORD OSBuildNumber;
         WORD OSCSDVersion;
         ULONG OSPlatformId;
         ULONG ImageSubsystem;
         ULONG ImageSubsystemMajorVersion;
         ULONG ImageSubsystemMinorVersion;
         ULONG ImageProcessAffinityMask;
         ULONG GdiHandleBuffer[34];
         PVOID PostProcessInitRoutine;
         PVOID TlsExpansionBitmap;
         ULONG TlsExpansionBitmapBits[32];
         ULONG SessionId;
         ULARGE_INTEGER AppCompatFlags;
         ULARGE_INTEGER AppCompatFlagsUser;
         PVOID pShimData;
         PVOID AppCompatInfo;
         UNICODE_STRING CSDVersion;
         _ACTIVATION_CONTEXT_DATA * ActivationContextData;
         _ASSEMBLY_STORAGE_MAP * ProcessAssemblyStorageMap;
         _ACTIVATION_CONTEXT_DATA * SystemDefaultActivationContextData;
         _ASSEMBLY_STORAGE_MAP * SystemAssemblyStorageMap;
         ULONG MinimumStackCommit;
         _FLS_CALLBACK_INFO * FlsCallback;
         LIST_ENTRY FlsListHead;
         PVOID FlsBitmap;
         ULONG FlsBitmapBits[4];
         ULONG FlsHighIndex;
         PVOID WerRegistrationData;
         PVOID WerShipAssertPtr;
    } PEB, *PPEB;
    

    这个 Ldr 的数据类型是 _PEB_LDR_DATA:

    typedef struct _PEB_LDR_DATA
    {
     ULONG Length;
     BOOLEAN Initialized; 
     PVOID SsHandle; 
     LIST_ENTRY InLoadOrderModuleList;				// <---------
     LIST_ENTRY InMemoryOrderModuleList; 
     LIST_ENTRY InInitializationOrderModuleList;
    } PEB_LDR_DATA,*PPEB_LDR_DATA; 
    
    

    InLoadOrderModuleList 成员保存了模块信息,而模块信息的结构为 _LDR_DATA_TABLE_ENTRY。

    typedef struct _LDR_DATA_TABLE_ENTRY
    {
    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderLinks;
    LIST_ENTRY InInitializationOrderLinks;
    PVOID      DllBase;
    PVOID      EntryPoint;
    ULONG32    SizeOfImage;
    UINT8      Unknow0[0x4];
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    }LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
    

    所以 ,我们获取到了这个结构.因为是链表.可以遍历链表. 根据DllBase判断 你的模块基址跟这个模块基址是否一样.如果一样那么我们就断开链表,从而实现 dll 的隐藏。

    代码参考来自:https://cloud.tencent.com/developer/article/1432475

    #include <stdio.h>
    #include <Windows.h>
    #include <stdlib.h>
    
    DWORD g_isHide = 0;
    typedef struct _UNICODE_STRING
    {
        USHORT Length;
        USHORT MaximumLength;
        PWSTR  Buffer;
    } UNICODE_STRING, *PUNICODE_STRING;
    
    typedef struct _PEB_LDR_DATA {
        ULONG                   Length;
        BOOLEAN                 Initialized;
        PVOID                   SsHandle;
        LIST_ENTRY              InLoadOrderModuleList;
        LIST_ENTRY              InMemoryOrderModuleList;
        LIST_ENTRY              InInitializationOrderModuleList;
    } PEB_LDR_DATA, *PPEB_LDR_DATA;
    
    typedef struct _LDR_MODULE
    {
        LIST_ENTRY          InLoadOrderModuleList;   //+0x00
        LIST_ENTRY          InMemoryOrderModuleList; //+0x08  
        LIST_ENTRY          InInitializationOrderModuleList; //+0x10
        void*               BaseAddress;  //+0x18
        void*               EntryPoint;   //+0x1c
        ULONG               SizeOfImage;
        UNICODE_STRING      FullDllName;
        UNICODE_STRING      BaseDllName;
        ULONG               Flags;
        SHORT               LoadCount;
        SHORT               TlsIndex;
        HANDLE              SectionHandle;
        ULONG               CheckSum;
        ULONG               TimeDateStamp;
    } LDR_MODULE, *PLDR_MODULE;
    void HideDll()                          //这个函数是主要的
    {
        HMODULE hMod = ::GetModuleHandle("ntdll.dll");
        PLIST_ENTRY Head, Cur;
        PPEB_LDR_DATA ldr;
        PLDR_MODULE ldm;
        __asm
        {
            mov eax, fs:[0x30]                  //获取PEB结构
            mov ecx, [eax + 0x0c] //Ldr                     //获取_PEB_LDR_DATA结构
            mov ldr, ecx
        }
        Head = &(ldr->InLoadOrderModuleList);               //获取模块链表地址
        Cur = Head->Flink;                                  //获取指向的结点.
        do
        {
            ldm = CONTAINING_RECORD(Cur, LDR_MODULE, InLoadOrderModuleList); //获取 _LDR_DATA_TABLE_ENTRY结构体地址
            //printf("EntryPoint [0x%X]\n",ldm->BaseAddress);
            if (hMod == ldm->BaseAddress)                                    //判断要隐藏的DLL基址跟结构中的基址是否一样
            {
                g_isHide = 1;                                                //如果进入.则标志置为1,表示已经开始进行隐藏了.
                ldm->InLoadOrderModuleList.Blink->Flink =                    //双向链表. 断开链表
                    ldm->InLoadOrderModuleList.Flink;
                ldm->InLoadOrderModuleList.Flink->Blink =
                    ldm->InLoadOrderModuleList.Blink;
                ldm->InInitializationOrderModuleList.Blink->Flink =
                    ldm->InInitializationOrderModuleList.Flink;
                ldm->InInitializationOrderModuleList.Flink->Blink =
                    ldm->InInitializationOrderModuleList.Blink;
                ldm->InMemoryOrderModuleList.Blink->Flink =
                    ldm->InMemoryOrderModuleList.Flink;
                ldm->InMemoryOrderModuleList.Flink->Blink =
                    ldm->InMemoryOrderModuleList.Blink;
                break;
            }
            Cur = Cur->Flink;
        } while (Head != Cur);
    }
    
    int main()
    {
    
        printf("按键开始隐藏\r\n");
        getchar();
        HideDll();
    
        if (g_isHide == 0)
        {
            printf("没有成功隐藏\r\n");
            system("pause");
            return 0;
        }
    
        printf("成功隐藏\r\n");
        system("pause");
        return 0;
    }
    

    其他参考:https://www.cnblogs.com/theseventhson/p/14401689.html

  • 相关阅读:
    与(&,&&)和或(|,||)的区别
    vue笔记(更新中)
    echarts实现心脏图的滚动三种实现方法
    生成四则运算
    软件工程第四次作业
    软件工程第三次作业
    软件工程第二次作业
    软件工程第一次作业
    前端优化
    关于事件监听
  • 原文地址:https://www.cnblogs.com/csnd/p/15613326.html
Copyright © 2020-2023  润新知