
Change Module Name at Runtime
Created the Monday 18 July 2022. Updated 3 weeks, 4 days ago.
It is possible to change the name of the current process or any of its modules at runtime. This is achieved by accessing the process PEB’s member ‘Ldr’, in particular it has a member ‘InOrderMemoryLinks’ which we can iterate through to get a list of the process’s modules.
On each iteration it gets a PLDR_DATA_TABLE_ENTRY
structure to work with which contains a member UNICODE_STRING FullDllName
, which can be overwritten with the module name.
Technique Identifier
Code Snippets
// changeModuleNameRuntime.cpp : This file contains the 'main' function. Program execution begins and ends there.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <Windows.h>
#include <Winternl.h>
typedef struct _MYPEB {
UCHAR InheritedAddressSpace;
UCHAR ReadImageFileExecOptions;
UCHAR BeingDebugged;
UCHAR Spare;
PVOID Mutant;
PVOID ImageBaseAddress;
PEB_LDR_DATA* Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PVOID FastPebLockRoutine;
PVOID FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID* KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PVOID FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID* ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
UCHAR Spare2[0x4];
ULARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID** ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper; //PPS_POST_PREOCESS_INIT_ROUTINE?
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
PVOID ProcessWindowStation;
} MYPEB, * PMYPEB;
void ChangeModuleName(wchar_t* szModule, wchar_t* newName)
{
PPEB PEB = (PPEB)__readgsqword(0x60);
_LIST_ENTRY* f = PEB->Ldr->InMemoryOrderModuleList.Flink;
bool Found = FALSE;
while (!Found)
{
PLDR_DATA_TABLE_ENTRY dataEntry = CONTAINING_RECORD(f, LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
if (wcsstr(dataEntry->FullDllName.Buffer, szModule) != NULL)
{
wcscpy(dataEntry->FullDllName.Buffer, newName);
Found = TRUE;
return;
}
f = dataEntry->InMemoryOrderLinks.Flink;
}
}
int main()
{
ChangeModuleName((wchar_t*)L"myApplication.exe", (wchar_t*) L"NEW_MODULE_NAME"); //you can also change to a module name with no file extension if you want to hide your module
}