From 0988e8e07866898c2406f34683915f63f4aec019 Mon Sep 17 00:00:00 2001 From: keowu Date: Sat, 19 Jul 2025 22:06:32 -0300 Subject: [PATCH] feat: Working on the base for Memory CRC32 Protection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Working on a new feature to allow users to protect obfuscated code with a memory protection mechanism, inspired by VMProtect, where the protector uses CRC32 to validate if a page was modified on disk or in memory. - This is just the base to start building the feature. It’s still in development and I hope it evolves a lot. --- RyujinConsole/RyujinConsole/RyujinCore.hh | 1 + .../Ryujin/Models/RyujinObfuscatorConfig.hh | 1 + .../RyujinCore/RyujinObfuscationCore.cc | 13 ++++++ .../RyujinCore/RyujinObfuscationCore.hh | 2 + RyujinCore/Ryujin/Utils/RyujinCRC32Utils.cc | 41 +++++++++++++++++++ RyujinCore/Ryujin/Utils/RyujinCRC32Utils.hh | 20 +++++++++ RyujinCore/RyujinCore.vcxproj | 2 + RyujinCore/RyujinCore.vcxproj.filters | 6 +++ RyujinGUI/RyujinCore.hh | 1 + 9 files changed, 87 insertions(+) create mode 100644 RyujinCore/Ryujin/Utils/RyujinCRC32Utils.cc create mode 100644 RyujinCore/Ryujin/Utils/RyujinCRC32Utils.hh diff --git a/RyujinConsole/RyujinConsole/RyujinCore.hh b/RyujinConsole/RyujinConsole/RyujinCore.hh index 75fd67f..3266617 100644 --- a/RyujinConsole/RyujinConsole/RyujinCore.hh +++ b/RyujinConsole/RyujinConsole/RyujinCore.hh @@ -23,6 +23,7 @@ public: bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary + bool m_isMemoryProtection; // Memory CRC32 protection RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate diff --git a/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh b/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh index dc525a2..8c9e3b0 100644 --- a/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh +++ b/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh @@ -21,6 +21,7 @@ public: bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary + bool m_isMemoryProtection; // Memory CRC32 protection RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate // todo: passes diff --git a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc index 5d8ba2c..1e8e0d6 100644 --- a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc +++ b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc @@ -1941,6 +1941,15 @@ void RyujinObfuscationCore::insertAntiDump() { } +void RyujinObfuscationCore::insertMemoryProtection() { + + unsigned char ucTest[]{ 0xDE, 0xAD, 0xBE, 0xEF }; + + RyujinCRC32Utils crcTest; + std::printf("RyujinObfuscationCore::insertMemoryProtection.TEST: 0x%X\n", crcTest.crc32(ucTest, 4)); + +} + void RyujinObfuscationCore::updateBasicBlocksContext() { auto new_obfuscated_opcodes = getProcessedProc().getUpdateOpcodes(); @@ -1992,7 +2001,11 @@ BOOL RyujinObfuscationCore::Run(bool& RyujinRunOncePass) { // Update our basic blocks context to rela 1-1 for the new obfuscated opcodes. this->updateBasicBlocksContext(); + //Insert stub for memory crc32 protection + this->insertMemoryProtection(); + RyujinRunOncePass = FALSE; + } //Update basic blocks view based on the new obfuscated diff --git a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh index 008be33..7e9e589 100644 --- a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh +++ b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh @@ -12,6 +12,7 @@ #include "../Models/RyujinProcedure.hh" #include "../Models/RyujinObfuscatorConfig.hh" #include "../RyujinCore/BasicBlockerBuilder.hh" +#include "../Utils/RyujinCRC32Utils.hh" class RyujinObfuscationCore { @@ -31,6 +32,7 @@ private: void insertVirtualization(); void insertAntiDebug(); void insertAntiDump(); + void insertMemoryProtection(); void insertBreakDecompilers(asmjit::x86::Assembler& a); std::vector 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); diff --git a/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.cc b/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.cc new file mode 100644 index 0000000..1d779a2 --- /dev/null +++ b/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.cc @@ -0,0 +1,41 @@ +#include "RyujinCRC32Utils.hh" + +auto RyujinCRC32Utils::checksum_crc32gentab() -> void { + + unsigned long poly = 0xEDB88320L; + for (int i = 0; i < 256; i++) { + + unsigned long crc = i; + + for (int j = 8; j > 0; j--) { + + if (crc & 1) crc = (crc >> 1) ^ poly; + else crc >>= 1; + + } + + m_crc_tab[i] = crc; + } + +} + +auto RyujinCRC32Utils::checksum_crc32(unsigned char* block, unsigned int length) -> uint32_t { + + register unsigned long crc = 0xFFFFFFFF; + + for (unsigned long i = 0; i < length; i++) crc = ((crc >> 8) & 0x00FFFFFF) ^ m_crc_tab[(crc ^ *block++) & 0xFF]; + + return (crc ^ 0xFFFFFFFF); +} + +auto RyujinCRC32Utils::crc32(unsigned char* block, unsigned int length) -> uint32_t { + + if (!m_bInitialized) { + + checksum_crc32gentab(); + m_bInitialized = TRUE; + + } + + return checksum_crc32(block, length); +} \ No newline at end of file diff --git a/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.hh b/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.hh new file mode 100644 index 0000000..ac46e3f --- /dev/null +++ b/RyujinCore/Ryujin/Utils/RyujinCRC32Utils.hh @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +class RyujinCRC32Utils { + +private: + uint32_t m_crc_tab[256]; + BOOL m_bInitialized = FALSE; + + auto checksum_crc32gentab() -> void; + + auto checksum_crc32(unsigned char* block, unsigned int length) -> uint32_t; + +public: + + auto crc32(unsigned char* block, unsigned int length) -> uint32_t; + +}; + diff --git a/RyujinCore/RyujinCore.vcxproj b/RyujinCore/RyujinCore.vcxproj index 4f03177..b53e227 100644 --- a/RyujinCore/RyujinCore.vcxproj +++ b/RyujinCore/RyujinCore.vcxproj @@ -188,6 +188,7 @@ + @@ -197,6 +198,7 @@ + diff --git a/RyujinCore/RyujinCore.vcxproj.filters b/RyujinCore/RyujinCore.vcxproj.filters index 1e1090f..3de4bc9 100644 --- a/RyujinCore/RyujinCore.vcxproj.filters +++ b/RyujinCore/RyujinCore.vcxproj.filters @@ -63,6 +63,9 @@ Ryujin + + Ryujin\Utils + @@ -86,6 +89,9 @@ Ryujin\RyujinCore + + Ryujin\Utils + diff --git a/RyujinGUI/RyujinCore.hh b/RyujinGUI/RyujinCore.hh index 68611b3..9ab0dfc 100644 --- a/RyujinGUI/RyujinCore.hh +++ b/RyujinGUI/RyujinCore.hh @@ -23,6 +23,7 @@ public: bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary + bool m_isMemoryProtection; // Memory CRC32 protection RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate