diff --git a/Efi Bundler/Efi Bundler.sln b/Efi Bundler/Efi Bundler.sln new file mode 100644 index 0000000..a0f17f7 --- /dev/null +++ b/Efi Bundler/Efi Bundler.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30503.244 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Efi Bundler", "Efi Bundler.vcxproj", "{EE860038-E3DD-4329-8D44-DF8B9ECBE420}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Debug|x64.ActiveCfg = Debug|x64 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Debug|x64.Build.0 = Debug|x64 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Debug|x86.ActiveCfg = Debug|Win32 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Debug|x86.Build.0 = Debug|Win32 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Release|x64.ActiveCfg = Release|x64 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Release|x64.Build.0 = Release|x64 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Release|x86.ActiveCfg = Release|Win32 + {EE860038-E3DD-4329-8D44-DF8B9ECBE420}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {6F313696-ED35-4BFB-B825-E3E8861D12E3} + EndGlobalSection +EndGlobal 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..3d9dc6b --- /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( + ((std::uint64_t)&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( + (std::uint8_t*)&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..c1d6626 --- /dev/null +++ b/Efi Bundler/shellcode.cpp @@ -0,0 +1,57 @@ +#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; ) + { + std::uint32_t reloc_count = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(std::uint16_t); + auto reloc_data = reinterpret_cast((std::uint8_t*)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_ABSOLUTE: + break; + 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..19f9f1c --- /dev/null +++ b/Efi Bundler/utils.h @@ -0,0 +1,84 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define NT_HEADER(x) reinterpret_cast( std::uint64_t(x) + reinterpret_cast(x)->e_lfanew ) +namespace impl +{ + using uq_handle = std::unique_ptr; + + __forceinline std::uint32_t get_process_id(const std::wstring_view process_name) + { + // open a system snapshot of all loaded processes + uq_handle snap_shot{ CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0), &CloseHandle }; + + if (snap_shot.get() == INVALID_HANDLE_VALUE) + { + return 0; + } + + PROCESSENTRY32W process_entry{ sizeof(PROCESSENTRY32W) }; + + // enumerate through processes + for (Process32FirstW(snap_shot.get(), &process_entry); Process32NextW(snap_shot.get(), &process_entry); ) + if (std::wcscmp(process_name.data(), process_entry.szExeFile) == 0) + return process_entry.th32ProcessID; + + return 0; + } + + __forceinline void open_binary_file(const std::string& file, std::vector& data) + { + std::ifstream fstr(file, std::ios::binary); + fstr.unsetf(std::ios::skipws); + fstr.seekg(0, std::ios::end); + + const auto file_size = fstr.tellg(); + + fstr.seekg(NULL, std::ios::beg); + data.reserve(static_cast(file_size)); + data.insert(data.begin(), std::istream_iterator(fstr), std::istream_iterator()); + } + + __forceinline bool enable_privilege(const std::wstring_view privilege_name) + { + HANDLE token_handle = nullptr; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token_handle)) + {; + return false; + } + + LUID luid{}; + if (!LookupPrivilegeValueW(nullptr, privilege_name.data(), &luid)) + { + return false; + } + + TOKEN_PRIVILEGES token_state{}; + token_state.PrivilegeCount = 1; + token_state.Privileges[0].Luid = luid; + token_state.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; + + if (!AdjustTokenPrivileges(token_handle, FALSE, &token_state, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr)) + { + return false; + } + + CloseHandle(token_handle); + + return true; + } +} \ No newline at end of file