From 2b44a500f7fa0d1b6baacbc84d1a02906b3ed81a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:27:57 +0000 Subject: [PATCH 01/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de3a1b1..58d4f4d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +
From 90a98c1876b7af0d3dea1529fc14fe11ba00eb53 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:28:17 +0000 Subject: [PATCH 02/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 58d4f4d..9744f64 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@
+ + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 9bdab5ff08b173f093c4f3f76f33b54dec172d0f Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:29:06 +0000 Subject: [PATCH 03/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 9744f64..52628fc 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From d8abcac27c2ae84d9b23ae59d02f853751789518 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:30:44 +0000 Subject: [PATCH 04/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52628fc..7dfdd71 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 36c2dca39b89fcb766594802b29a874d4f72b9ff Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:31:13 +0000 Subject: [PATCH 05/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7dfdd71..a518b72 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- + From 8f117cd136e0a8be0a4b4fcd4d26dfc5ea75a17c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:31:32 +0000 Subject: [PATCH 06/47] Update README.md --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index a518b72..e2d8460 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@
- - + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 3f9bf97a6d74983d1f015c5812f4edb8ddbeec22 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:31:50 +0000 Subject: [PATCH 07/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e2d8460..b50a0d3 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 5e421134c96b4ae39b588a9b959bfe1530777662 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:32:25 +0000 Subject: [PATCH 08/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b50a0d3..d16cca2 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 44e1d2b66393271a6c3bcca6217c25c14c7f00f8 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:32:53 +0000 Subject: [PATCH 09/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d16cca2..3478c7a 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@
- + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 366f9c1555b86cf4e85ea786536b03e303be0b35 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:33:14 +0000 Subject: [PATCH 10/47] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3478c7a..dbebba7 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 4fbd67e1b429a76669bfbb776aa811be2be0d6e2 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:34:12 +0000 Subject: [PATCH 11/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index dbebba7..2597d1f 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ + + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 9812339ddb2d5019c064d6a74c16251aed4a4aea Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:34:41 +0000 Subject: [PATCH 12/47] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2597d1f..eb8cce6 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ + # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 7e84894e02047c417bba7310426a3f81c989f4ff Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:35:10 +0000 Subject: [PATCH 13/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index eb8cce6..c7e170f 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +
From c3ffb1de75678242080f0903a87ec91ece9ce85f Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:35:21 +0000 Subject: [PATCH 14/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c7e170f..c5241b1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +
From 706ec5c25ec903817ffe8628ff0b7b45d6ec2b6e Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:35:33 +0000 Subject: [PATCH 15/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c5241b1..87ebf7c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- +
From 6c34e67b576314bda3365ff94a81598fe075b3a0 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:38:21 +0000 Subject: [PATCH 16/47] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 87ebf7c..2d16fd2 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@
- -
From 334382694d5b2f7f046882c240d331636612c0a7 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:39:52 +0000 Subject: [PATCH 17/47] Update README.md --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 2d16fd2..8608d8e 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,8 @@
- - - + + Figure 1. [Theodosius I](https://en.wikipedia.org/wiki/Theodosius_I)
# Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From ce0e544fdc4c226853920b7197b5669b92a4f673 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:40:07 +0000 Subject: [PATCH 18/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8608d8e..19e67e6 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ - Figure 1. [Theodosius I](https://en.wikipedia.org/wiki/Theodosius_I) +

Figure 1. [Theodosius I](https://en.wikipedia.org/wiki/Theodosius_I)

# Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 0f044a6250f24440923fc83454238630bb878f79 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:40:40 +0000 Subject: [PATCH 19/47] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 19e67e6..a632ba1 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ -

Figure 1. [Theodosius I](https://en.wikipedia.org/wiki/Theodosius_I)

+

Figure 1. Theodosius I

# Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 9cfab60fc50a35536902d0514d12422da507c140 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:40:50 +0000 Subject: [PATCH 20/47] Update README.md --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index a632ba1..af2aa69 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,6 @@
- -

Figure 1. Theodosius I

# Theodosius - Jit linker, Mapper, Mutator, and Obfuscator From 3ff9d4f3fd92ddb970c99b5fba09c4f0be32c3d9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:50:55 +0000 Subject: [PATCH 21/47] Update README.md --- README.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index af2aa69..24da0b3 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,16 @@ # Theodosius - Jit linker, Mapper, Mutator, and Obfuscator Theodosius (Theo for short) is a jit linker created entirely for obfuscation and mutation of both code, and code flow. The project is extremely modular in design and supports -both kernel and usermode projects. Since Theo inherits HMDM (highly modular driver mapper), any vulnerable driver that exposes arbitrary MSR writes, or physical memory read/write can be used with this framework. This is possible since HMDM inherits VDM (vulnerable driver manipulation), and MSREXEC (elevation of arbitrary MSR writes to kernel execution). +both kernel and usermode projects. Since Theo inherits HMDM (highly modular driver mapper), any vulnerable driver that exposes arbitrary MSR writes, or physical memory read/write can be used with this framework to map unsigned code into the kernel. This is possible since HMDM inherits VDM (vulnerable driver manipulation), and MSREXEC (elevation of arbitrary MSR writes to kernel execution). -Since Theo is a jit linker, unexported symbols from PE files can be jit linked. Resolving such symbols is open ended and allows the user of this framework to handle how they want to resolve symbols. More on this later (check out example projects). \ No newline at end of file +Since Theo is a jit linker, unexported symbols can be jit linked. Resolving such symbols is open ended and allows the programmer of this framework to handle how they want to resolve symbols. More on this later (check out example projects). + +# 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. + +### Obfuscation - Base Class + +The base class, as described in the above section, contains a handful of util routines such as `get_size()`, + +### Mutation - Inherts Obfuscation \ No newline at end of file From 8d5ac32e66f4bb0307dc0d2145bfaa5feaa2014a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:54:46 +0000 Subject: [PATCH 22/47] Update README.md --- README.md | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 24da0b3..240acf4 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,34 @@ The usage of the word obfuscation in this project is use to define any changes m ### Obfuscation - Base Class -The base class, as described in the above section, contains a handful of util routines such as `get_size()`, +The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). LEA, nor CALL are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. + +```cpp +reloc_t inline_jmp_reloc +{ + reloc_type::next_instruction_addr, + JMP_RIP_ADDR_IDX +}; + +reloc_t inline_jmp_branch +{ + reloc_type::jcc, + JMP_RIP_ADDR_IDX, + *reinterpret_cast(rva_fix_addr) +}; + +std::printf(" > fixing JCC rva...\n"); +std::printf(" > new rva = 0x%x\n", JMP_RIP_SIZE); +std::printf(" > old rva = 0x%x\n", + *reinterpret_cast(rva_fix_addr)); + +// when you inherit obfuscate please be mindful of JCC rvas... +*reinterpret_cast(rva_fix_addr) = JMP_RIP_SIZE; + +gadget_stack.push_back({ instruction.second, {} }); +gadget_stack.push_back({ jmp_rip, inline_jmp_reloc }); +gadget_stack.push_back({ jmp_rip, inline_jmp_branch }); +``` + +### Mutation - Inherts Obfuscation -### Mutation - Inherts Obfuscation \ No newline at end of file From 604645d16d7dc220379ce4e3cd79c9810d5c193b Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 06:55:22 +0000 Subject: [PATCH 23/47] Update README.md --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 240acf4..982b271 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,9 @@ reloc_t inline_jmp_branch *reinterpret_cast(rva_fix_addr) }; -std::printf(" > fixing JCC rva...\n"); -std::printf(" > new rva = 0x%x\n", JMP_RIP_SIZE); -std::printf(" > old rva = 0x%x\n", - *reinterpret_cast(rva_fix_addr)); +std::printf("> fixing JCC rva...\n"); +std::printf("> new rva = 0x%x\n", JMP_RIP_SIZE); +std::printf("> old rva = 0x%x\n", *reinterpret_cast(rva_fix_addr)); // when you inherit obfuscate please be mindful of JCC rvas... *reinterpret_cast(rva_fix_addr) = JMP_RIP_SIZE; From 500fb51007be03016e4b92e5831d7fc9a55eef57 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:04:10 +0000 Subject: [PATCH 24/47] Update README.md --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index 982b271..dd7dc59 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,52 @@ both kernel and usermode projects. Since Theo inherits HMDM (highly modular driv Since Theo is a jit linker, unexported symbols can be jit linked. Resolving such symbols is open ended and allows the programmer of this framework to handle how they want to resolve symbols. More on this later (check out example projects). +# RIP Relative Addressing + +In order to allow for a routine to be scattered throughout a 64bit address space, RIP relative addressing must not be used. In order to facilitate this, a very special version +of clang-cl is used which can use `mcmodel=large`. This will generate instructions which do not use RIP relative addressing when referencing symbols outside of the routine in which the +instruction itself resides. The only exception to this is JCC instructions, (besides call) also known as branching instructions. Take this c++ code for an example: + +```cpp + +ObfuscateRoutine +extern "C" int ModuleEntry() +{ + MessageBoxA(0, "Demo", "Hello From Obfuscated Routine!", 0); + UsermodeMutateDemo(); + UsermodeNoObfuscation(); +} +``` + +This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: + +```nasm +0x00: ; void UsermodeNoObfuscation(void) +0x00: public ?UsermodeNoObfuscation@@YAXXZ +0x00: ?UsermodeNoObfuscation@@YAXXZ proc near ; CODE XREF: ModuleEntry+42↓p +0x00: var_4 = dword ptr -4 +0x00: 48 83 EC 28 sub rsp, 28h +0x04: C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 +0x0C: loc_C: +0x0C: 83 7C 24 24 05 cmp [rsp+28h+var_4], 5 +0x11: 0F 83 38 00 00 00 jnb loc_4F +0x17: 31 C0 xor eax, eax +0x19: 48 BA 28 01 00 00 00 00 00 00 mov rdx, offset ??_C@_04DKDMNOEB@Demo?$AA@ ; "Demo" +0x23: 49 B8 00 01 00 00 00 00 00 00 mov r8, offset ??_C@_0CD@JEJKPGNA@Hello?5... ; "Hello From Non-Obfuscated Routine!" +0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA +0x37: 45 31 C9 xor r9d, r9d ; uType +0x3A: 44 89 C9 mov ecx, r9d ; hWnd +0x3D: FF D0 call rax ; MessageBoxA +0x3F: 8B 44 24 24 mov eax, [rsp+28h+var_4] +0x43: 83 C0 01 add eax, 1 +0x46: 89 44 24 24 mov [rsp+28h+var_4], eax +0x4A: E9 BD FF FF FF jmp loc_C +0x4F: loc_4F: +0x4F: 48 83 C4 28 add rsp, 28h +0x53: C3 retn +0x53: ?UsermodeNoObfuscation@@YAXXZ endp +``` + # 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. From f5652f5f4f767e2322fbcf97c04a0daa4e02841c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:11:53 +0000 Subject: [PATCH 25/47] Update README.md --- README.md | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/README.md b/README.md index dd7dc59..30929e7 100644 --- a/README.md +++ b/README.md @@ -57,39 +57,34 @@ This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a ro 0x53: ?UsermodeNoObfuscation@@YAXXZ endp ``` -# 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. +As you can see from the code above, (sorry for the terrible syntax highlighting), references to strings and calls to functions are done by first loading the address of the symbol into a register and then interfacing with the symbol. -### Obfuscation - Base Class +```nasm +0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA +; ... +0x3D: FF D0 call rax ; MessageBoxA +``` -The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). LEA, nor CALL are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. +Each of these instructions can be anywhere in virtual memory and it would not effect code execution one bit. However this is not the case with routines which have conditional branches. Take the following c++ code for example. ```cpp -reloc_t inline_jmp_reloc +ObfuscateRoutine +void LoopDemo() { - reloc_type::next_instruction_addr, - JMP_RIP_ADDR_IDX -}; + for (auto idx = 0u; idx < 10; ++idx) + DbgPrint("> Loop Demo: %d\n", idx); +} +``` -reloc_t inline_jmp_branch -{ - reloc_type::jcc, - JMP_RIP_ADDR_IDX, - *reinterpret_cast(rva_fix_addr) -}; +This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: + +# Obfuscation -std::printf("> fixing JCC rva...\n"); -std::printf("> new rva = 0x%x\n", JMP_RIP_SIZE); -std::printf("> old rva = 0x%x\n", *reinterpret_cast(rva_fix_addr)); +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. -// when you inherit obfuscate please be mindful of JCC rvas... -*reinterpret_cast(rva_fix_addr) = JMP_RIP_SIZE; +### Obfuscation - Base Class -gadget_stack.push_back({ instruction.second, {} }); -gadget_stack.push_back({ jmp_rip, inline_jmp_reloc }); -gadget_stack.push_back({ jmp_rip, inline_jmp_branch }); -``` +The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). LEA, nor CALL are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. ### Mutation - Inherts Obfuscation From 8a135491300c82069d348031ada422e3928fea54 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:16:36 +0000 Subject: [PATCH 26/47] Update README.md --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 30929e7..242714e 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,6 @@ of clang-cl is used which can use `mcmodel=large`. This will generate instructio instruction itself resides. The only exception to this is JCC instructions, (besides call) also known as branching instructions. Take this c++ code for an example: ```cpp - ObfuscateRoutine extern "C" int ModuleEntry() { @@ -78,6 +77,10 @@ void LoopDemo() This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: +```nasm + +``` + # 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. From 5bbd5676ddbb431cf0d3ad8157fa07cf9d66c577 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:17:25 +0000 Subject: [PATCH 27/47] Update README.md --- README.md | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 242714e..aa7d17e 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,28 @@ void LoopDemo() This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: ```nasm - +0x58 ; void LoopDemo(void) +0x58 public ?LoopDemo@@YAXXZ +0x58 ?LoopDemo@@YAXXZ proc near +0x58 var_4 = dword ptr -4 +0x58 +0x58 48 83 EC 28 sub rsp, 28h +0x5C C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 +0x64 loc_64: +0x64 83 7C 24 24 0A cmp [rsp+28h+var_4], 0Ah +0x69 0F 83 2A 00 00 00 jnb loc_99 +0x6F 8B 54 24 24 mov edx, [rsp+28h+var_4] +0x73 48 B9 60 01 00 00 00 00 00 00 mov rcx, offset ??_C@_0BB@HGKDPLMC@?$.... ; "> Loop Demo: %d\n" +0x7D 48 B8 38 02 00 00 00 00 00 00 mov rax, offset DbgPrint +0x87 FF D0 call rax ; DbgPrint +0x89 8B 44 24 24 mov eax, [rsp+28h+var_4] +0x8D 83 C0 01 add eax, 1 +0x90 89 44 24 24 mov [rsp+28h+var_4], eax +0x94 E9 CB FF FF FF jmp loc_64 +0x99 loc_99: +0x99 48 83 C4 28 add rsp, 28h +0x9D C3 retn +0x9D ?LoopDemo@@YAXXZ endp ``` # Obfuscation From 962b29d1401b941fbdc0b2a12fc8faf145c0c0dd Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:20:04 +0000 Subject: [PATCH 28/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index aa7d17e..68f0c79 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,8 @@ This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a ro 0x9D ?LoopDemo@@YAXXZ endp ``` +Uh oh, `jnb loc_99`?, thats RIP relative! In order to handle branching operations, a "jump table" is generated by `obfuscation::obfuscate` explicit default constructor. Instead of branching to the RIP relative code, it will instead branch to an inline jump (`JMP [RIP+0x0]`). + # 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. From 1406e65630144b1891ca8850ee6cc0a507eb5367 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:20:45 +0000 Subject: [PATCH 29/47] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 68f0c79..391c75f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ extern "C" int ModuleEntry() This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: -```nasm +``` 0x00: ; void UsermodeNoObfuscation(void) 0x00: public ?UsermodeNoObfuscation@@YAXXZ 0x00: ?UsermodeNoObfuscation@@YAXXZ proc near ; CODE XREF: ModuleEntry+42↓p @@ -58,7 +58,7 @@ This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a ro As you can see from the code above, (sorry for the terrible syntax highlighting), references to strings and calls to functions are done by first loading the address of the symbol into a register and then interfacing with the symbol. -```nasm +``` 0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA ; ... 0x3D: FF D0 call rax ; MessageBoxA @@ -77,7 +77,7 @@ void LoopDemo() This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: -```nasm +``` 0x58 ; void LoopDemo(void) 0x58 public ?LoopDemo@@YAXXZ 0x58 ?LoopDemo@@YAXXZ proc near From 64ce5865829735f2711c32ef7e159ccdcb262007 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:37:47 +0000 Subject: [PATCH 30/47] Update README.md --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 391c75f..62f9b71 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,16 @@ This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a ro 0x9D ?LoopDemo@@YAXXZ endp ``` -Uh oh, `jnb loc_99`?, thats RIP relative! In order to handle branching operations, a "jump table" is generated by `obfuscation::obfuscate` explicit default constructor. Instead of branching to the RIP relative code, it will instead branch to an inline jump (`JMP [RIP+0x0]`). +Uh oh, `jnb loc_99`?, thats RIP relative! In order to handle branching operations, a "jump table" is generated by `obfuscation::obfuscate` explicit default constructor. Instead of branching to the RIP relative code, it will instead branch to an inline jump (`JMP [RIP+0x0]`). As demonstrated below, the branching operation is altered to branch to an asbolute jump. + +``` +ffff998b`c5369e60 0f830e000000 jnb ffff998b`c5369e74 +ffff998b`c5369e66 ff2500000000 jmp qword ptr [ffff998b`c5369e6c] +... +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. # Obfuscation From 4e47217461e45eacae9f229df62bd6758d99b013 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:42:24 +0000 Subject: [PATCH 31/47] Update README.md --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/README.md b/README.md index 62f9b71..f2922b1 100644 --- a/README.md +++ b/README.md @@ -123,3 +123,16 @@ The base class, as described in the above section, contains a handful of util ro ### Mutation - Inherts Obfuscation +This class inherits from `obfuscate` and adds additional code, or "mutation". This class is a small example of how to use inheritance with `obfuscate` base class. It generates a stack push/pop palindrome. The state of the stack is restored before the routines actual instruction is executed. The assembly will now look like this in memory: + +``` +push gp +push gp +push gp +... +pop gp +pop gp +pop gp +exec routine instruction +jmp next instruction +``` \ No newline at end of file From ef2a63c682278de17282841c02b9eef7e657e10a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:44:09 +0000 Subject: [PATCH 32/47] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index f2922b1..a5d2d96 100644 --- a/README.md +++ b/README.md @@ -119,7 +119,11 @@ The usage of the word obfuscation in this project is use to define any changes m ### Obfuscation - Base Class -The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). LEA, nor CALL are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. +The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). + + +LEA's, nor CALL's are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. + ### Mutation - Inherts Obfuscation From 003e5cc3410e331513539a1b7e20224ae8da32de Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 07:58:50 +0000 Subject: [PATCH 33/47] Update README.md --- README.md | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a5d2d96..bf5f52f 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,22 @@ both kernel and usermode projects. Since Theo inherits HMDM (highly modular driv Since Theo is a jit linker, unexported symbols can be jit linked. Resolving such symbols is open ended and allows the programmer of this framework to handle how they want to resolve symbols. More on this later (check out example projects). +# Linking - Dynamic And Static + +### What Is A Linker + +A linker is a program which takes object files produces by a compiler and generates a final executable native to the operating system. A linker interfaces with not only object files but also static libraries, "lib" files. What is a "lib" file? Well a lib file is just an archive of obj's. You can invision it as a zip/rar without any compression, just concatination of said object files. + +### Object Files + +If you define a c++ file called "main.cpp" the compiler will generate an object file by the name of "main.obj". When you refer to data or code defined in another c/c++ file, the linker uses a symbol table to resolve the address of said code/data. In this situation I am the linker and I resolve all of your symbols :). + +### Static Linking + +Static linking is when the linker links entire routines not created by you, into your code. Say `memcpy` (if its not inlined), will be staticlly linked with the CRT. Static linking also allows for your code to be more independant as all the code you need you bring with you. However, with Theo, you cannot link static libraries which are not compiled with `mcmodel=large`. Theo supports actual static linking, in other words, using multiple static libraries at the same time. + +### Dynamic Linking + # RIP Relative Addressing In order to allow for a routine to be scattered throughout a 64bit address space, RIP relative addressing must not be used. In order to facilitate this, a very special version @@ -139,4 +155,6 @@ pop gp pop gp exec routine instruction jmp next instruction -``` \ No newline at end of file +``` + +Again this is just a demo/POC on how you can inherit `obfuscate`. This also shows an example of how to use `asmjit`. \ No newline at end of file From 052b9de00e3e343ce1458f785a0351746d0aedd6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:01:15 +0000 Subject: [PATCH 34/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index bf5f52f..af3d386 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ Since Theo is a jit linker, unexported symbols can be jit linked. Resolving such A linker is a program which takes object files produces by a compiler and generates a final executable native to the operating system. A linker interfaces with not only object files but also static libraries, "lib" files. What is a "lib" file? Well a lib file is just an archive of obj's. You can invision it as a zip/rar without any compression, just concatination of said object files. +Theo is a jit linker, which means it will link objs together and map them into memory all at once. For usability however, instead of handling object files, Theo can parse entire lib files and extract the objects out of the lib. + ### Object Files If you define a c++ file called "main.cpp" the compiler will generate an object file by the name of "main.obj". When you refer to data or code defined in another c/c++ file, the linker uses a symbol table to resolve the address of said code/data. In this situation I am the linker and I resolve all of your symbols :). From 26c915b6c9adb170f6c8fb568b3c183b43c2b8ec Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:01:55 +0000 Subject: [PATCH 35/47] Update README.md --- README.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index af3d386..c1b0ca0 100644 --- a/README.md +++ b/README.md @@ -11,23 +11,23 @@ both kernel and usermode projects. Since Theo inherits HMDM (highly modular driv Since Theo is a jit linker, unexported symbols can be jit linked. Resolving such symbols is open ended and allows the programmer of this framework to handle how they want to resolve symbols. More on this later (check out example projects). -# Linking - Dynamic And Static +### Linking - Dynamic And Static -### What Is A Linker +#### Object Files -A linker is a program which takes object files produces by a compiler and generates a final executable native to the operating system. A linker interfaces with not only object files but also static libraries, "lib" files. What is a "lib" file? Well a lib file is just an archive of obj's. You can invision it as a zip/rar without any compression, just concatination of said object files. +If you define a c++ file called "main.cpp" the compiler will generate an object file by the name of "main.obj". When you refer to data or code defined in another c/c++ file, the linker uses a symbol table to resolve the address of said code/data. In this situation I am the linker and I resolve all of your symbols :). -Theo is a jit linker, which means it will link objs together and map them into memory all at once. For usability however, instead of handling object files, Theo can parse entire lib files and extract the objects out of the lib. +#### What Is A Linker -### Object Files +A linker is a program which takes object files produces by a compiler and generates a final executable native to the operating system. A linker interfaces with not only object files but also static libraries, "lib" files. What is a "lib" file? Well a lib file is just an archive of obj's. You can invision it as a zip/rar without any compression, just concatination of said object files. -If you define a c++ file called "main.cpp" the compiler will generate an object file by the name of "main.obj". When you refer to data or code defined in another c/c++ file, the linker uses a symbol table to resolve the address of said code/data. In this situation I am the linker and I resolve all of your symbols :). +Theo is a jit linker, which means it will link objs together and map them into memory all at once. For usability however, instead of handling object files, Theo can parse entire lib files and extract the objects out of the lib. -### Static Linking +#### Static Linking Static linking is when the linker links entire routines not created by you, into your code. Say `memcpy` (if its not inlined), will be staticlly linked with the CRT. Static linking also allows for your code to be more independant as all the code you need you bring with you. However, with Theo, you cannot link static libraries which are not compiled with `mcmodel=large`. Theo supports actual static linking, in other words, using multiple static libraries at the same time. -### Dynamic Linking +#### Dynamic Linking # RIP Relative Addressing From a989d0c3b74f51fe117b9f5554c9e02f9841cbc5 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:04:01 +0000 Subject: [PATCH 36/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index c1b0ca0..69a4e93 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,8 @@ Static linking is when the linker links entire routines not created by you, into #### Dynamic Linking +Dynamic linking is when external symbols are resolved at runtime. This is done by imports and exports in DLL's (dynamiclly linked libraries). Theo supports "dynamic linking", or in better terms, linking against exported routines. You can see examples of this inside of both usermode and kernelmode examples. + # RIP Relative Addressing In order to allow for a routine to be scattered throughout a 64bit address space, RIP relative addressing must not be used. In order to facilitate this, a very special version From a15346f2b42ae763eac6f45089158cf5ae3348ce Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:07:05 +0000 Subject: [PATCH 37/47] Update README.md --- README.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 69a4e93..c369239 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ The linker is able to get the address of the branching code by taking the rip re 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. -### Obfuscation - Base Class +### Obfuscate - Base Class The base class, as described in the above section, contains a handful of util routines and a single explicit constructor which is the corner stone of the class. The constructor fixes JCC relative virtual addresses so that if the condition is met, instead of jumping instruction pointer relativitly, it will jump to an addition jmp (`JMP [RIP+0x0]`). @@ -145,6 +145,19 @@ The base class, as described in the above section, contains a handful of util ro LEA's, nor CALL's are rip relative, even for symbols defined inside of the routine in which the instruction is compiled into. In other words JCC instructions are the only instruction pointer relative instructions that are generated. +``` +instruction +jmp next instruction + + +instruction +jmp next instruction + + +instruction +jmp next instruction +``` + ### Mutation - Inherts Obfuscation This class inherits from `obfuscate` and adds additional code, or "mutation". This class is a small example of how to use inheritance with `obfuscate` base class. It generates a stack push/pop palindrome. The state of the stack is restored before the routines actual instruction is executed. The assembly will now look like this in memory: From b216ecfbb209d1917101f55057b96ccd82bab0a9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:07:43 +0000 Subject: [PATCH 38/47] Update README.md --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index c369239..f771226 100644 --- a/README.md +++ b/README.md @@ -163,6 +163,30 @@ jmp next instruction This class inherits from `obfuscate` and adds additional code, or "mutation". This class is a small example of how to use inheritance with `obfuscate` base class. It generates a stack push/pop palindrome. The state of the stack is restored before the routines actual instruction is executed. The assembly will now look like this in memory: ``` +push gp +push gp +push gp +... +pop gp +pop gp +pop gp +exec routine instruction +jmp next instruction + +push gp +push gp +push gp +push gp +push gp +... +pop gp +pop gp +pop gp +pop gp +pop gp +exec routine instruction +jmp next instruction + push gp push gp push gp From 7f7ffe7d4095950939992f11bd25ec13a71448c0 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:17:15 +0000 Subject: [PATCH 39/47] 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. From ab4458ca343813d752f098401bad0943fe5cbbc7 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:26:01 +0000 Subject: [PATCH 40/47] Update README.md --- README.md | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/README.md b/README.md index d94db55..ed32c15 100644 --- a/README.md +++ b/README.md @@ -172,7 +172,49 @@ theo::memcpy_t _memcpy = ### theo::malloc_t - allocate executable memory +This lambda is used to allocate executable memory. Any method will do as long as the memcpy lambda can write to the allocated memory. An MSREXEC example for this lambda is defined below. +```cpp +theo::malloc_t _kalloc = [&](std::size_t size) -> void* +{ + void* alloc_base; + msrexec.exec + ( + [&](void* krnl_base, get_system_routine_t get_kroutine) -> void + { + using ex_alloc_pool_t = + void* (*)(std::uint32_t, std::size_t); + + const auto ex_alloc_pool = + reinterpret_cast( + get_kroutine(krnl_base, "ExAllocatePool")); + + alloc_base = ex_alloc_pool(NULL, size); + } + ); + return alloc_base; +}; +``` + +This lambda uses MSREXEC to allocate kernel memory via ExAllocatePool. However this is completely open ended on how you want to do it, you can allocate your memory into discarded +sections, you can allocate your memory in another address space, etc... Its extremely modular. + + +Another, yet simple, usermode example for this lambda is defined below. + +```cpp +theo::malloc_t _alloc = [&](std::size_t size) -> void* +{ + return VirtualAllocEx + ( + phandle, + nullptr, + size, + MEM_COMMIT | MEM_RESERVE, + PAGE_EXECUTE_READWRITE + ); +}; +``` # Obfuscation From 3b5c442f32039cea37c37993915ef27583270957 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:27:36 +0000 Subject: [PATCH 41/47] Update README.md --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index ed32c15..e1db379 100644 --- a/README.md +++ b/README.md @@ -216,6 +216,8 @@ theo::malloc_t _alloc = [&](std::size_t size) -> void* }; ``` +### `theo::resolve_symbol_t` - + # 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. From 041460c89da2a56363b44eced87e7bbfd18325f4 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:30:34 +0000 Subject: [PATCH 42/47] Update README.md --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 81 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index e1db379..d373345 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ The linker is able to get the address of the branching code by taking the rip re 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 +### `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: @@ -170,7 +170,7 @@ theo::memcpy_t _memcpy = }; ``` -### theo::malloc_t - allocate executable memory +### `theo::malloc_t` - allocate executable memory This lambda is used to allocate executable memory. Any method will do as long as the memcpy lambda can write to the allocated memory. An MSREXEC example for this lambda is defined below. @@ -216,7 +216,85 @@ theo::malloc_t _alloc = [&](std::size_t size) -> void* }; ``` -### `theo::resolve_symbol_t` - +### `theo::resolve_symbol_t` - resolve external symbol + +This lambda will try and resolve external symbols. Symbols which are not defined inside of any object files. For example `PiddbCacheTable`, an unexported ntoskrnl symbol, which normally people sig scan for, can now be jit linked. This is possible by parsing a MAP file, however you can recode this to support PDB's, etc. Again its completely opened ended on how you want to resolve symbols. + +```cpp +theo::resolve_symbol_t resolve_symbol = +[&, &extern_symbols = extern_symbols](const char* symbol_name) -> std::uintptr_t +{ + 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); + + // false if we found the symbol... + return (!(result = utils::kmodule::get_export(drv_name, symbol_name))); + } + ); + } + + return result; +}; +``` # Obfuscation From 04c70ae7cb8c28e1a8eaf513ffc553b5fcf34373 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:32:21 +0000 Subject: [PATCH 43/47] Update README.md --- README.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/README.md b/README.md index d373345..1488f92 100644 --- a/README.md +++ b/README.md @@ -296,6 +296,35 @@ theo::resolve_symbol_t resolve_symbol = }; ``` +Another example of this lambda can be viewed in the usermode examples. This routine simply loops over every single module mapped into the specific process you want to map/link with. + +```cpp +theo::resolve_symbol_t _resolver = + [&, &extern_symbols = extern_symbols](const char* symbol_name) -> std::uintptr_t +{ + auto loaded_modules = std::make_unique(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( + GetProcAddress(LoadLibrary(file_name), symbol_name)))) + break; + } + + return result; +}; +``` + # 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. From 0a6cd11a34b9fbdedae1e53cca8c44e2c008f880 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:38:58 +0000 Subject: [PATCH 44/47] Update README.md --- README.md | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) diff --git a/README.md b/README.md index 1488f92..8682dae 100644 --- a/README.md +++ b/README.md @@ -325,6 +325,59 @@ theo::resolve_symbol_t _resolver = }; ``` +### Creating Instance + +Once all three lambdas are defined, you can then create a `theo::hmm_ctx` (highly modular mapper context). This class is like the one from HMDM however it requires an extra lambda to resolve external symbols. + +```cpp +theo::hmm_ctx drv_mapper({ _alloc, _memcpy, _resolver }); + +const auto drv_entry = + reinterpret_cast( + drv_mapper.map_objs(image_objs)); +``` + +### Calling Entry + +#### MSREXEC - Call Entry Example + +The entry point of the mapped code is not invoked by `hmm_ctx`, but rather its left up to you to call. An example of calling the entry point can be seen below. + +```cpp +int result; +msrexec.exec([&result, drv_entry = drv_entry] + (void* krnl_base, get_system_routine_t get_kroutine) -> void +{ + using drv_entry_t = int(*)(); + result = reinterpret_cast(drv_entry)(); +}); +``` + +#### VDM - Call Entry Example + +Another example, this one using VDM, can be seen below. + +```cpp +const auto entry_result = + vdm.syscall( + reinterpret_cast(drv_entry)); +``` + +#### WinAPI - CreateRemoteThread + +Another example, this one using WinAPI's, can be seen below. + +```cpp +std::uint32_t tid = 0u; +CreateRemoteThread +( + phandle, NULL, + NULL, drv_entry, + NULL, NULL, + (LPDWORD)&tid +); +``` + # 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. From fb01039a528dab8db91cd4880ee3f3a1301101ed Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:40:09 +0000 Subject: [PATCH 45/47] Add LICENSE --- LICENSE | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..1b26028 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, _xeroxz +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. From 15e848a5db89bbd5716aecb89b1196e0e8acbedc Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 8 Mar 2021 08:41:09 +0000 Subject: [PATCH 46/47] Update README.md --- README.md | 204 +++++++++++++++++++++++++++--------------------------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/README.md b/README.md index 8682dae..791536b 100644 --- a/README.md +++ b/README.md @@ -31,108 +31,6 @@ Static linking is when the linker links entire routines not created by you, into Dynamic linking is when external symbols are resolved at runtime. This is done by imports and exports in DLL's (dynamiclly linked libraries). Theo supports "dynamic linking", or in better terms, linking against exported routines. You can see examples of this inside of both usermode and kernelmode examples. -# RIP Relative Addressing - -In order to allow for a routine to be scattered throughout a 64bit address space, RIP relative addressing must not be used. In order to facilitate this, a very special version -of clang-cl is used which can use `mcmodel=large`. This will generate instructions which do not use RIP relative addressing when referencing symbols outside of the routine in which the -instruction itself resides. The only exception to this is JCC instructions, (besides call) also known as branching instructions. Take this c++ code for an example: - -```cpp -ObfuscateRoutine -extern "C" int ModuleEntry() -{ - MessageBoxA(0, "Demo", "Hello From Obfuscated Routine!", 0); - UsermodeMutateDemo(); - UsermodeNoObfuscation(); -} -``` - -This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: - -``` -0x00: ; void UsermodeNoObfuscation(void) -0x00: public ?UsermodeNoObfuscation@@YAXXZ -0x00: ?UsermodeNoObfuscation@@YAXXZ proc near ; CODE XREF: ModuleEntry+42↓p -0x00: var_4 = dword ptr -4 -0x00: 48 83 EC 28 sub rsp, 28h -0x04: C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 -0x0C: loc_C: -0x0C: 83 7C 24 24 05 cmp [rsp+28h+var_4], 5 -0x11: 0F 83 38 00 00 00 jnb loc_4F -0x17: 31 C0 xor eax, eax -0x19: 48 BA 28 01 00 00 00 00 00 00 mov rdx, offset ??_C@_04DKDMNOEB@Demo?$AA@ ; "Demo" -0x23: 49 B8 00 01 00 00 00 00 00 00 mov r8, offset ??_C@_0CD@JEJKPGNA@Hello?5... ; "Hello From Non-Obfuscated Routine!" -0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA -0x37: 45 31 C9 xor r9d, r9d ; uType -0x3A: 44 89 C9 mov ecx, r9d ; hWnd -0x3D: FF D0 call rax ; MessageBoxA -0x3F: 8B 44 24 24 mov eax, [rsp+28h+var_4] -0x43: 83 C0 01 add eax, 1 -0x46: 89 44 24 24 mov [rsp+28h+var_4], eax -0x4A: E9 BD FF FF FF jmp loc_C -0x4F: loc_4F: -0x4F: 48 83 C4 28 add rsp, 28h -0x53: C3 retn -0x53: ?UsermodeNoObfuscation@@YAXXZ endp -``` - -As you can see from the code above, (sorry for the terrible syntax highlighting), references to strings and calls to functions are done by first loading the address of the symbol into a register and then interfacing with the symbol. - -``` -0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA -; ... -0x3D: FF D0 call rax ; MessageBoxA -``` - -Each of these instructions can be anywhere in virtual memory and it would not effect code execution one bit. However this is not the case with routines which have conditional branches. Take the following c++ code for example. - -```cpp -ObfuscateRoutine -void LoopDemo() -{ - for (auto idx = 0u; idx < 10; ++idx) - DbgPrint("> Loop Demo: %d\n", idx); -} -``` - -This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: - -``` -0x58 ; void LoopDemo(void) -0x58 public ?LoopDemo@@YAXXZ -0x58 ?LoopDemo@@YAXXZ proc near -0x58 var_4 = dword ptr -4 -0x58 -0x58 48 83 EC 28 sub rsp, 28h -0x5C C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 -0x64 loc_64: -0x64 83 7C 24 24 0A cmp [rsp+28h+var_4], 0Ah -0x69 0F 83 2A 00 00 00 jnb loc_99 -0x6F 8B 54 24 24 mov edx, [rsp+28h+var_4] -0x73 48 B9 60 01 00 00 00 00 00 00 mov rcx, offset ??_C@_0BB@HGKDPLMC@?$.... ; "> Loop Demo: %d\n" -0x7D 48 B8 38 02 00 00 00 00 00 00 mov rax, offset DbgPrint -0x87 FF D0 call rax ; DbgPrint -0x89 8B 44 24 24 mov eax, [rsp+28h+var_4] -0x8D 83 C0 01 add eax, 1 -0x90 89 44 24 24 mov [rsp+28h+var_4], eax -0x94 E9 CB FF FF FF jmp loc_64 -0x99 loc_99: -0x99 48 83 C4 28 add rsp, 28h -0x9D C3 retn -0x9D ?LoopDemo@@YAXXZ endp -``` - -Uh oh, `jnb loc_99`?, thats RIP relative! In order to handle branching operations, a "jump table" is generated by `obfuscation::obfuscate` explicit default constructor. Instead of branching to the RIP relative code, it will instead branch to an inline jump (`JMP [RIP+0x0]`). As demonstrated below, the branching operation is altered to branch to an asbolute jump. - -``` -ffff998b`c5369e60 0f830e000000 jnb ffff998b`c5369e74 -ffff998b`c5369e66 ff2500000000 jmp qword ptr [ffff998b`c5369e6c] -... -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. @@ -378,6 +276,108 @@ CreateRemoteThread ); ``` +# RIP Relative Addressing + +In order to allow for a routine to be scattered throughout a 64bit address space, RIP relative addressing must not be used. In order to facilitate this, a very special version +of clang-cl is used which can use `mcmodel=large`. This will generate instructions which do not use RIP relative addressing when referencing symbols outside of the routine in which the +instruction itself resides. The only exception to this is JCC instructions, (besides call) also known as branching instructions. Take this c++ code for an example: + +```cpp +ObfuscateRoutine +extern "C" int ModuleEntry() +{ + MessageBoxA(0, "Demo", "Hello From Obfuscated Routine!", 0); + UsermodeMutateDemo(); + UsermodeNoObfuscation(); +} +``` + +This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: + +``` +0x00: ; void UsermodeNoObfuscation(void) +0x00: public ?UsermodeNoObfuscation@@YAXXZ +0x00: ?UsermodeNoObfuscation@@YAXXZ proc near ; CODE XREF: ModuleEntry+42↓p +0x00: var_4 = dword ptr -4 +0x00: 48 83 EC 28 sub rsp, 28h +0x04: C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 +0x0C: loc_C: +0x0C: 83 7C 24 24 05 cmp [rsp+28h+var_4], 5 +0x11: 0F 83 38 00 00 00 jnb loc_4F +0x17: 31 C0 xor eax, eax +0x19: 48 BA 28 01 00 00 00 00 00 00 mov rdx, offset ??_C@_04DKDMNOEB@Demo?$AA@ ; "Demo" +0x23: 49 B8 00 01 00 00 00 00 00 00 mov r8, offset ??_C@_0CD@JEJKPGNA@Hello?5... ; "Hello From Non-Obfuscated Routine!" +0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA +0x37: 45 31 C9 xor r9d, r9d ; uType +0x3A: 44 89 C9 mov ecx, r9d ; hWnd +0x3D: FF D0 call rax ; MessageBoxA +0x3F: 8B 44 24 24 mov eax, [rsp+28h+var_4] +0x43: 83 C0 01 add eax, 1 +0x46: 89 44 24 24 mov [rsp+28h+var_4], eax +0x4A: E9 BD FF FF FF jmp loc_C +0x4F: loc_4F: +0x4F: 48 83 C4 28 add rsp, 28h +0x53: C3 retn +0x53: ?UsermodeNoObfuscation@@YAXXZ endp +``` + +As you can see from the code above, (sorry for the terrible syntax highlighting), references to strings and calls to functions are done by first loading the address of the symbol into a register and then interfacing with the symbol. + +``` +0x2D: 48 B8 A0 01 00 00 00 00 00 00 mov rax, offset MessageBoxA +; ... +0x3D: FF D0 call rax ; MessageBoxA +``` + +Each of these instructions can be anywhere in virtual memory and it would not effect code execution one bit. However this is not the case with routines which have conditional branches. Take the following c++ code for example. + +```cpp +ObfuscateRoutine +void LoopDemo() +{ + for (auto idx = 0u; idx < 10; ++idx) + DbgPrint("> Loop Demo: %d\n", idx); +} +``` + +This c++ function, compiled by clang-cl with `mcmodel=large`, will generate a routine with the following instructions: + +``` +0x58 ; void LoopDemo(void) +0x58 public ?LoopDemo@@YAXXZ +0x58 ?LoopDemo@@YAXXZ proc near +0x58 var_4 = dword ptr -4 +0x58 +0x58 48 83 EC 28 sub rsp, 28h +0x5C C7 44 24 24 00 00 00 00 mov [rsp+28h+var_4], 0 +0x64 loc_64: +0x64 83 7C 24 24 0A cmp [rsp+28h+var_4], 0Ah +0x69 0F 83 2A 00 00 00 jnb loc_99 +0x6F 8B 54 24 24 mov edx, [rsp+28h+var_4] +0x73 48 B9 60 01 00 00 00 00 00 00 mov rcx, offset ??_C@_0BB@HGKDPLMC@?$.... ; "> Loop Demo: %d\n" +0x7D 48 B8 38 02 00 00 00 00 00 00 mov rax, offset DbgPrint +0x87 FF D0 call rax ; DbgPrint +0x89 8B 44 24 24 mov eax, [rsp+28h+var_4] +0x8D 83 C0 01 add eax, 1 +0x90 89 44 24 24 mov [rsp+28h+var_4], eax +0x94 E9 CB FF FF FF jmp loc_64 +0x99 loc_99: +0x99 48 83 C4 28 add rsp, 28h +0x9D C3 retn +0x9D ?LoopDemo@@YAXXZ endp +``` + +Uh oh, `jnb loc_99`?, thats RIP relative! In order to handle branching operations, a "jump table" is generated by `obfuscation::obfuscate` explicit default constructor. Instead of branching to the RIP relative code, it will instead branch to an inline jump (`JMP [RIP+0x0]`). As demonstrated below, the branching operation is altered to branch to an asbolute jump. + +``` +ffff998b`c5369e60 0f830e000000 jnb ffff998b`c5369e74 +ffff998b`c5369e66 ff2500000000 jmp qword ptr [ffff998b`c5369e6c] +... +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. + # 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.