You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Theodosius/Examples/Theodosius-Usermode/main.cpp

168 lines
3.9 KiB

4 years ago
#include <iostream>
#include <Windows.h>
#include <psapi.h>
#include <filesystem>
#include "theo.h"
#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;
}
// another flag so we break...
if (argv[idx][0] == '-' && argv[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 < 3 || strcmp(argv[1], "--libs"))
{
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;
}
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");
return -1;
}
std::uint32_t pid_offset = 0u, pid = 0u;
for (auto idx = 3; idx < argc; ++idx)
if (!strcmp(argv[idx], "--pid"))
pid_offset = idx + 1;
if (!pid_offset || !(pid = std::atoi(argv[pid_offset])))
{
std::printf("[!] invalid pid...\n");
return -1;
}
const auto phandle =
OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
if (phandle == INVALID_HANDLE_VALUE)
{
std::printf("[!] failed to open handle...\n");
return -1;
}
theo::malloc_t _alloc = [&](std::size_t size) -> void*
{
const auto result = VirtualAllocEx
(
phandle,
nullptr,
size,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
if (!result)
{
std::printf("[!] failed to allocate virtual memory...\n");
exit(-1);
}
return result;
};
theo::memcpy_t _memcpy =
[&](void* dest, const void* src, std::size_t size) -> void*
{
SIZE_T bytes_handled;
if (!WriteProcessMemory(phandle, dest, src, size, &bytes_handled))
{
std::printf("[!] failed to write process memory...\n");
exit(-1);
}
return dest;
};
theo::resolve_symbol_t _resolver =
[&, &extern_symbols = extern_symbols](const char* symbol_name) -> std::uintptr_t
{
auto loaded_modules = std::make_unique<HMODULE[]>(64);
std::uintptr_t result = 0u, loaded_module_sz = 0u;
if (!EnumProcessModules(phandle,
loaded_modules.get(), 512, (PDWORD)&loaded_module_sz))
return {};
for (auto i = 0u; i < loaded_module_sz / 8u; i++)
{
wchar_t file_name[MAX_PATH] = L"";
if (!GetModuleFileNameExW(phandle,
loaded_modules.get()[i], file_name, _countof(file_name)))
continue;
if ((result = reinterpret_cast<std::uintptr_t>(
GetProcAddress(LoadLibrary(file_name), symbol_name))))
break;
}
return result;
};
theo::hmm_ctx mapper({ _alloc, _memcpy, _resolver });
if (!mapper.map_objs(image_objs))
{
std::printf("[!] failed to map object files...\n");
return -1;
}
const auto module_entry =
4 years ago
reinterpret_cast<LPTHREAD_START_ROUTINE>(
mapper.get_symbol("ModuleEntry"));
4 years ago
std::printf("[+] module entry -> 0x%p\n", module_entry);
4 years ago
std::getchar();
std::uint32_t tid = 0u;
CreateRemoteThread(phandle, NULL,
NULL, module_entry, NULL, NULL, (LPDWORD)&tid);
4 years ago
std::printf("[+] thread id = %d\n", tid);
std::printf("[+] press enter to close...\n");
std::getchar();
}