feat: Break Decompilers and Disassemblers feature
- Ryujin can now break decompilers and disassemblers using a simple technique. This feature was inspired by a talk from BinjaDev at Off by One Conf. It will definitely be improved in the near future with more techniques.
This commit is contained in:
@@ -18,7 +18,7 @@
|
||||
- Anti-Debug User + Kernel
|
||||
- Troll Reversers(Exclusive)
|
||||
- Anti-Dump
|
||||
- Anti-Disassembly(Planned - **TODO**)
|
||||
- Anti-Disassembly + Anti-Decompiler
|
||||
- Custom Passes(Planned - **TODO**)
|
||||
|
||||
---
|
||||
|
||||
@@ -183,6 +183,9 @@ void RyujinObfuscationCore::obfuscateIat() {
|
||||
code.init(runtime.environment());
|
||||
asmjit::x86::Assembler a(&code);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// Using `rdgsbase rax` to store the base address of the GS segment in RAX -> rdgsbase rax
|
||||
a.emit(asmjit::x86::Inst::kIdRdgsbase, asmjit::x86::rax);
|
||||
|
||||
@@ -216,6 +219,9 @@ void RyujinObfuscationCore::obfuscateIat() {
|
||||
// call rax -> Calling the IAT
|
||||
a.call(asmjit::x86::rax);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// Obtaining the new section buffer
|
||||
auto& opcodeBuffer = code.sectionById(0)->buffer();
|
||||
// Obtaining the pointer to the buffer of raw opcode data generated
|
||||
@@ -780,6 +786,9 @@ void RyujinObfuscationCore::insertVirtualization() {
|
||||
code.init(runtime.environment());
|
||||
asmjit::x86::Assembler a(&code);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// Saving the current value of RCX
|
||||
a.push(asmjit::x86::rcx);
|
||||
// Saving the current value of RDX
|
||||
@@ -815,6 +824,9 @@ void RyujinObfuscationCore::insertVirtualization() {
|
||||
// Restoring the original value of RCX
|
||||
a.pop(asmjit::x86::rcx);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// Retrieving from ASMJIT<49>s JIT the resulting opcodes generated by our algorithm
|
||||
auto& opcodeBuffer = code.sectionById(0)->buffer();
|
||||
const auto pOpcodeBuffer = opcodeBuffer.data();
|
||||
@@ -1573,6 +1585,9 @@ void RyujinObfuscationCore::insertAntiDebug() {
|
||||
a.pop(asmjit::x86::rcx);
|
||||
a.pop(asmjit::x86::rax);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// pop RFLAGS
|
||||
a.popfq();
|
||||
|
||||
@@ -1900,6 +1915,9 @@ void RyujinObfuscationCore::insertAntiDump() {
|
||||
a.pop(asmjit::x86::rcx);
|
||||
a.pop(asmjit::x86::rax);
|
||||
|
||||
// Breaking Decompilers
|
||||
insertBreakDecompilers(a);
|
||||
|
||||
// pop RFLAGS
|
||||
a.popfq();
|
||||
|
||||
@@ -1931,6 +1949,22 @@ void RyujinObfuscationCore::updateBasicBlocksContext() {
|
||||
|
||||
}
|
||||
|
||||
void RyujinObfuscationCore::insertBreakDecompilers(asmjit::x86::Assembler& a) {
|
||||
|
||||
//Breaking Decompilers(https://youtu.be/6UlxrDYng88?t=1287)
|
||||
a.push(asmjit::x86::rbx);
|
||||
|
||||
std::vector<unsigned char> breakDecompilerOneByteTrick{
|
||||
|
||||
0xEB, 0xFF, 0xC3
|
||||
|
||||
};
|
||||
a.embed(breakDecompilerOneByteTrick.data(), breakDecompilerOneByteTrick.size());
|
||||
|
||||
a.pop(asmjit::x86::rbx);
|
||||
|
||||
}
|
||||
|
||||
BOOL RyujinObfuscationCore::Run(bool& RyujinRunOncePass) {
|
||||
|
||||
//Add padding spaces
|
||||
|
||||
@@ -31,6 +31,7 @@ private:
|
||||
void insertVirtualization();
|
||||
void insertAntiDebug();
|
||||
void insertAntiDump();
|
||||
void insertBreakDecompilers(asmjit::x86::Assembler& a);
|
||||
std::vector<uint8_t> fix_branch_near_far_short(uint8_t original_opcode, uint64_t jmp_address, uint64_t target_address);
|
||||
uint32_t findOpcodeOffset(const uint8_t* data, size_t dataSize, const void* opcode, size_t opcodeSize);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user