finished external symbol resolver demo...

2.0
_xeroxz 4 years ago
parent fdc6da3a19
commit 6099c23138

@ -1,6 +1,8 @@
#include "Theodosius.h" #include "Theodosius.h"
ObfuscateRoutine extern "C" void drv_entry() MutateRoutine extern "C" void drv_entry()
{ {
DbgPrint("> Hello World!\n"); DbgPrint("> Hello World!\n");
DbgPrint("> PiDDBCacheTable = 0x%p\n", &PiDDBCacheTable);
DbgPrint("> win32kfull!NtUserRegisterShellPTPListener = 0x%p\n", &NtUserRegisterShellPTPListener);
} }

@ -3,5 +3,9 @@
#define ObfuscateRoutine __declspec(code_seg(".theo"), noinline) #define ObfuscateRoutine __declspec(code_seg(".theo"), noinline)
#define MutateRoutine __declspec(code_seg(".theo1"), 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 DbgPrint(const char* format, ...);
extern "C" unsigned long long IoGetCurrentProcess(); extern "C" unsigned long long IoGetCurrentProcess();

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LocalDebuggerCommandArguments>C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib</LocalDebuggerCommandArguments> <LocalDebuggerCommandArguments>--libs C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib --maps C:\Users\_xeroxz\Desktop\ntoskrnl.exe.map</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LocalDebuggerCommandArguments>C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib</LocalDebuggerCommandArguments> <LocalDebuggerCommandArguments>--libs C:\Users\_xeroxz\Desktop\drv\DemoDrv.lib --maps C:\Users\_xeroxz\Desktop\ntoskrnl.exe.map</LocalDebuggerCommandArguments>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup> </PropertyGroup>
</Project> </Project>

@ -16,13 +16,13 @@
#pragma comment(lib, "Dbghelp.lib") #pragma comment(lib, "Dbghelp.lib")
namespace theo namespace theo
{ {
using kalloc_t = std::function<decltype(malloc)>; using malloc_t = std::function<decltype(malloc)>;
using kmemcpy_t = std::function<decltype(memcpy)>; using memcpy_t = std::function<decltype(memcpy)>;
using kmemset_t = std::function<decltype(memset)>; using kmemset_t = std::function<decltype(memset)>;
using resolve_symbol_t = std::function<std::uintptr_t(const char*)>; using resolve_symbol_t = std::function<std::uintptr_t(const char*)>;
using image_entry_t = std::uintptr_t; using image_entry_t = std::uintptr_t;
using mapper_routines_t = std::tuple<kalloc_t, kmemcpy_t, resolve_symbol_t>; using mapper_routines_t = std::tuple<malloc_t, memcpy_t, resolve_symbol_t>;
class hmm_ctx class hmm_ctx
{ {
@ -30,8 +30,8 @@ namespace theo
explicit hmm_ctx(const mapper_routines_t& routines); explicit hmm_ctx(const mapper_routines_t& routines);
auto map_objs(std::vector<lnk::obj_buffer_t>& objs) -> image_entry_t; auto map_objs(std::vector<lnk::obj_buffer_t>& objs) -> image_entry_t;
kalloc_t kalloc; malloc_t kalloc;
kmemcpy_t kmemcpy; memcpy_t kmemcpy;
resolve_symbol_t resolve_symbol; resolve_symbol_t resolve_symbol;
private: private:
bool map_symbols(std::vector<lnk::obj_buffer_t>& objs); bool map_symbols(std::vector<lnk::obj_buffer_t>& objs);

@ -28,6 +28,39 @@ namespace lnk
return result - sym.section_offset; 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<obj_buffer_t>& objs) -> bool auto get_objs(std::string lib_path, std::vector<obj_buffer_t>& objs) -> bool
{ {
std::vector<std::uint8_t> lib_file; std::vector<std::uint8_t> lib_file;

@ -3,6 +3,7 @@
#include <winternl.h> #include <winternl.h>
#include <vector> #include <vector>
#include <functional> #include <functional>
#include <fstream>
#include "../utils.hpp" #include "../utils.hpp"
namespace lnk namespace lnk
@ -54,8 +55,11 @@ namespace lnk
}; };
using obj_buffer_t = std::vector<std::uint8_t>; using obj_buffer_t = std::vector<std::uint8_t>;
using map_symbols_t = std::map<std::string, std::pair<std::uint32_t, std::uint32_t>>;
auto get_symbol_size(symbol_t& sym, obj_buffer_t& obj) -> std::uint32_t; auto get_symbol_size(symbol_t& sym, obj_buffer_t& obj) -> std::uint32_t;
auto get_objs(std::string lib_path, std::vector<obj_buffer_t>& objs) -> bool; auto get_objs(std::string lib_path, std::vector<obj_buffer_t>& objs) -> bool;
auto get_map_symbols(std::string map_path) -> map_symbols_t;
namespace sym namespace sym
{ {

@ -5,25 +5,65 @@
#include "hmdm_ctx.h" #include "hmdm_ctx.h"
#include "linker/linker.hpp" #include "linker/linker.hpp"
using extern_symbols_t = std::vector<std::pair<std::string, lnk::map_symbols_t>>;
using objs_buffer_t = std::vector<lnk::obj_buffer_t>;
auto get_mapping_info(int argc, char** argv) -> std::pair<objs_buffer_t, extern_symbols_t>
{
auto maps_offset = 0u;
std::vector<lnk::obj_buffer_t> image_objs;
std::vector<std::pair<std::string, lnk::map_symbols_t>> 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) 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; return -1;
} }
// read each .obj file from directory into std::vector... auto [image_objs, extern_symbols] = get_mapping_info(argc, argv);
std::vector<lnk::obj_buffer_t> image_objs; std::printf("[+] number of objs = %d\n", image_objs.size());
if (!lnk::get_objs(argv[1], image_objs))
if (!image_objs.size())
{ {
std::printf("> failed to parse lib...\n"); std::printf("[!] failed to parse .lib...\n");
return -1; 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) if (drv_status != STATUS_SUCCESS || drv_handle == INVALID_HANDLE_VALUE)
{ {
std::printf("> failed to load driver... reason -> 0x%x\n", drv_status); 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); 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; void* alloc_base;
msrexec.exec msrexec.exec
@ -57,7 +97,7 @@ int main(int argc, char** argv)
return alloc_base; return alloc_base;
}; };
theo::kmemcpy_t _kmemcpy = theo::memcpy_t _kmemcpy =
[&](void* dest, const void* src, std::size_t size) -> void* [&](void* dest, const void* src, std::size_t size) -> void*
{ {
void* result = nullptr; void* result = nullptr;
@ -74,11 +114,89 @@ int main(int argc, char** argv)
); );
return result; return result;
}; };
theo::resolve_symbol_t resolve_symbol = 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<const char*>(
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<std::uintptr_t>(
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<std::uintptr_t>(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<const char*>(
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 }); theo::hmm_ctx drv_mapper({ _kalloc, _kmemcpy, resolve_symbol });

Loading…
Cancel
Save