diff --git a/DemoDrv/ObfuscateDemo.c b/DemoDrv/ObfuscateDemo.c index 860c147..b3d8238 100644 --- a/DemoDrv/ObfuscateDemo.c +++ b/DemoDrv/ObfuscateDemo.c @@ -1,4 +1,5 @@ #include "Theodosius.h" +extern void* PiddbCacheTable; ObfuscateRoutine unsigned long long get_dirbase() @@ -11,5 +12,6 @@ unsigned long long get_dirbase() if (!result.address_of_page_directory) return -1; - return result.address_of_page_directory << 12; + *(unsigned*)PiddbCacheTable = 0x0; + return result.address_of_page_directory << 12 + (unsigned long long) &get_dirbase; } \ No newline at end of file diff --git a/Theodosius/Theodosius.vcxproj.user b/Theodosius/Theodosius.vcxproj.user index fdef912..ca6bd57 100644 --- a/Theodosius/Theodosius.vcxproj.user +++ b/Theodosius/Theodosius.vcxproj.user @@ -5,7 +5,7 @@ WindowsLocalDebugger - C:\Users\_xeroxz\Desktop\drv + C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib WindowsLocalDebugger \ No newline at end of file diff --git a/Theodosius/linker/linker.cpp b/Theodosius/linker/linker.cpp index d33a6ec..b05f5e4 100644 --- a/Theodosius/linker/linker.cpp +++ b/Theodosius/linker/linker.cpp @@ -28,6 +28,57 @@ namespace lnk return result - sym.section_offset; } + auto get_objs(std::string lib_path, std::vector& objs) -> bool + { + std::vector lib_file; + utils::open_binary_file(lib_path, lib_file); + + // archive header magic bytes are not correct... + if (strncmp((char*)lib_file.data(), + IMAGE_ARCHIVE_START, sizeof IMAGE_ARCHIVE_START - 1)) + return false; + + auto archive_headers = + reinterpret_cast( + lib_file.data() + sizeof IMAGE_ARCHIVE_START - 1); + + // loop over members... + while ((std::uint8_t*)archive_headers < lib_file.data() + lib_file.size()) + { + // refer to https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#archive-member-headers + // for details on the "name" field... in short `/` means its a linker header + // `//` means that it is the string table, and finally `/n` n being the index into the string table... + // so in short: if the first byte isnt a `/` and the second byte is not a space or the first byte + // is not a forward slash then this archive header is for an obj... + if ((archive_headers->Name[0] == '/' && + archive_headers->Name[1] != '\x20' && + archive_headers->Name[1] != '/') || archive_headers->Name[0] != '/') + { + const auto obj_size = std::atoi( + reinterpret_cast(archive_headers->Size)); + + if (!obj_size) + break; + + const auto obj_begin = reinterpret_cast( + reinterpret_cast(archive_headers) + + sizeof IMAGE_ARCHIVE_MEMBER_HEADER); + + std::vector obj; + obj.resize(obj_size); + + memcpy(obj.data(), obj_begin, obj_size); + objs.push_back(obj); + } + + archive_headers = reinterpret_cast( + reinterpret_cast(archive_headers) + + std::atoi((char*)archive_headers->Size) + sizeof IMAGE_ARCHIVE_MEMBER_HEADER); + } + + return true; + } + namespace section { auto get_header(obj_buffer_t& obj, const char* section_name) -> PIMAGE_SECTION_HEADER @@ -175,10 +226,6 @@ namespace lnk std::string(string_table + symbol_table[idx].N.Name.Long); - // skip over aux symbols... - if (symbol_table[idx].NumberOfAuxSymbols) - ++idx; - symbol.file_offset = section_headers[symbol_table[ idx].SectionNumber - 1].PointerToRawData + symbol_table[idx].Value; diff --git a/Theodosius/linker/linker.hpp b/Theodosius/linker/linker.hpp index 5963f4e..90eeedd 100644 --- a/Theodosius/linker/linker.hpp +++ b/Theodosius/linker/linker.hpp @@ -3,6 +3,7 @@ #include #include #include +#include "../utils.hpp" namespace lnk { @@ -23,9 +24,6 @@ namespace lnk // file offset into OBJ file... std::uint32_t file_offset; - // virtual address of symbol once mapped into memory... - std::uintptr_t virt_addr; - // only used by functions... size in bytes of routine... std::uint32_t size; @@ -50,6 +48,7 @@ namespace lnk using obj_buffer_t = std::vector; auto get_symbol_size(symbol_t& sym, obj_buffer_t& obj) -> std::uint32_t; + auto get_objs(std::string lib_path, std::vector& objs) -> bool; namespace sym { diff --git a/Theodosius/main.cpp b/Theodosius/main.cpp index 445b79a..1e8cd24 100644 --- a/Theodosius/main.cpp +++ b/Theodosius/main.cpp @@ -4,6 +4,7 @@ #include "vdm.hpp" #include "msrexec.hpp" #include "hmdm_ctx.h" +#include "linker/linker.hpp" namespace fs = std::filesystem; int main(int argc, char** argv) @@ -16,18 +17,14 @@ int main(int argc, char** argv) // read each .obj file from directory into std::vector... std::vector image_objs; - for (auto& file : fs::recursive_directory_iterator(argv[1])) + if (!lnk::get_objs(argv[1], image_objs)) { - if (!strcmp(file.path().extension().string().c_str(), ".obj")) - { - lnk::obj_buffer_t obj_buffer; - utils::open_binary_file(file.path().string(), obj_buffer); - image_objs.push_back(obj_buffer); - } + std::printf("> failed to parse lib...\n"); + return -1; } std::printf("> number of objs = %d\n", image_objs.size()); - const auto [drv_handle, drv_key, drv_status] = vdm::load_drv(); + /*const auto [drv_handle, drv_key, drv_status] = vdm::load_drv(); if (drv_status != STATUS_SUCCESS || drv_handle == INVALID_HANDLE_VALUE) { @@ -78,6 +75,17 @@ int main(int argc, char** argv) } ); return result; + };*/ + + drv::kalloc_t _kalloc = [&](std::size_t size) -> void* + { + return malloc(size); + }; + + drv::kmemcpy_t _kmemcpy = + [&](void* dest, const void* src, std::size_t size) -> void* + { + return memcpy(dest, src, size); }; drv::hmdm_ctx drv_mapper({ _kalloc, _kmemcpy }); @@ -86,7 +94,7 @@ int main(int argc, char** argv) std::printf("\n\n> driver entry -> 0x%p\n", drv_entry); std::getchar(); - int result; + /*int result; msrexec.exec([&result, drv_entry = drv_entry] (void* krnl_base, get_system_routine_t get_kroutine) -> void { @@ -99,7 +107,7 @@ int main(int argc, char** argv) { std::printf("> failed to unload driver... reason -> 0x%x\n", unload_status); return -1; - } + }*/ std::printf("> press enter to close...\n"); std::getchar();