feat: Independent "Ryujin Core as a library" for better usability
- Ryujin now includes a component called Core, where the main obfuscator logic resides. It functions as an independent library that can be used anywhere. - RyujinConsole now operates by loading the RyujinCore library to run the obfuscator. - This is a preparation step for additional Ryujin components, such as a future Ryujin GUI and more features like passes and advanced obfuscation options.
This commit is contained in:
12
RyujinCore/Ryujin/Models/RyujinBasicBlock.hh
Normal file
12
RyujinCore/Ryujin/Models/RyujinBasicBlock.hh
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
#include "RyujinInstruction.hh"
|
||||
|
||||
class RyujinBasicBlock {
|
||||
|
||||
public:
|
||||
std::vector<RyujinInstruction> instructions;
|
||||
std::vector<std::vector<ZyanU8>> opcodes;
|
||||
uintptr_t start_address;
|
||||
uintptr_t end_address;
|
||||
|
||||
};
|
||||
8
RyujinCore/Ryujin/Models/RyujinInstruction.hh
Normal file
8
RyujinCore/Ryujin/Models/RyujinInstruction.hh
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
struct RyujinInstruction {
|
||||
|
||||
ZydisDisassembledInstruction instruction;
|
||||
uintptr_t addressofinstruction;
|
||||
|
||||
};
|
||||
16
RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh
Normal file
16
RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#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
|
||||
// todo: passes
|
||||
|
||||
};
|
||||
35
RyujinCore/Ryujin/Models/RyujinProcedure.hh
Normal file
35
RyujinCore/Ryujin/Models/RyujinProcedure.hh
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
#include "RyujinBasicBlock.hh"
|
||||
|
||||
class RyujinProcedure {
|
||||
|
||||
public:
|
||||
std::string name;
|
||||
uintptr_t address;
|
||||
uintptr_t size;
|
||||
std::vector<RyujinBasicBlock> basic_blocks;
|
||||
|
||||
std::vector<ZyanU8> getUpdateOpcodes() {
|
||||
|
||||
std::vector<unsigned char> result;
|
||||
|
||||
for (auto& block : basic_blocks) {
|
||||
|
||||
auto& blocks = block.opcodes;
|
||||
|
||||
for (size_t i = 0; i < blocks.size(); ++i) {
|
||||
const auto& block = blocks[i];
|
||||
if (!block.empty()) {
|
||||
for (const auto& byte : block) {
|
||||
result.emplace_back(byte);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
};
|
||||
117
RyujinCore/Ryujin/PDB/RyujinPdbParsing.hh
Normal file
117
RyujinCore/Ryujin/PDB/RyujinPdbParsing.hh
Normal file
@@ -0,0 +1,117 @@
|
||||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <dbghelp.h>
|
||||
#pragma comment(lib, "DbgHelp.lib")
|
||||
#include "../Models/RyujinProcedure.hh"
|
||||
|
||||
#define SymTagFunction 5
|
||||
|
||||
class RyujinPdbParsing {
|
||||
|
||||
private:
|
||||
|
||||
static BOOL CALLBACK EnumSymbolsCallback(PSYMBOL_INFO pSymInfo, ULONG SymbolSize, PVOID UserContext) {
|
||||
|
||||
auto* vecSymbols = reinterpret_cast<std::vector<RyujinProcedure>*>(UserContext);
|
||||
|
||||
//Daddy, is this symbol a function entry ?!
|
||||
if (pSymInfo->Tag == SymTagFunction) {
|
||||
|
||||
RyujinProcedure proc;
|
||||
proc.name = pSymInfo->Name;
|
||||
proc.address = pSymInfo->Address;
|
||||
proc.size = pSymInfo->Size;
|
||||
vecSymbols->emplace_back(proc);
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
static std::vector<RyujinProcedure> ExtractProceduresFromPdb(uintptr_t mappedPebase, uintptr_t szFile, const std::string& strInputFilePath, const std::string& strPdbFilePath) {
|
||||
|
||||
std::vector<RyujinProcedure> procs;
|
||||
|
||||
::SymSetOptions(
|
||||
|
||||
_In_ SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME
|
||||
|
||||
);
|
||||
|
||||
if (!::SymInitialize(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_opt_ nullptr,
|
||||
_In_ NULL
|
||||
|
||||
)) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "RyujinPdbParsing::ExtractProceduresFromPdb: SymInitialize failed..\n"
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
auto strPdbDirectory = strPdbFilePath.substr(0, strPdbFilePath.find_last_of("\\/"));
|
||||
|
||||
::SymSetSearchPath(
|
||||
|
||||
::GetCurrentProcess(),
|
||||
strPdbDirectory.c_str()
|
||||
|
||||
);
|
||||
|
||||
auto loadedModuleBase = ::SymLoadModule64(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_opt_ nullptr,
|
||||
_In_opt_ strInputFilePath.c_str(),
|
||||
_In_opt_ nullptr,
|
||||
_In_ mappedPebase,
|
||||
_In_ szFile
|
||||
|
||||
);
|
||||
|
||||
if (loadedModuleBase == 0) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "RyujinPdbParsing::ExtractProceduresFromPdb: Failed to load SymLoadModule64..\n"
|
||||
|
||||
);
|
||||
|
||||
::SymCleanup(
|
||||
|
||||
_In_ ::GetCurrentProcess()
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
::SymEnumSymbols(
|
||||
|
||||
_In_ ::GetCurrentProcess(),
|
||||
_In_ loadedModuleBase,
|
||||
_In_opt_ nullptr,
|
||||
_In_ RyujinPdbParsing::EnumSymbolsCallback,
|
||||
_In_opt_ &procs
|
||||
|
||||
);
|
||||
|
||||
::SymCleanup(
|
||||
|
||||
_In_::GetCurrentProcess()
|
||||
|
||||
);
|
||||
|
||||
return procs;
|
||||
}
|
||||
|
||||
};
|
||||
655
RyujinCore/Ryujin/Ryujin.cc
Normal file
655
RyujinCore/Ryujin/Ryujin.cc
Normal file
@@ -0,0 +1,655 @@
|
||||
#include "Ryujin.hh"
|
||||
|
||||
Ryujin::Ryujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath) {
|
||||
|
||||
m_strInputFilePath.assign(strInputFilePath.begin(), strInputFilePath.end());
|
||||
m_strOutputFilePath.assign(strOutputFilePath.begin(), strOutputFilePath.end());
|
||||
m_strPdbFilePath.assign(strPdbFilePath.begin(), strPdbFilePath.end());
|
||||
|
||||
auto mappedInfo = RyujinUtils::MapPortableExecutableFileIntoMemory(m_strInputFilePath, m_mappedPE);
|
||||
|
||||
m_szFile = mappedInfo.second;
|
||||
m_isInitialized = mappedInfo.first;
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: failed to initilize.\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
m_ryujinProcedures = RyujinPdbParsing::ExtractProceduresFromPdb(
|
||||
|
||||
reinterpret_cast<uintptr_t>(m_mappedPE.get()),
|
||||
m_szFile,
|
||||
m_strInputFilePath,
|
||||
m_strPdbFilePath
|
||||
|
||||
);
|
||||
|
||||
if (m_ryujinProcedures.size() == 0) {
|
||||
|
||||
m_isInitialized = FALSE;
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: No Associate PDB file found for the input binary.."
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
||||
|
||||
auto imgDos = reinterpret_cast<PIMAGE_DOS_HEADER>(m_mappedPE.get());
|
||||
|
||||
if (imgDos->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::run: Invalid PE File.\n"
|
||||
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto imgNt = reinterpret_cast<PIMAGE_NT_HEADERS>(m_mappedPE.get() + imgDos->e_lfanew);
|
||||
|
||||
if (imgNt->Signature != IMAGE_NT_SIGNATURE) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::run: Invalid NT headers for the input PE File.\n"
|
||||
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: not initilized.\n"
|
||||
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (config.m_strProceduresToObfuscate.size() == 0) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: not provided functions to obfuscate.\n"
|
||||
|
||||
);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
std::vector<RyujinObfuscationCore> processed_procs;
|
||||
|
||||
for (auto& proc : m_ryujinProcedures) {
|
||||
|
||||
auto it = std::find(config.m_strProceduresToObfuscate.begin(), config.m_strProceduresToObfuscate.end(), proc.name);
|
||||
|
||||
if (it == config.m_strProceduresToObfuscate.end()) continue;
|
||||
|
||||
std::printf(
|
||||
|
||||
"[WORKING ON]: %s\n",
|
||||
proc.name.c_str()
|
||||
|
||||
);
|
||||
|
||||
// Is a valid procedure ?
|
||||
if (proc.size == 0) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::Ryujin: The candidate is a ghost function cannot obfuscate this..\n"
|
||||
|
||||
);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
//Get procedure opcodes from mapped pe file
|
||||
auto ucOpcodes = new unsigned char[proc.size] { 0 };
|
||||
std::memcpy(
|
||||
|
||||
ucOpcodes,
|
||||
reinterpret_cast<void*>(proc.address),
|
||||
proc.size
|
||||
|
||||
);
|
||||
|
||||
//Create basic blocks
|
||||
RyujinBasicBlockerBuilder rybb(ZYDIS_MACHINE_MODE_LONG_64, ZydisStackWidth_::ZYDIS_STACK_WIDTH_64);
|
||||
proc.basic_blocks = rybb.createBasicBlocks(ucOpcodes, proc.size, proc.address);
|
||||
|
||||
//Is time to obfuscate ?
|
||||
RyujinObfuscationCore obc(config, proc, reinterpret_cast<uintptr_t>(m_mappedPE.get()));
|
||||
obc.Run();
|
||||
|
||||
//TODO: Custom passes support
|
||||
|
||||
//Storing processed procs
|
||||
processed_procs.push_back(obc);
|
||||
|
||||
//Clean up opcodes
|
||||
delete[] ucOpcodes;
|
||||
|
||||
}
|
||||
|
||||
//Add section
|
||||
char chSectionName[8]{ '.', 'R', 'y', 'u', 'j', 'i', 'n', '\0' };
|
||||
if (config.m_isRandomSection) RyujinUtils::randomizeSectionName(chSectionName);
|
||||
|
||||
RyujinPESections peSections;
|
||||
peSections.AddNewSection(m_strInputFilePath, chSectionName);
|
||||
|
||||
uintptr_t offsetVA = 0, miniVmEnterAddress = 0;
|
||||
std::vector<unsigned char> opcodesWithRelocsFixed;
|
||||
|
||||
//Insert minivm enter routine
|
||||
if (config.m_isVirtualized) {
|
||||
|
||||
// Ryujin MiniVM Routine
|
||||
std::vector<unsigned char> miniVmEnter {
|
||||
/*
|
||||
#pragma optimize("", off)
|
||||
__declspec(noinline) __declspec(safebuffers)uintptr_t miniVmExecute(uintptr_t rcx, uintptr_t rdx) {
|
||||
|
||||
unsigned char reg = (rdx >> 16) & 0xFF;
|
||||
unsigned char op = (rdx >> 8) & 0xFF;
|
||||
uint64_t value = rdx & 0xFF;
|
||||
|
||||
uintptr_t result = rcx;
|
||||
|
||||
switch (op) {
|
||||
|
||||
case 1:
|
||||
result += value;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
result -= value;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
result *= value;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
result /= value;
|
||||
break;
|
||||
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
#pragma optimize("", on)
|
||||
*/
|
||||
0x48, 0x89, 0x54, 0x24, 0x10, 0x48, 0x89, 0x4C, 0x24, 0x08, 0x48, 0x83,
|
||||
0xEC, 0x28, 0x48, 0x8B, 0x44, 0x24, 0x38, 0x48, 0xC1, 0xE8, 0x10, 0x48,
|
||||
0x25, 0xFF, 0x00, 0x00, 0x00, 0x88, 0x44, 0x24, 0x01, 0x48, 0x8B, 0x44,
|
||||
0x24, 0x38, 0x48, 0xC1, 0xE8, 0x08, 0x48, 0x25, 0xFF, 0x00, 0x00, 0x00,
|
||||
0x88, 0x04, 0x24, 0x48, 0x8B, 0x44, 0x24, 0x38, 0x48, 0x25, 0xFF, 0x00,
|
||||
0x00, 0x00, 0x48, 0x89, 0x44, 0x24, 0x10, 0x48, 0x8B, 0x44, 0x24, 0x30,
|
||||
0x48, 0x89, 0x44, 0x24, 0x08, 0x0F, 0xB6, 0x04, 0x24, 0x88, 0x44, 0x24,
|
||||
0x04, 0x80, 0x7C, 0x24, 0x04, 0x01, 0x74, 0x17, 0x80, 0x7C, 0x24, 0x04,
|
||||
0x02, 0x74, 0x27, 0x80, 0x7C, 0x24, 0x04, 0x03, 0x74, 0x37, 0x80, 0x7C,
|
||||
0x24, 0x04, 0x04, 0x74, 0x42, 0xEB, 0x53, 0x48, 0x8B, 0x44, 0x24, 0x10,
|
||||
0x48, 0x8B, 0x4C, 0x24, 0x08, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48,
|
||||
0x89, 0x44, 0x24, 0x08, 0xEB, 0x45, 0x48, 0x8B, 0x44, 0x24, 0x10, 0x48,
|
||||
0x8B, 0x4C, 0x24, 0x08, 0x48, 0x2B, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89,
|
||||
0x44, 0x24, 0x08, 0xEB, 0x2E, 0x48, 0x8B, 0x44, 0x24, 0x08, 0x48, 0x0F,
|
||||
0xAF, 0x44, 0x24, 0x10, 0x48, 0x89, 0x44, 0x24, 0x08, 0xEB, 0x1C, 0x33,
|
||||
0xD2, 0x48, 0x8B, 0x44, 0x24, 0x08, 0x48, 0xF7, 0x74, 0x24, 0x10, 0x48,
|
||||
0x89, 0x44, 0x24, 0x08, 0xEB, 0x09, 0x48, 0xC7, 0x44, 0x24, 0x08, 0x00,
|
||||
0x00, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24, 0x08, 0x48, 0x83, 0xC4, 0x28,
|
||||
0xC3
|
||||
|
||||
};
|
||||
|
||||
// Inserting the Ryujin MiniVm stub at the beginning of Ryujin section
|
||||
opcodesWithRelocsFixed.insert(opcodesWithRelocsFixed.end(), miniVmEnter.begin(), miniVmEnter.end());
|
||||
|
||||
// Storing the MiniVm Stub Offset
|
||||
miniVmEnterAddress = peSections.getRyujinSectionVA();
|
||||
|
||||
// Calculating the size of the MiniVM Stub
|
||||
offsetVA += miniVmEnter.size();
|
||||
|
||||
}
|
||||
|
||||
for (auto& obc : processed_procs) {
|
||||
|
||||
// Getting new obfuscated opcodes
|
||||
auto tempValued = obc.getProcessedProc().getUpdateOpcodes();
|
||||
|
||||
// Fix relocations
|
||||
obc.applyRelocationFixupsToInstructions(reinterpret_cast<uintptr_t>(imgDos), peSections.getRyujinSectionVA() + offsetVA, tempValued);
|
||||
|
||||
// Removing and adding a jump in the original procedure and removing original opcodes for a jump to the new obfuscated code
|
||||
obc.removeOldOpcodeRedirect(peSections.mappedPeDiskBaseAddress(), peSections.getRyujinMappedPeSize(), reinterpret_cast<uintptr_t>(imgDos) + peSections.getRyujinSectionVA() + offsetVA, config.m_isIgnoreOriginalCodeRemove);
|
||||
|
||||
// Inserindo MiniVMEnter
|
||||
if (config.m_isVirtualized) obc.InsertMiniVmEnterProcedureAddress(reinterpret_cast<uintptr_t>(imgDos), miniVmEnterAddress, tempValued);
|
||||
|
||||
// Destructing class
|
||||
obc.~RyujinObfuscationCore();
|
||||
|
||||
// Inserting procedures into the list of corrected opcodes
|
||||
opcodesWithRelocsFixed.insert(opcodesWithRelocsFixed.end(), tempValued.begin(), tempValued.end());
|
||||
|
||||
// Incrementing the offset with the size of the opcodes in question
|
||||
offsetVA += tempValued.size();
|
||||
|
||||
}
|
||||
|
||||
// Encrypt all obfuscated code
|
||||
if (config.m_isEncryptObfuscatedCode && !config.m_isRandomSection) {
|
||||
|
||||
/*
|
||||
To "encrypt" all the obfuscated code:
|
||||
1 - We will encrypt byte by byte of our vector that contains the new opcodes for the section.
|
||||
2 - We will insert the stub that decrypts and its respective opcodes into the vector of new opcodes.
|
||||
3 - We will replace the original entry point with our stub. Our stub will jump to the original entry point after deobfuscation.
|
||||
4 - We will then have the code ready to be properly executed.
|
||||
*/
|
||||
|
||||
/*
|
||||
Begin TeaDelKew algorithm Implementation
|
||||
(C) Jo<4A>o Vitor(@Keowu) avaliable on https://github.com/keowu/gamespy/blob/main/code_base/Kurumi/TeaDelKewTests/TeaDelKewAlgo.hh#L2
|
||||
*/
|
||||
|
||||
// Aligning the data so we can run TeaDelKew
|
||||
while (opcodesWithRelocsFixed.size() % 8 != 0) {
|
||||
|
||||
opcodesWithRelocsFixed.push_back(0x00);
|
||||
offsetVA += 1;
|
||||
|
||||
}
|
||||
|
||||
// TEADELKEW key
|
||||
uint32_t key[4] = {
|
||||
|
||||
0x77122545, 0x88998877, 0x9944DEAD, 0x10CAFEB4
|
||||
|
||||
};
|
||||
|
||||
// TEADELKEW KeyBox
|
||||
uint32_t kew_box[12] = {
|
||||
|
||||
0x77122545, 0x88998877, 0x9944DEAD, 0x10CAFEB4,
|
||||
0x45B0B0C4, 0x35DEADDE, 0x25C4C4C4, 0x85634897,
|
||||
0x56123456, 0x11454545, 0x12323232, 0x95959595
|
||||
|
||||
};
|
||||
|
||||
// Encrypting all the opcode generated by the obfuscator using the TeaDelKew algorithm
|
||||
for (size_t i = 0; i < opcodesWithRelocsFixed.size(); i += 8) {
|
||||
|
||||
uint32_t* block = reinterpret_cast<uint32_t*>(&opcodesWithRelocsFixed[i]);
|
||||
|
||||
uint32_t v0 = ~block[0];
|
||||
uint32_t v1 = ~block[1];
|
||||
|
||||
uint32_t sum = 0;
|
||||
uint32_t delta = 0x00B0B0C4;
|
||||
|
||||
uint32_t k0 = key[0] ^ 0xDEADBEEF;
|
||||
uint32_t k1 = key[1] ^ 0xDEADBEEF;
|
||||
uint32_t k2 = key[2] ^ 0xDEADBEEF;
|
||||
uint32_t k3 = key[3] ^ 0xDEADBEEF;
|
||||
|
||||
for (int j = 0; j < 2048; j++) {
|
||||
|
||||
v1 ^= kew_box[j % 12];
|
||||
v0 ^= kew_box[j % 12];
|
||||
v1 ^= (j * 0x44444444 ^ ~j);
|
||||
v0 ^= (j * 0x44444444 ^ ~j);
|
||||
|
||||
}
|
||||
|
||||
for (int j = 0; j < 2048; j++) {
|
||||
|
||||
v0 += ~((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k0);
|
||||
sum += delta;
|
||||
v1 += ~((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k1);
|
||||
|
||||
}
|
||||
|
||||
block[0] = v0;
|
||||
block[1] = v1;
|
||||
}
|
||||
|
||||
// Entry point stub to decrypt the obfuscated code
|
||||
std::vector<unsigned char> entryPoint = {
|
||||
|
||||
/*
|
||||
#pragma optimize("", off)
|
||||
__declspec(noinline) __declspec(safebuffers)void ryujinEntryPoint() {
|
||||
|
||||
auto peb = reinterpret_cast<PVOID>(__readgsqword(0x60));
|
||||
if (!peb) return;
|
||||
|
||||
auto imageBase = *reinterpret_cast<PVOID*>(reinterpret_cast<BYTE*>(peb) + 0x10);
|
||||
if (!imageBase) return;
|
||||
|
||||
auto dos = reinterpret_cast<PIMAGE_DOS_HEADER>(imageBase);
|
||||
if (dos->e_magic != 0x5A4D) return;
|
||||
|
||||
auto nt = reinterpret_cast<PIMAGE_NT_HEADERS64>(reinterpret_cast<BYTE*>(imageBase) + dos->e_lfanew);
|
||||
if (nt->Signature != 0x00004550) return;
|
||||
|
||||
auto numSections = nt->FileHeader.NumberOfSections;
|
||||
auto section = IMAGE_FIRST_SECTION(nt);
|
||||
|
||||
char name[9] { 0 };
|
||||
char chLookingName[9] { '.', 'R', 'y', 'u', 'j', 'i', 'n', '\0' };
|
||||
uintptr_t rvaEntryPointOriginal = 0x9999999999999999;
|
||||
uintptr_t szStub = 0x8888888888888888;
|
||||
|
||||
for (auto i = 0; i < numSections; ++i, ++section) {
|
||||
|
||||
for (auto j = 0; j < 8; ++j) name[j] = section->Name[j];
|
||||
name[8] = 0;
|
||||
|
||||
auto rva = section->VirtualAddress;
|
||||
auto size = section->Misc.VirtualSize;
|
||||
auto va = reinterpret_cast<uintptr_t>((BYTE*)imageBase + rva);
|
||||
|
||||
if (name[0] == chLookingName[0] && name[1] == chLookingName[1] && name[2] == chLookingName[2] && name[3] == chLookingName[3]
|
||||
&& name[4] == chLookingName[4] && name[5] == chLookingName[5] && name[6] == chLookingName[6]) {
|
||||
|
||||
uint32_t kew_box[12] = {
|
||||
|
||||
0x77122545, 0x88998877, 0x9944DEAD, 0x10CAFEB4,
|
||||
0x45B0B0C4, 0x35DEADDE, 0x25C4C4C4, 0x85634897,
|
||||
0x56123456, 0x11454545, 0x12323232, 0x95959595
|
||||
|
||||
};
|
||||
|
||||
for (auto i = 0; i < (size - szStub); i += 8) {
|
||||
|
||||
if ((i + 8) > (size - szStub)) break;
|
||||
|
||||
auto* block = reinterpret_cast<uint32_t*>(va + i);
|
||||
|
||||
auto v0 = block[0];
|
||||
auto v1 = block[1];
|
||||
|
||||
uint32_t key[4] = {
|
||||
|
||||
0x77122545, 0x88998877,
|
||||
0x9944DEAD, 0x10CAFEB4
|
||||
|
||||
};
|
||||
|
||||
uint32_t sum = 0x85862000, delta = 0x00B0B0C4;
|
||||
|
||||
uint32_t k0 = key[0] ^ 0xDEADBEEF, k1 = key[1] ^ 0xDEADBEEF,
|
||||
k2 = key[2] ^ 0xDEADBEEF, k3 = key[3] ^ 0xDEADBEEF;
|
||||
|
||||
for (auto j = 0; j < 2048; j++) {
|
||||
|
||||
v1 -= ~((v0 << 4 ^ v0 >> 5) + v0) ^ (sum + k1);
|
||||
sum -= delta;
|
||||
v0 -= ~((v1 << 4 ^ v1 >> 5) + v1) ^ (sum + k0);
|
||||
|
||||
}
|
||||
|
||||
for (auto j = 0; j < 2048; j++) {
|
||||
|
||||
v1 ^= kew_box[j % 12];
|
||||
v0 ^= kew_box[j % 12];
|
||||
v1 ^= (j * 0x44444444 ^ ~j);
|
||||
v0 ^= (j * 0x44444444 ^ ~j);
|
||||
|
||||
}
|
||||
|
||||
block[0] = ~v0;
|
||||
block[1] = ~v1;
|
||||
}
|
||||
|
||||
using tpdEntryPoint = void(__stdcall*)();
|
||||
tpdEntryPoint oep = reinterpret_cast<tpdEntryPoint>(reinterpret_cast<uintptr_t>(imageBase) + rvaEntryPointOriginal);
|
||||
oep();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
#pragma optimize("", on)
|
||||
*/
|
||||
0x40, 0x57, 0x48, 0x81, 0xEC, 0x20, 0x01, 0x00, 0x00, 0x65, 0x48, 0x8B,
|
||||
0x04, 0x25, 0x60, 0x00, 0x00, 0x00, 0x48, 0x89, 0x84, 0x24, 0xB0, 0x00,
|
||||
0x00, 0x00, 0x48, 0x83, 0xBC, 0x24, 0xB0, 0x00, 0x00, 0x00, 0x00, 0x75,
|
||||
0x05, 0xE9, 0x26, 0x06, 0x00, 0x00, 0x48, 0x8B, 0x84, 0x24, 0xB0, 0x00,
|
||||
0x00, 0x00, 0x48, 0x8B, 0x40, 0x10, 0x48, 0x89, 0x44, 0x24, 0x78, 0x48,
|
||||
0x83, 0x7C, 0x24, 0x78, 0x00, 0x75, 0x05, 0xE9, 0x08, 0x06, 0x00, 0x00,
|
||||
0x48, 0x8B, 0x44, 0x24, 0x78, 0x48, 0x89, 0x84, 0x24, 0xB8, 0x00, 0x00,
|
||||
0x00, 0x48, 0x8B, 0x84, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x0F, 0xB7, 0x00,
|
||||
0x3D, 0x4D, 0x5A, 0x00, 0x00, 0x74, 0x05, 0xE9, 0xE4, 0x05, 0x00, 0x00,
|
||||
0x48, 0x8B, 0x84, 0x24, 0xB8, 0x00, 0x00, 0x00, 0x48, 0x63, 0x40, 0x3C,
|
||||
0x48, 0x8B, 0x4C, 0x24, 0x78, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48,
|
||||
0x89, 0x84, 0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x84, 0x24, 0x80,
|
||||
0x00, 0x00, 0x00, 0x81, 0x38, 0x50, 0x45, 0x00, 0x00, 0x74, 0x05, 0xE9,
|
||||
0xB0, 0x05, 0x00, 0x00, 0x48, 0x8B, 0x84, 0x24, 0x80, 0x00, 0x00, 0x00,
|
||||
0x0F, 0xB7, 0x40, 0x06, 0x66, 0x89, 0x44, 0x24, 0x58, 0x48, 0x8B, 0x84,
|
||||
0x24, 0x80, 0x00, 0x00, 0x00, 0x0F, 0xB7, 0x40, 0x14, 0x48, 0x8B, 0x8C,
|
||||
0x24, 0x80, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x44, 0x01, 0x18, 0x48, 0x89,
|
||||
0x44, 0x24, 0x68, 0x48, 0x8D, 0x44, 0x24, 0x48, 0x48, 0x8B, 0xF8, 0x33,
|
||||
0xC0, 0xB9, 0x09, 0x00, 0x00, 0x00, 0xF3, 0xAA, 0xC6, 0x44, 0x24, 0x30,
|
||||
0x2E, 0xC6, 0x44, 0x24, 0x31, 0x52, 0xC6, 0x44, 0x24, 0x32, 0x79, 0xC6,
|
||||
0x44, 0x24, 0x33, 0x75, 0xC6, 0x44, 0x24, 0x34, 0x6A, 0xC6, 0x44, 0x24,
|
||||
0x35, 0x69, 0xC6, 0x44, 0x24, 0x36, 0x6E, 0xC6, 0x44, 0x24, 0x37, 0x00,
|
||||
0x48, 0x8D, 0x44, 0x24, 0x38, 0x48, 0x8B, 0xF8, 0x33, 0xC0, 0xB9, 0x01,
|
||||
0x00, 0x00, 0x00, 0xF3, 0xAA, 0x48, 0xB8, 0x99, 0x99, 0x99, 0x99, 0x99,
|
||||
0x99, 0x99, 0x99, 0x48, 0x89, 0x84, 0x24, 0x08, 0x01, 0x00, 0x00, 0x48,
|
||||
0xB8, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x48, 0x89, 0x84,
|
||||
0x24, 0xC0, 0x00, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x5C, 0x00, 0x00, 0x00,
|
||||
0x00, 0xEB, 0x18, 0x8B, 0x44, 0x24, 0x5C, 0xFF, 0xC0, 0x89, 0x44, 0x24,
|
||||
0x5C, 0x48, 0x8B, 0x44, 0x24, 0x68, 0x48, 0x83, 0xC0, 0x28, 0x48, 0x89,
|
||||
0x44, 0x24, 0x68, 0x0F, 0xB7, 0x44, 0x24, 0x58, 0x39, 0x44, 0x24, 0x5C,
|
||||
0x0F, 0x8D, 0xE2, 0x04, 0x00, 0x00, 0xC7, 0x44, 0x24, 0x40, 0x00, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x0A, 0x8B, 0x44, 0x24, 0x40, 0xFF, 0xC0, 0x89, 0x44,
|
||||
0x24, 0x40, 0x83, 0x7C, 0x24, 0x40, 0x08, 0x7D, 0x19, 0x48, 0x63, 0x44,
|
||||
0x24, 0x40, 0x48, 0x63, 0x4C, 0x24, 0x40, 0x48, 0x8B, 0x54, 0x24, 0x68,
|
||||
0x0F, 0xB6, 0x04, 0x02, 0x88, 0x44, 0x0C, 0x48, 0xEB, 0xD6, 0xB8, 0x01,
|
||||
0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0, 0x08, 0xC6, 0x44, 0x04, 0x48, 0x00,
|
||||
0x48, 0x8B, 0x44, 0x24, 0x68, 0x8B, 0x40, 0x0C, 0x89, 0x84, 0x24, 0x90,
|
||||
0x00, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24, 0x68, 0x8B, 0x40, 0x08, 0x89,
|
||||
0x44, 0x24, 0x64, 0x8B, 0x84, 0x24, 0x90, 0x00, 0x00, 0x00, 0x48, 0x8B,
|
||||
0x4C, 0x24, 0x78, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x84,
|
||||
0x24, 0x00, 0x01, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x00, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x00, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0x42, 0x04, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x01, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x01, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0x1E, 0x04, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x02, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x02, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0xFA, 0x03, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x03, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x03, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0xD6, 0x03, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x04, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x04, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0xB2, 0x03, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x05, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x05, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0x8E, 0x03, 0x00, 0x00, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x48, 0x6B,
|
||||
0xC0, 0x06, 0x0F, 0xBE, 0x44, 0x04, 0x48, 0xB9, 0x01, 0x00, 0x00, 0x00,
|
||||
0x48, 0x6B, 0xC9, 0x06, 0x0F, 0xBE, 0x4C, 0x0C, 0x30, 0x3B, 0xC1, 0x0F,
|
||||
0x85, 0x6A, 0x03, 0x00, 0x00, 0xC7, 0x84, 0x24, 0xC8, 0x00, 0x00, 0x00,
|
||||
0x45, 0x25, 0x12, 0x77, 0xC7, 0x84, 0x24, 0xCC, 0x00, 0x00, 0x00, 0x77,
|
||||
0x88, 0x99, 0x88, 0xC7, 0x84, 0x24, 0xD0, 0x00, 0x00, 0x00, 0xAD, 0xDE,
|
||||
0x44, 0x99, 0xC7, 0x84, 0x24, 0xD4, 0x00, 0x00, 0x00, 0xB4, 0xFE, 0xCA,
|
||||
0x10, 0xC7, 0x84, 0x24, 0xD8, 0x00, 0x00, 0x00, 0xC4, 0xB0, 0xB0, 0x45,
|
||||
0xC7, 0x84, 0x24, 0xDC, 0x00, 0x00, 0x00, 0xDE, 0xAD, 0xDE, 0x35, 0xC7,
|
||||
0x84, 0x24, 0xE0, 0x00, 0x00, 0x00, 0xC4, 0xC4, 0xC4, 0x25, 0xC7, 0x84,
|
||||
0x24, 0xE4, 0x00, 0x00, 0x00, 0x97, 0x48, 0x63, 0x85, 0xC7, 0x84, 0x24,
|
||||
0xE8, 0x00, 0x00, 0x00, 0x56, 0x34, 0x12, 0x56, 0xC7, 0x84, 0x24, 0xEC,
|
||||
0x00, 0x00, 0x00, 0x45, 0x45, 0x45, 0x11, 0xC7, 0x84, 0x24, 0xF0, 0x00,
|
||||
0x00, 0x00, 0x32, 0x32, 0x32, 0x12, 0xC7, 0x84, 0x24, 0xF4, 0x00, 0x00,
|
||||
0x00, 0x95, 0x95, 0x95, 0x95, 0x48, 0xC7, 0x44, 0x24, 0x70, 0x00, 0x00,
|
||||
0x00, 0x00, 0xEB, 0x0E, 0x48, 0x8B, 0x44, 0x24, 0x70, 0x48, 0x83, 0xC0,
|
||||
0x08, 0x48, 0x89, 0x44, 0x24, 0x70, 0x8B, 0x44, 0x24, 0x64, 0x48, 0x2B,
|
||||
0x84, 0x24, 0xC0, 0x00, 0x00, 0x00, 0x48, 0x39, 0x44, 0x24, 0x70, 0x0F,
|
||||
0x83, 0x93, 0x02, 0x00, 0x00, 0x48, 0x8B, 0x44, 0x24, 0x70, 0x48, 0x83,
|
||||
0xC0, 0x08, 0x8B, 0x4C, 0x24, 0x64, 0x48, 0x2B, 0x8C, 0x24, 0xC0, 0x00,
|
||||
0x00, 0x00, 0x48, 0x3B, 0xC1, 0x76, 0x05, 0xE9, 0x74, 0x02, 0x00, 0x00,
|
||||
0x48, 0x8B, 0x44, 0x24, 0x70, 0x48, 0x8B, 0x8C, 0x24, 0x00, 0x01, 0x00,
|
||||
0x00, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x84, 0x24, 0x88,
|
||||
0x00, 0x00, 0x00, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0, 0x00,
|
||||
0x48, 0x8B, 0x8C, 0x24, 0x88, 0x00, 0x00, 0x00, 0x8B, 0x04, 0x01, 0x89,
|
||||
0x44, 0x24, 0x20, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0, 0x01,
|
||||
0x48, 0x8B, 0x8C, 0x24, 0x88, 0x00, 0x00, 0x00, 0x8B, 0x04, 0x01, 0x89,
|
||||
0x44, 0x24, 0x24, 0xC7, 0x84, 0x24, 0xA0, 0x00, 0x00, 0x00, 0x45, 0x25,
|
||||
0x12, 0x77, 0xC7, 0x84, 0x24, 0xA4, 0x00, 0x00, 0x00, 0x77, 0x88, 0x99,
|
||||
0x88, 0xC7, 0x84, 0x24, 0xA8, 0x00, 0x00, 0x00, 0xAD, 0xDE, 0x44, 0x99,
|
||||
0xC7, 0x84, 0x24, 0xAC, 0x00, 0x00, 0x00, 0xB4, 0xFE, 0xCA, 0x10, 0xC7,
|
||||
0x44, 0x24, 0x44, 0x00, 0x20, 0x86, 0x85, 0xC7, 0x84, 0x24, 0x98, 0x00,
|
||||
0x00, 0x00, 0xC4, 0xB0, 0xB0, 0x00, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x48,
|
||||
0x6B, 0xC0, 0x00, 0x8B, 0x84, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x35, 0xEF,
|
||||
0xBE, 0xAD, 0xDE, 0x89, 0x84, 0x24, 0x9C, 0x00, 0x00, 0x00, 0xB8, 0x04,
|
||||
0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0, 0x01, 0x8B, 0x84, 0x04, 0xA0, 0x00,
|
||||
0x00, 0x00, 0x35, 0xEF, 0xBE, 0xAD, 0xDE, 0x89, 0x84, 0x24, 0x94, 0x00,
|
||||
0x00, 0x00, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC0, 0x02, 0x8B,
|
||||
0x84, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x35, 0xEF, 0xBE, 0xAD, 0xDE, 0x89,
|
||||
0x84, 0x24, 0xF8, 0x00, 0x00, 0x00, 0xB8, 0x04, 0x00, 0x00, 0x00, 0x48,
|
||||
0x6B, 0xC0, 0x03, 0x8B, 0x84, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x35, 0xEF,
|
||||
0xBE, 0xAD, 0xDE, 0x89, 0x84, 0x24, 0xFC, 0x00, 0x00, 0x00, 0xC7, 0x44,
|
||||
0x24, 0x60, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0A, 0x8B, 0x44, 0x24, 0x60,
|
||||
0xFF, 0xC0, 0x89, 0x44, 0x24, 0x60, 0x81, 0x7C, 0x24, 0x60, 0x00, 0x08,
|
||||
0x00, 0x00, 0x7D, 0x7E, 0x8B, 0x44, 0x24, 0x20, 0xC1, 0xE0, 0x04, 0x8B,
|
||||
0x4C, 0x24, 0x20, 0xC1, 0xE9, 0x05, 0x33, 0xC1, 0x03, 0x44, 0x24, 0x20,
|
||||
0xF7, 0xD0, 0x8B, 0x8C, 0x24, 0x94, 0x00, 0x00, 0x00, 0x8B, 0x54, 0x24,
|
||||
0x44, 0x03, 0xD1, 0x8B, 0xCA, 0x33, 0xC1, 0x8B, 0x4C, 0x24, 0x24, 0x2B,
|
||||
0xC8, 0x8B, 0xC1, 0x89, 0x44, 0x24, 0x24, 0x8B, 0x84, 0x24, 0x98, 0x00,
|
||||
0x00, 0x00, 0x8B, 0x4C, 0x24, 0x44, 0x2B, 0xC8, 0x8B, 0xC1, 0x89, 0x44,
|
||||
0x24, 0x44, 0x8B, 0x44, 0x24, 0x24, 0xC1, 0xE0, 0x04, 0x8B, 0x4C, 0x24,
|
||||
0x24, 0xC1, 0xE9, 0x05, 0x33, 0xC1, 0x03, 0x44, 0x24, 0x24, 0xF7, 0xD0,
|
||||
0x8B, 0x8C, 0x24, 0x9C, 0x00, 0x00, 0x00, 0x8B, 0x54, 0x24, 0x44, 0x03,
|
||||
0xD1, 0x8B, 0xCA, 0x33, 0xC1, 0x8B, 0x4C, 0x24, 0x20, 0x2B, 0xC8, 0x8B,
|
||||
0xC1, 0x89, 0x44, 0x24, 0x20, 0xE9, 0x6E, 0xFF, 0xFF, 0xFF, 0xC7, 0x44,
|
||||
0x24, 0x28, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x0A, 0x8B, 0x44, 0x24, 0x28,
|
||||
0xFF, 0xC0, 0x89, 0x44, 0x24, 0x28, 0x81, 0x7C, 0x24, 0x28, 0x00, 0x08,
|
||||
0x00, 0x00, 0x0F, 0x8D, 0x83, 0x00, 0x00, 0x00, 0x8B, 0x44, 0x24, 0x28,
|
||||
0x99, 0xB9, 0x0C, 0x00, 0x00, 0x00, 0xF7, 0xF9, 0x8B, 0xC2, 0x48, 0x98,
|
||||
0x8B, 0x84, 0x84, 0xC8, 0x00, 0x00, 0x00, 0x8B, 0x4C, 0x24, 0x24, 0x33,
|
||||
0xC8, 0x8B, 0xC1, 0x89, 0x44, 0x24, 0x24, 0x8B, 0x44, 0x24, 0x28, 0x99,
|
||||
0xB9, 0x0C, 0x00, 0x00, 0x00, 0xF7, 0xF9, 0x8B, 0xC2, 0x48, 0x98, 0x8B,
|
||||
0x84, 0x84, 0xC8, 0x00, 0x00, 0x00, 0x8B, 0x4C, 0x24, 0x20, 0x33, 0xC8,
|
||||
0x8B, 0xC1, 0x89, 0x44, 0x24, 0x20, 0x69, 0x44, 0x24, 0x28, 0x44, 0x44,
|
||||
0x44, 0x44, 0x8B, 0x4C, 0x24, 0x28, 0xF7, 0xD1, 0x33, 0xC1, 0x8B, 0x4C,
|
||||
0x24, 0x24, 0x33, 0xC8, 0x8B, 0xC1, 0x89, 0x44, 0x24, 0x24, 0x69, 0x44,
|
||||
0x24, 0x28, 0x44, 0x44, 0x44, 0x44, 0x8B, 0x4C, 0x24, 0x28, 0xF7, 0xD1,
|
||||
0x33, 0xC1, 0x8B, 0x4C, 0x24, 0x20, 0x33, 0xC8, 0x8B, 0xC1, 0x89, 0x44,
|
||||
0x24, 0x20, 0xE9, 0x65, 0xFF, 0xFF, 0xFF, 0x8B, 0x44, 0x24, 0x20, 0xF7,
|
||||
0xD0, 0xB9, 0x04, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC9, 0x00, 0x48, 0x8B,
|
||||
0x94, 0x24, 0x88, 0x00, 0x00, 0x00, 0x89, 0x04, 0x0A, 0x8B, 0x44, 0x24,
|
||||
0x24, 0xF7, 0xD0, 0xB9, 0x04, 0x00, 0x00, 0x00, 0x48, 0x6B, 0xC9, 0x01,
|
||||
0x48, 0x8B, 0x94, 0x24, 0x88, 0x00, 0x00, 0x00, 0x89, 0x04, 0x0A, 0xE9,
|
||||
0x48, 0xFD, 0xFF, 0xFF, 0x48, 0x8B, 0x84, 0x24, 0x08, 0x01, 0x00, 0x00,
|
||||
0x48, 0x8B, 0x4C, 0x24, 0x78, 0x48, 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48,
|
||||
0x89, 0x84, 0x24, 0x10, 0x01, 0x00, 0x00, 0xFF, 0x94, 0x24, 0x10, 0x01,
|
||||
0x00, 0x00, 0x90, 0xE9, 0xF7, 0xFA, 0xFF, 0xFF, 0x48, 0x81, 0xC4, 0x20,
|
||||
0x01, 0x00, 0x00, 0x5F, 0xC3
|
||||
|
||||
};
|
||||
|
||||
// Parsing the PE file
|
||||
auto imgDos = reinterpret_cast<PIMAGE_DOS_HEADER>(peSections.mappedPeDiskBaseAddress());
|
||||
auto ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(reinterpret_cast<uint8_t*>(imgDos) + imgDos->e_lfanew);
|
||||
|
||||
// Finding the OEP (Original Entry Point) to store it
|
||||
DWORD OEP = ntHeader->OptionalHeader.AddressOfEntryPoint;
|
||||
// Storing the size of the entry point stub, which will be the only non-encrypted code in the obfuscated code section
|
||||
SIZE_T sizeOep = entryPoint.size();
|
||||
|
||||
// Setting a new entry point as the entry point stub that will decrypt the obfuscated executable code
|
||||
ntHeader->OptionalHeader.AddressOfEntryPoint = peSections.getRyujinSectionVA() + offsetVA;
|
||||
|
||||
// Modifying the stub to adapt to the OEP of the original entry point
|
||||
std::vector<unsigned char> pattern = {
|
||||
0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99
|
||||
};
|
||||
auto it = std::search(entryPoint.begin(), entryPoint.end(), pattern.begin(), pattern.end());
|
||||
std::memset(&*(it), 0, 8);
|
||||
std::memcpy(&*(it), &OEP, sizeof(OEP));
|
||||
|
||||
/*
|
||||
Modifying the stub to adapt and ignore the entry point stub decryption code itself,
|
||||
in a way that skips its size so it doesn<73>t break the stub
|
||||
when it decrypts the executable code.
|
||||
*/
|
||||
pattern.assign({
|
||||
0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88
|
||||
});
|
||||
it = std::search(entryPoint.begin(), entryPoint.end(), pattern.begin(), pattern.end());
|
||||
std::memset(&*(it), 0, 8);
|
||||
std::memcpy(&*(it), &sizeOep, sizeof(sizeOep));
|
||||
|
||||
// Inserting the opcodes of our stub into our vector along with the rest of the obfuscated and encrypted code
|
||||
opcodesWithRelocsFixed.insert(opcodesWithRelocsFixed.end(), entryPoint.begin(), entryPoint.end());
|
||||
|
||||
// Log to inform the user that our code has been properly encrypted.
|
||||
std::printf("[!] OEP: %llx - Inserting Decryption code routine on: %llx\n", imgNt->OptionalHeader.AddressOfEntryPoint, offsetVA);
|
||||
|
||||
}
|
||||
|
||||
//Process new opcodes
|
||||
peSections.ProcessOpcodesNewSection(opcodesWithRelocsFixed);
|
||||
|
||||
//Save output file
|
||||
peSections.FinishNewSection(m_strOutputFilePath);
|
||||
|
||||
}
|
||||
|
||||
void Ryujin::listRyujinProcedures() {
|
||||
|
||||
if (!m_isInitialized) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_ "Ryujin::listRyujinProcedures: not initialized.\n"
|
||||
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::printf("=== Ryujin Procedures ===\n");
|
||||
|
||||
for (const auto& procedure : m_ryujinProcedures) {
|
||||
|
||||
std::printf(
|
||||
"Name: %-30s | Address: 0x%016llx | Size: 0x%llx\n",
|
||||
procedure.name.c_str(),
|
||||
procedure.address,
|
||||
procedure.size
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
std::printf("==========================\n");
|
||||
|
||||
}
|
||||
34
RyujinCore/Ryujin/Ryujin.hh
Normal file
34
RyujinCore/Ryujin/Ryujin.hh
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include <Zydis/Zydis.h>
|
||||
#include <Zydis/SharedTypes.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include "PDB/RyujinPdbParsing.hh"
|
||||
#include "Utils/RyujinUtils.hh"
|
||||
#include "Models/RyujinObfuscatorConfig.hh"
|
||||
#include "RyujinCore/BasicBlockerBuilder.hh"
|
||||
#include "RyujinCore/RyujinObfuscationCore.hh"
|
||||
#include "Utils/RyujinPESections.hh"
|
||||
|
||||
class Ryujin {
|
||||
|
||||
private:
|
||||
std::shared_ptr<unsigned char> m_mappedPE;
|
||||
std::string m_strInputFilePath;
|
||||
std::string m_strPdbFilePath;
|
||||
std::string m_strOutputFilePath;
|
||||
uintptr_t m_szFile;
|
||||
BOOL m_isInitialized;
|
||||
std::vector<RyujinProcedure> m_ryujinProcedures;
|
||||
|
||||
bool todoAction() { return FALSE; }
|
||||
|
||||
public:
|
||||
Ryujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath);
|
||||
bool run(const RyujinObfuscatorConfig& config);
|
||||
void listRyujinProcedures();
|
||||
~Ryujin() { }
|
||||
|
||||
};
|
||||
|
||||
100
RyujinCore/Ryujin/RyujinCore/BasicBlockerBuilder.cc
Normal file
100
RyujinCore/Ryujin/RyujinCore/BasicBlockerBuilder.cc
Normal file
@@ -0,0 +1,100 @@
|
||||
#include "BasicBlockerBuilder.hh"
|
||||
|
||||
bool RyujinBasicBlockerBuilder::isControlFlow(const ZydisDecodedInstruction& instruction) const {
|
||||
|
||||
return (instruction.meta.category == ZYDIS_CATEGORY_CALL ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_RET ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_UNCOND_BR ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_COND_BR ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_SYSTEM ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_INTERRUPT ||
|
||||
instruction.meta.category == ZYDIS_CATEGORY_SYSCALL);
|
||||
}
|
||||
|
||||
RyujinBasicBlockerBuilder::RyujinBasicBlockerBuilder(ZydisMachineMode machine, ZydisStackWidth stack) {
|
||||
|
||||
::ZydisDecoderInit(
|
||||
|
||||
_Inout_ &decoder,
|
||||
_In_ machine,
|
||||
_In_ stack
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
std::vector<RyujinBasicBlock> RyujinBasicBlockerBuilder::createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address) {
|
||||
|
||||
std::vector<RyujinBasicBlock> blocks;
|
||||
|
||||
std::size_t offset = 0;
|
||||
uintptr_t curr_addr = start_address;
|
||||
|
||||
while (offset < szOpcode) {
|
||||
|
||||
RyujinBasicBlock block;
|
||||
block.start_address = start_address;
|
||||
|
||||
std::size_t inner = offset;
|
||||
while (inner < szOpcode) {
|
||||
|
||||
ZydisDisassembledInstruction instr;
|
||||
if (!ZYAN_SUCCESS(::ZydisDisassembleIntel(
|
||||
|
||||
_In_ ZYDIS_MACHINE_MODE_LONG_64,
|
||||
_In_ curr_addr + (inner - offset),
|
||||
_In_ chOpcode + inner,
|
||||
_In_ szOpcode - inner,
|
||||
_Out_ &instr
|
||||
|
||||
))) {
|
||||
|
||||
std::printf(
|
||||
|
||||
"RyujinBasicBlockerBuilder::createBasicBlocks: Zydis disam failed %llx\n",
|
||||
inner
|
||||
|
||||
);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
//Storing the instruction relative to the basic block
|
||||
RyujinInstruction inst;
|
||||
inst.addressofinstruction = curr_addr + (inner - offset);
|
||||
inst.instruction = instr;
|
||||
|
||||
block.instructions.push_back(
|
||||
|
||||
inst
|
||||
|
||||
);
|
||||
|
||||
//Storing the original opcodes from basic block
|
||||
block.opcodes.emplace_back(
|
||||
|
||||
chOpcode + inner,
|
||||
chOpcode + inner + instr.info.length
|
||||
|
||||
);
|
||||
|
||||
inner += instr.info.length;
|
||||
|
||||
//Theres a branch ? so let's preparate the next block
|
||||
if (isControlFlow(
|
||||
|
||||
instr.info
|
||||
|
||||
)) break;
|
||||
|
||||
}
|
||||
|
||||
block.end_address = curr_addr + (inner - offset);
|
||||
blocks.push_back(std::move(block));
|
||||
|
||||
curr_addr = block.end_address;
|
||||
offset = inner;
|
||||
}
|
||||
|
||||
return blocks;
|
||||
}
|
||||
17
RyujinCore/Ryujin/RyujinCore/BasicBlockerBuilder.hh
Normal file
17
RyujinCore/Ryujin/RyujinCore/BasicBlockerBuilder.hh
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
#include <Zydis/Zydis.h>
|
||||
#include <Zydis/SharedTypes.h>
|
||||
#include <vector>
|
||||
#include "../Models/RyujinBasicBlock.hh"
|
||||
|
||||
class RyujinBasicBlockerBuilder {
|
||||
|
||||
private:
|
||||
ZydisDecoder decoder;
|
||||
bool isControlFlow(const ZydisDecodedInstruction& instruction) const;
|
||||
|
||||
public:
|
||||
RyujinBasicBlockerBuilder(ZydisMachineMode machine, ZydisStackWidth stack);
|
||||
std::vector<RyujinBasicBlock> createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address);
|
||||
|
||||
};
|
||||
1263
RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc
Normal file
1263
RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.cc
Normal file
File diff suppressed because it is too large
Load Diff
75
RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh
Normal file
75
RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh
Normal file
@@ -0,0 +1,75 @@
|
||||
#pragma once
|
||||
#include <Windows.h>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <cstdint>
|
||||
#include <random>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <asmjit/asmjit.h>
|
||||
#include <Zydis/Zydis.h>
|
||||
#include <Zydis/SharedTypes.h>
|
||||
#include "../Models/RyujinProcedure.hh"
|
||||
#include "../Models/RyujinObfuscatorConfig.hh"
|
||||
#include "../RyujinCore/BasicBlockerBuilder.hh"
|
||||
|
||||
class RyujinObfuscationCore {
|
||||
|
||||
private:
|
||||
const int MAX_PADDING_SPACE_INSTR = 7;
|
||||
const int MAX_JUNK_GENERATION_ITERATION = 5;
|
||||
std::vector<ZydisRegister> m_unusedRegisters;
|
||||
std::vector<RyujinBasicBlock> m_obfuscated_bb;
|
||||
uintptr_t m_ProcImageBase;
|
||||
RyujinProcedure m_proc;
|
||||
RyujinObfuscatorConfig m_config;
|
||||
BOOL extractUnusedRegisters();
|
||||
void updateBasicBlocksContext();
|
||||
void addPaddingSpaces();
|
||||
void obfuscateIat();
|
||||
void insertJunkCode();
|
||||
void insertVirtualization();
|
||||
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);
|
||||
|
||||
inline std::pair<int, int> findBlockId(ZyanU8 uopcode, ZyanI64 value, ZyanU8 idx, ZyanU8 szData) {
|
||||
|
||||
int block_id = 0;
|
||||
int opcode_id = 0;
|
||||
|
||||
for (auto& block : m_proc.basic_blocks) {
|
||||
|
||||
opcode_id = 0;
|
||||
|
||||
for (auto& opcode : block.opcodes) {
|
||||
|
||||
auto data = opcode.data();
|
||||
auto size = opcode.size();
|
||||
|
||||
if (data[0] == uopcode) //0xFF ?
|
||||
|
||||
if (std::memcmp(&*(data + idx), &value, szData) == 0) // Is it the same memory immediate?
|
||||
|
||||
return std::make_pair(block_id, opcode_id);
|
||||
|
||||
|
||||
opcode_id++;
|
||||
|
||||
}
|
||||
|
||||
block_id++;
|
||||
}
|
||||
|
||||
return std::make_pair(-1, -1);
|
||||
};
|
||||
|
||||
public:
|
||||
RyujinObfuscationCore(const RyujinObfuscatorConfig& config, const RyujinProcedure& proc, uintptr_t ProcImageBase);
|
||||
void applyRelocationFixupsToInstructions(uintptr_t imageBase, DWORD virtualAddress, std::vector<unsigned char>& new_opcodes);
|
||||
void removeOldOpcodeRedirect(uintptr_t newMappedPE, std::size_t szMapped, uintptr_t newObfuscatedAddress, bool isIgnoreOriginalCodeRemove = false);
|
||||
void InsertMiniVmEnterProcedureAddress(uintptr_t imageBase, uintptr_t virtualAddress, std::vector<unsigned char>& new_opcodes);
|
||||
BOOL Run();
|
||||
RyujinProcedure getProcessedProc();
|
||||
~RyujinObfuscationCore();
|
||||
|
||||
};
|
||||
158
RyujinCore/Ryujin/Utils/RyujinPESections.cc
Normal file
158
RyujinCore/Ryujin/Utils/RyujinPESections.cc
Normal file
@@ -0,0 +1,158 @@
|
||||
#include "RyujinPESections.hh"
|
||||
|
||||
BOOL RyujinPESections::AddNewSection(const std::string& strInputFilePath, char chSectionName[8]) {
|
||||
|
||||
auto mappedDiskPE = RyujinUtils::MapDiskPE(strInputFilePath);
|
||||
|
||||
m_szFile = mappedDiskPE.second;
|
||||
|
||||
m_ucModifiedPeMap = new unsigned char[m_szFile]{ 0 };
|
||||
|
||||
std::memcpy(
|
||||
|
||||
m_ucModifiedPeMap,
|
||||
mappedDiskPE.first,
|
||||
m_szFile
|
||||
|
||||
);
|
||||
|
||||
::UnmapViewOfFile(
|
||||
|
||||
_In_ mappedDiskPE.first
|
||||
|
||||
);
|
||||
|
||||
m_dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(m_ucModifiedPeMap);
|
||||
if (m_dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
|
||||
delete[] m_ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
m_ntHeader = reinterpret_cast<PIMAGE_NT_HEADERS>(m_ucModifiedPeMap + m_dosHeader->e_lfanew);
|
||||
if (m_ntHeader->Signature != IMAGE_NT_SIGNATURE) {
|
||||
|
||||
delete[] m_ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto sectionTableSize = m_ntHeader->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
||||
if (m_dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sectionTableSize > m_ntHeader->OptionalHeader.SizeOfHeaders) {
|
||||
|
||||
//No space to insert a new section on this PE FILE :(
|
||||
|
||||
delete[] m_ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//Adding the new section
|
||||
std::memcpy(
|
||||
|
||||
m_newSection.Name,
|
||||
chSectionName,
|
||||
sizeof(chSectionName)
|
||||
|
||||
);
|
||||
|
||||
auto imgLastSection = IMAGE_FIRST_SECTION(m_ntHeader) + (m_ntHeader->FileHeader.NumberOfSections - 1);
|
||||
|
||||
m_newSection.VirtualAddress = ALIGN_UP(
|
||||
imgLastSection->VirtualAddress + imgLastSection->Misc.VirtualSize,
|
||||
m_ntHeader->OptionalHeader.SectionAlignment
|
||||
);
|
||||
|
||||
m_newSection.PointerToRawData = ALIGN_UP(
|
||||
imgLastSection->PointerToRawData + imgLastSection->SizeOfRawData,
|
||||
m_ntHeader->OptionalHeader.FileAlignment
|
||||
);
|
||||
|
||||
m_newSection.PointerToRelocations = JACKPOTNUMBER;
|
||||
|
||||
m_newSection.NumberOfRelocations = JACKPOTNUMBER;
|
||||
|
||||
m_newSection.PointerToLinenumbers = JACKPOTNUMBER;
|
||||
|
||||
m_newSection.NumberOfLinenumbers = JACKPOTNUMBER;
|
||||
|
||||
m_newSection.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL RyujinPESections::ProcessOpcodesNewSection(std::vector<unsigned char>& opcodeData) {
|
||||
|
||||
m_newSection.Misc.VirtualSize = opcodeData.size();
|
||||
m_newSection.SizeOfRawData = ALIGN_UP(opcodeData.size(), m_ntHeader->OptionalHeader.FileAlignment);
|
||||
|
||||
//Let's add a new section entry on the section table
|
||||
auto newSectionEntry = IMAGE_FIRST_SECTION(m_ntHeader) + m_ntHeader->FileHeader.NumberOfSections;
|
||||
std::memcpy(
|
||||
|
||||
newSectionEntry,
|
||||
&m_newSection,
|
||||
sizeof(IMAGE_SECTION_HEADER)
|
||||
|
||||
);
|
||||
|
||||
//Let's incement section number
|
||||
m_ntHeader->FileHeader.NumberOfSections++;
|
||||
|
||||
//Updating size of img
|
||||
m_ntHeader->OptionalHeader.SizeOfImage = ALIGN_UP(m_newSection.VirtualAddress + m_newSection.Misc.VirtualSize, m_ntHeader->OptionalHeader.SectionAlignment);
|
||||
|
||||
//New PE Sz
|
||||
m_szNewSec = m_newSection.PointerToRawData + m_newSection.SizeOfRawData;
|
||||
|
||||
m_ucResizedPE = reinterpret_cast<unsigned char*>(std::realloc(
|
||||
|
||||
m_ucModifiedPeMap,
|
||||
m_szNewSec
|
||||
|
||||
));
|
||||
|
||||
if (!m_ucResizedPE) {
|
||||
|
||||
//Failed to realocate PE
|
||||
delete[] m_ucModifiedPeMap;
|
||||
delete[] m_ucResizedPE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//Zeroing the extended PE region
|
||||
if (m_szNewSec > m_szFile) std::memset(
|
||||
|
||||
m_ucResizedPE + m_szFile,
|
||||
0,
|
||||
m_szNewSec - m_szFile
|
||||
|
||||
);
|
||||
|
||||
//Copying the new opcodes to the new section
|
||||
std::memcpy(
|
||||
|
||||
m_ucResizedPE + m_newSection.PointerToRawData,
|
||||
opcodeData.data(),
|
||||
opcodeData.size()
|
||||
|
||||
);
|
||||
|
||||
//In order to allow fix relocs latter we want:
|
||||
//allow get va out of this class
|
||||
//give acess to the new allocated area
|
||||
//give access to the new size
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL RyujinPESections::FinishNewSection(const std::string& strOutputFilePath) {
|
||||
|
||||
auto bSucess = RyujinUtils::SaveBuffer(strOutputFilePath, m_ucResizedPE, m_szNewSec);
|
||||
|
||||
if (!bSucess) return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
56
RyujinCore/Ryujin/Utils/RyujinPESections.hh
Normal file
56
RyujinCore/Ryujin/Utils/RyujinPESections.hh
Normal file
@@ -0,0 +1,56 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <Windows.h>
|
||||
|
||||
#include "RyujinUtils.hh"
|
||||
|
||||
#define ALIGN_UP(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
|
||||
#define JACKPOTNUMBER 0x777
|
||||
|
||||
class RyujinPESections {
|
||||
|
||||
private:
|
||||
IMAGE_SECTION_HEADER m_newSection;
|
||||
PIMAGE_DOS_HEADER m_dosHeader;
|
||||
PIMAGE_NT_HEADERS m_ntHeader;
|
||||
unsigned char* m_ucModifiedPeMap;
|
||||
uintptr_t m_szFile;
|
||||
unsigned char* m_ucResizedPE;
|
||||
uintptr_t m_szNewSec;
|
||||
|
||||
public:
|
||||
|
||||
uintptr_t getRyujinSectionVA() {
|
||||
|
||||
return m_newSection.VirtualAddress;
|
||||
}
|
||||
|
||||
unsigned char* getRyujinSection() {
|
||||
|
||||
return m_ucResizedPE;
|
||||
}
|
||||
|
||||
uintptr_t mappedPeDiskBaseAddress() {
|
||||
|
||||
return reinterpret_cast<uintptr_t>(m_dosHeader);
|
||||
}
|
||||
|
||||
uintptr_t getRyujinSectionSize() {
|
||||
|
||||
return m_szNewSec;
|
||||
}
|
||||
|
||||
uintptr_t getRyujinMappedPeSize() {
|
||||
|
||||
return m_szFile;
|
||||
}
|
||||
|
||||
BOOL AddNewSection(const std::string& strInputFilePath, char chSectionName[8]);
|
||||
|
||||
BOOL ProcessOpcodesNewSection(std::vector<unsigned char>& opcodeData);
|
||||
|
||||
BOOL FinishNewSection(const std::string& strOutputFilePath);
|
||||
|
||||
};
|
||||
1
RyujinCore/Ryujin/Utils/RyujinUtils.cc
Normal file
1
RyujinCore/Ryujin/Utils/RyujinUtils.cc
Normal file
@@ -0,0 +1 @@
|
||||
#include "RyujinUtils.hh"
|
||||
254
RyujinCore/Ryujin/Utils/RyujinUtils.hh
Normal file
254
RyujinCore/Ryujin/Utils/RyujinUtils.hh
Normal file
@@ -0,0 +1,254 @@
|
||||
#pragma once
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <Windows.h>
|
||||
|
||||
#define ALIGN_UP(value, alignment) ((value + alignment - 1) & ~(alignment - 1))
|
||||
|
||||
namespace RyujinUtils {
|
||||
|
||||
inline std::pair<BOOL, uintptr_t> MapPortableExecutableFileIntoMemory(const std::string& m_strInputFilePath, std::shared_ptr<unsigned char>& mappedPE) {
|
||||
|
||||
auto hFile = ::CreateFileA(
|
||||
|
||||
_In_ m_strInputFilePath.c_str(),
|
||||
_In_ GENERIC_READ,
|
||||
_In_ FILE_SHARE_READ | FILE_SHARE_DELETE,
|
||||
_In_opt_ nullptr,
|
||||
_In_ OPEN_EXISTING,
|
||||
_In_ FILE_ATTRIBUTE_NORMAL,
|
||||
_In_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
|
||||
OutputDebugStringA(
|
||||
|
||||
_In_opt_ "RyujinUtils::MapExecutableFileIntoMemory: failed because cannot open a handle for input PE FILE\n"
|
||||
|
||||
);
|
||||
|
||||
return std::make_pair(FALSE, 0);
|
||||
}
|
||||
|
||||
LARGE_INTEGER szFile;
|
||||
if (!::GetFileSizeEx(
|
||||
_In_ hFile,
|
||||
_Out_ &szFile
|
||||
)) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_opt_ "RyujinUtils::MapExecutableFileIntoMemory: was not possible to get filesizeru for the PE FILE\n"
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
return std::make_pair(FALSE, 0);
|
||||
}
|
||||
|
||||
auto hMap = ::CreateFileMappingA(
|
||||
|
||||
_In_ hFile,
|
||||
_In_opt_ nullptr,
|
||||
_In_ PAGE_READONLY | SEC_IMAGE,
|
||||
_In_ NULL,
|
||||
_In_ NULL,
|
||||
_In_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
if (!hMap) {
|
||||
|
||||
::OutputDebugStringA(
|
||||
|
||||
_In_opt_ "RyujinUtils::MapExecutableFileIntoMemory: was not possible to create a mapping to the PE FILE.\n"
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hMap
|
||||
|
||||
);
|
||||
|
||||
return std::make_pair(FALSE, 0);
|
||||
}
|
||||
|
||||
mappedPE = std::shared_ptr<unsigned char>(
|
||||
|
||||
reinterpret_cast<unsigned char*>(
|
||||
|
||||
::MapViewOfFile(
|
||||
|
||||
_In_ hMap,
|
||||
_In_ FILE_MAP_READ,
|
||||
_In_ NULL,
|
||||
_In_ NULL,
|
||||
_In_ NULL
|
||||
|
||||
)
|
||||
|
||||
),
|
||||
[](unsigned char* p) {
|
||||
|
||||
if (p) ::UnmapViewOfFile(
|
||||
|
||||
_In_ p
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hMap
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
return std::make_pair(TRUE, szFile.QuadPart);
|
||||
}
|
||||
|
||||
inline void randomizeSectionName(char* chName) {
|
||||
|
||||
const char charset[] { "abcdefghijklmnopqrstuvwxyz" };
|
||||
for (size_t i = 0; i < 8 - 1; ++i) chName[i] = charset[std::rand() % (sizeof(charset) - 1)];
|
||||
chName[8 - 1] = '\0';
|
||||
|
||||
}
|
||||
|
||||
inline BOOL SaveBuffer(const std::string& strPath, unsigned char* ucBuffer, uintptr_t szBuffer) {
|
||||
|
||||
auto hFile = ::CreateFileA(
|
||||
|
||||
_In_ strPath.c_str(),
|
||||
_In_ GENERIC_WRITE,
|
||||
_In_ 0,
|
||||
_In_opt_ nullptr,
|
||||
_In_ CREATE_ALWAYS,
|
||||
_In_ FILE_ATTRIBUTE_NORMAL,
|
||||
_In_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) return FALSE;
|
||||
|
||||
DWORD szWritten{ 0 };
|
||||
::WriteFile(
|
||||
|
||||
_In_ hFile,
|
||||
_In_ ucBuffer,
|
||||
_In_ szBuffer,
|
||||
_Out_ &szWritten,
|
||||
_Inout_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
return szWritten == szBuffer;
|
||||
}
|
||||
|
||||
inline std::pair<unsigned char*, SIZE_T> MapDiskPE(const std::string& strPath) {
|
||||
|
||||
auto hFile = ::CreateFileA(
|
||||
|
||||
_In_ strPath.c_str(),
|
||||
_In_ GENERIC_READ,
|
||||
_In_ FILE_SHARE_READ,
|
||||
_In_opt_ nullptr,
|
||||
_In_ OPEN_EXISTING,
|
||||
_In_ FILE_ATTRIBUTE_NORMAL,
|
||||
_In_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE) return { nullptr, 0 };
|
||||
|
||||
LARGE_INTEGER fileSize;
|
||||
if (!::GetFileSizeEx(
|
||||
|
||||
_In_ hFile,
|
||||
_Out_ &fileSize
|
||||
|
||||
) || fileSize.QuadPart == 0) {
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
SIZE_T outSize = static_cast<SIZE_T>(fileSize.QuadPart);
|
||||
|
||||
HANDLE hMapping = ::CreateFileMappingA(
|
||||
|
||||
_In_ hFile,
|
||||
_In_opt_ nullptr,
|
||||
_In_ PAGE_READONLY,
|
||||
_In_ 0,
|
||||
_In_ 0,
|
||||
_In_opt_ nullptr
|
||||
|
||||
);
|
||||
|
||||
if (!hMapping) {
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
auto outData = static_cast<unsigned char*>(::MapViewOfFile(
|
||||
|
||||
_In_ hMapping,
|
||||
_In_ FILE_MAP_READ,
|
||||
_In_ 0,
|
||||
_In_ 0,
|
||||
_In_ 0
|
||||
|
||||
));
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hMapping
|
||||
|
||||
);
|
||||
|
||||
::CloseHandle(
|
||||
|
||||
_In_ hFile
|
||||
|
||||
);
|
||||
|
||||
if (!outData) return { nullptr, 0 };
|
||||
|
||||
return { outData, outSize };
|
||||
}
|
||||
|
||||
};
|
||||
14
RyujinCore/RyujinCore.cc
Normal file
14
RyujinCore/RyujinCore.cc
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "RyujinCore.hh"
|
||||
|
||||
RYUJINCORE_API BOOL __stdcall RunRyujinCore(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) {
|
||||
|
||||
std::unique_ptr<Ryujin> ryujin = std::make_unique<Ryujin>(strInputFilePath, strPdbFilePath, strOutputFilePath);
|
||||
|
||||
ryujin.get()->listRyujinProcedures();
|
||||
|
||||
ryujin.get()->run(config);
|
||||
|
||||
ryujin.reset();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
8
RyujinCore/RyujinCore.hh
Normal file
8
RyujinCore/RyujinCore.hh
Normal file
@@ -0,0 +1,8 @@
|
||||
#ifdef RYUJINCORE_EXPORTS
|
||||
#define RYUJINCORE_API __declspec(dllexport)
|
||||
#else
|
||||
#define RYUJINCORE_API __declspec(dllimport)
|
||||
#endif
|
||||
#include "Ryujin/Ryujin.hh"
|
||||
|
||||
RYUJINCORE_API BOOL __stdcall RunRyujinCore(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig &config);
|
||||
181
RyujinCore/RyujinCore.vcxproj
Normal file
181
RyujinCore/RyujinCore.vcxproj
Normal file
@@ -0,0 +1,181 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<VCProjectVersion>17.0</VCProjectVersion>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{aeff626b-1317-4c8f-94b3-b3d405ae65b2}</ProjectGuid>
|
||||
<RootNamespace>RyujinCore</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<TargetName>RyujinCore</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<TargetName>RyujinCore</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<TargetName>RyujinCore</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<TargetName>RyujinCore</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>_DEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
<PreprocessorDefinitions>NDEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableUAC>false</EnableUAC>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="RyujinCore.hh" />
|
||||
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh" />
|
||||
<ClInclude Include="Ryujin\Models\RyujinInstruction.hh" />
|
||||
<ClInclude Include="Ryujin\Models\RyujinObfuscatorConfig.hh" />
|
||||
<ClInclude Include="Ryujin\Models\RyujinProcedure.hh" />
|
||||
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh" />
|
||||
<ClInclude Include="Ryujin\Ryujin.hh" />
|
||||
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh" />
|
||||
<ClInclude Include="Ryujin\RyujinCore\RyujinObfuscationCore.hh" />
|
||||
<ClInclude Include="Ryujin\Utils\RyujinPESections.hh" />
|
||||
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="dllmain.cc" />
|
||||
<ClCompile Include="RyujinCore.cc" />
|
||||
<ClCompile Include="Ryujin\Ryujin.cc" />
|
||||
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc" />
|
||||
<ClCompile Include="Ryujin\RyujinCore\RyujinObfuscationCore.cc" />
|
||||
<ClCompile Include="Ryujin\Utils\RyujinPESections.cc" />
|
||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
93
RyujinCore/RyujinCore.vcxproj.filters
Normal file
93
RyujinCore/RyujinCore.vcxproj.filters
Normal file
@@ -0,0 +1,93 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<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="Ryujin">
|
||||
<UniqueIdentifier>{75c5a07c-f3a0-4780-a2d6-82b6c759efbb}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ryujin\Models">
|
||||
<UniqueIdentifier>{cf207520-50f1-4f26-9b7d-0a6ad7fd1fb1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ryujin\PDB">
|
||||
<UniqueIdentifier>{81beb1cb-a0b6-4118-8a39-bd558f8f5522}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ryujin\RyujinCore">
|
||||
<UniqueIdentifier>{49f30cd7-8ed7-42f3-b599-9f7fddf5c547}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ryujin\Utils">
|
||||
<UniqueIdentifier>{4284f652-8f94-493b-acb5-178e17622669}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="cpp.hint" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="RyujinCore.hh">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Ryujin.hh">
|
||||
<Filter>Ryujin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh">
|
||||
<Filter>Ryujin\Models</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Models\RyujinInstruction.hh">
|
||||
<Filter>Ryujin\Models</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Models\RyujinObfuscatorConfig.hh">
|
||||
<Filter>Ryujin\Models</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Models\RyujinProcedure.hh">
|
||||
<Filter>Ryujin\Models</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Utils\RyujinPESections.hh">
|
||||
<Filter>Ryujin\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh">
|
||||
<Filter>Ryujin\Utils</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\RyujinCore\RyujinObfuscationCore.hh">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh">
|
||||
<Filter>Ryujin\PDB</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="RyujinCore.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="dllmain.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\Ryujin.cc">
|
||||
<Filter>Ryujin</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\Utils\RyujinPESections.cc">
|
||||
<Filter>Ryujin\Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc">
|
||||
<Filter>Ryujin\Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\RyujinCore\RyujinObfuscationCore.cc">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
2
RyujinCore/cpp.hint
Normal file
2
RyujinCore/cpp.hint
Normal file
@@ -0,0 +1,2 @@
|
||||
#define RYUJINCORE_API __declspec(dllexport)
|
||||
#define RYUJINCORE_API __declspec(dllimport)
|
||||
17
RyujinCore/dllmain.cc
Normal file
17
RyujinCore/dllmain.cc
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <Windows.h>
|
||||
|
||||
BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) {
|
||||
|
||||
switch (ul_reason_for_call) {
|
||||
|
||||
case DLL_PROCESS_ATTACH:
|
||||
case DLL_THREAD_ATTACH:
|
||||
case DLL_THREAD_DETACH:
|
||||
case DLL_PROCESS_DETACH:
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user