Module (PEB/LDR) Hiding (4 Methods)

Forum for discussion about user-mode development.
kerpow1
Posts: 32
Joined: Sat Aug 15, 2015 7:15 am

Module (PEB/LDR) Hiding (4 Methods)

Post by kerpow1 » Sun Oct 11, 2015 10:50 am

InLoadOrderModuleList
InMemoryOrderModuleList
InInitializationOrderModuleList
LdrpHashTable

Code: Select all

//===========================================================================
typedef struct _PEB_LDR_DATA
{
	ULONG			Length;
	BOOLEAN			Initialized;
	PVOID			SsHandle;
	LIST_ENTRY		InLoadOrderModuleList;
	LIST_ENTRY		InMemoryOrderModuleList;
	LIST_ENTRY		InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
//===========================================================================
typedef struct _LDR_MODULE
{
	LIST_ENTRY		InLoadOrderModuleList;
	LIST_ENTRY		InMemoryOrderModuleList;
	LIST_ENTRY		InInitializationOrderModuleList;
	PVOID			BaseAddress;
	PVOID			EntryPoint;
	ULONG			SizeOfImage;
	UNICODE_STRING	FullDllName;
	UNICODE_STRING	BaseDllName;
	ULONG			Flags;
	SHORT			LoadCount;
	SHORT			TlsIndex;
	LIST_ENTRY		HashTableEntry;
	ULONG			TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
//===========================================================================
void UnlinkModule(char *szModule)
{
	DWORD dwPEB = 0, dwOffset = 0;
	PLIST_ENTRY pUserModuleHead, pUserModule;
	PPEB_LDR_DATA pLdrData;
	PLDR_MODULE pLdrModule = NULL;
	PUNICODE_STRING lpModule = NULL;
	char szModuleName[512];
	int i = 0, n = 0;

	_asm
	{
		pushad
		mov eax, fs: [48]
		mov dwPEB, eax
		popad
	}

	pLdrData=(PPEB_LDR_DATA)(PDWORD)(*(PDWORD)(dwPEB + 12));

	for(; i < 3; i++)
	{
		switch(i)
		{
		case 0:
			pUserModuleHead = pUserModule =(PLIST_ENTRY)(&(pLdrData->InLoadOrderModuleList));
			dwOffset = 0;
			break;

		case 1:
			pUserModuleHead = pUserModule =(PLIST_ENTRY)(&(pLdrData->InMemoryOrderModuleList));
			dwOffset = 8;
			break;
		case 2:
			pUserModuleHead = pUserModule =(PLIST_ENTRY)(&(pLdrData->InInitializationOrderModuleList));
			dwOffset = 16;
			break;
		}

		while(pUserModule->Flink != pUserModuleHead)
		{
			pUserModule = pUserModule->Flink;
			lpModule =(PUNICODE_STRING)(((DWORD)(pUserModule)) +(36-dwOffset));
			
			for(n = 0; n <(lpModule->Length)/2 && n < 512; n++)
				szModuleName[n] =(CHAR)(*((lpModule->Buffer)+(n)));
			
			szModuleName[n] = '\0';
			if(strstr(szModuleName, szModule))
			{
				if (!pLdrModule)
					pLdrModule = (PLDR_MODULE)(((DWORD)(pUserModule)) - dwOffset);
				pUserModule->Blink->Flink = pUserModule->Flink;
				pUserModule->Flink->Blink = pUserModule->Blink;
			}
		}
	}
	
	// Unlink from LdrpHashTable
	if (pLdrModule)
	{
		pLdrModule->HashTableEntry.Blink->Flink = pLdrModule->HashTableEntry.Flink;
		pLdrModule->HashTableEntry.Flink->Blink = pLdrModule->HashTableEntry.Blink;
	}
}
Done a million times before but may be useful.

Microwave89
Posts: 52
Joined: Sat Dec 01, 2012 11:28 am

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by Microwave89 » Sun Oct 11, 2015 3:45 pm

In addition to posting x86 code where x86 systems are continuing decrease why don't you solely push eax if you don't destroy the other registers contents?
Even if the instruction length is the same for "push eax" and "pushad" it will still take a longer time. (Although that isn't too important nowadays and in that type of application.)

Better include <intrin.h> header and use following code:
dwPEB = __readfsdword(0x30);

Best Regards - Microwave89

User avatar
EP_X0FF
Global Moderator
Posts: 4882
Joined: Sun Mar 07, 2010 5:35 am
Location: Russian Federation
Contact:

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by EP_X0FF » Mon Oct 12, 2015 3:15 am

Code: Select all

lpModule =(PUNICODE_STRING)(((DWORD)(pUserModule)) +(36-dwOffset));
....

Code: Select all

	RtlEnterCriticalSection( (PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);

	Head = &NtCurrentPeb()->Ldr->InLoadOrderModuleList;
	Next = Head->Flink;
	bFound = FALSE;

	while ( Next != Head ) {

		Entry = CONTAINING_RECORD(Next, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if ( Entry->DllBase == DllHandle ) {

			bFound = TRUE;
			RemoveEntryList(&Entry->InLoadOrderLinks);
			RemoveEntryList(&Entry->InInitializationOrderLinks);
			RemoveEntryList(&Entry->HashLinks);

			switch ( dwFlags ) {

			case DLL_RENAME_MEMORYORDERENTRY:

				RandomizeDllName(Entry);
				break;

			default:
				RemoveEntryList(&Entry->InMemoryOrderLinks);
				break;
			}
		
		}
		Next = Next->Flink;
	}

	RtlLeaveCriticalSection( (PRTL_CRITICAL_SECTION)NtCurrentPeb()->LoaderLock);
Ring0 - the source of inspiration

User avatar
Brock
Posts: 212
Joined: Wed Apr 28, 2010 3:13 am
Location: Valparaiso, Florida USA
Contact:

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by Brock » Mon Oct 12, 2015 12:37 pm

As EP_X0FF pointed out, you need to engage the loader lock so the module list doesn't change during enumeration of loaded modules. Also, in case you're unaware Kerpow1, modules hidden through PEB hiding can still be identified/discovered from usermode with PSAPI!GetMappedFileNameA/W or by calling NtQueryVirtualMemory directly with the MemorySectionName information class. So, this PEB unlinking doesn't defeat lower-level methods of virtual memory enumeration and name querying
Accept nothing less than STATUS_SUCCESS

kerpow1
Posts: 32
Joined: Sat Aug 15, 2015 7:15 am

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by kerpow1 » Mon Oct 12, 2015 4:58 pm

Yeh I see that HookShark uses ZwQueryVirtualMemory or something similar to have a view of the entire PEB for its analysis tool.

This ofc isn't strong and is limited, I am looking into VAD currently as I see this is the ideal approach.

User avatar
Brock
Posts: 212
Joined: Wed Apr 28, 2010 3:13 am
Location: Valparaiso, Florida USA
Contact:

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by Brock » Tue Oct 13, 2015 6:31 am

Yeah, that's where ZwQueryVirtualMemory(MemorySectionName) gets its info from, the VAD tree for the specified process
Accept nothing less than STATUS_SUCCESS

kerpow1
Posts: 32
Joined: Sat Aug 15, 2015 7:15 am

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by kerpow1 » Wed Oct 14, 2015 5:53 pm

I am trying approach of removing vad currently, BlackBone method seems like it doesn't work, Darkthon himself posting some issues he was having but never submitted a revision.

Do you know of any other documentation on hiding a dll from VAD that may be useful? Thanks

kerpow1
Posts: 32
Joined: Sat Aug 15, 2015 7:15 am

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by kerpow1 » Thu Oct 15, 2015 7:13 am

Sorry for bump, so i have got vad working and checking against;

pchunter, powertools, gmer, hookshark (32 and 64) my module that i inject into spawned svchost is hidden, i cannot locate it anywhere.

now when i test with process hacker x64 (driver disabled) and check strings then mapped, private i can clearly see the memory of my dll and the name but searching for handle/dll in process hacker returns no result. question is am i missing something here?

thanks

User avatar
Brock
Posts: 212
Joined: Wed Apr 28, 2010 3:13 am
Location: Valparaiso, Florida USA
Contact:

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by Brock » Thu Oct 15, 2015 3:39 pm

VMMAP will probably list the regions too then. Sounds like your code is incorrect but most importantly why "hide" a DLL to begin with? Sounds a bit sketchy tbh since it's mostly used to evade game cheat detection software.
Accept nothing less than STATUS_SUCCESS

kerpow1
Posts: 32
Joined: Sat Aug 15, 2015 7:15 am

Re: Module (PEB/LDR) Hiding (4 Methods)

Post by kerpow1 » Thu Oct 15, 2015 4:31 pm

Yes whether it is to do with evasion or protection, same principle. My code is correct but I guess there is a way to still review the modules code/text section which tools like phacker use. Maybe someone is familiar with the methods phacker uses.

Post Reply