fixed some JCC issues... added new reloc type..

2.0
_xeroxz 4 years ago
parent 32c2b17fcf
commit 979bb6c2a1

@ -50,12 +50,15 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
<ExecutablePath>$(LLVMInstallDir)\bin;$(ExecutablePath);</ExecutablePath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DebuggerFlavor>DbgengKernelDebugger</DebuggerFlavor>
<EnableInf2cat>false</EnableInf2cat>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\</IntDir>
<IncludePath>$(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH)</IncludePath>
<ExecutablePath>$(LLVMInstallDir)\bin;$(ExecutablePath);</ExecutablePath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
@ -99,6 +102,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="Theodosius.h" />
<ClInclude Include="Types.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

@ -18,5 +18,8 @@
<ClInclude Include="Theodosius.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Types.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
</Project>

@ -1,8 +1,36 @@
#include "Theodosius.h"
#include "Types.h"
MutateRoutine extern "C" void drv_entry()
// this routine is not obfuscated...
void PrintCR3()
{
ULONG_PTR Cr3Value =
*reinterpret_cast<ULONG_PTR*>(
IoGetCurrentProcess() + CR3_OFFSET);
DbgPrint("> Current CR3 = 0x%p\n", Cr3Value);
}
ObfuscateRoutine void LoopDemo()
{
// JCC's work! :)
for (auto idx = 0u; idx < 10; ++idx)
DbgPrint("> Loop Demo: %d\n", idx);
}
// entry point must be named "DrvEntry" for this example...
MutateRoutine extern "C" void DrvEntry()
{
DbgPrint("> Hello World!\n");
// non-exported symbols being resolved by jit linker...
DbgPrint("> PiDDBCacheTable = 0x%p\n", &PiDDBCacheTable);
DbgPrint("> win32kfull!NtUserRegisterShellPTPListener = 0x%p\n", &NtUserRegisterShellPTPListener);
// example of referencing itself...
DbgPrint("> DrvEntry = 0x%p\n", &DrvEntry);
// example of calling other obfuscated/non obfuscated routines...
PrintCR3();
LoopDemo();
}

@ -1,11 +1,3 @@
#pragma once
#include <intrin.h>
#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();
#define MutateRoutine __declspec(code_seg(".theo1"), noinline)

@ -0,0 +1,24 @@
#pragma once
#define NT_SUCCESS(x) ((x) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
#define CR3_OFFSET 0x28
using NTSTATUS = unsigned long;
using PVOID = void*;
using HANDLE = unsigned long;
using UCHAR = unsigned char;
using USHORT = unsigned short;
using ULONG = unsigned long;
using PULONG = unsigned long*;
typedef unsigned long long ULONG_PTR;
// this is a demo of resolving non-exported symbols...
// win32kfull.sys export example...
extern "C" void NtUserRegisterShellPTPListener();
extern "C" void* PiDDBCacheTable;
extern "C" unsigned char* IoGetCurrentProcess();
extern "C" unsigned long DbgPrint(const char* format, ...);
extern "C" PVOID ExAllocatePool(ULONG, ULONG);
extern "C" void ExFreePool(PVOID);

@ -1635,9 +1635,9 @@ typedef enum ZydisMnemonic_
/**
* Maximum value of this enum.
*/
ZYDIS_MNEMONIC_MAX_VALUE = ZYDIS_MNEMONIC_XTEST,
/**
* The minimum number of bits required to represent all values of this enum.
*/
ZYDIS_MNEMONIC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MNEMONIC_MAX_VALUE)
} ZydisMnemonic;
ZYDIS_MNEMONIC_MAX_VALUE = ZYDIS_MNEMONIC_XTEST,
/**
* The minimum number of bits required to represent all values of this enum.
*/
ZYDIS_MNEMONIC_REQUIRED_BITS = ZYAN_BITS_TO_REPRESENT(ZYDIS_MNEMONIC_MAX_VALUE)
} ZydisMnemonic;

@ -47,7 +47,7 @@ namespace theo
}
std::printf("[+] linking complete...\n");
return mapped_symbols["drv_entry"];
return mapped_symbols["DrvEntry"];
}
bool hmm_ctx::map_symbols(std::vector<lnk::obj_buffer_t>& objs)
@ -143,8 +143,8 @@ namespace theo
continue;
std::printf(" > mapping obfuscated routine %s into memory...\n", symbol.symbol_name.c_str());
std::int32_t instruc_offset = 0u;
unsigned instruc_offset = 0u;
while (true) // TODO: this is bad code... dont do this!
{
auto symbol_name = symbol.symbol_name;
@ -176,9 +176,16 @@ namespace theo
switch (reloc.type)
{
case obfuscation::reloc_type::none:
break;
case obfuscation::reloc_type::jcc:
{
const auto next_instruc_symbol =
std::string(symbol.symbol_name).append("@")
.append(std::to_string(instruc_offset + instruc_len + reloc.rva));
*reinterpret_cast<std::uintptr_t*>(fix_reloc_addr) =
mapped_symbols[next_instruc_symbol];
break;
}
case obfuscation::reloc_type::next_instruction_addr:
{
const auto next_instruc_symbol =
@ -190,6 +197,10 @@ namespace theo
break; // we resolved our own relocation...
}
case obfuscation::reloc_type::none:
{
break;
}
default:
{
// check this instruction to see if it needs any relocs...

@ -180,18 +180,8 @@ int main(int argc, char** argv)
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; }
// false if we found the symbol...
return (!(result = utils::kmodule::get_export(drv_name, symbol_name)));
}
);
}

@ -7,8 +7,11 @@ namespace obfuscation
:
instruction(info)
{
switch (instruction.first.mnemonic)
// idk what i did to zydis but + 1 fixed it?
// this is brutal... TODO: figure out tf is going on here...
switch (instruction.first.mnemonic + 1)
{
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JB:
case ZYDIS_MNEMONIC_JBE:
case ZYDIS_MNEMONIC_JCXZ:
@ -16,7 +19,6 @@ namespace obfuscation
case ZYDIS_MNEMONIC_JKNZD:
case ZYDIS_MNEMONIC_JKZD:
case ZYDIS_MNEMONIC_JL:
case ZYDIS_MNEMONIC_JLE:
case ZYDIS_MNEMONIC_JNB:
case ZYDIS_MNEMONIC_JNBE:
case ZYDIS_MNEMONIC_JNL:
@ -31,38 +33,53 @@ namespace obfuscation
case ZYDIS_MNEMONIC_JS:
case ZYDIS_MNEMONIC_JZ:
{
const auto rva_fix_offset = instruction.first.length -
(instruction.first.operands[0].size / 8);
const auto rva_fix_addr =
instruction.second.data() + rva_fix_offset;
reloc_t inline_jmp_reloc
{
JMP_RIP_ADDR_IDX,
reloc_type::next_instruction_addr
reloc_type::next_instruction_addr,
JMP_RIP_ADDR_IDX
};
const auto rva_fix_offset = instruction.first.length -
(instruction.first.operands[0].size / 8);
const auto rva_fix_addr =
instruction.second.data() + rva_fix_offset;
reloc_t inline_jmp_branch
{
reloc_type::jcc,
JMP_RIP_ADDR_IDX,
*reinterpret_cast<std::int32_t*>(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<std::uint32_t*>(rva_fix_addr));
*reinterpret_cast<std::int32_t*>(rva_fix_addr));
// when you inherit obfuscate please be mindful of JCC rvas...
*reinterpret_cast<std::uint32_t*>(rva_fix_addr) = JMP_RIP_SIZE;
*reinterpret_cast<std::int32_t*>(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_reloc });
gadget_stack.push_back({ jmp_rip, inline_jmp_branch });
break;
}
case ZYDIS_MNEMONIC_JMP:
{
const auto rva_fix_offset = instruction.first.length -
(instruction.first.operands[0].size / 8);
const auto rva_fix_addr =
instruction.second.data() + rva_fix_offset;
reloc_t inline_jmp_reloc
{
JMP_RIP_ADDR_IDX,
reloc_type::next_instruction_addr
{
reloc_type::jcc,
JMP_RIP_ADDR_IDX,
*reinterpret_cast<std::int32_t*>(rva_fix_addr)
};
gadget_stack.push_back({ jmp_rip, inline_jmp_reloc });
break;
}
@ -75,8 +92,8 @@ namespace obfuscation
{
reloc_t inline_jmp_reloc
{
JMP_RIP_ADDR_IDX,
reloc_type::next_instruction_addr
reloc_type::next_instruction_addr,
JMP_RIP_ADDR_IDX
};
gadget_stack.push_back({ instruction.second, {} });
@ -157,6 +174,6 @@ namespace obfuscation
// instruction gets executed...
gadget_stack.insert(
gadget_stack.begin(),
{ std::move(stack_palindrome), {NULL, reloc_type::none} });
{ std::move(stack_palindrome), {reloc_type::none, NULL, NULL } });
}
}

@ -22,13 +22,15 @@ namespace obfuscation
enum class reloc_type
{
none = -1,
next_instruction_addr = 1
jcc = 1,
next_instruction_addr = 2
};
struct reloc_t
{
std::uint32_t offset;
reloc_type type;
std::uint32_t offset;
std::int32_t rva;
};
using instruction_info_t = std::pair<ZydisDecodedInstruction, std::vector<std::uint8_t>>;

@ -284,6 +284,13 @@ namespace utils
DONT_RESOLVE_DLL_REFERENCES
);
if (!module_base)
{
// free the RTL_PROCESS_MODULES buffer...
VirtualFree(buffer, NULL, MEM_RELEASE);
return NULL;
}
const auto image_base =
reinterpret_cast<std::uintptr_t>(
modules->Modules[idx].ImageBase);

Loading…
Cancel
Save