| 85 | } |
| 86 | |
| 87 | int LoadPe(void* dllData, std::string_view callExport) |
| 88 | { |
| 89 | // Loader code based on Shellcode Reflective DLL Injection by Nick Landers https://github.com/monoxgas/sRDI |
| 90 | // which is derived from "Improved Reflective DLL Injection" from Dan Staples https://disman.tl/2015/01/30/an-improved-reflective-dll-injection-technique.html |
| 91 | // which itself is derived from the original project by Stephen Fewer. https://github.com/stephenfewer/ReflectiveDLLInjection |
| 92 | |
| 93 | auto dosHeader = Rva2Va<PIMAGE_DOS_HEADER>(dllData, 0); |
| 94 | auto ntHeaders = Rva2Va<PIMAGE_NT_HEADERS>(dllData, dosHeader->e_lfanew); |
| 95 | auto sizeOfImage = ntHeaders->OptionalHeader.SizeOfImage; |
| 96 | |
| 97 | // Perform sanity checks on the image (Stolen from https://github.com/fancycode/MemoryModule/blob/master/MemoryModule.c) |
| 98 | |
| 99 | if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) |
| 100 | return 1; |
| 101 | |
| 102 | if (ntHeaders->FileHeader.Machine != HostMachine) |
| 103 | return 1; |
| 104 | |
| 105 | if (ntHeaders->OptionalHeader.SectionAlignment & 1) |
| 106 | return 1; |
| 107 | |
| 108 | // Align the image to the page size (Stolen from https://github.com/fancycode/MemoryModule/blob/master/MemoryModule.c) |
| 109 | |
| 110 | auto sectionHeader = IMAGE_FIRST_SECTION(ntHeaders); |
| 111 | DWORD lastSectionEnd = 0; |
| 112 | DWORD endOfSection; |
| 113 | for (size_t i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, sectionHeader++) |
| 114 | { |
| 115 | if (sectionHeader->SizeOfRawData == 0) |
| 116 | endOfSection = sectionHeader->VirtualAddress + ntHeaders->OptionalHeader.SectionAlignment; |
| 117 | else |
| 118 | endOfSection = sectionHeader->VirtualAddress + sectionHeader->SizeOfRawData; |
| 119 | |
| 120 | if (endOfSection > lastSectionEnd) |
| 121 | lastSectionEnd = endOfSection; |
| 122 | } |
| 123 | |
| 124 | SYSTEM_INFO sysInfo; |
| 125 | GetNativeSystemInfo(&sysInfo); |
| 126 | auto alignedImageSize = AlignValueUp(ntHeaders->OptionalHeader.SizeOfImage, sysInfo.dwPageSize); |
| 127 | if (alignedImageSize != AlignValueUp(lastSectionEnd, sysInfo.dwPageSize)) |
| 128 | return 1; |
| 129 | |
| 130 | UINT_PTR baseAddress = (UINT_PTR)VirtualAlloc(NULL, alignedImageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); |
| 131 | if (!baseAddress) |
| 132 | return 1; |
| 133 | |
| 134 | // set global module data |
| 135 | moduleData.m_DllBaseAddress = baseAddress; |
| 136 | moduleData.m_SizeOfTheDll = ntHeaders->OptionalHeader.SizeOfImage; |
| 137 | |
| 138 | /// Copy headers |
| 139 | memcpy((void*)baseAddress, dllData, ntHeaders->OptionalHeader.SizeOfHeaders); |
| 140 | |
| 141 | // STEP 3: Load in the sections |
| 142 | sectionHeader = IMAGE_FIRST_SECTION(ntHeaders); |
| 143 | for (int i = 0; i < ntHeaders->FileHeader.NumberOfSections; i++, sectionHeader++) |
| 144 | { |
no test coverage detected