# Storing Payload in .text Section

## <mark style="color:red;">.text</mark>

known as a text segment or simply as text, is a portion of an object file or the corresponding section of the program's virtual address space that contains executable instructions

this is the most common way to store your payload in a PE file, here what you do is try to add your malicious code to the **main** function of the program

```python
#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 (you can use any payload you want)
	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;
}
```

to store the payload in .text section we should create a free memory space in the program process and it should be as long as the payload and give it read,write permissions so we can copy our payload to this memory space and then give the memory space read, execute permissions so we can execute the payload in a new Thread

you can be wondering why when we allocated the new memory buffer we gave it only read write permissions and when we copied the payload to this memory buffer then we gave it execute permission, why we don't give it read write execute permissions when we allocated the memory buffer ?

simply because it will be detected by the windows defender because allocating a memory space that have full permissions is suspicious so this is why we're doing like this to bypass this

### <mark style="color:red;">exec\_mem = VirtualAlloc(0, payload\_len, MEM\_COMMIT | MEM\_RESERVE, PAGE\_READWRITE);</mark>

It is using the Windows API function VirtualAlloc to allocate a block of memory in the process's virtual address space. The VirtualAlloc function takes four arguments:

docs => <mark style="color:blue;">**<https://learn.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc>**</mark>

```cpp
LPVOID VirtualAlloc(
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);
```

1. <mark style="color:purple;">**lpAddress:**</mark> This parameter is set to **0** in this example, which indicates that the operating system should determine the base address of the allocated memory block.
2. <mark style="color:purple;">**dwSize:**</mark> This parameter is set to **payload\_len**, which specifies the size, in bytes, of the memory block to be allocated.
3. <mark style="color:purple;">**flAllocationType:**</mark> This parameter is set to **MEM\_COMMIT | MEM\_RESERVE**. MEM\_COMMIT specifies that the pages should be committed, or physically allocated in the system's memory. MEM\_RESERVE specifies that the pages should be reserved, but not initially committed. This means that the operating system will reserve the necessary space in the virtual address space of the process, but will not allocate any physical memory until it is actually needed.
4. <mark style="color:purple;">**flProtect:**</mark> This parameter is set to **PAGE\_READWRITE**, which specifies the protection attributes of the memory pages. In this case, the pages will have read and write access, but not execute access.&#x20;
5. <mark style="color:purple;">**exec\_mem:**</mark> is a variable name that appears to be used to refer to a pointer to the block of memory that is being allocated by the VirtualAlloc() function call
6. Overall, this line of code is allocating a block of memory in the process's virtual address space with a specified size, protection attributes, and allocation type. The memory block can be used to store executable code or other data in our case we will store our payload and execute it.

### <mark style="color:red;">RtlMoveMemory(exec\_mem, payload, payload\_len);</mark>

**RtlMoveMemory** is a Windows API function that is used to copy a block of memory from one location to another. In the provided code snippet, RtlMoveMemory is being used to copy the payload buffer into the memory block that was allocated using VirtualAlloc() and stored in the exec\_mem pointer.

```cpp
VOID RtlMoveMemory(
  _Out_       VOID UNALIGNED *Destination,
  _In_  const VOID UNALIGNED *Source,
  _In_        SIZE_T         Length
);   
```

Here's a breakdown of the parameters being passed to RtlMoveMemory:

1. <mark style="color:purple;">**Destination:**</mark> The first parameter is the destination buffer, which is the exec\_mem pointer. This tells the function where to copy the source buffer to.
2. <mark style="color:purple;">**Source:**</mark> The second parameter is the source buffer, which is payload. This is the data that will be copied into the destination buffer.
3. <mark style="color:purple;">**Length:**</mark> The third parameter is the length of the data to be copied, which is payload\_len. This specifies the number of bytes to be copied from the source buffer to the destination buffer.
4. Overall, the RtlMoveMemory function is being used in this code snippet to copy the contents of the payload buffer into the allocated memory block pointed to by exec\_mem. This is typically done when the payload buffer contains executable code that needs to be executed later. By copying the code into the allocated memory block, it becomes possible to execute the code by jumping to the memory location pointed to by the exec\_mem pointer.

### <mark style="color:red;">rv = VirtualProtect(exec\_mem, payload\_len, PAGE\_EXECUTE\_READ, \&oldprotect);</mark>

In the provided code snippet, rv is a variable that is being used to store the return value of the VirtualProtect() function call.

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

Here's a breakdown of the parameters being passed to VirtualProtect():

1. <mark style="color:purple;">**lpAddress:**</mark> The first parameter is the starting address of the memory region to be modified, which is the exec\_mem pointer. This tells the function which memory block to modify.
2. <mark style="color:purple;">**dwSize:**</mark> The second parameter is the size of the memory region to be modified, which is payload\_len. This specifies the number of bytes to modify starting from the address pointed to by exec\_mem.
3. <mark style="color:purple;">**flNewProtect:**</mark> The third parameter specifies the new memory protection level to apply to the memory region. In this case, it is set to PAGE\_EXECUTE\_READ, which allows the memory region to be executed as well as read.
4. <mark style="color:purple;">**lpflOldProtect:**</mark> The fourth parameter is a pointer to a variable that will receive the previous protection level of the memory region. In this case, it is the oldprotect variable.

The VirtualProtect() function returns a nonzero value if the function call succeeds, indicating that the memory protection level was changed successfully. If the function call fails, it returns zero.

The return value of VirtualProtect() is being stored in the rv variable, which can be used later in the program to determine if the function call was successful or not.

### <mark style="color:red;">The last Piece of our Code</mark>

```c
if ( rv != 0 ) {
    th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
    WaitForSingleObject(th, -1);
}
```

In the provided code snippet, the return value of the VirtualProtect() function call is being checked to see if it is nonzero. If the return value is nonzero, it indicates that the memory protection level was changed successfully.

If the return value of **VirtualProtect()** is **nonzero**, the code block inside the if statement is executed. Here is what is happening inside that code block:

A new thread is created using the **CreateThread()** function. This function creates a new thread to execute the code specified in the **exec\_mem** pointer.

```cpp
HANDLE CreateThread(
  [in, optional]  LPSECURITY_ATTRIBUTES   lpThreadAttributes,
  [in]            SIZE_T                  dwStackSize,
  [in]            LPTHREAD_START_ROUTINE  lpStartAddress,
  [in, optional]  __drv_aliasesMem LPVOID lpParameter,
  [in]            DWORD                   dwCreationFlags,
  [out, optional] LPDWORD                 lpThreadId
);
```

1. <mark style="color:purple;">**lpThreadAttributes:**</mark> The first parameter of CreateThread() is set to 0, which means that the new thread will inherit the default security attributes of the calling process.
2. <mark style="color:purple;">**dwStackSize:**</mark> The second parameter of CreateThread() is also set to 0, which means that the new thread will use the default stack size for the calling thread.
3. <mark style="color:purple;">**lpStartAddress:**</mark> The third parameter of CreateThread() is cast to an LPTHREAD\_START\_ROUTINE type, which is a function pointer that specifies the starting address of the thread. In this case, it is set to the exec\_mem pointer, which points to the memory block that was previously filled with executable code.
4. <mark style="color:purple;">**lpParameter:**</mark> The fourth and fifth parameters of CreateThread() are set to 0, which means that no arguments are passed to the thread function and the thread will run immediately after creation.
5. <mark style="color:purple;">**dwCreationFlags:**</mark> The last parameter of CreateThread() is also set to 0, which means that the thread is created with default creation flags.
6. <mark style="color:purple;">**lpThreadId:**</mark>  this parameter is optional and is not specified in the code snippet

```cpp
DWORD WaitForSingleObject(
  [in] HANDLE hHandle,
  [in] DWORD  dwMilliseconds
);
```

The WaitForSingleObject() function is called with these parameters :&#x20;

1. <mark style="color:purple;">**hHandle:**</mark>  th handle is the first parameter (th is a handle to the thread executing the memory space where we have copied the payload)and this tells the function to wait for the thread to complete before continuing execution
2. <mark style="color:purple;">**dwMilliseconds:**</mark> The second parameter is -1 this tells the function to wait indefinitely.

Overall, the code block inside the if statement is being used to create a new thread that executes the code in the exec\_mem memory block ,which was previously filled with executable code <mark style="color:orange;">**(Payload)**</mark> using RtlMoveMemory(). By waiting for the thread to complete using WaitForSingleObject(), the program ensures that the code in the memory block has been executed before continuing with the rest of the program.
