x32下的DLL隐藏

Posted ibinary

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了x32下的DLL隐藏相关的知识,希望对你有一定的参考价值。

原理主要就是PEB 中模块断链. 这里整理下代码.原理可以看下另一篇我写的帖子.
https://www.cnblogs.com/iBinary/p/9601860.html

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include <Windows.h>
#include <winnt.h>

typedef struct _UNICODE_STRING 
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
 UNICODE_STRING;

typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;


/*
DLL 劫持的实现

1.首先我们加载我们想要劫持的DLL. 获取其DLLModule
2.遍历PEB中的模块表.找到->DllBae,修改为我们劫持DLL的hModule即可.

*/
#define LDRP_STATIC_LINK                        0x00000002
#define LDRP_IMAGE_DLL                          0x00000004
#define LDRP_LOAD_IN_PROGRESS                   0x00001000
#define LDRP_UNLOAD_IN_PROGRESS                 0x00002000
#define LDRP_ENTRY_PROCESSED                    0x00004000
#define LDRP_ENTRY_INSERTED                     0x00008000
#define LDRP_CURRENT_LOAD                       0x00010000
#define LDRP_FAILED_BUILTIN_LOAD                0x00020000
#define LDRP_DONT_CALL_FOR_THREADS              0x00040000
#define LDRP_PROCESS_ATTACH_CALLED              0x00080000
#define LDRP_DEBUG_SYMBOLS_LOADED               0x00100000
#define LDRP_IMAGE_NOT_AT_BASE                  0x00200000
#define LDRP_COR_IMAGE                          0x00400000
#define LDR_COR_OWNS_UNMAP                      0x00800000
#define LDRP_SYSTEM_MAPPED                      0x01000000
#define LDRP_IMAGE_VERIFYING                    0x02000000
#define LDRP_DRIVER_DEPENDENT_DLL               0x04000000
#define LDRP_ENTRY_NATIVE                       0x08000000
#define LDRP_REDIRECTED                         0x10000000
#define LDRP_NON_PAGED_DEBUG_INFO               0x20000000
#define LDRP_MM_LOADED                          0x40000000
#define LDRP_COMPAT_DATABASE_PROCESSED          0x80000000


typedef struct _LDR_DATA_TABLE_ENTRY

    LIST_ENTRY InLoadOrderLinks;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
    PVOID DllBase;
    PVOID EntryPoint;
    ULONG SizeOfImage;
    UNICODE_STRING FullDllName;
    UNICODE_STRING BaseDllName;
    ULONG Flags;
    USHORT LoadCount;
    USHORT TlsIndex;
    union
    
        LIST_ENTRY HashLinks;
        PVOID SectionPointer;
    ;
    ULONG CheckSum;
    union
    
        ULONG TimeDateStamp;
        PVOID LoadedImports;
    ;
    PVOID EntryPointActivationContext;
    PVOID PatchInformation;
 LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;



typedef struct _PEB_LDR_DATA 
    ULONG                  Length;
    BOOLEAN              Initialized;
    PVOID                  SsHandle;
    LIST_ENTRY            InLoadOrderModuleList;          //按加载顺序
    LIST_ENTRY            InMemoryOrderModuleList;      //按内存顺序
    LIST_ENTRY            InInitializationOrderModuleList;//按初始化顺序
    PVOID         EntryInProgress;
 PEB_LDR_DATA, *PPEB_LDR_DATA;


typedef struct _LDR_MODULE 
    LIST_ENTRY          InLoadOrderModuleList;
    LIST_ENTRY          InMemoryOrderModuleList;
    LIST_ENTRY          InInitializationOrderModuleList;
    PVOID               BaseAddress;
    PVOID               EntryPoint;
    ULONG               SizeOfImage;
    UNICODE_STRING      FullDllName;
    UNICODE_STRING      BaseDllName;
    ULONG               Flags;
    SHORT               LoadCount;
    SHORT               TlsIndex;
    LIST_ENTRY          HashTableEntry;
    ULONG               TimeDateStamp;
 LDR_MODULE, *PLDR_MODULE;

void PreprocessUnloadDll(HMODULE hLibModule)

    PPEB_LDR_DATA   pLdr = NULL;
    PLDR_MODULE     FirstModule = NULL;
    PLDR_MODULE     GurrentModule = NULL;
    __try
    
        __asm
        
            mov esi, fs:[0x30]
            mov esi, [esi + 0x0C]
            mov pLdr, esi
        

        FirstModule = (PLDR_MODULE)(pLdr->InLoadOrderModuleList.Flink);
        GurrentModule = FirstModule;
        while (!(GurrentModule->BaseAddress == hLibModule))
        
            GurrentModule = (PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink);
            if (GurrentModule == FirstModule)
            
                return;
            
        

        //
        //  设置 LDRP_PROCESS_ATTACH_CALLED
        //
        GurrentModule->Flags |= LDRP_PROCESS_ATTACH_CALLED;

        //
        //  设置
        //
        int oldLoadCount = GurrentModule->LoadCount;
        GurrentModule->LoadCount = 1;
        return;
    

    __except (EXCEPTION_EXECUTE_HANDLER)
    
        return;
    


VOID HideModule(HMODULE hLibModule)

    PPEB_LDR_DATA   pLdr = NULL;
    PLDR_MODULE     FirstModule = NULL;
    PLDR_MODULE     GurrentModule = NULL;
    __try
    
        __asm
        
            mov esi, fs:[0x30]
            mov esi, [esi + 0x0C]
            mov pLdr, esi
        

        FirstModule = (PLDR_MODULE)(pLdr->InLoadOrderModuleList.Flink);
        GurrentModule = FirstModule;


        while (!(GurrentModule->BaseAddress == hLibModule)) //判断结束位置
        
            GurrentModule = (PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink);
            if (GurrentModule == FirstModule)
                break;
        
        if (GurrentModule->BaseAddress != hLibModule)
            return;

        //
        //  Dll解除链接
        //
        ((PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Flink))->InLoadOrderModuleList.Blink = GurrentModule->InLoadOrderModuleList.Blink;
        ((PLDR_MODULE)(GurrentModule->InLoadOrderModuleList.Blink))->InLoadOrderModuleList.Flink = GurrentModule->InLoadOrderModuleList.Flink;

        memset(GurrentModule->FullDllName.Buffer, 0, GurrentModule->FullDllName.Length);
        memset(GurrentModule, 0, sizeof(PLDR_MODULE));

        PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hLibModule;
        PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)(LPBYTE(hLibModule) + dosHeader->e_lfanew);

        if ((dosHeader->e_magic == IMAGE_DOS_SIGNATURE) && (ntHeaders->Signature == IMAGE_NT_SIGNATURE))
        
            memset(dosHeader, 0, sizeof(*dosHeader));
            memset(ntHeaders, 0, sizeof(*ntHeaders));
        
    

    __except (EXCEPTION_EXECUTE_HANDLER)
    
        return;
    



BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)




    switch (ul_reason_for_call)
    
    case DLL_PROCESS_ATTACH:


        HideModule(hModule);
        return TRUE;

    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    
    return TRUE;

检测:


 MEMORY_BASIC_INFORMATION mbi_thunk;
 PVOID AllocationBase = NULL;
 TCHAR FilePath[MAX_PATH];
 for (LPSTR Addr = (LPSTR)0x00000000; ::VirtualQueryEx(hProcess, Addr, &mbi_thunk, sizeof(mbi_thunk)); Addr = LPSTR(mbi_thunk.BaseAddress) + mbi_thunk.RegionSize)
 
  if ((mbi_thunk.AllocationBase > AllocationBase) && (GetMappedFileName(hProcess, mbi_thunk.BaseAddress, FilePath, _countof(FilePath)) > 0))
  
   AllocationBase = mbi_thunk.AllocationBase;
   KdPrint((_T("MODULE:%x, %s\\r\\n"), AllocationBase, FilePath));
  
 

以上是关于x32下的DLL隐藏的主要内容,如果未能解决你的问题,请参考以下文章

C语言隐藏窗口

如何隐藏 DLL 中的导出函数

Visual Studio 2008 输出 - 隐藏 dll 加载和卸载

可执行dll加载(x32,x64):选择正确的

编译时如何在 DLL 文件中隐藏字符串?

E语言中如何释放DLL