diff --git a/Efi Bundler/Efi Bundler.vcxproj b/Efi Bundler/Efi Bundler.vcxproj
new file mode 100644
index 0000000..399fcff
--- /dev/null
+++ b/Efi Bundler/Efi Bundler.vcxproj
@@ -0,0 +1,161 @@
+
+
+
+
+ Debug
+ Win32
+
+
+ Release
+ Win32
+
+
+ Debug
+ x64
+
+
+ Release
+ x64
+
+
+
+ 16.0
+ Win32Proj
+ {ee860038-e3dd-4329-8d44-df8b9ecbe420}
+ EfiBundler
+ 10.0
+
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+ Application
+ true
+ v142
+ Unicode
+
+
+ Application
+ false
+ v142
+ true
+ Unicode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+ false
+
+
+ true
+
+
+ false
+
+
+
+ Level3
+ true
+ WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+ Level3
+ true
+ _DEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ false
+ false
+
+
+ Console
+ true
+
+
+
+
+ Level3
+ true
+ true
+ true
+ NDEBUG;_CONSOLE;%(PreprocessorDefinitions)
+ true
+ stdcpp17
+ false
+ Disabled
+ false
+
+
+ Console
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Efi Bundler/Efi Bundler.vcxproj.filters b/Efi Bundler/Efi Bundler.vcxproj.filters
new file mode 100644
index 0000000..4fc8d9a
--- /dev/null
+++ b/Efi Bundler/Efi Bundler.vcxproj.filters
@@ -0,0 +1,35 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/Efi Bundler/Efi Bundler.vcxproj.user b/Efi Bundler/Efi Bundler.vcxproj.user
new file mode 100644
index 0000000..545fb0f
--- /dev/null
+++ b/Efi Bundler/Efi Bundler.vcxproj.user
@@ -0,0 +1,11 @@
+
+
+
+ C:\Users\xerox\Desktop\bootmgfw.efi C:\Users\xerox\Desktop\voyager.efi
+ WindowsLocalDebugger
+
+
+ C:\Users\xerox\Desktop\bootmgfw.efi C:\Users\xerox\Desktop\voyager.efi
+ WindowsLocalDebugger
+
+
\ No newline at end of file
diff --git a/Efi Bundler/bundler.cpp b/Efi Bundler/bundler.cpp
new file mode 100644
index 0000000..5d28d8a
--- /dev/null
+++ b/Efi Bundler/bundler.cpp
@@ -0,0 +1,92 @@
+#include "bundler.h"
+
+namespace bundler
+{
+ std::pair add_section(std::vector& image, const char* name, std::size_t size, std::uint32_t protect)
+ {
+ auto align = [](std::uint32_t size, std::uint32_t align, std::uint32_t addr) -> std::uint32_t
+ {
+ if (!(size % align))
+ return addr + size;
+ return addr + (size / align + 1) * align;
+ };
+
+ auto section_header = reinterpret_cast(
+ ((UINT64)&NT_HEADER(image.data())->OptionalHeader) +
+ NT_HEADER(image.data())->FileHeader.SizeOfOptionalHeader);
+
+ auto new_section = §ion_header[NT_HEADER(image.data())->FileHeader.NumberOfSections];
+ memset(new_section, NULL, sizeof(IMAGE_SECTION_HEADER));
+ memcpy(new_section->Name, name, 8);
+
+ new_section->Characteristics = protect;
+ section_header[NT_HEADER(image.data())->FileHeader.NumberOfSections].Misc.VirtualSize =
+ align(size, NT_HEADER(image.data())->OptionalHeader.SectionAlignment, NULL);
+
+ new_section->VirtualAddress = align(section_header[
+ NT_HEADER(image.data())->FileHeader.NumberOfSections - 1].Misc.VirtualSize,
+ NT_HEADER(image.data())->OptionalHeader.SectionAlignment, section_header[
+ NT_HEADER(image.data())->FileHeader.NumberOfSections - 1].VirtualAddress);
+
+ new_section->SizeOfRawData =
+ align(size, NT_HEADER(image.data())->OptionalHeader.FileAlignment, 0);
+
+ new_section->PointerToRawData =
+ align(section_header[NT_HEADER(image.data())->FileHeader.NumberOfSections - 1].SizeOfRawData,
+ NT_HEADER(image.data())->OptionalHeader.FileAlignment, section_header[NT_HEADER(image.data())->
+ FileHeader.NumberOfSections - 1].PointerToRawData);
+
+ NT_HEADER(image.data())->OptionalHeader.SizeOfImage = section_header[
+ NT_HEADER(image.data())->FileHeader.NumberOfSections].VirtualAddress +
+ section_header[NT_HEADER(image.data())->FileHeader.NumberOfSections].Misc.VirtualSize;
+
+ ++NT_HEADER(image.data())->FileHeader.NumberOfSections;
+ auto raw_data_rva = new_section->PointerToRawData;
+ auto virt_data_rva = new_section->VirtualAddress;
+ auto raw_data_size = new_section->SizeOfRawData;
+
+ image.resize(raw_data_rva + raw_data_size);
+ memset(image.data() + raw_data_rva, NULL, raw_data_size);
+ return { raw_data_rva, virt_data_rva };
+ }
+
+ // module_base is .efi section base in this case...
+ std::uint32_t map_module(std::uint8_t* module_base, std::vector& map_from)
+ {
+ // copy nt headers...
+ memcpy(module_base, map_from.data(), NT_HEADER(map_from.data())->OptionalHeader.SizeOfHeaders);
+ auto sections = reinterpret_cast(
+ (UINT8*)&NT_HEADER(map_from.data())->OptionalHeader +
+ NT_HEADER(map_from.data())->FileHeader.SizeOfOptionalHeader);
+
+ // copy sections...
+ for (auto i = 0u; i < NT_HEADER(map_from.data())->FileHeader.NumberOfSections; ++i)
+ {
+ auto section = §ions[i];
+ memcpy(module_base + section->VirtualAddress, map_from.data() + section->PointerToRawData, section->SizeOfRawData);
+ }
+
+ return NT_HEADER(map_from.data())->OptionalHeader.AddressOfEntryPoint;
+ }
+
+ void bundle(std::vector& bundle_into, std::vector& bundle_module)
+ {
+ auto [trp_section_disk, trp_section_virt] = add_section(bundle_into, ".trp", sizeof shellcode::stub, SECTION_RWX);
+ auto [mod_section_disk, mod_section_virt] = add_section(bundle_into, ".efi", bundle_module.size(), SECTION_RWX);
+ bundler::map_module(bundle_into.data() + mod_section_disk, bundle_module);
+
+ std::printf("[+] added .trp section at rva -> 0x%x, size -> 0x%x\n", trp_section_virt, sizeof shellcode::stub);
+ std::printf("[+] added .efi section at rva -> 0x%x, size -> 0x%x\n", mod_section_virt, bundle_module.size());
+
+ // setup stub shellcode...
+ *reinterpret_cast(&shellcode::stub[25]) = mod_section_virt - trp_section_virt;
+ *reinterpret_cast(&shellcode::stub[45]) = trp_section_virt;
+ *reinterpret_cast(&shellcode::stub[75]) = NT_HEADER(bundle_into.data())->OptionalHeader.AddressOfEntryPoint;
+ memcpy(bundle_into.data() + trp_section_disk, shellcode::stub, sizeof shellcode::stub);
+ std::printf("[+] added stub code to .trp section...\n");
+
+ // set entry point to .trp section...
+ NT_HEADER(bundle_into.data())->OptionalHeader.AddressOfEntryPoint = trp_section_virt;
+ std::printf("[+] changed base modules entry point to -> (.trp section base) 0x%x\n", trp_section_virt);
+ }
+}
\ No newline at end of file
diff --git a/Efi Bundler/bundler.h b/Efi Bundler/bundler.h
new file mode 100644
index 0000000..986d710
--- /dev/null
+++ b/Efi Bundler/bundler.h
@@ -0,0 +1,15 @@
+#pragma once
+#include "shellcode.h"
+#define SECTION_RWX ((IMAGE_SCN_MEM_WRITE | \
+ IMAGE_SCN_CNT_CODE | \
+ IMAGE_SCN_CNT_UNINITIALIZED_DATA | \
+ IMAGE_SCN_MEM_EXECUTE | \
+ IMAGE_SCN_CNT_INITIALIZED_DATA | \
+ IMAGE_SCN_MEM_READ))
+
+namespace bundler
+{
+ std::pair add_section(std::vector& image, const char* name, std::size_t size, std::uint32_t protect);
+ std::uint32_t map_module(std::uint8_t* module_base, std::vector& map_from);
+ void bundle(std::vector& bundle_into, std::vector& bundle_module);
+}
diff --git a/Efi Bundler/main.cpp b/Efi Bundler/main.cpp
new file mode 100644
index 0000000..172bff7
--- /dev/null
+++ b/Efi Bundler/main.cpp
@@ -0,0 +1,38 @@
+#include "bundler.h"
+
+int __cdecl main(int argc, char** argv)
+{
+ if (argc < 2)
+ {
+ std::printf("[!] invalid amount of parameters\n");
+ return -1;
+ }
+
+ std::vector efi_module;
+ std::vector bootmgfw;
+
+ impl::open_binary_file(argv[1], bootmgfw);
+ impl::open_binary_file(argv[2], efi_module);
+
+ if (efi_module.empty() || bootmgfw.empty())
+ {
+ std::printf("[!] unable to load efi module(s)...\n");
+ return -1;
+ }
+
+ efi_module.resize(NT_HEADER(efi_module.data())->OptionalHeader.SizeOfImage);
+ std::printf("bundling efi module, size -> 0x%x\n",
+ NT_HEADER(efi_module.data())->OptionalHeader.SizeOfImage);
+
+ bootmgfw.resize(NT_HEADER(bootmgfw.data())->OptionalHeader.SizeOfImage);
+ std::printf("bundling module into bootmgfw, size before patch -> 0x%x\n",
+ NT_HEADER(bootmgfw.data())->OptionalHeader.SizeOfImage);
+
+ bundler::bundle(bootmgfw, efi_module);
+ std::ofstream new_file("result.efi", std::ios::binary);
+ new_file.write((char*)bootmgfw.data(), bootmgfw.size());
+ new_file.close();
+
+ std::printf("bundled modules together....\n");
+ std::getchar();
+}
\ No newline at end of file
diff --git a/Efi Bundler/shellcode.cpp b/Efi Bundler/shellcode.cpp
new file mode 100644
index 0000000..d695595
--- /dev/null
+++ b/Efi Bundler/shellcode.cpp
@@ -0,0 +1,55 @@
+#include "shellcode.h"
+
+namespace shellcode
+{
+ void* entry_stub(void* a, void* b)
+ {
+ // 0xDEADBEEF is replaced at runtime...
+ auto module_base = reinterpret_cast(&entry_stub) + 0xDEADBEEF;
+ auto bootmgfw_base = reinterpret_cast(&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(module_base + base_reloc_dir->VirtualAddress);
+ for (auto current_size = 0u; current_size < base_reloc_dir->Size; )
+ {
+ auto reloc_count = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(UINT16);
+ auto reloc_data = reinterpret_cast((UINT8*)reloc + sizeof(IMAGE_BASE_RELOCATION));
+ auto reloc_base = reinterpret_cast(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_DIR64:
+ {
+ auto rva = reinterpret_cast(reloc_base + offset);
+ *rva = module_base + (*rva - NT_HEADER(module_base)->OptionalHeader.ImageBase);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+
+ current_size += reloc->SizeOfBlock;
+ reloc = reinterpret_cast(reloc_data);
+ }
+ }
+
+ // call our entry...
+ reinterpret_cast(
+ module_base + NT_HEADER(module_base)->OptionalHeader.AddressOfEntryPoint)(a, b);
+
+ // call the original entry...
+ return reinterpret_cast(
+ bootmgfw_base + NT_HEADER(bootmgfw_base)->OptionalHeader.AddressOfEntryPoint)(a, b);
+ }
+}
\ No newline at end of file
diff --git a/Efi Bundler/shellcode.h b/Efi Bundler/shellcode.h
new file mode 100644
index 0000000..ba7d1c1
--- /dev/null
+++ b/Efi Bundler/shellcode.h
@@ -0,0 +1,76 @@
+#pragma once
+#include
+#include
+#include "utils.h"
+
+namespace shellcode
+{
+ void* entry_stub(void* a, void* b);
+ // void* entry_stub(void* a, void* b)
+ // + 75, Real entry point RVA
+ // + 25, RVA to bundled module base... (gunna be a section base address)
+ // + 45, RVA to bootmgfw base address... (number is positive, assembly subtracts this number)
+ inline char stub[] =
+ {
+ 0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x4C, 0x24, 0x08,
+ 0x48, 0x81, 0xEC, 0x98, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x05,
+ 0xE8, 0xFF, 0xFF, 0xFF, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0x48,
+ 0x03, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x28, 0x48, 0x8D, 0x05,
+ 0xD4, 0xFF, 0xFF, 0xFF, 0xB9, 0xEF, 0xBE, 0xAD, 0xDE, 0x48,
+ 0x2B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x48, 0x48, 0x8B, 0x44,
+ 0x24, 0x48, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B, 0x4C, 0x24,
+ 0x48, 0xC7, 0x44, 0x01, 0x28, 0xEF, 0xBE, 0xAD, 0xDE, 0x48,
+ 0x8B, 0x44, 0x24, 0x28, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B,
+ 0x4C, 0x24, 0x28, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0xB9,
+ 0x08, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC9, 0x05, 0x48, 0x8D,
+ 0x84, 0x08, 0x88, 0x00, 0x00, 0x00, 0x48, 0x89, 0x44, 0x24,
+ 0x60, 0x48, 0x8B, 0x44, 0x24, 0x60, 0x83, 0x38, 0x00, 0x0F,
+ 0x84, 0x4E, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24, 0x60,
+ 0x8B, 0x00, 0x48, 0x8B, 0x4C, 0x24, 0x28, 0x48, 0x03, 0xC8,
+ 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x40, 0xC7, 0x44,
+ 0x24, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24,
+ 0x60, 0x8B, 0x40, 0x04, 0x39, 0x44, 0x24, 0x3C, 0x0F, 0x83,
+ 0x1D, 0x01, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24, 0x40, 0x8B,
+ 0x40, 0x04, 0x48, 0x83, 0xE8, 0x08, 0x33, 0xD2, 0xB9, 0x02,
+ 0x00, 0x00, 0x00, 0x48, 0xF7, 0xF1, 0x48, 0x89, 0x44, 0x24,
+ 0x70, 0x48, 0x8B, 0x44, 0x24, 0x40, 0x48, 0x83, 0xC0, 0x08,
+ 0x48, 0x89, 0x44, 0x24, 0x50, 0x48, 0x8B, 0x44, 0x24, 0x40,
+ 0x8B, 0x00, 0x48, 0x8B, 0x4C, 0x24, 0x28, 0x48, 0x03, 0xC8,
+ 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x78, 0xC7, 0x44,
+ 0x24, 0x38, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x18, 0x8B, 0x44,
+ 0x24, 0x38, 0xFF, 0xC0, 0x89, 0x44, 0x24, 0x38, 0x48, 0x8B,
+ 0x44, 0x24, 0x50, 0x48, 0x83, 0xC0, 0x02, 0x48, 0x89, 0x44,
+ 0x24, 0x50, 0x8B, 0x44, 0x24, 0x38, 0x48, 0x3B, 0x44, 0x24,
+ 0x70, 0x0F, 0x83, 0x89, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x44,
+ 0x24, 0x50, 0x0F, 0xB7, 0x00, 0x66, 0x89, 0x44, 0x24, 0x20,
+ 0x0F, 0xB7, 0x44, 0x24, 0x20, 0xC1, 0xF8, 0x0C, 0x66, 0x89,
+ 0x44, 0x24, 0x30, 0x0F, 0xB7, 0x44, 0x24, 0x20, 0x25, 0xFF,
+ 0x0F, 0x00, 0x00, 0x66, 0x89, 0x44, 0x24, 0x34, 0x0F, 0xB7,
+ 0x44, 0x24, 0x30, 0x89, 0x44, 0x24, 0x58, 0x83, 0x7C, 0x24,
+ 0x58, 0x0A, 0x74, 0x02, 0xEB, 0x49, 0x0F, 0xB7, 0x44, 0x24,
+ 0x34, 0x48, 0x8B, 0x4C, 0x24, 0x78, 0x48, 0x03, 0xC8, 0x48,
+ 0x8B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x68, 0x48, 0x8B, 0x44,
+ 0x24, 0x28, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B, 0x4C, 0x24,
+ 0x68, 0x48, 0x8B, 0x54, 0x24, 0x28, 0x48, 0x8B, 0x44, 0x02,
+ 0x30, 0x48, 0x8B, 0x09, 0x48, 0x2B, 0xC8, 0x48, 0x8B, 0xC1,
+ 0x48, 0x8B, 0x4C, 0x24, 0x28, 0x48, 0x03, 0xC8, 0x48, 0x8B,
+ 0xC1, 0x48, 0x8B, 0x4C, 0x24, 0x68, 0x48, 0x89, 0x01, 0xE9,
+ 0x50, 0xFF, 0xFF, 0xFF, 0x48, 0x8B, 0x44, 0x24, 0x40, 0x8B,
+ 0x40, 0x04, 0x8B, 0x4C, 0x24, 0x3C, 0x03, 0xC8, 0x8B, 0xC1,
+ 0x89, 0x44, 0x24, 0x3C, 0x48, 0x8B, 0x44, 0x24, 0x50, 0x48,
+ 0x89, 0x44, 0x24, 0x40, 0xE9, 0xD1, 0xFE, 0xFF, 0xFF, 0x48,
+ 0x8B, 0x44, 0x24, 0x28, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B,
+ 0x4C, 0x24, 0x28, 0x8B, 0x44, 0x01, 0x28, 0x48, 0x8B, 0x4C,
+ 0x24, 0x28, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,
+ 0x84, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x94, 0x24,
+ 0xA8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x8C, 0x24, 0xA0, 0x00,
+ 0x00, 0x00, 0xFF, 0x94, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48,
+ 0x8B, 0x44, 0x24, 0x48, 0x48, 0x63, 0x40, 0x3C, 0x48, 0x8B,
+ 0x4C, 0x24, 0x48, 0x8B, 0x44, 0x01, 0x28, 0x48, 0x8B, 0x4C,
+ 0x24, 0x48, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,
+ 0x84, 0x24, 0x88, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x94, 0x24,
+ 0xA8, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x8C, 0x24, 0xA0, 0x00,
+ 0x00, 0x00, 0xFF, 0x94, 0x24, 0x88, 0x00, 0x00, 0x00, 0x48,
+ 0x81, 0xC4, 0x98, 0x00, 0x00, 0x00, 0xC3
+ };
+}
\ No newline at end of file
diff --git a/Efi Bundler/utils.h b/Efi Bundler/utils.h
new file mode 100644
index 0000000..b31ad4f
--- /dev/null
+++ b/Efi Bundler/utils.h
@@ -0,0 +1,84 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include