feat: Improve Custom Pass feature code, docs, and demos
- Improved the Custom Pass code to align with Ryujin coding standards. - Added clear and helpful comments for better understanding of how RyujinCustomPassDemo works. - Improved README.md for better structure and readability as user-facing documentation. - Updated demo images for Ryujin and added more visual examples.
This commit is contained in:
39
README.md
39
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).
|
||||
|
||||
@@ -9,9 +9,40 @@
|
||||
|
||||
void RyujinCustomPassDemo(RyujinProcedure* proc) {
|
||||
|
||||
std::printf("Ol<EFBFBD> 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")) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
BIN
imgs/demo1.png
BIN
imgs/demo1.png
Binary file not shown.
|
Before Width: | Height: | Size: 170 KiB After Width: | Height: | Size: 76 KiB |
BIN
imgs/demo2.png
BIN
imgs/demo2.png
Binary file not shown.
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 103 KiB |
Reference in New Issue
Block a user