How to hide dll
Pn (Pnluck) <pn_luckyahooit> Sunday, August 5 2007 07:58.36 CDT


Time ago I wrote a little function, which called at the DLL_PROCESS_ATTACH in the DllMain, allowed to hide the dll itself.

BOOL APIENTRY DllMain( HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
if(ul_reason_for_call == DLL_PROCESS_ATTACH)
{
HideDll((ULONG_PTR)hModule);
}
return TRUE;
}

The function hooks the LDR_MODULE structure (it is accessible from PEB), as you can see:

bool HideDll(ULONG_PTR DllHandle)
{
ULONG_PTR ldr_addr;
PEB_LDR_DATA* ldr_data;
LDR_MODULE  *modulo, *prec, *next;

__try
{

/*
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
...
} PEB
*/
      
        //The asm code is only for IA-32 architecture
__asm mov eax, fs:[0x30]  //get il PEB ADDR
__asm add eax, 0xc        
        __asm mov eax,[eax]      //get LoaderData ADDR
__asm mov ldr_addr, eax

ldr_data = (PEB_LDR_DATA*)ldr_addr ;  //init PEB_LDR_DATA struct.

modulo = (LDR_MODULE*)ldr_data->InLoadOrderModuleList.Flink;

while(modulo->BaseAddress != 0)
{
if( (ULONG_PTR)modulo->BaseAddress == DllHandle)
{
if(modulo->InInitializationOrderModuleList.Blink == NULL) return false;

//Get the precedent and the successive struct according to the initialization order
prec = (LDR_MODULE*)(ULONG_PTR)((ULONG_PTR)modulo->InInitializationOrderModuleList.Blink - 16);
next = (LDR_MODULE*)(ULONG_PTR)((ULONG_PTR)modulo->InInitializationOrderModuleList.Flink - 16);

//And change values
prec->InInitializationOrderModuleList.Flink = modulo->InInitializationOrderModuleList.Flink;
next->InInitializationOrderModuleList.Blink = modulo->InInitializationOrderModuleList.Blink;
  
    //Now change  InLoad e InMem normally
prec = (LDR_MODULE*)modulo->InLoadOrderModuleList.Blink;
next = (LDR_MODULE*)modulo->InLoadOrderModuleList.Flink;

//Precedent struct
prec->InLoadOrderModuleList.Flink = modulo->InLoadOrderModuleList.Flink;
prec->InMemoryOrderModuleList.Flink = modulo->InMemoryOrderModuleList.Flink;

//Successive struct
next->InLoadOrderModuleList.Blink = modulo->InLoadOrderModuleList.Blink;
next->InMemoryOrderModuleList.Blink = modulo->InMemoryOrderModuleList.Blink;

                        //Now if you want: memset(modulo,0,sizeof(LDR_MODULE));
            
return true;
}
modulo = (LDR_MODULE*)modulo->InLoadOrderModuleList.Flink;
}

}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return false;
}


Structures used are:

#ifndef UNICODE_STRING
typedef struct _UNICODE_STRING {
  USHORT  Length;
  USHORT  MaximumLength;
  PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
#endif

#ifndef LDR_MODULE
typedef struct _LDR_MODULE {
LIST_ENTRY InLoadOrderModuleList;  //<-- InLoad points here
LIST_ENTRY InMemoryOrderModuleList; //<-- PInMem points here
LIST_ENTRY InInitializationOrderModuleList;  //<-- InInitia points here
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;
#endif

#ifndef PEB_LDR_DATA
typedef struct _PEB_LDR_DATA
{
         ULONG Length;
         UCHAR Initialized;
         PVOID SsHandle;
         LIST_ENTRY InLoadOrderModuleList;
         LIST_ENTRY InMemoryOrderModuleList;
         LIST_ENTRY InInitializationOrderModuleList;
         PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
#endif


That's all!

Comments
Pnluck Posted: Sunday, August 5 2007 08:03.39 CDT
I tested it on winxp sp2, but not on vista, can anyone test it on vista??
Thx

Pnluck Posted: Saturday, July 5 2008 11:16.52 CDT
This is the win64 version of list dll


void ListDll()
{
PEB_LDR_DATA* ldr_data;
LDR_MODULE  *module;
ULONG_PTR *PEB;

__try
{
PEB = (ULONG_PTR *) (*(ULONG_PTR *) ( (ULONG_PTR) __readgsqword(0x30)  + 0x60 ));
ldr_data = (PEB_LDR_DATA*) (*(ULONG_PTR *)((ULONG_PTR)PEB + 0x18));


module = (LDR_MODULE*)ldr_data->InLoadOrderModuleList.Flink;

//ora listo tutte le dll presenti
while(module->BaseAddress != 0)
{
_tprintf(TEXT("%08llx \t %s\n"),(ULONG_PTR)module->BaseAddress,module->BaseDllName.Buffer);
module = (LDR_MODULE*)module->InLoadOrderModuleList.Flink;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return;
}
}


a911 Posted: Thursday, April 16 2009 13:47.17 CDT
I use some kind of this code, but cut down to:

#define CUT_LIST(item) \
    item.Blink->Flink = item.Flink; \
    item.Flink->Blink = item.Blink

void HideModule(HMODULE hModule)
{
    ULONG_PTR DllHandle = (ULONG_PTR)hModule;
    PPEB_LDR_DATA pebLdrData;
    PLDR_MODULE mod;

    __asm {
        mov eax, fs:[0x30]        //get PEB ADDR
        add eax, 0x0C        
        mov eax, [eax]            //get LoaderData ADDR
        mov pebLdrData, eax
    }

    for (
        mod = (PLDR_MODULE)pebLdrData->InLoadOrderModuleList.Flink;
        mod->BaseAddress != 0;
        mod = (PLDR_MODULE)mod->InLoadOrderModuleList.Flink
    ) {
        if ((HMODULE)mod->BaseAddress == hModule) {
            CUT_LIST(mod->InLoadOrderModuleList);
            CUT_LIST(mod->InInitializationOrderModuleList);
            CUT_LIST(mod->InMemoryOrderModuleList);
        
            ZeroMemory(mod, sizeof(LDR_MODULE));
            return;
        }
    }
}