# Process Hollowing

Process Hollowing is the technique in which we can modify the process before it starts executing.

By starting the process in `Suspended` mode using the CreateProcess API.

### CreateProcess API

CreateProcess API will do 3 things before starting the execution of the binary

1. It will allocate the virtual memory space for the new process
2. It will allocate the stack along with TEB (Thread Environment Block) and PEB (Process Environment Block)
3. It will loads the DLLs and the EXE to the memory.

### Key points required for process hollowing

1. **zwqueryinformationprocess** : It is a winapi call which can be used to retrieve information about the process.

```csharp
NTSTATUS WINAPI ZwQueryInformationProcess(
  _In_      HANDLE           ProcessHandle,
  _In_      PROCESSINFOCLASS ProcessInformationClass,
  _Out_     PVOID            ProcessInformation,
  _In_      ULONG            ProcessInformationLength,
  _Out_opt_ PULONG           ReturnLength
);
```

* ProcessHandle: Handle to the Process
* ProcessInformationClass: Type of information to be retrieved from the process
* ProcessInformation:
* ProcessInformationLength:
* ReturnLength:

#### ProcessInformationClass

We will select the `ProcessBasicInformation` which is `0` because we need the PEB address, the whole table is present [here](https://docs.microsoft.com/en-us/windows/win32/procthread/zwqueryinformationprocess)

We need PEB address because we can then find the `base address` of the executable, then it can be parsed in order to find the `Entrypoint` of the EXE.

#### WorkFlow (To find BaseAddress of executable)

```
ProcessInformationClass --> ProcessBasicInformation --> PEB address --> 0x10 bytes into PEB --> Base Address of Executable Reached 
```

1. Now, We have the PEB address but we can not read it, because it's on a remote process. So in order to read it we can use `ReadProcessMemory`.

#### ReadProcessMemory

This will be used to read the contents of the PEB at offset of `0x10`

#### PE File Structure (Read more at [Here](obsidian://open?vault=OSEP_NOTES\&file=PE%20Header))

After reaching to the base address, we will read `0x200` bytes (using `ReadProcessMemory`) from the base address.

#### Workflow (To read the offset to e\_lfanew)

By analysing these `0x200` bytes, we will find the address of `e_lfanew` at `0x3c` offset from the base address of executable.

```
Base Address of Executable Reached  --> ReadProcessMemory --> 0x200 bytes  --> inspect the 0x200 memory space locally --> 0x3c from base address locally --> e_lfanew reached
```

* **e\_lfanew**: 4 byte offset which tells us where the PE header is located (offset to PE Header)
* ADD the offset we got from `e_lfanew` to `BaseAddress of executable`

```
e_lfanew offset + base address of executable == PE Header memory address
```

Now we need to navigate to the `AddressofEntryPoint` which is `0x28` from the **PE header** location

```
PE Header memory address --> 0x28 --> AddressofEntryPoint (we got offset as its RVA)
```

#### AddressofEntryPoint (0x28 from PE Header)

Here we will get the RVA for `Entrypoint` of the application, and RVA is just an `offset` so it needs to be Added with the base address of the remote proccess to find the absolute virtual memory address.

```
Base Address of Executable Reached --> ADD RVA in it --> Base address of the entrypoint of application is reached.
```

### Case Study

**Steps before actual calculations**

1. Start the process in `Suspended` mode
2. Use `zwqueryinformationprocess` to find the PEB Address

**Now Actual Case Study**

* we have the PEB Address: `0x3004000`

**Task: Find the memory address of the entrypoint of the application**

1. We ADD `0x10` in PEB Address == (`0x3004010`) -> to find the Base Address of the executable, we read the value of the address above and it comes out as `0x7ffff01000000`

* Base Address of the Executable == `0x7ffff01000000`

1. Read the `0x200` bytes using `ReadProcessMemory` for inspecting locally
2. Check the `0x3c` location from `Base Address of the Executable` == `0x7ffff0100003c` to find the e\_lfanew header

* e\_lfanew header at `0x7ffff0100003c` will give the offset to `PE Header`
* `PE Header` the offset we got is `0x110`

1. Add the total offset bytes to the `Base Address of the Executable` -> `0x7ffff01000000` + `0x110` == `0x7ffff01000110`

* So PE Header is at `0x7ffff01000110`

1. From PE Header, we need to read `0x28` ahead in order to find the RVA for `Entrypoint` of the application

* PE Header memory address + `0x28` -> `0x7ffff01000110` + `0x28` == `0x7ffff01000138`
* RVA memory address found (`0x7ffff01000138`)
* So navigating to this address will lead us to the `Entrypoint of the application`

1. Add the offset received from RVA to `Base Address of the Executable`

```
PEB Address -> base address of executable (0x10) -> e_lfanew (base address of executable + 0x3c) -> PE Header (offset got from e_lfanew + base address of executable) -> RVA to Application entry point (PE Header + 0x28 bytes)
```

1. Now we just need to overwrite the memory space from this `Base Address of the Executable` with our shellcode to run it
