#pragma once
#include <Windows.h>
// basicly rewrite from github.com/hasherezade/pe_to_shellcode
// thanks to @hasherezade 's project!

char stub32[] = "\x60\x6a\x30\x58\x64\x8b\x00\x8b\x40\x0c\x8b\x70\x0c\xad\x96\xad\x8b\x68\x18\xe8\x11\x00\x00\x00\x7a\x8e\x25\xe9\xff\x1f\x7c\xc9\x8d\xbd\xc1\x3f\x4a\x0d\xce\x09\x00\x5e\x89\xeb\x8b\x45\x3c\x03\x5c\x05\x78\x99\x89\xe8\x89\xef\x42\x03\x43\x20\x03\x3c\x90\x83\xc8\xff\x32\x07\x6a\x08\x59\xd1\xe8\x73\x05\x35\x20\x83\xb8\xed\xe2\xf5\x47\x38\x0f\x75\xeb\xf7\xd0\x39\x06\x75\xd7\x89\xef\x89\xe8\x03\x7b\x24\x0f\xb7\x3c\x57\x03\x43\x1c\x8b\x04\xb8\x01\xe8\x50\xad\x2a\x0e\x75\xbe\x8b\x74\x24\x34\x8b\x6e\x3c\x01\xf5\xb5\x30\x6a\x40\x51\xff\x75\x50\x6a\x00\xff\x54\x24\x10\x50\x89\xe3\x8b\x4d\x54\x89\xc7\x56\xf3\xa4\x5e\x66\x8b\x4d\x14\x8d\x54\x0d\x18\x66\x8b\x4d\x06\x97\x60\x03\x72\x14\x03\x7a\x0c\x8b\x4a\x10\xf3\xa4\x61\x83\xc2\x28\xe2\xee\x60\xb1\x80\x8b\x2c\x29\x85\xed\x74\x3b\x01\xfd\x8b\x4d\x0c\xe3\x34\x03\x0b\x51\xff\x53\x08\x91\x8b\x7d\x10\x8b\x75\x00\x85\xf6\x0f\x44\xf7\x03\x33\x03\x3b\xad\x85\xc0\x74\x14\x0f\xba\xf0\x1f\x72\x04\x03\x03\x40\x40\x51\x50\x51\xff\x53\x0c\x59\xab\xeb\xe7\x83\xc5\x14\xeb\xc7\x61\xb1\xa0\x8d\x54\x0d\x00\x03\x3a\x31\xc9\x60\x8b\x4f\x04\x83\xe9\x08\x99\x0f\xb7\x44\x17\x08\x50\x80\xe4\xf0\x80\xfc\x30\x58\x75\x12\x80\xe4\x0f\x03\x07\x03\x03\x8b\x30\x2b\x75\x34\x03\x33\x89\x30\x31\xc0\x85\xc0\x75\x22\x42\x42\x39\xd1\x7f\xd5\x61\x03\x4f\x04\x03\x7f\x04\x39\x4a\x04\x7f\xc1\x31\xc9\x51\x51\x49\x51\xff\x53\x10\x8b\x45\x28\x03\x03\xff\xd0\x8d\x63\x14\x61\xc2\x04\x00";
bool overwrite_hdr(BYTE* my_exe, size_t exe_size, DWORD raw)
{
	BYTE redir_code[] = "\x90" //"\x4D" //dec ebp
		"\x90" //"\x5A" //pop edx
		"\x90" //"\x45" //inc ebp
		"\x90" //"\x52" //push edx
		"\xE8\x00\x00\x00\x00" //call <next_line>
		"\x5B" // pop ebx
		"\x48\x83\xEB\x09" // sub ebx,9
		"\x53" // push ebx (Image Base)
		"\x48\x81\xC3" // add ebx,
		"\x59\x04\x00\x00" // value
		"\xFF\xD3" // call ebx
		"\xc3"; // ret

	size_t offset = sizeof(redir_code) - 8;

	memcpy(redir_code + offset, &raw, sizeof(DWORD));
	memcpy(my_exe, redir_code, sizeof(redir_code));
	return true;
}
char* shellcodify(char* my_exe, DWORD exe_size, DWORD& out_size)
{
	out_size = 0;
	size_t stub_size = sizeof(stub32);
	size_t ext_size = exe_size + stub_size;
	char* ext_buf = (char*)VirtualAlloc(0, ext_size, 0x3000, PAGE_EXECUTE_READWRITE);
	if (!ext_buf) {
		return nullptr;
	}
	memcpy(ext_buf, my_exe, exe_size);
	memcpy(ext_buf + exe_size, stub32, stub_size);

	DWORD raw_addr = exe_size;
	overwrite_hdr((PBYTE)ext_buf, ext_size, raw_addr);

	out_size = ext_size;
	return ext_buf;
}