feat: IatObfuscation option, Section Name Randomizing, New Section Logic
- Adding a new option on obfuscator for IAT obfuscation support. - Adding a new logic to randomize section names. - Adding the initial logic to add a new section in the PE file. and writing some ideas and some things to be able to continue the logic in a correct way.
This commit is contained in:
@@ -2,8 +2,9 @@
|
||||
class RyujinObfuscatorConfig {
|
||||
|
||||
public:
|
||||
bool m_isRandomSection; // Randomize the name of the new section with the processed code -> Ryujin standard
|
||||
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)
|
||||
std::vector<std::string> m_strProceduresToObfuscate; // Names of the procedures to obfuscate
|
||||
|
||||
@@ -97,7 +97,12 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
||||
|
||||
if (it == config.m_strProceduresToObfuscate.end()) continue;
|
||||
|
||||
std::printf("[WORKING ON]: %s\n", proc.name.c_str());
|
||||
std::printf(
|
||||
|
||||
"[WORKING ON]: %s\n",
|
||||
proc.name.c_str()
|
||||
|
||||
);
|
||||
|
||||
// Is a valid procedure ?
|
||||
if (proc.size == 0) {
|
||||
@@ -125,11 +130,30 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
||||
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 ?
|
||||
if (config.m_isVirtualized) todoAction();
|
||||
if (config.m_isIatObfuscation) todoAction();
|
||||
if (config.m_isJunkCode) todoAction();
|
||||
|
||||
//TODO: Custom passes support
|
||||
|
||||
//Clean up opcodes
|
||||
delete[] ucOpcodes;
|
||||
|
||||
}
|
||||
|
||||
//More obfuscation
|
||||
if (config.m_isIgnoreOriginalCodeRemove) todoAction();
|
||||
|
||||
//Add section
|
||||
char chSectionName[8]{ '.', 'R', 'y', 'u', 'j', 'i', 'n', '\0' };
|
||||
if (config.m_isRandomSection) RyujinUtils::randomizeSectionName(chSectionName);
|
||||
RyujinUtils::AddNewSection(m_mappedPE, m_szFile, chSectionName);
|
||||
|
||||
//Fix relocations
|
||||
|
||||
//Save output file
|
||||
|
||||
}
|
||||
|
||||
void Ryujin::listRyujinProcedures() {
|
||||
|
||||
@@ -20,6 +20,8 @@ private:
|
||||
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);
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
#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) {
|
||||
@@ -121,5 +123,83 @@ namespace RyujinUtils {
|
||||
return std::make_pair(TRUE, szFile.QuadPart);
|
||||
}
|
||||
|
||||
inline BOOL AddNewSection(std::shared_ptr<unsigned char>& mappedPE, uintptr_t szFile, char chSectionName[8]) {
|
||||
|
||||
auto ucModifiedPeMap = new unsigned char[szFile] { 0 };
|
||||
std::memcpy(
|
||||
|
||||
ucModifiedPeMap,
|
||||
mappedPE.get(),
|
||||
szFile
|
||||
|
||||
);
|
||||
|
||||
auto dosHeader = reinterpret_cast<PIMAGE_DOS_HEADER>(ucModifiedPeMap);
|
||||
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
|
||||
|
||||
delete[] ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto ntHeaders = reinterpret_cast<PIMAGE_NT_HEADERS>(ucModifiedPeMap + dosHeader->e_lfanew);
|
||||
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
|
||||
|
||||
delete[] ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
auto sectionTableSize = ntHeaders->FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER);
|
||||
if (dosHeader->e_lfanew + sizeof(IMAGE_NT_HEADERS) + sectionTableSize > ntHeaders->OptionalHeader.SizeOfHeaders) {
|
||||
|
||||
//No space to insert a new section on this PE FILE :(
|
||||
|
||||
delete[] ucModifiedPeMap;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//Adding the new section
|
||||
IMAGE_SECTION_HEADER newSection{ 0 };
|
||||
std::memcpy(
|
||||
|
||||
newSection.Name,
|
||||
chSectionName,
|
||||
sizeof(chSectionName)
|
||||
|
||||
);
|
||||
|
||||
auto imgLastSection = IMAGE_FIRST_SECTION(ntHeaders) + (ntHeaders->FileHeader.NumberOfSections - 1);
|
||||
|
||||
newSection.VirtualAddress = ALIGN_UP(
|
||||
imgLastSection->VirtualAddress + imgLastSection->Misc.VirtualSize,
|
||||
ntHeaders->OptionalHeader.SectionAlignment
|
||||
);
|
||||
|
||||
newSection.PointerToRawData = ALIGN_UP(
|
||||
imgLastSection->PointerToRawData + imgLastSection->SizeOfRawData,
|
||||
ntHeaders->OptionalHeader.FileAlignment
|
||||
);
|
||||
|
||||
newSection.Characteristics = IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ;
|
||||
|
||||
//Return the following in order to put data and calculate relocs:
|
||||
//newSection.VirtualAddress
|
||||
//newSection.Misc.VirtualSize = size of new code;
|
||||
//newSection.SizeOfRawData = ALIGN_UP(size of new code, ntHeaders->OptionalHeader.FileAlignment);
|
||||
//Maybe is better wrap this things in a full new class ??
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user