diff --git a/DemoDrv/DriverEntry.cpp b/DemoDrv/DriverEntry.cpp
index c6048e1..33dc13d 100644
--- a/DemoDrv/DriverEntry.cpp
+++ b/DemoDrv/DriverEntry.cpp
@@ -1,6 +1,8 @@
#include "Theodosius.h"
-ObfuscateRoutine extern "C" void drv_entry()
+MutateRoutine extern "C" void drv_entry()
{
DbgPrint("> Hello World!\n");
+ DbgPrint("> PiDDBCacheTable = 0x%p\n", &PiDDBCacheTable);
+ DbgPrint("> win32kfull!NtUserRegisterShellPTPListener = 0x%p\n", &NtUserRegisterShellPTPListener);
}
\ No newline at end of file
diff --git a/DemoDrv/Theodosius.h b/DemoDrv/Theodosius.h
index 970f7ab..cb3e70b 100644
--- a/DemoDrv/Theodosius.h
+++ b/DemoDrv/Theodosius.h
@@ -3,5 +3,9 @@
#define ObfuscateRoutine __declspec(code_seg(".theo"), noinline)
#define MutateRoutine __declspec(code_seg(".theo1"), noinline)
+// win32kfull.sys export example...
+extern "C" void NtUserRegisterShellPTPListener();
+extern "C" void* PiDDBCacheTable;
+
extern "C" unsigned long DbgPrint(const char* format, ...);
extern "C" unsigned long long IoGetCurrentProcess();
\ No newline at end of file
diff --git a/Theodosius/Theodosius.vcxproj.user b/Theodosius/Theodosius.vcxproj.user
index cfba79c..b3192f3 100644
--- a/Theodosius/Theodosius.vcxproj.user
+++ b/Theodosius/Theodosius.vcxproj.user
@@ -1,11 +1,11 @@
- C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib
+ --libs C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib --maps C:\Users\_xeroxz\Desktop\ntoskrnl.exe.map
WindowsLocalDebugger
- C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib
+ --libs C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib --maps C:\Users\_xeroxz\Desktop\ntoskrnl.exe.map
WindowsLocalDebugger
\ No newline at end of file
diff --git a/Theodosius/hmdm_ctx.h b/Theodosius/hmdm_ctx.h
index 9c62677..11568d7 100644
--- a/Theodosius/hmdm_ctx.h
+++ b/Theodosius/hmdm_ctx.h
@@ -16,13 +16,13 @@
#pragma comment(lib, "Dbghelp.lib")
namespace theo
{
- using kalloc_t = std::function;
- using kmemcpy_t = std::function;
+ using malloc_t = std::function;
+ using memcpy_t = std::function;
using kmemset_t = std::function;
using resolve_symbol_t = std::function;
using image_entry_t = std::uintptr_t;
- using mapper_routines_t = std::tuple;
+ using mapper_routines_t = std::tuple;
class hmm_ctx
{
@@ -30,8 +30,8 @@ namespace theo
explicit hmm_ctx(const mapper_routines_t& routines);
auto map_objs(std::vector& objs) -> image_entry_t;
- kalloc_t kalloc;
- kmemcpy_t kmemcpy;
+ malloc_t kalloc;
+ memcpy_t kmemcpy;
resolve_symbol_t resolve_symbol;
private:
bool map_symbols(std::vector& objs);
diff --git a/Theodosius/linker/linker.cpp b/Theodosius/linker/linker.cpp
index 48a8128..384edf1 100644
--- a/Theodosius/linker/linker.cpp
+++ b/Theodosius/linker/linker.cpp
@@ -28,6 +28,39 @@ namespace lnk
return result - sym.section_offset;
}
+ auto get_map_symbols(std::string map_path) -> map_symbols_t
+ {
+ std::ifstream map_file(map_path);
+
+ if (!map_file.is_open())
+ return { {}, {} };
+
+ std::string line;
+ map_symbols_t result;
+ while (std::getline(map_file, line))
+ {
+ const auto colon_index = line.find(":");
+ if (colon_index == std::string::npos)
+ break;
+
+ const auto section_number =
+ std::strtoul(line.substr(1,
+ colon_index).c_str(), NULL, 16);
+
+ const auto section_offset =
+ std::strtoull(line.substr(
+ colon_index + 1, 16).c_str(), NULL, 16);
+
+ auto symbol = line.substr(
+ colon_index + 16 + 8,
+ line.length() - (colon_index + 16 + 7));
+
+ symbol[symbol.length()] = '\0';
+ result[symbol] = { section_number, section_offset };
+ }
+ return result;
+ }
+
auto get_objs(std::string lib_path, std::vector& objs) -> bool
{
std::vector lib_file;
diff --git a/Theodosius/linker/linker.hpp b/Theodosius/linker/linker.hpp
index a52c67c..90a0948 100644
--- a/Theodosius/linker/linker.hpp
+++ b/Theodosius/linker/linker.hpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include "../utils.hpp"
namespace lnk
@@ -54,8 +55,11 @@ namespace lnk
};
using obj_buffer_t = std::vector;
+ using map_symbols_t = std::map>;
+
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;
+ auto get_map_symbols(std::string map_path) -> map_symbols_t;
namespace sym
{
diff --git a/Theodosius/main.cpp b/Theodosius/main.cpp
index 39987ea..1dac4d6 100644
--- a/Theodosius/main.cpp
+++ b/Theodosius/main.cpp
@@ -5,25 +5,65 @@
#include "hmdm_ctx.h"
#include "linker/linker.hpp"
+using extern_symbols_t = std::vector>;
+using objs_buffer_t = std::vector;
+
+auto get_mapping_info(int argc, char** argv) -> std::pair
+{
+ auto maps_offset = 0u;
+ std::vector image_objs;
+ std::vector> extern_symbols;
+
+ for (auto idx = 2; idx < argc; ++idx)
+ {
+ if (!strcmp(argv[idx], "--maps"))
+ {
+ maps_offset = idx + 1;
+ break;
+ }
+
+ if (!lnk::get_objs(argv[idx], image_objs))
+ {
+ std::printf("> failed to parse lib...\n");
+ return {};
+ }
+ }
+
+ if (maps_offset)
+ {
+ for (auto idx = maps_offset; idx <= argc - 1; ++idx)
+ {
+ extern_symbols.push_back
+ ({
+ std::filesystem::path(argv[idx]).stem().string(),
+ lnk::get_map_symbols(argv[idx])
+ });
+ }
+ }
+
+ return { image_objs, extern_symbols };
+}
+
int main(int argc, char** argv)
{
- if (argc < 2)
+ if (argc < 3 || strcmp(argv[1], "--libs"))
{
- std::printf("> please provide a folder of objs to be linked...\n");
+ std::printf("[!] invalid usage... please use one of the following:\n");
+ std::printf(" > theo.exe --libs one.lib two.lib three.lib\n");
+ std::printf(" > theo.exe --libs one.lib --maps ntoskrnl.exe.map win32kbase.sys.map\n");
return -1;
}
- // read each .obj file from directory into std::vector...
- std::vector image_objs;
- if (!lnk::get_objs(argv[1], image_objs))
+ auto [image_objs, extern_symbols] = get_mapping_info(argc, argv);
+ std::printf("[+] number of objs = %d\n", image_objs.size());
+
+ if (!image_objs.size())
{
- std::printf("> failed to parse lib...\n");
+ 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();
-
if (drv_status != STATUS_SUCCESS || drv_handle == INVALID_HANDLE_VALUE)
{
std::printf("> failed to load driver... reason -> 0x%x\n", drv_status);
@@ -37,7 +77,7 @@ int main(int argc, char** argv)
};
vdm::msrexec_ctx msrexec(_write_msr);
- theo::kalloc_t _kalloc = [&](std::size_t size) -> void*
+ theo::malloc_t _kalloc = [&](std::size_t size) -> void*
{
void* alloc_base;
msrexec.exec
@@ -57,7 +97,7 @@ int main(int argc, char** argv)
return alloc_base;
};
- theo::kmemcpy_t _kmemcpy =
+ theo::memcpy_t _kmemcpy =
[&](void* dest, const void* src, std::size_t size) -> void*
{
void* result = nullptr;
@@ -74,11 +114,89 @@ int main(int argc, char** argv)
);
return result;
};
-
+
theo::resolve_symbol_t resolve_symbol =
- [&](const char* symbol_name) -> std::uintptr_t
+ [&, &extern_symbols = extern_symbols](const char* symbol_name) -> std::uintptr_t
{
- return utils::kmodule::get_export("ntoskrnl.exe", symbol_name);
+ std::uintptr_t result = 0u;
+ for (auto& [drv_name, drv_symbols] : extern_symbols)
+ {
+ // each kernel module... find a driver with a matching map file name...
+ // I.E ntoskrnl.exe.map == ntoskrnl.exe...
+ utils::kmodule::each_module
+ (
+ [&, &drv_name = drv_name, &drv_symbols = drv_symbols]
+ (PRTL_PROCESS_MODULE_INFORMATION drv_info, const char* drv_path) -> bool
+ {
+ const auto _drv_name =
+ reinterpret_cast(
+ drv_info->OffsetToFileName + drv_info->FullPathName);
+
+ // if this is the driver, load it, loop over its sections
+ // calc the absolute virtual address of the symbol...
+ if (!strcmp(_drv_name, drv_name.c_str()))
+ {
+ const auto drv_load_addr =
+ reinterpret_cast(
+ LoadLibraryExA(drv_path, NULL, DONT_RESOLVE_DLL_REFERENCES));
+
+ std::uint32_t section_count = 1u;
+ utils::pe::each_section
+ (
+ [&, &drv_symbols = drv_symbols]
+ (PIMAGE_SECTION_HEADER section_header, std::uintptr_t img_base) -> bool
+ {
+ if (section_count == drv_symbols[symbol_name].first)
+ {
+ result = reinterpret_cast(drv_info->ImageBase) +
+ section_header->VirtualAddress + drv_symbols[symbol_name].second;
+
+ // we found the symbol...
+ return false;
+ }
+
+ ++section_count;
+ // keep going over sections...
+ return true;
+ }, drv_load_addr
+ );
+ }
+
+ // keep looping over modules until we resolve the symbol...
+ return !result;
+ }
+ );
+ }
+
+ // if the symbol was not resolved in any of the map files then try
+ // to see if its an export from any other drivers...
+ if (!result)
+ {
+ utils::kmodule::each_module
+ (
+ [&](PRTL_PROCESS_MODULE_INFORMATION drv_info, const char* drv_path) -> bool
+ {
+ const auto drv_name =
+ reinterpret_cast(
+ drv_info->OffsetToFileName + drv_info->FullPathName);
+
+ __try
+ {
+ const auto temp_result =
+ utils::kmodule::get_export(drv_name, symbol_name);
+
+ if (!temp_result)
+ return true;
+
+ // false if we found the symbol...
+ return (!(result = temp_result));
+ }
+ __except (EXCEPTION_EXECUTE_HANDLER) { return true; }
+ }
+ );
+ }
+
+ return result;
};
theo::hmm_ctx drv_mapper({ _kalloc, _kmemcpy, resolve_symbol });