feat: Improve RyujinGUI to support RyujinCore

- RyujinGUI now uses RyujinCore to properly obfuscate code with full configuration support.
- Added new Ryujin logo.
- Added new Ryujin banner.
- Improved UI design, components, and more.
This commit is contained in:
keowu
2025-07-03 09:37:46 -03:00
parent 6d146f06bf
commit 9d5c6fb06c
9 changed files with 290 additions and 82 deletions

View File

@@ -1,16 +1,16 @@
#include "RyujinApp.hh"
bool RyujinApp::OnInit() {
auto* frame = new wxFrame(
nullptr,
wxID_ANY,
"Ryujin Obfuscator",
wxDefaultPosition,
wxSize(
850,
650,
580
),
@@ -18,7 +18,7 @@ bool RyujinApp::OnInit() {
);
frame->SetBackgroundColour(
frame->SetBackgroundColour(
wxColour(
25,
@@ -26,7 +26,6 @@ bool RyujinApp::OnInit() {
25
));
frame->SetFont(
wxFont(
@@ -34,49 +33,48 @@ bool RyujinApp::OnInit() {
wxFONTFAMILY_SWISS,
wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_NORMAL
));
auto* panel = new wxPanel(
frame,
wxID_ANY
);
panel->SetBackgroundColour(
frame->GetBackgroundColour( )
);
auto* topSizer = new wxBoxSizer(
wxVERTICAL
);
auto* title = new wxStaticText(
frame,
wxID_ANY,
"Ryujin Obfuscator"
);
title->SetFont(
wxFont(
if (
auto* icon = LoadPngFromRes(
18,
wxFONTFAMILY_SWISS,
wxFONTSTYLE_NORMAL,
wxFONTWEIGHT_BOLD
panel,
wxID_ANY,
IDB_PNG1
));
title->SetForegroundColour(
))
topSizer->Add(
icon,
0,
wxALIGN_CENTER | wxTOP,
10
*wxWHITE
);
);
topSizer->Add(
title,
0,
wxALIGN_CENTER | wxTOP,
20
);
topSizer->Add(
new wxStaticLine(
frame
panel
),
0,
@@ -88,18 +86,18 @@ bool RyujinApp::OnInit() {
auto* pathBox = new wxStaticBoxSizer(
wxVERTICAL,
frame,
panel,
"Paths"
);
pathBox->GetStaticBox()->SetForegroundColour(
pathBox->GetStaticBox( )->SetForegroundColour(
*wxWHITE
);
m_input = DrawnPathRow(
frame,
panel,
pathBox,
"Input EXE:",
wxID_HIGHEST + 1
@@ -107,15 +105,15 @@ bool RyujinApp::OnInit() {
);
m_pdb = DrawnPathRow(
frame,
pathBox,
"PDB File:",
panel,
pathBox,
"PDB File:",
wxID_HIGHEST + 2
);
m_output = DrawnPathRow(
frame,
panel,
pathBox,
"Output EXE:",
wxID_HIGHEST + 3
@@ -133,11 +131,11 @@ bool RyujinApp::OnInit() {
auto* optionsBox = new wxStaticBoxSizer(
wxVERTICAL,
frame,
panel,
"Obfuscation Options"
);
optionsBox->GetStaticBox()->SetForegroundColour(
optionsBox->GetStaticBox( )->SetForegroundColour(
*wxWHITE
@@ -152,37 +150,37 @@ bool RyujinApp::OnInit() {
);
m_virtualize = DrawnStyledCheckbox(
frame,
panel,
"Virtualize"
);
m_junk = DrawnStyledCheckbox(
frame,
panel,
"Junk Code"
);
m_encrypt = DrawnStyledCheckbox(
frame,
panel,
"Encrypt"
);
m_randomSection = DrawnStyledCheckbox(
frame,
panel,
"Random Section"
);
m_obfuscateIat = DrawnStyledCheckbox(
frame,
panel,
"Obfuscate IAT"
);
m_ignoreOriginalCodeRemove = DrawnStyledCheckbox(
frame,
panel,
"Ignore Original Code Removal"
);
@@ -217,7 +215,6 @@ bool RyujinApp::OnInit() {
m_ignoreOriginalCodeRemove
);
optionsBox->Add(
optionsSizer,
@@ -238,18 +235,18 @@ bool RyujinApp::OnInit() {
auto* procBox = new wxStaticBoxSizer(
wxVERTICAL,
frame,
panel,
"Procedures to Obfuscate"
);
procBox->GetStaticBox()->SetForegroundColour(
procBox->GetStaticBox( )->SetForegroundColour(
*wxWHITE
);
m_procList = new wxListBox(
frame,
panel,
wxID_ANY,
wxDefaultPosition,
wxDefaultSize,
@@ -258,6 +255,14 @@ bool RyujinApp::OnInit() {
wxBORDER_NONE
);
m_procList->SetMinSize(
wxSize(
-1,
200
));
m_procList->SetBackgroundColour(
wxColour(
@@ -288,10 +293,10 @@ bool RyujinApp::OnInit() {
procBtnRow->Add(
DrawnRyujinButton(
frame,
panel,
"Add",
wxID_HIGHEST + 4
),
0,
wxRIGHT,
@@ -301,10 +306,10 @@ bool RyujinApp::OnInit() {
procBtnRow->Add(
DrawnRyujinButton(
frame,
panel,
"Remove",
wxID_HIGHEST + 5
));
procBox->Add(
@@ -324,14 +329,14 @@ bool RyujinApp::OnInit() {
m_progress = new wxGauge(
frame,
panel,
wxID_ANY,
100
);
m_progress->SetMinSize(
wxSize(
-1,
14
@@ -355,7 +360,7 @@ bool RyujinApp::OnInit() {
auto* runBtn = DrawnRyujinButton(
frame,
panel,
"Run Obfuscator",
wxID_HIGHEST + 6
@@ -406,15 +411,21 @@ bool RyujinApp::OnInit() {
);
frame->CreateStatusBar();
frame->SetSizerAndFit(
panel->SetSizer(
topSizer
);
frame->Centre();
frame->Show();
topSizer->SetSizeHints(
panel
);
frame->Fit( );
frame->Centre( );
frame->Show( );
frame->CreateStatusBar( );
BindFileDialogs(
frame
@@ -434,6 +445,7 @@ bool RyujinApp::OnInit() {
return true;
}
auto RyujinApp::DrawnPathRow(wxWindow* parent, wxBoxSizer* sizer, const wxString& label, int buttonId) -> wxTextCtrl* {
auto* row = new wxBoxSizer(
@@ -596,7 +608,7 @@ auto RyujinApp::BindListEvents(wxFrame* frame) -> void {
frame->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
wxTextEntryDialog dlg(frame, "Enter comma-separated procedures or a unique procedure name:");
wxTextEntryDialog dlg(frame, "Enter comma-separated procedures or a unique procedure name:", "Procedures to obfuscate");
if (dlg.ShowModal() == wxID_OK) {
wxArrayString list = wxSplit(dlg.GetValue(), ',');
@@ -620,13 +632,122 @@ auto RyujinApp::BindListEvents(wxFrame* frame) -> void {
auto RyujinApp::BindRunEvent(wxFrame* frame) -> void {
frame->Bind(wxEVT_BUTTON, [=](wxCommandEvent&) {
frame->SetStatusText("Starting obfuscation...");
m_progress->Pulse();
wxMilliSleep(1000);
m_progress->SetValue(100);
frame->SetStatusText("Obfuscation complete.");
std::thread([=]() {
RyujinObfuscatorConfig core;
// Options Configuration
core.m_isEncryptObfuscatedCode = m_encrypt->IsChecked();
core.m_isIatObfuscation = m_obfuscateIat->IsChecked();
core.m_isIgnoreOriginalCodeRemove = m_ignoreOriginalCodeRemove->IsChecked();
core.m_isJunkCode = m_junk->IsChecked();
core.m_isRandomSection = m_randomSection->IsChecked();
core.m_isVirtualized = m_virtualize->IsChecked();
// Procedures to obfuscate
std::vector<std::string> procsToObfuscate;
auto count = m_procList->GetCount();
procsToObfuscate.reserve(count);
for (auto i = 0; i < count; ++i) {
auto item = m_procList->GetString(i);
procsToObfuscate.push_back(item.ToStdString());
}
core.m_strProceduresToObfuscate.assign(procsToObfuscate.begin(), procsToObfuscate.end());
auto bSuccess = core.RunRyujin(m_input->GetValue().ToStdString(), m_pdb->GetValue().ToStdString(), m_output->GetValue().ToStdString(), core);
frame->CallAfter([=]() {
if (bSuccess) {
m_progress->SetValue(100);
frame->SetStatusText("Obfuscation complete.");
} else {
m_progress->SetValue(50);
frame->SetStatusText("Obfuscation error.");
}
});
}).detach();
}, wxID_HIGHEST + 6);
}
}
auto RyujinApp::LoadPngFromRes(wxWindow* parent, wxWindowID id, int resId) -> wxStaticBitmap* {
wxImage::AddHandler(
new wxPNGHandler
);
auto hInst = reinterpret_cast<HINSTANCE>(GetModuleHandle(
_In_ NULL
));
auto rs = FindResource(
_In_ hInst,
_In_ MAKEINTRESOURCE(resId),
_In_ wxT("PNG")
);
if (!rs) return nullptr;
auto hGlob = LoadResource(
_In_opt_ hInst,
_In_ rs
);
auto* data = LockResource(
_In_ hGlob
);
auto size = SizeofResource(
_In_opt_ hInst,
_In_ rs
);
wxMemoryInputStream mis(
data,
size
);
wxImage img(
mis,
wxBITMAP_TYPE_PNG
);
if (!img.IsOk( )) return nullptr;
return new wxStaticBitmap(
parent,
id,
wxBitmap(
img
));
}

View File

@@ -3,6 +3,10 @@
#include <wx/gauge.h>
#include <wx/textdlg.h>
#include <wx/statline.h>
#include <wx/mstream.h>
#include <thread>
#include "resource.h"
#include "RyujinCore.hh"
class RyujinApp : public wxApp {
@@ -25,6 +29,7 @@ private:
auto BindFileDialogs(wxFrame* frame) -> void;
auto BindListEvents(wxFrame* frame) -> void;
auto BindRunEvent(wxFrame* frame) -> void;
auto LoadPngFromRes(wxWindow* parent, wxWindowID id, int resId) -> wxStaticBitmap*;
public:
bool OnInit() override;

View File

@@ -0,0 +1,32 @@
#pragma once
#include <vector>
#include <Windows.h>
#include <string>
class RyujinObfuscatorConfig {
public:
bool m_isRandomSection; // Randomize the name of the new section with the processed code -> ".Ryujin" standard
bool m_isVirtualized; // Virtualize the code [Try as much as possible]
bool m_isIatObfuscation; //Process IAT Obfuscation
bool m_isJunkCode; // Insert junk code to confuse
bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs)
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
std::vector<std::string> m_strProceduresToObfuscate; // Names of the procedures to obfuscate
bool RunRyujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) {
using tpdRunRyujinCore = BOOL(__stdcall*)(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config);
auto hModule = LoadLibraryW(L"RyujinCore.dll");
if (!hModule) return FALSE;
auto RunRyujinCore = reinterpret_cast<tpdRunRyujinCore>(GetProcAddress(hModule, "RunRyujinCore"));
if (!RunRyujinCore) return FALSE;
return RunRyujinCore(strInputFilePath, strPdbFilePath, strOutputFilePath, config);
}
};

Binary file not shown.

View File

@@ -93,7 +93,8 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories);libwebp.lib</AdditionalLibraryDirectories>
<AdditionalDependencies>libwebp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
@@ -111,7 +112,8 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_lib;%(AdditionalLibraryDirectories);libwebp.lib</AdditionalLibraryDirectories>
<AdditionalDependencies>libwebp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -125,7 +127,8 @@
<Link>
<SubSystem>Windows</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;%(AdditionalLibraryDirectories);libwebp.lib</AdditionalLibraryDirectories>
<AdditionalDependencies>libwebp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
@@ -143,14 +146,23 @@
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>$(WXWIN)\lib\vc_x64_lib;%(AdditionalLibraryDirectories);libwebp.lib</AdditionalLibraryDirectories>
<AdditionalDependencies>libwebp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="RyujinApp.cc" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="resource.h" />
<ClInclude Include="RyujinApp.hh" />
<ClInclude Include="RyujinCore.hh" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RyujinGUI.rc" />
</ItemGroup>
<ItemGroup>
<Image Include="..\..\imgs\logogui.png" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">

View File

@@ -13,15 +13,37 @@
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="RyujinCore">
<UniqueIdentifier>{38744ed6-b50a-4be0-bf17-6128092b44eb}</UniqueIdentifier>
</Filter>
<Filter Include="RyujinGUI">
<UniqueIdentifier>{77bfeccd-c1fb-48af-af85-98b6afe4398c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="RyujinApp.cc">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="RyujinCore.hh">
<Filter>RyujinCore</Filter>
</ClInclude>
<ClInclude Include="RyujinApp.hh">
<Filter>RyujinGUI</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="RyujinApp.cc">
<Filter>RyujinGUI</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="RyujinGUI.rc">
<Filter>Resource Files</Filter>
</ResourceCompile>
</ItemGroup>
<ItemGroup>
<Image Include="..\..\imgs\logogui.png">
<Filter>Resource Files</Filter>
</Image>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,16 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by RyujinGUI.rc
//
#define IDB_PNG1 101
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

BIN
imgs/logogui.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
imgs/ryujin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB