> For the complete documentation index, see [llms.txt](https://www.redteam.fail/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.redteam.fail/osep-notes/process-injection/vanilla-process-injection.md).

# Vanilla Process Injection

#### Process Injection

In order to perform vanilla process Injection we require three following Win32 api calls

* VirtualAllocEx
* WriteProcessMemory
* CreateRemoteThread

**VirtualAllocEx**

This Win32 API call is used for allocating space in the memory space of the remote process or current process (depends upon the parsed process)

\[syntax]

```csharp
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress, 
  uint dwSize, uint flAllocationType, uint flProtect);
```

\[Argument Explanation]

* hProcess: The handle of the remote process or current process to be passed as IntPtr
* lpAddress: The desired address in the memory space as we want this to be automatically allocated we will pass IntPtr.Zero so that API can allocate space automatically
* dwSize: Size to be allocated (In Bytes) for example 0x1000 (passed for 1000 bytes)
* flAllocationType: This is to specify the type of memory allocation:
  * MEM\_COMMIT: Allocates memory charges (from the overall size of memory and the paging files on disk) for the specified reserved memory pages (0x1000)
  * MEM\_RESERVE: Reserves a range of the process's virtual address space without allocating any actual physical storage in memory or in the paging file on disk (0x2000)
  * In order to pass them together in the API Call we will pass them as 0x3000
* flProtect: This parameter specifies the memory protection for the region of pages to be allocated, for us we need Read, Write and Execute permissions so the constant value for it is 0x40

\[Final Form]

```csharp
IntPtr addr = VirtualAllocEx(hProcess, IntPtr.Zero, 0x1000, 0x3000, 0x40);
```

**WriteProcessMemory**

This Win32 API call is used for writing the shellcode to the allocated memory space

\[syntax]

```csharp
[DllImport("kernel32.dll")]
static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, 
    byte[] lpBuffer, Int32 nSize, out IntPtr lpNumberOfBytesWritten);
```

\[Argument Explanation]

* hProcess: The handle of the remote process or current process to be passed as IntPtr
* lpBaseAddress: It requires the handle to the memory space we allocated earlier
* lpBuffer: The Buffer to be copied (the shellcode basically)
* nSize: The length of the buffer (buf.length)
* lpNumberOfBytesWritten: It requires a pointer to the memory to output how much data was copied, basically we don't need this so we will create a fake variable as IntPtr and pass it.

\[Final Form]

```csharp
IntPtr outSize;
WriteProcessMemory(hProcess, addr, buf, buf.Length, out outSize);
```

**CreateRemoteThread**

This Win32 API call will create a thread which will run in the virtual address space of another process

\[syntax]

```csharp
[DllImport("kernel32.dll")]
static extern IntPtr CreateRemoteThread(IntPtr hProcess, IntPtr lpThreadAttributes, 
 uint dwStackSize, IntPtr lpStartAddress, IntPtr lpParameter, uint dwCreationFlags, IntPtr lpThreadId);
```

\[Argument Explanation]

* hProcess: The handle of the remote process or current process to be passed as IntPtr
* lpThreadAttributes: This is to specify a security descriptor for the new thread which will determine if child process can inherit, we don't need this hence we will pass as `IntPtr.Zero` as NULL.
* dwStackSize: The initial size of stack in bytes, we will pass `0` so new thread will use default size
* lpStartAddress: We will pass the pointer of the memory space which we allocated and written earlier
* lpParameter: This parameter is for any arguments to be passed with the function, which we currently don't have so we will pass `IntPtr.Zero` as NULL
* dwCreationFlags: This flag will control what happens after the thread is created, we will pass `0` so that it starts executing immediately after cration
* lpThreadId: Pointer to a variable that receives the thread identifier, we don't need this so we will pass `IntPtr.Zero` as NULL

\[Final Form]

```csharp
IntPtr hThread = CreateRemoteThread(hProcess, IntPtr.Zero, 0, addr, IntPtr.Zero, 0, IntPtr.Zero);
```

These are all the Win32 API calls which is needed for process injection, I will not post any code because already a lot of examples are available publicly so the best idea is to supply a link to the Exact Process Injection code available online:

* Process Injection By [Chvancooten](https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/Shellcode%20Process%20Injector)

`Note: These are my personal notes which might be inaccurate`


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://www.redteam.fail/osep-notes/process-injection/vanilla-process-injection.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
