(35)3环PEB断链
一、断链原理
3环下PEB断链是一种常见的模块隐藏技术,原理是修改 _PEB_LDR_DATA 中的三个双向链表,删除链表中的项,让 CreateToolhelp32Snapshot 之类的API无法通过模块列表枚举DLL。
以 InLoadOrderModuleList 链表为例,画个简单的示意图:
所谓断链,就是把三个链表断掉,让3环的API读不出模块信息。最简单的做法就是让Head的Flink和Blink指向它自己。
二、隐藏所有模块
// PEB断链.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>// 内核Unicode字符串
typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;// LDR链表头
typedef struct _PEB_LDR_DATA
{DWORD Length;bool Initialized;PVOID SsHandle;// LIST_ENTRY 是双端链表项,指向前后节点LIST_ENTRY InLoadOrderModuleList; // 指向了 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()
{ PPEB_LDR_DATA ldr; PLDR_DATA_TABLE_ENTRY ldte;// 获取LDR__asm{mov eax,fs:[0x30] // PEB mov ecx,[eax + 0x0c] // LDRmov ldr,ecx }PLIST_ENTRY Head; // 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;
}int _tmain(int argc, _TCHAR* argv[])
{printf("未断链前状态(敲任意字符开始断链)\n");getchar();HideModule();printf("断链后状态.\n");getchar();return 0;
}
断链前:
断链后:
三、隐藏特定模块
如果想隐藏某个特定模块,例如隐藏掉 kernel32.dll,可以这样做:
// PEB断链.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include <Windows.h>// 内核Unicode字符串
typedef struct _UNICODE_STRING {USHORT Length;USHORT MaximumLength;PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;// LDR链表头
typedef struct _PEB_LDR_DATA
{DWORD Length;bool Initialized;PVOID SsHandle;// LIST_ENTRY 是双端链表项,指向前后节点LIST_ENTRY InLoadOrderModuleList; // 指向了 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;// 获取LDR__asm{mov eax,fs:[0x30] // PEB mov ecx,[eax + 0x0c] // LDRmov ldr,ecx }PLIST_ENTRY Head, Cur; // Head 指向链表第一项,第一项不存储模块信息;Cur指向第二项,是第一个存储了模块信息的项// 分别将三个链表断链处理Head = &(ldr->InLoadOrderModuleList);Cur = Head->Flink;do{// CONTAINING_RECORD宏的作用是传入一个地址,一个结构体类型和该地址属于结构体中的哪个属性,返回结构体基址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 { // CONTAINING_RECORD宏的作用是传入一个地址,一个结构体类型和该地址属于结构体中的哪个属性,返回结构体基址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 { // CONTAINING_RECORD宏的作用是传入一个地址,一个结构体类型和该地址属于结构体中的哪个属性,返回结构体基址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 _tmain(int argc, _TCHAR* argv[])
{printf("未断链前状态(敲任意字符开始断链)\n");getchar();HideModule(GetModuleHandleA("kernel32.dll"));printf("断链后状态.\n");getchar();return 0;
}
断链前:
断链后:
(35)3环PEB断链相关推荐
- 4.PEB断链隐藏模块
0x4 PEB断链隐藏模块 1.如何找到_PEB_LDR_DATA 由_TEB找到_PEB,_PEB偏移0xC找到_PEB_LDR_DATA 2.基础知识 _LDR_DATA_TABLE_ENTRY结 ...
- (53)进程结构体EPROCESS,擦除 DebugPort 实现反调试,ActiveProcessLinks 断链实现进程隐藏
一.进程的作用 进程最重要的作用是提供了CR3,10-10-12分页下CR3指向页目录表,2-9-9-12分页下CR3指向页目录指针表. 每个进程有一个或多个线程.本质上,没有进程切换,只有线程切换. ...
- (54)线程结构体 ETHREAD,线程断链
一.回顾 上次课我们学习了进程,我们知道了进程是空间概念,最主要的功能是提供CR3,而线程才是CPU调度的最小单位: 更早的时候做SSDT HOOK FindWindow 时我们还了解到了,当3环程序 ...
- _ETHREAD断链 —— 实现线程隐藏
简介 线程所属的父进程 _EPROCESS 结构体中的 ThreadListHead 成员是当前进程中所有线程的双向链表头,该成员有两个,分别在 0x50 和 0x190 处.我们可以通过该线程链表头 ...
- nats断链情况总结
1.客户端启动时nats server连不上 代码段: func setupConnOptions() []nats.Option {opts := make([]nats.Option,0)opts ...
- c语言断链隐藏dll,利用C++ R3层断链实现模块隐藏功能
一.模块隐藏的实现原理 普通API查找模块实现思路:其通过查询在R3中的PEB(Process Environment Block 进程环境块)与TEB(Thread Environment Bloc ...
- 关于递归删除链表节点为什么不会断链问题解释
问题的由来: 当你第一次实现用递归实现链表删除功能的时候,是否有一丝丝的考虑过.这个问题呢?为什么对于非递归版本的删除必须要知道当前要删除节点的前驱,而需要对其前驱节点的next域指针进行修改. ...
- 断链在平曲线计算中的处理——短链篇
第十二篇 断链在平曲线计算中的处理--短链篇 1. 短链在平曲线编程数据库里的处理方法 断链是在一些线路设计或施工中因某种情况下而产生的,具体原因在此不做讨论,短链就是断链的其中一种常见形式,另一种 ...
- 应用使用Druid连接池经常性断链问题分析
前段时间有应用使用Druid连接池经常的提示断链报错,整个问题排查分析过程很有意思.这里将Druid连接池.数据库层以及负载均衡层的配置分析下,记录整个问题的分析过程,同时梳理下Druid连接池的配置 ...
最新文章
- 三月新增电脑病毒400万 被感染计算机多达2000万
- Phalcon和YII的优点
- java异常处理学习总结
- C#中System.ServiceProgress报错
- 从字到词,大词典中文BERT模型的探索之旅
- 中国房地产市值已经超过450万亿,为何还不见房价下跌?
- document 文挡对象详解(JavaScript脚本语言描述)
- php画弧,php绘制一条弧线的方法
- Reporting Services Catalog Database File Existence error during installing SQL Server 2008 R2
- Remoting事件序列一:客户端触发服务器端事件
- innosetup 安装前、卸载前判断是否有进程正在运行转
- android Intent调用地图应用客户端
- 实战来了!聊聊电商系统中红包雨功能的设计与实现
- c语言编译九行菱形,C语言打印菱形
- Windows2003下运行JSP,环境配置教程(J2SDK+Tomcat5+IIS)
- Quasi-globally Optimal and Near/True Real-time Vanishing Point Estimation in Manhattan World 论文阅读学习
- html5充值页面(Vue)
- nz-upload的[nzCustomRequest]自定义上传
- Spring源码解析之 Bean与BeanDefinition详解
- MFC CImage图像失真的解决方法
热门文章
- Dataset:GiveMeSomeCredit数据集的简介、下载、使用方法之详细攻略
- Database之SQLSever:SQLSever数据库管理(GUI法/SQL语句命令法两种方法实现备份(完整备份、差异备份、日志备份)、还原、删除、修改数据库等案例)之详细攻略
- AI:2020年7月10日世界人工智能大会WAIC青少年人工智能创新发展论坛《人工智能从娃娃抓起》
- AI开发者大会之AI学习与进阶实践:2020年7月3日《如何转型搞AI?》、《基于AI行业价值的AI学习与进阶路径》、《自动机器学习与前沿AI开源项目》、《使用TensorFlow实现经典模型》
- Py之torchvision:torchvision库的简介、安装、使用方法之详细攻略
- 成功解决没有tf.nn.rnn_cell属性
- 成功解决from nets import inception_resnet_v2 ModuleNotFoundError: No module named 'nets'
- BZOJ3569: DZY Loves Chinese II(线性基构造)
- 通过构造函数来创建新对象
- 兰山天书(贺兰山岩画)