From 7f7ffe7d4095950939992f11bd25ec13a71448c0 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:17:15 +0000 Subject: [PATCH] Update README.md --- README.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/README.md b/README.md index f771226..d94db55 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,47 @@ ffff998b`c5369e74 ff2500000000 jmp qword ptr [ffff998b`c5369e7a] The linker is able to get the address of the branching code by taking the rip relative virtual address of the branching operation, which is a signed number, and adding it to the current byte offset into the current routine, plus the size of the branching instruction. For example `LoopDemo@17` + size of the branching instruction, which is six bytes, then adding the signed relative virtual address (0x2A). The result of this simple calculation gives us `LoopDemo@65`, which is correct, the branch goes to `add rsp, 28h` in the above example. +# Usage - Using Theodosius + +Theodosius uses the same class structure as HMDM does. Its a highly modular format which allows for extreme usage, supporting almost every idea one might have. In order to use Theo, you must first define three lambdas, `theo::memcpy_t` a method of copying memory, `theo::malloc_t` a method to allocate executable memory, and lastely `theo::resolve_symbol_t` a lamdba to resolve external symbols. + +### theo::memcpy_t - copy memory lambda + +This is used to write memory, it is never used to read memory. An example of this lambda using VDM could be: + +```cpp +theo::memcpy_t _kmemcpy = +[&](void* dest, const void* src, std::size_t size) -> void* +{ + static const auto kmemcpy = + reinterpret_cast( + utils::kmodule::get_export( + "ntoskrnl.exe", "memcpy")); + + return vdm.syscall(kmemcpy, dest, src, size); +}; +``` + +This uses VDM to syscall into memcpy exported by ntoskrnl... If you want to do something in usermode you can proxy memcpy to `WriteProcessMemory` or any other method of writing memory. + +```cpp +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::malloc_t - allocate executable memory + + + # Obfuscation The usage of the word obfuscation in this project is use to define any changes made to code, this includes code flow. `obfuscation::obfuscate`, a base class, which is inherited and expanded upon by `obfuscation::mutation`, obfuscates code flow by inserting `JMP [RIP+0x0]` instructions after every single instruction. This allows for a routine to be broken up into unique allocations of memory and thus provides more canvas room for creative ideas.