3环PEB断链实现

那么我们首先定义_PEB_LDR_DATA_LDR_DATA_TABLE_ENTRY结构

// LDR链表头
typedef struct _PEB_LDR_DATA
{
    DWORD Length;
    bool Initialized;
    PVOID SsHandle;
    LIST_ENTRY InLoadOrderModuleList; // 指向了 InLoadOrderModuleList 链表的第一项
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA,*PPEB_LDR_DATA;

typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY          InLoadOrderModuleList;
    LIST_ENTRY          InMemoryOrderModuleList;
    LIST_ENTRY          InInitializationOrderModuleList;
    void*               BaseAddress;
    void*               EntryPoint;  
    ULONG               SizeOfImage;
    UNICODE_STRING        FullDllName;
    UNICODE_STRING      BaseDllName;
    ULONG               Flags;
    SHORT               LoadCount;
    SHORT               TlsIndex;
    HANDLE              SectionHandle;
    ULONG               CheckSum;
    ULONG               TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

然后通过汇编定位到LDR

    __asm
    {
        mov eax,fs:[0x30] // PEB 
        mov ecx,[eax + 0x0c] // LDR
        mov ldr,ecx  
    }

因为这里三个双向链表的结构都是一样的,这里就以InLoadOrderModuleList来进行断链示范,这里要实现断链,最简单的做法就是让Head的Flink和Blink指向它自己

首先通过获取到的ldr结构指向InLoadOrderModuleList

Head = &(ldr->InLoadOrderModuleList);

然后通过CONTAINING_RECORD这个宏返回结构体基址

Cur = Head->Flink;
ldte = CONTAINING_RECORD( Cur, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleLi

 

void CONTAINING_RECORD(
   address,
   type,
   field
);

进行断链操作

        ldte->InInitializationOrderModuleList.Blink->Flink = ldte->InInitializationOrderModuleList.Flink;  
        ldte->InInitializationOrderModuleList.Flink->Blink = ldte->InInitializationOrderModuleList.Blink;    

然后将指针指向下一个结构

Cur = Cur->Flink;

因为需要遍历链表进行断链指向自身的操作,这里就需要写一个循环进行断链,完整代码如下

// killPEB.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <Windows.h>

typedef struct _UNICODE_STRING {
    USHORT Length;
    USHORT MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _PEB_LDR_DATA
{
    DWORD Length;
    bool Initialized;
    PVOID SsHandle;
    LIST_ENTRY InLoadOrderModuleList;
    LIST_ENTRY InMemoryOrderModuleList;
    LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA,*PPEB_LDR_DATA;

// LDR表项,存储了模块信息
typedef struct _LDR_DATA_TABLE_ENTRY
{
    LIST_ENTRY          InLoadOrderModuleList;
    LIST_ENTRY          InMemoryOrderModuleList;
    LIST_ENTRY          InInitializationOrderModuleList;
    void*               BaseAddress;
    void*               EntryPoint;  
    ULONG               SizeOfImage;
    UNICODE_STRING        FullDllName;
    UNICODE_STRING      BaseDllName;
    ULONG               Flags;
    SHORT               LoadCount;
    SHORT               TlsIndex;
    HANDLE              SectionHandle;
    ULONG               CheckSum;
    ULONG               TimeDateStamp;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

void HideModule(HMODULE hModule)
{    
    PPEB_LDR_DATA ldr;  
    PLDR_DATA_TABLE_ENTRY ldte;
    __asm
    {
        mov eax,fs:[0x30]  
        mov ecx,[eax + 0x0c] 
        mov ldr,ecx  
    }
    
    PLIST_ENTRY Head, Cur; 

    Head = &(ldr->InLoadOrderModuleList);
    Cur = Head->Flink;
    
    do
    {
        
        ldte = CONTAINING_RECORD( Cur, LDR_DATA_TABLE_ENTRY, InLoadOrderModuleList);
        if (ldte->BaseAddress == hModule)
        {        
            
            ldte->InLoadOrderModuleList.Blink->Flink = ldte->InLoadOrderModuleList.Flink;  
            ldte->InLoadOrderModuleList.Flink->Blink = ldte->InLoadOrderModuleList.Blink;         
        }
        Cur = Cur->Flink;
    } while(Head != Cur);
    
    Head = &(ldr->InMemoryOrderModuleList);
    Cur = Head->Flink;
    
    do  
    {  
        
        ldte = CONTAINING_RECORD( Cur, LDR_DATA_TABLE_ENTRY, InMemoryOrderModuleList);  
        if (ldte->BaseAddress == hModule)
        {
            
            ldte->InMemoryOrderModuleList.Blink->Flink = ldte->InMemoryOrderModuleList.Flink;  
            ldte->InMemoryOrderModuleList.Flink->Blink = ldte->InMemoryOrderModuleList.Blink;         
        }
        Cur = Cur->Flink;

    } while(Head != Cur);
    
    Head = &(ldr->InInitializationOrderModuleList);
    Cur = Head->Flink;
    
    do  
    {  
        
        ldte = CONTAINING_RECORD( Cur, LDR_DATA_TABLE_ENTRY, InInitializationOrderModuleList);  
        if (ldte->BaseAddress == hModule)
        {

            ldte->InInitializationOrderModuleList.Blink->Flink = ldte->InInitializationOrderModuleList.Flink;  
            ldte->InInitializationOrderModuleList.Flink->Blink = ldte->InInitializationOrderModuleList.Blink;                     
        }
        Cur = Cur->Flink;
    } while(Head != Cur);
}

int main(int argc, CHAR* argv[])
{
    printf("点任意按键开始断链");
    getchar();
    HideModule(GetModuleHandleA("kernel32.dll"));
    printf("断链成功\n");
    getchar();
    return 0;
}

这里在没有开始断链的时候可以看到是由3个模块的

锻炼之后可以发现kerner32.dll已经被隐藏

如果要实现所有模块的隐藏,直接将模块判断的代码删除即可

void HideModule_All()
{    
    PPEB_LDR_DATA ldr;  
    PLDR_DATA_TABLE_ENTRY ldte;
    // 获取LDR
    __asm
    {
        mov eax,fs:[0x30] 
        mov ecx,[eax + 0x0c] 
        mov ldr,ecx  
    }
    
    PLIST_ENTRY Head; 

    Head = &(ldr->InLoadOrderModuleList);
    Head->Flink = Head->Blink = Head;
    Head = &(ldr->InMemoryOrderModuleList);
    Head->Flink = Head->Blink = Head;
    Head = &(ldr->InInitializationOrderModuleList);
    Head->Flink = Head->Blink = Head;    
}

实现效果如下

断链之后,模块已经全部看不到了

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值