1937特种兵下载-qq管理器
![进程隐藏](/uploads/image/0218.jpg)
2023年3月31日发(作者:宝宝取名软件 破解)
再谈隐藏进程中的DLL模块
再谈隐藏进程中的DLL模块
学习各种⾼级外挂制作技术,马上去百度搜索"魔⿁作坊",点击第⼀个站进⼊,快速成为做挂达⼈。
相当⽼的话题,⼤约⼀年前就写过这个东西了,不过那时候知识⽐较有限,也不了解内核,因此实现得很粗浅,现在再写⼀
下,权当是对这个⽼问题的总结吧。
先谈谈正规DLL的隐藏⽅法,这⾥说的正规DLL,是指⽤LoadLibrary以正常⽅式加载的DLL。
⼀、从PEB的Ldr链中消失
这个很简单,看雪上NetRoc有⼀篇关于这个的⽂章,从分析原理到编程实现,虽然技术不算⾼深,但是思路⾮常精彩。来复
习⼀下吧~~
lkd>dt_PEB7ffdc000//当前PEB的地址
nt!_PEB
...
+0x00cLdr:0x001a1e90_PEB_LDR_DATA//这⾥指向Ldr结构lkd>dt_PEB_LDR_DATA0x001a1e90//这个结构⾥有三个链表
的表头
nt!_PEB_LDR_DATA
+0x000Length:0x28
+0x004Initialized:0x1''
+0x008SsHandle:(null)
+0x00cInLoadOrderModuleList:_LIST_ENTRY[0x1a1ec0-0x1a34f8]
+0x014InMemoryOrderModuleList:_LIST_ENTRY[0x1a1ec8-0x1a3500]
+0x01cInInitializationOrderModuleList:_LIST_ENTRY[0x1a1f28-0x1a3508]
+0x024EntryInProgress:(null)
这⾥看到有三个链表,其实三个链表的内容是⼀样的,但是链表的顺序不⼀样,分别按加载顺序、内存顺序、初始化顺序排列
也就是说每⼀个DLL由⼀个LDR_DATA_TABLE_ENTRY结构描述,但是第⼀个结构被链⼊了三个链表。取⼀个来看看:
lkd>dt_LDR_DATA_TABLE_ENTRY0x1a34f8
nt!_LDR_DATA_TABLE_ENTRY
+0x000InLoadOrderLinks:_LIST_ENTRY[0x1a1e9c-0x1a3450]
+0x008InMemoryOrderLinks:_LIST_ENTRY[0x1a1ea4-0x1a3458]
+0x010InInitializationOrderLinks:_LIST_ENTRY[0x1a1eac-0x1a3460]
+0x018DllBase:0x20000000
+0x01cEntryPoint:(null)
+0x020SizeOfImage:0x549000
+0x024FullDllName:_UNICODE_STRING"C:"
+0x02cBaseDllName:_UNICODE_STRING""
......//省略部分内容
随便取⼀个链表进⾏遍历,根据DllBase找到⾃⼰的DLL之后,从三个链中RemoveEntryList就可以了,这样所有使⽤PEB-
>Ldr结构来枚举DLL链表的就⽆法找到了。
由于⼤部分ARK对隐藏DLL的查找并不是很重视(⽐如RKU,Gmer,XueTr,Atool,NIAP),因此该⽅法就可以bypass很多ARK了,
还是有⼀定市场的~
但对IceSword是个例外,下⾯就来说说如何bypassIceSword
⼆、从VAD树中消失
IceSword在枚举进程模块时使⽤的是ZwQueryVirtualMemory,查询的InfoClass是MemorySectionName(或者叫
MemoryMappedFilenameInformation,值为2)。NtQueryVirtualMemory⾸先判断Vad->ControlArea->FilePointer是否有效,
若有效则调⽤ObQueryNameString查询此⽂件对象的名称,最终由⽂件系统完成此次查询⼯作。
关于VAD的详细知识,可以参考《JIURL玩玩Win2k内存篇VAD》,这⾥不作为重点,知道是平衡⼆叉树就可以了,树的根结
点在EPROCESS中。
lkd>dt_EPROCESS83f915b8
nt!_EPROCESS
...
+0x11cVadRoot:0x84079c08
该成员是⼀个MMVAD类型的结构,⽽成员LeftChild和RightChild分别是该结点的左⼦结点和右⼦结点。
lkd>dt_MMVAD0x84079c08
nt!_MMVAD
+0x000StartingVpn:0x8e0
+0x004EndingVpn:0x8e0
+0x008Parent:(null)
+0x00cLeftChild:0x843b1128_MMVAD//左孩⼦
+0x010RightChild:0x840bf4a0_MMVAD//右孩⼦
+0x014u:__unnamed//标志位
+0x018ControlArea:(null)
+0x01cFirstPrototypePte:(null)
+0x020LastContiguousPte:(null)
+0x024u2:__unnamed
要对⽬标DLL实施隐藏时,先获取该DLL基址,然后遍历VAD树,根据MMVAD->Starti
ngVpn做匹配(StartingVpn实际上是内存地址的⾼20位,⽐如0x7c800000在这⾥将只显⽰为0x7c800)找到⽬标DLL的VAD结
构(这⾥以为例,其加载地址正为0x7c800000):
lkd>dt_MMVAD84174a18
nt!_MMVAD
+0x000StartingVpn:0x7c800
+0x004EndingVpn:0x7c91b
+0x008Parent:0x841223a0_MMVAD
+0x00cLeftChild:0x84120470_MMVAD
+0x010RightChild:0x841a4790_MMVAD
+0x014u:__unnamed
+0x018ControlArea:0x876d0b88_CONTROL_AREA//关键域
+0x01cFirstPrototypePte:0xe177d6f0_MMPTE
+0x020LastContiguousPte:0xfffffffc_MMPTE
+0x024u2:__unnamed
lkd>dt_CONTROL_AREA0x876d0b88
nt!_CONTROL_AREA
...
+0x024FilePointer:0x876d0b10_FILE_OBJECT外//⽬标在这⾥
好了,看到FILE_OBJECT了,这时你应该会想到系统是从这⾥取到的⽂件名吧,没错,这⼉就是我们要动⼿脚的地⽅。根据
⼩伟、Sysnap等⼈的测试,只要把ControlArea->FilePointer->填0就可以实现该DLL的隐藏(根据字符串的特
性,实际上只需要把第⼀个字符填0就可以了),此时ZwQueryVirtualMemory将返回0xC0000039错误,即“指定的路径⽆效”,
⾃然也就枚举不到了。⽽且对于那些共享的dll,如系统的,或在不同进程中被加载2次或以上的dll,虽然是在
不同进程中,但是使⽤的是同⼀个共享的ControlArea结构,因此只需要改⼀个,那么在所有进程中都将实现隐藏,这对于隐藏
全局钩⼦类型的dll显然是⾮常⽅便的。
IS是在ZwQueryVirtualMemory查完全⽆法枚举到DLL时才采⽤枚举PEB的⽅法,因此结合前⾯的Ldr断链法,⾜以搞定N多
ARK了。
我所说的“从VAD树中消失”只是使该VAD的信息从IS的查询结果中消失,⽽并不是真的摘掉该VAD~~
值得⼀说的是,Sysnap的YasKit在检测隐藏DLL⽅⾯也是⽐较强的,但是对于动了VAD的,似乎也⽆能为⼒~
三、抹掉PE特征
有的⼯具可以直接枚举所有有效内存并检查PE标记来确定是否有隐藏DLL,因此需要把PE特征抹掉来对抗之,⽅法很简单,
把PE头整个填零就可以了。
这种⽅法主要是作为前两种⽅法的补充,单独搞是没有意义的。
再来说说⾮正规⽅式加载的DLL,怎么个⾮正规呢?其实就是不⽤LoadLibrary,⾃已实现Loader的功能.
实现Loader功能之后,不管你是Load别的DLL,或者DLL⾃已Load⾃⼰(⽼V的ReloadAndRun同样适⽤于DLL),在Load完成
后,不会出现在PEB->Ldr链中,它的VAD也不会与FILE_OBJECT发⽣任何关系,然后再抹掉PE特征,隐藏效果与上⾯的正
规隐藏法相当,甚⾄要更隐蔽⼀些~~
再极端⼀点,DLL也可以完全不要,注⼊具有相同功能的shellcode然后开线程执⾏就可以了,只是shellcode写起来⿇烦⼀点
⽽已,写Loader也⿇烦啊~~
总之只要能把我们的代码跑起来就OK,DLL隐藏就写到这⼉~~
更多推荐
进程隐藏
发布评论