http://www.openrce.org/blog/view/844/How_to_hide_dllQuote:
The 'CloakDLL' code is not a "prank" by any means, this method of hiding your module from the PEB list has been a known working means of evading detection by VAC2 (VALVE ANTI-CHEAT) for some years now. If you're familiar with the site OpenRCE as I'm sure you are, Pnluck posted an article detailing this a couple years ago:
Please refer to the CloakDll referenced in one of the previous posts in this thread. In particular, pay close attention to how the PEB address is calculated and compare this to how the PEB address is calculated in your link. The PEB address in the above Cloakdll is based on a "local" memory calculation. The code in the link has the PEB address calculated on the "remote" targeted memory. That is because it is calculated in the injected DLL. The PEB of the "remote" targeted memory is what is required to cloak a module. Secondly, look at the naked function in the above listed CloakDll. Do you notice all the C statements in this naked function????? Those C statements should be translated to inline assembly.
A cursory review of the code in your posted link gives me the impression that it probably would work. Although I have not tested it.
But anyway, here is a "sanitized" version of my Cloaking util which has only been tested on XP SP2 and lower. It has not been tested on Vista. It will only enumerate the loaded modules in the remote process. It will NOT cloak any modules because I've removed the necessary statements that actually cloak the module since this is a PG13 board and they frown on anything hacking related.
But anyway, if you wish to discuss this further, please post a reference to this issue on the SysInternals site. I won't stopping in here too often.Code:#pragma comment(lib, "advapi32.lib")
#pragma comment(lib, "shlwapi.lib")
#include<windows.h>
#include <stdio.h>
#include <tlhelp32.h>
#include <shlwapi.h>
typedef struct _UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
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_DATA_ENTRY , *PLDR_DATA_ENTRY;
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 _PEB
{
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN SpareBool;
HANDLE Mutant;
HMODULE ImageBaseAddress;
PPEB_LDR_DATA LdrData;
int *ProcessParameters;
PVOID SubSystemData;
HANDLE ProcessHeap;
PRTL_CRITICAL_SECTION FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
int TlsBitmap;
ULONG TlsBitmapBits[2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID *ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID *ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG ImageProcessAffinityMask;
ULONG GdiHandleBuffer[34];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
ULONG TlsExpansionBitmapBits[32];
ULONG SessionId;
} PEB, *PPEB;
VOID DisplayError( CHAR * pMessage )
{
DWORD eNum;
CHAR sysMsg[256] = {0};
CHAR* p;
eNum = GetLastError( );
FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, eNum,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
sysMsg, 256, NULL );
p = sysMsg;
while( ( *p > 31 ) || ( *p == 9 ) )
++p;
do { *p-- = 0; } while( ( p >= sysMsg ) &&
( ( *p == '.' ) || ( *p < 33 ) ) );
printf( "\n%s error %d (%s)", pMessage, eNum, sysMsg );
}
BOOL EnableDebugPrivilege( BOOL Enable )
{
BOOL Success = FALSE;
HANDLE hToken = NULL;
do
{
if( !OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken ) )
{
DisplayError("OpenProcessToken failed");
break;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
if( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid ) )
{
DisplayError("LookupPrivilegeValue failed");
break;
}
tp.Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0;
if( !AdjustTokenPrivileges( hToken, FALSE, &tp, sizeof(tp), NULL, NULL ) )
{
DisplayError("AdjusttokenPrivileges failed");
break;
}
Success = TRUE;
}
while( 0 );
if( hToken != NULL )
{
if( !CloseHandle( hToken ) )
DisplayError("CloseHandle failed");
}
return Success;
}
DWORD GetProcessId( CHAR *pProcessName )
{
PROCESSENTRY32 pe;
HANDLE thSnapshot;
BOOL bReturnValue;
DWORD dwPID = 0;
thSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(thSnapshot == INVALID_HANDLE_VALUE)
{
DisplayError("CreateToolhelp32Snapshot failed");
printf("Unable to create toolhelp snapshot\n");
return 0;
}
pe.dwSize = sizeof(PROCESSENTRY32);
bReturnValue = Process32First(thSnapshot, &pe);
while(bReturnValue)
{
if(StrStrI(pe.szExeFile, pProcessName) )
{
dwPID = pe.th32ProcessID;
break;
}
bReturnValue = Process32Next(thSnapshot,&pe);
}
return dwPID;
}
BOOL HideDLL( CHAR *pProcess, CHAR *pDLL2Hide )
{
char szBuffer[256] = {0};
char szUnicodeBuffer[512] = {0};
DWORD (*addressOfRtlGetCurrentPeb)();
DWORD dwPID = 0;
DWORD dwTargetTID;
PEB * pPebAddress;
PEB * pPebAddress1;
PEB_LDR_DATA * PebLdrData;
LDR_DATA_ENTRY module,lastModule,nextModule;
LIST_ENTRY * ListEntryPointer2FirstModule;
HANDLE hProcess,hRemoteThread;
dwPID = GetProcessId(pProcess);
if(dwPID == 0)
{
printf("Process: %s not found\n", pProcess);
return FALSE;
}
if((addressOfRtlGetCurrentPeb = (DWORD (__cdecl*) (VOID)) GetProcAddress(GetModuleHandle("ntdll"),"RtlGetCurrentPeb"))==NULL)
{
DisplayError("GetProcAddress failed");
return FALSE;
}
if(EnableDebugPrivilege( TRUE ) == FALSE )
{
DisplayError("EnableDebugPrivilege failed");
return FALSE;
}
if((hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,dwPID))==NULL)
{
DisplayError("OpenProcess failed");
return FALSE;
}
if((hRemoteThread = CreateRemoteThread(hProcess,NULL,0,(LPTHREAD_START_ROUTINE)addressOfRtlGetCurrentPeb,NULL,0,&dwTargetTID))==NULL)
{
DisplayError("CreateRemoteThread failed");
CloseHandle( hProcess );
return FALSE;
}
WaitForSingleObject(hRemoteThread,INFINITE);
GetExitCodeThread(hRemoteThread,(LPDWORD)&pPebAddress1);
if(!ReadProcessMemory(hProcess,((BYTE*)pPebAddress1)+0x0c,&PebLdrData,4,NULL))
{
DisplayError("ReadProcessMemory #1 failed");
CloseHandle( hProcess );
return FALSE;
}
if(!ReadProcessMemory(hProcess,((BYTE*)PebLdrData)+0x0c,&ListEntryPointer2FirstModule,4,NULL))
{
DisplayError("ReadProcessMemory #2 failed");
CloseHandle( hProcess );
return FALSE;
}
if(!ReadProcessMemory(hProcess,((BYTE*)ListEntryPointer2FirstModule),&module,sizeof(LDR_DATA_ENTRY),NULL))
{
DisplayError("ReadProcessMemory #3 failed");
CloseHandle( hProcess );
return FALSE;
}
if(!ReadProcessMemory(hProcess,((BYTE*)module.BaseDllName.Buffer),szUnicodeBuffer,module.BaseDllName.Length,NULL))
{
DisplayError("ReadProcessMemory #4 failed");
CloseHandle( hProcess );
return FALSE;
}
WideCharToMultiByte(CP_ACP,0,(LPCWSTR)szUnicodeBuffer,-1,szBuffer,256,NULL,NULL);
do{
printf("%-30s 0x%2x 0x%2x\n",szBuffer, module.BaseAddress, module.SizeOfImage);
if((BYTE *)module.InLoadOrderModuleList.Flink==(((BYTE*)PebLdrData)+0x0c))
break;
if(!ReadProcessMemory(hProcess,((BYTE*)module.InLoadOrderModuleList.Flink),&module,sizeof(LDR_DATA_ENTRY),NULL))
{
DisplayError("ReadProcessMemory #5 failed");
CloseHandle( hProcess );
return FALSE;
}
ZeroMemory(szUnicodeBuffer,512);
if(!ReadProcessMemory(hProcess,((BYTE*)module.BaseDllName.Buffer),szUnicodeBuffer,module.BaseDllName.Length,NULL))
{
DisplayError("ReadProcessMemory #6 failed");
CloseHandle( hProcess );
return FALSE;
}
WideCharToMultiByte(CP_ACP,0,(LPCWSTR)szUnicodeBuffer,-1,szBuffer,256,NULL,NULL);
}while(1);
return TRUE;
}
INT main( INT argc, CHAR **argv )
{
HideDLL(argv[1], argv[2]);
return 0;
}