diff --git a/README.md b/README.md index ddd1465..da3c731 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,43 @@ For both options, you will need exclusively a PE file (Apanas, executable, for n --- +## Custom Pass Support + +In addition to the standard techniques available via CLI or GUI options, RyÅ«jin also supports a Custom Pass feature. This allows anyone to implement a callback that is invoked during the obfuscation flow, enabling users to extend RyÅ«jin’s capabilities with custom features specific to their code. + +To do this, the user must follow a specific callback model: + +```c++ +void RyujinCustomPassDemo(RyujinProcedure* proc); +``` + +Each time the callback is invoked, a ```RyujinProcedure``` instance is provided, allowing the user to modify execution scopes, basic block structures, and more. The class definition can be found in [RyujinProcedure.hh](https://github.com/keowu/Ryujin/blob/main/RyujinCore/Ryujin/Models/RyujinProcedure.hh). Additionally, a usage example is available in [RyujinConsole.cc](https://github.com/keowu/Ryujin/blob/main/RyujinConsole/RyujinConsole/RyujinConsole.cc#L10), No additional configuration file changes are required. The ```RyujinObfuscatorConfig``` class already includes all necessary settings for immediate use. + +## Dependencies + +To compile RyujinCore, RyujinConsole, and RyujinGUI, critical dependencies must be installed via [Microsoft VCPKG](https://github.com/microsoft/vcpkg), You can install them using the following commands: + +``` +vcpkg install asmjit +vcpkg install zydis +``` + +For a consistent development environment, consider the following versions: + +``` +asmjit:x64-windows - 2024-06-28 +zycore:x64-windows - 1.5.0 +zydis:x64-windows - 4.1.0 +``` + +In addition to these critical dependencies, some optional ones exist, for example, ```wxWidgets```, which is required to build RyujinGUI. It can be obtained from the [wxWidgets website](https://wxwidgets.org/downloads/). + +## Research Paper + +If you enjoy understanding how things work technically and exploring deep concepts, consider reading the **RyÅ«jin paper**: + +**TODO** + ## Getting Started -GITHUB_WIKI_URL +For more detailed usage information and explanations of each feature intended for daily use, consider reading the [**RyÅ«jin Wiki**](https://github.com/keowu/Ryujin/wiki). diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.cc b/RyujinConsole/RyujinConsole/RyujinConsole.cc index 42646df..803d4d2 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.cc +++ b/RyujinConsole/RyujinConsole/RyujinConsole.cc @@ -9,9 +9,40 @@ void RyujinCustomPassDemo(RyujinProcedure* proc) { - std::printf("Olá mundinho!\n"); + /* + This is a sample callback that demonstrates how Ryujin users can register callbacks during its operation/integration to be used with the RyujinCore engine. + This callback provides direct access to the RyujinProcedure class, which encapsulates all the logic of basic blocks and information about each obfuscated procedure, + allowing modifications and extensions limited only by the implementer's creativity. + In this example, the registered callback is used solely to display relevant information about each procedure to be obfuscated, as a demonstration. - std::printf("Meu custom pass foi chamado para(teste) -> %s\n", proc->name.c_str()); + A sample output: + ---------------------------------------------- + RyujinCustomPassDemo get called for subadd + subadd has 31 bytes, resides on 0x7ff6c7fd1100, with 1 basic blocks. + Instructions: + mov [rsp+0x08], ecx + mov eax, [rsp+0x08] + add eax, 0x0A + mov [rsp+0x08], eax + mov eax, [rsp+0x08] + sub eax, 0x02 + mov [rsp+0x08], eax + mov eax, [rsp+0x08] + ret + ---------------------------------------------- + */ + + std::printf("----------------------------------------------\n"); + std::printf("RyujinCustomPassDemo get called for %s\n", proc->name.c_str()); + std::printf("%s has %lld bytes, resides on 0x%llx, with %llx basic blocks.\n", proc->name.c_str(), proc->size, proc->address, proc->basic_blocks.size()); + + std::printf("Instructions:\n"); + + for (auto& block : proc->basic_blocks) + for (auto& inst : block.instructions) + std::printf("%s\n", inst.instruction.text); + + std::printf("----------------------------------------------\n"); } @@ -101,6 +132,7 @@ auto main(int argc, char* argv[]) -> int { config.m_isAntiDump = has_flag(args, "--AntiDump"); config.m_isMemoryProtection = has_flag(args, "--MemoryProtection"); + // Registering a new custom pass for invocation via callback config.RegisterCallback(RyujinCustomPassDemo); if (has_flag(args, "--procs")) { diff --git a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc index c880e13..0c22c6a 100644 --- a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc +++ b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc @@ -2439,6 +2439,21 @@ BOOL RyujinObfuscationCore::Run(bool& RyujinRunOncePass) { } + // Checking if we have any user-registered callbacks + if (m_config.m_callbacks.callbackCount > 0) + // Iterating over each registered callback + for (auto i = 0; i < m_config.m_callbacks.callbackCount; i++) + // If it's a valid address + if (m_config.m_callbacks.callbacks[i]) { + + // We invoke the callback, passing the m_proc instance by reference to allow user modifications. + m_config.m_callbacks.callbacks[i](&m_proc); + + // We update the Basic Blocks context to stay 1:1 with the user's modifications. + this->updateBasicBlocksContext(); + + } + if (RyujinRunOncePass) { if (this->m_config.m_isMemoryProtection && (!this->m_config.m_isAntiDump || !this->m_config.m_isEncryptObfuscatedCode || !this->m_config.m_isRandomSection)) { @@ -2455,11 +2470,6 @@ BOOL RyujinObfuscationCore::Run(bool& RyujinRunOncePass) { } - if (m_config.m_callbacks.callbackCount > 0) - for (int i = 0; i < m_config.m_callbacks.callbackCount; i++) - if (m_config.m_callbacks.callbacks[i]) - m_config.m_callbacks.callbacks[i](&m_proc); - return TRUE; } diff --git a/imgs/demo1.png b/imgs/demo1.png index 660242b..c0d9b2b 100644 Binary files a/imgs/demo1.png and b/imgs/demo1.png differ diff --git a/imgs/demo2.png b/imgs/demo2.png index feef4cb..17b28d6 100644 Binary files a/imgs/demo2.png and b/imgs/demo2.png differ