moved flag checking interface and updated it to check all flags
main
James 3 years ago
parent 3e73d359b8
commit 9b2a12bd12

@ -5,7 +5,10 @@
#define CODE_FLAG_IS_REL_JMP (1<<1) #define CODE_FLAG_IS_REL_JMP (1<<1)
#define CODE_FLAG_IS_INST (1<<2) #define CODE_FLAG_IS_INST (1<<2)
#define CODE_FLAG_DO_NOT_DIVIDE (1<<3) #define CODE_FLAG_DO_NOT_DIVIDE (1<<3)
#define CODE_FLAG_IS_OBFUSCATED (1<<4) #define CODE_FLAG_GROUP_START (1<<4)
#define CODE_FLAG_IS_RIP_REL (1<<5) //Figure out how to deal with this... #define CODE_FLAG_GROUP_END (1<<5)
#define CODE_FLAG_HAS_ASM_OP (1<<6) //Call all of the pre assembly operations
#define CODE_FLAG_IS_RIP_REL (1<<7) //Figure out how to deal with this...
#endif #endif

@ -157,6 +157,8 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="DataLog.cpp" />
<ClCompile Include="Flags.cpp" />
<ClCompile Include="Jit.cpp" /> <ClCompile Include="Jit.cpp" />
<ClCompile Include="Junk.cpp" /> <ClCompile Include="Junk.cpp" />
<ClCompile Include="NativeCode.cpp" /> <ClCompile Include="NativeCode.cpp" />
@ -175,6 +177,8 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Code.h" /> <ClInclude Include="Code.h" />
<ClInclude Include="DataLog.h" />
<ClInclude Include="Flags.h" />
<ClInclude Include="Jit.h" /> <ClInclude Include="Jit.h" />
<ClInclude Include="Junk.h" /> <ClInclude Include="Junk.h" />
<ClInclude Include="NativeCode.h" /> <ClInclude Include="NativeCode.h" />

@ -47,6 +47,12 @@
<ClInclude Include="RipOrInst.h"> <ClInclude Include="RipOrInst.h">
<Filter>Obfuscator\Jit\RipOrInst</Filter> <Filter>Obfuscator\Jit\RipOrInst</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="DataLog.h">
<Filter>DataLog</Filter>
</ClInclude>
<ClInclude Include="Flags.h">
<Filter>Obfuscator\Flags</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="Main.cpp" /> <ClCompile Include="Main.cpp" />
@ -92,6 +98,12 @@
<ClCompile Include="RipOrInst.cpp"> <ClCompile Include="RipOrInst.cpp">
<Filter>Obfuscator\Jit\RipOrInst</Filter> <Filter>Obfuscator\Jit\RipOrInst</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="DataLog.cpp">
<Filter>DataLog</Filter>
</ClCompile>
<ClCompile Include="Flags.cpp">
<Filter>Obfuscator\Flags</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="Xed"> <Filter Include="Xed">
@ -136,6 +148,12 @@
<Filter Include="Obfuscator\Branching\OpaqueBranching"> <Filter Include="Obfuscator\Branching\OpaqueBranching">
<UniqueIdentifier>{9b60f523-bf84-4740-9ee6-b8f34a317078}</UniqueIdentifier> <UniqueIdentifier>{9b60f523-bf84-4740-9ee6-b8f34a317078}</UniqueIdentifier>
</Filter> </Filter>
<Filter Include="DataLog">
<UniqueIdentifier>{b4404de7-66a7-4dac-b993-58db5b5b2989}</UniqueIdentifier>
</Filter>
<Filter Include="Obfuscator\Flags">
<UniqueIdentifier>{296c0b55-edbb-45ab-b946-ec83e5441678}</UniqueIdentifier>
</Filter>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<MASM Include="Assembly.asm" /> <MASM Include="Assembly.asm" />

@ -0,0 +1 @@
#include "DataLog.h"

@ -0,0 +1,7 @@
#ifndef __DATALOG_H
#define __DATALOG_H
#endif

@ -0,0 +1,47 @@
#include "Flags.h"
PNATIVE_CODE_LINK FlgEmitPushfqInst()
{
UCHAR RawData[] = { 0x9C };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInstruction, Link->RawData, 1);
return Link;
}
PNATIVE_CODE_LINK FlgEmitPopfqInst()
{
UCHAR RawData[] = { 0x9D };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST, RawData, 1);
XedDecode(&Link->XedInstruction, Link->RawData, 1);
return Link;
}
BOOL FlgAreFlagsClobbered(PNATIVE_CODE_LINK Inst, PNATIVE_CODE_LINK Stop)
{
XED_FLAG_SET Ledger;
CONST XED_SIMPLE_FLAG* SimpleFlags = XedDecodedInstGetRflagsInfo(&Inst->XedInstruction);
CONST XED_FLAG_SET* _Ledger1 = XedSimpleFlagGetWrittenFlagSet(SimpleFlags);
CONST XED_FLAG_SET* _Ledger2 = XedSimpleFlagGetUndefinedFlagSet(SimpleFlags);
Ledger.flat = (_Ledger1->flat | _Ledger2->flat);
for (PNATIVE_CODE_LINK T = Inst->Next; T && T != Stop; T = T->Next)
{
if (T->Flags & CODE_FLAG_IS_LABEL)
continue;
CONST XED_SIMPLE_FLAG* InstFlags = XedDecodedInstGetRflagsInfo(&T->XedInstruction);
CONST XED_FLAG_SET* FlagsRead = XedSimpleFlagGetReadFlagSet(InstFlags);
if (FlagsRead->flat & Ledger.flat)
return FALSE;
CONST XED_FLAG_SET* FlagsWritten = XedSimpleFlagGetWrittenFlagSet(InstFlags);
CONST XED_FLAG_SET* FlagsUndefined = XedSimpleFlagGetUndefinedFlagSet(InstFlags);
Ledger.flat &= ~(Ledger.flat & (FlagsWritten->flat | FlagsUndefined->flat));
}
return TRUE;
}

@ -0,0 +1,13 @@
#ifndef __FLAGS_H
#define __FLAGS_H
#include "Windas.h"
#include "XedWrap.h"
#include "NativeCode.h"
PNATIVE_CODE_LINK FlgEmitPushfqInst();
PNATIVE_CODE_LINK FlgEmitPopfqInst();
BOOL FlgAreFlagsClobbered(PNATIVE_CODE_LINK Inst, PNATIVE_CODE_LINK Stop);
#endif

@ -1,27 +1,11 @@
#include "Jit.h" #include "Jit.h"
#include "Flags.h"
#include "RipXorInst.h" #include "RipXorInst.h"
#include "RipAndInst.h" #include "RipAndInst.h"
#include "RipOrInst.h" #include "RipOrInst.h"
#include "RipMovInst.h" #include "RipMovInst.h"
BOOL JitEmitPushfqInst(PNATIVE_CODE_BLOCK Block)
{
UCHAR RawData[] = { 0x9C };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, 1);
XedDecode(&Link->XedInstruction, Link->RawData, 1);
NcAppendToBlock(Block, Link);
return TRUE;
}
BOOL JitEmitPopfqInst(PNATIVE_CODE_BLOCK Block)
{
UCHAR RawData[] = { 0x9D };
PNATIVE_CODE_LINK Link = new NATIVE_CODE_LINK(CODE_FLAG_IS_INST | CODE_FLAG_DO_NOT_DIVIDE, RawData, 1);
XedDecode(&Link->XedInstruction, Link->RawData, 1);
NcAppendToBlock(Block, Link);
return TRUE;
}
BOOL JitCheckFlagCollisions(CONST XED_FLAG_SET* FlagsRead, XED_FLAG_SET Ledger) BOOL JitCheckFlagCollisions(CONST XED_FLAG_SET* FlagsRead, XED_FLAG_SET Ledger)
{ {
@ -302,12 +286,8 @@ PNATIVE_CODE_BLOCK JitEmitPreRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_D
if (!Block) if (!Block)
return NULL; return NULL;
if (SaveFlags && !JitEmitPushfqInst(Block)) if (SaveFlags)
{ NcAppendToBlock(Block, FlgEmitPushfqInst());
NcDeleteBlock(Block);
delete Block;
return NULL;
}
ULONG Count = FourByte; ULONG Count = FourByte;
while (Count) while (Count)
@ -356,12 +336,8 @@ PNATIVE_CODE_BLOCK JitEmitPreRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_D
} }
} }
if (SaveFlags && !JitEmitPopfqInst(Block)) if (SaveFlags)
{ NcAppendToBlock(Block, FlgEmitPopfqInst());
NcDeleteBlock(Block);
delete Block;
return NULL;
}
return Block; return Block;
} }
@ -376,12 +352,8 @@ PNATIVE_CODE_BLOCK JitEmitPostRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_
if (!Block) if (!Block)
return NULL; return NULL;
if (SaveFlags && !JitEmitPushfqInst(Block)) if (SaveFlags)
{ NcAppendToBlock(Block, FlgEmitPushfqInst());
NcDeleteBlock(Block);
delete Block;
return NULL;
}
ULONG Count = FourByte; ULONG Count = FourByte;
while (Count) while (Count)
@ -436,12 +408,8 @@ PNATIVE_CODE_BLOCK JitEmitPostRipBitwiseOp(PNATIVE_CODE_LINK Link, PJIT_BITWISE_
} }
} }
if (SaveFlags && !JitEmitPopfqInst(Block)) if (SaveFlags)
{ NcAppendToBlock(Block, FlgEmitPopfqInst());
NcDeleteBlock(Block);
delete Block;
return NULL;
}
return Block; return Block;
} }

@ -22,10 +22,6 @@ typedef struct _JIT_BITWISE_DATA
ULONG Data[5]; ULONG Data[5];
}JIT_BITWISE_DATA, *PJIT_BITWISE_DATA; }JIT_BITWISE_DATA, *PJIT_BITWISE_DATA;
BOOL JitEmitPushfqInst(PNATIVE_CODE_BLOCK Block);
BOOL JitEmitPopfqInst(PNATIVE_CODE_BLOCK Block);
BOOL JitCheckFlagCollisions(CONST XED_FLAG_SET* FlagsRead, XED_FLAG_SET Ledger); BOOL JitCheckFlagCollisions(CONST XED_FLAG_SET* FlagsRead, XED_FLAG_SET Ledger);
VOID JitUpdateConFlagsLedger(CONST XED_FLAG_SET* FlagsWritten, XED_FLAG_SET* Ledger); VOID JitUpdateConFlagsLedger(CONST XED_FLAG_SET* FlagsWritten, XED_FLAG_SET* Ledger);

@ -28,8 +28,8 @@ VOID PutToFile(PVOID Buffer, ULONG BufferSize)
{ {
std::ofstream fout; std::ofstream fout;
// //
fout.open("C:\\Users\\James\\Desktop\\fantern\\Test.m", std::ios::binary | std::ios::out); //fout.open("C:\\Users\\James\\Desktop\\fantern\\Test.m", std::ios::binary | std::ios::out);
//fout.open("C:\\Users\\Iizerd\\Desktop\\Leeg Hake\\Test.m", std::ios::binary | std::ios::out); fout.open("C:\\Users\\Iizerd\\Desktop\\Leeg Hake\\Test.m", std::ios::binary | std::ios::out);
fout.write((PCHAR)Buffer, BufferSize); fout.write((PCHAR)Buffer, BufferSize);
fout.close(); fout.close();
} }
@ -93,35 +93,30 @@ int main()
XedTablesInit(); XedTablesInit();
srand(time(NULL)); srand(time(NULL));
system("pause"); //system("pause");
NATIVE_CODE_BLOCK RetNumBlock; NATIVE_CODE_BLOCK RetNumBlock;
NcDisassemble(&RetNumBlock, RetNumCode, sizeof(RetNumCode)); NcDisassemble(&RetNumBlock, RetNumCode, sizeof(RetNumCode));
OBFUSCATOR Obf; OPBR_SETS Obf;
Obf.Flags = 0; Obf.Flags = 0;
Obf.MinSizeForOpaqueBranch = 1; Obf.ParentBlock = &RetNumBlock;
Obf.InstructionMutateChance = 100; Obf.Divisor = 1.3F;
Obf.OpaqueBranchChance = 100; Obf.MaxDepth = 10;
Obf.MinDepthForRandomOpaqueBranch = 0; Obf.MinBranchSize = 1;
Obf.GlobalBlock = &RetNumBlock; Obf.ChanceForBranch = 50;
Obf.BlockDivisionFactor = 2; Obf.MinDepthForBranch = 0;
Obf.MaxDepth = 800000; ObfGenerateOpaqueBranches(&Obf, &RetNumBlock);
ObfObfuscate1(&Obf, &RetNumBlock); INSTMUT_SETS Obf2;
Obf.MinSizeForOpaqueBranch = 5; Obf2.MutateChance = 100;
Obf.InstructionMutateChance = 0; ObfMutateInstructions(&Obf2, &RetNumBlock);
Obf.OpaqueBranchChance = 100;
ObfObfuscate1(&Obf, &RetNumBlock, 0); Obf.MinBranchSize = 27;
Obf.MinSizeForOpaqueBranch = 50; ObfGenerateOpaqueBranches(&Obf, &RetNumBlock);
ObfObfuscate1(&Obf, &RetNumBlock, 0); /*Obf.MinBranchSize = 27;
ObfGenerateOpaqueBranches(&Obf, &RetNumBlock);
Obf.MinBranchSize = 27;
printf("Finished second pas.\n"); ObfGenerateOpaqueBranches(&Obf, &RetNumBlock);*/
//Obf.MinSizeForOpaqueBranch = 200; //NcDebugPrint(&RetNumBlock);
//ObfObfuscate1(&Obf, &RetNumBlock);
//Obf.MinSizeForOpaqueBranch = 30;
//ObfObfuscate(&Obf, &RetNumBlock);
NcDebugPrint(&RetNumBlock);
ULONG AsmSize; ULONG AsmSize;
PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize); PVOID Asm = NcAssemble(&RetNumBlock, &AsmSize);

@ -10,6 +10,7 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK()
Label = 0UL; Label = 0UL;
RawData = NULL; RawData = NULL;
RawDataSize = 0UL; RawDataSize = 0UL;
AsmOperations.clear();
} }
_NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B) _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B)
@ -37,7 +38,13 @@ _NATIVE_CODE_LINK::_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode)
_NATIVE_CODE_LINK::~_NATIVE_CODE_LINK() _NATIVE_CODE_LINK::~_NATIVE_CODE_LINK()
{ {
if (RawData) if (RawData)
delete RawData; delete[] RawData;
for (STDPAIR<FN_INST_ASM_OP, PVOID> CONST& Op : AsmOperations)
{
if (Op.second)
delete[] Op.second;
}
} }
_NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK() _NATIVE_CODE_BLOCK::_NATIVE_CODE_BLOCK()
@ -128,7 +135,7 @@ ULONG NcCountInstructions(PNATIVE_CODE_BLOCK Block, BOOL CountCombinedAsOne)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
if (CountCombinedAsOne && T->Next && (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) && !(T->Next->Flags & CODE_FLAG_DO_NOT_DIVIDE)) if (CountCombinedAsOne && (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) && !(T->Flags & CODE_FLAG_GROUP_END))
continue; continue;
++InstructionCount; ++InstructionCount;
} }
@ -325,6 +332,13 @@ PNATIVE_CODE_LINK NcDeepCopyLink(PNATIVE_CODE_LINK Link)
delete NewLink; delete NewLink;
return NULL; return NULL;
} }
if (Link->Flags & CODE_FLAG_HAS_ASM_OP)
{
for (STDPAIR<FN_INST_ASM_OP, PVOID> CONST& Op : Link->AsmOperations)
{
NewLink->AsmOperations.emplace_back(Op.first, Op.second);
}
}
return NewLink; return NewLink;
} }
} }
@ -527,14 +541,23 @@ PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL)
continue; continue;
RtlCopyMemory(BufferOffset, T->RawData, T->RawDataSize); RtlCopyMemory(BufferOffset, T->RawData, T->RawDataSize);
if (T->Flags & CODE_FLAG_HAS_ASM_OP)
{
for (STDPAIR<FN_INST_ASM_OP, PVOID> CONST& Op : T->AsmOperations)
Op.first(T, BufferOffset, Op.second);
}
BufferOffset += T->RawDataSize; BufferOffset += T->RawDataSize;
} }
return Buffer; return Buffer;
} }
PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize, BOOL ChooseRandomDuplicateLabel)
{
return NULL;
}
VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block) VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block)
{ {
if (!Block->Start || !Block->End) if (!Block->Start || !Block->End)

@ -6,17 +6,21 @@
#include "Code.h" #include "Code.h"
struct _NATIVE_CODE_BLOCK; struct _NATIVE_CODE_BLOCK;
struct _NATIVE_CODE_LINK;
typedef BOOL(*FN_INST_ASM_OP)(_NATIVE_CODE_LINK* Link, PUCHAR ToMutate, PVOID Context);
typedef struct _NATIVE_CODE_LINK typedef struct _NATIVE_CODE_LINK
{ {
_NATIVE_CODE_LINK* Next; _NATIVE_CODE_LINK* Next;
_NATIVE_CODE_LINK* Prev; _NATIVE_CODE_LINK* Prev;
_NATIVE_CODE_BLOCK* Block; _NATIVE_CODE_BLOCK* Block;
ULONG Flags; ULONG Flags;
ULONG Label; ULONG Label;
PUCHAR RawData; PUCHAR RawData;
ULONG RawDataSize; ULONG RawDataSize;
XED_DECODED_INST XedInstruction; XED_DECODED_INST XedInstruction;
STDVECTOR<STDPAIR<FN_INST_ASM_OP, PVOID>> AsmOperations;
_NATIVE_CODE_LINK(); _NATIVE_CODE_LINK();
_NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B); _NATIVE_CODE_LINK(ULONG LabelId, _NATIVE_CODE_BLOCK* B);
_NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode = FALSE); _NATIVE_CODE_LINK(ULONG F, PVOID Rd, ULONG Rds, BOOL Decode = FALSE);
@ -73,6 +77,8 @@ BOOL NcDisassemble(PNATIVE_CODE_BLOCK Block, PVOID Buffer, ULONG BufferSize);
PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize); PVOID NcAssemble(PNATIVE_CODE_BLOCK Block, PULONG OutSize);
PVOID NcAssembleEx(PNATIVE_CODE_BLOCK Block, PULONG OutSize, BOOL ChooseRandomDuplicateLabel);
VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block); VOID NcDeleteBlock(PNATIVE_CODE_BLOCK Block);
VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block); VOID NcDebugPrint(PNATIVE_CODE_BLOCK Block);

@ -1,91 +1,41 @@
#include "Obfuscator.h" #include "Obfuscator.h"
BOOL ObfiRandomizeInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PVOID Context)
{
for (ULONG i = 0; i < Link->RawDataSize; i++)
ToMutate[i] = (rand() % 255);
return TRUE;
}
VOID ObfGenerateOpaqueBranches(POPBR_SETS Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth)
VOID ObfObfuscate1(POBFUSCATOR Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth)
{ {
if (Depth > Obf->MaxDepth) if (Depth > Obf->MaxDepth)
return; return;
ULONG InstructionCount = NcCountInstructions(Block, FALSE); ULONG InstructionCount = NcCountInstructions(Block, TRUE);
printf("Depth: %u, InstCount: %u\n", Depth, InstructionCount); if (InstructionCount > Obf->MinBranchSize)
if (InstructionCount <= Obf->MinSizeForOpaqueBranch)
{ {
for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) ULONG TargetCount = (ULONG)((FLOAT)InstructionCount / Obf->Divisor);
{
if ((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) || (T->Flags & CODE_FLAG_IS_REL_JMP))
{
T = T->Next;
continue;
}
PNATIVE_CODE_LINK RealNext = T->Next;
if ((rand() % 100) <= Obf->InstructionMutateChance)
{
PNATIVE_CODE_BLOCK PreOp = JitEmitPreRipMov(T);
PNATIVE_CODE_BLOCK PostOp = JitEmitPostRipMov(T);
if (T->Prev)
T->Prev->Next = PreOp->Start;
PreOp->End->Next = T;
NcInsertBlockBefore(T, PreOp, FALSE);
NcInsertBlockAfter(T, PostOp, FALSE);
if (Block->Start == T)
Block->Start = PreOp->Start;
if (Block->End == T)
Block->End = PostOp->End;
delete PreOp;
delete PostOp;
//for (ULONG i = 0; i < T->RawDataSize; i++)
// T->RawData[i] = (UCHAR)(rand() % 255);
T->Flags |= CODE_FLAG_DO_NOT_DIVIDE;
}
T = RealNext;
}
}
else
{
//ULONG TargetCount = max(Obf->MinSizeForOpaqueBranch, InstructionCount / ((Obf->Flags & OBF_ATTRIBUTE_RANDOMIZE_DIVISOR) ? (rand() % Obf->BlockDivisionFactor) : Obf->BlockDivisionFactor)); // max(Obf->MinBlockSize, InstructionCount / Obf->BlockDivisionFactor);
ULONG TargetCount = (InstructionCount / ((Obf->Flags & OBF_ATTRIBUTE_RANDOMIZE_DIVISOR) ? (rand() % Obf->BlockDivisionFactor) : Obf->BlockDivisionFactor)); // max(Obf->MinBlockSize, InstructionCount / Obf->BlockDivisionFactor);
ULONG CurrentCount = 0; ULONG CurrentCount = 0;
PNATIVE_CODE_LINK NewBlockStart = Block->Start; PNATIVE_CODE_LINK NewBlockStart = Block->Start;
for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;) for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;)
{ {
if (T->Flags & CODE_FLAG_IS_LABEL) if (T->Flags & CODE_FLAG_IS_LABEL || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE && !(T->Flags & CODE_FLAG_GROUP_END)))
{ {
T = T->Next; T = T->Next;
continue; continue;
} }
++CurrentCount; if (++CurrentCount >= TargetCount)
if (T->Flags & CODE_FLAG_DO_NOT_DIVIDE)
{ {
T = T->Next; if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize)
continue;
}
if (CurrentCount >= TargetCount)
{
if (Depth >= Obf->MinDepthForRandomOpaqueBranch && (rand() % 100) <= Obf->OpaqueBranchChance && CurrentCount <= Obf->MinSizeForOpaqueBranch)
{ {
NATIVE_CODE_BLOCK NotTaken, Taken; NATIVE_CODE_BLOCK NotTaken, Taken;
ObfCreateOpaqueBranches(NewBlockStart, T, &NotTaken, &Taken); ObfCreateOpaqueBranches(NewBlockStart, T, &NotTaken, &Taken);
ObfObfuscate1(Obf, &NotTaken, Depth + 1); ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1);
ObfObfuscate1(Obf, &Taken, Depth + 1); ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1);
ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->GlobalBlock), NcGenUnusedLabelId(Obf->GlobalBlock)); ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock));
ObfInsertOpaqueBranchBlock(NewBlockStart, T, &NotTaken); ObfInsertOpaqueBranchBlock(NewBlockStart, T, &NotTaken);
T = NotTaken.End; T = NotTaken.End;
} }
@ -94,7 +44,7 @@ VOID ObfObfuscate1(POBFUSCATOR Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth)
NATIVE_CODE_BLOCK TempBlock; NATIVE_CODE_BLOCK TempBlock;
if (NcDeepCopyPartialBlock(NewBlockStart, T, &TempBlock)) if (NcDeepCopyPartialBlock(NewBlockStart, T, &TempBlock))
{ {
ObfObfuscate1(Obf, &TempBlock, Depth + 1); ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1);
ObfInsertOpaqueBranchBlock(NewBlockStart, T, &TempBlock); ObfInsertOpaqueBranchBlock(NewBlockStart, T, &TempBlock);
} }
T = TempBlock.End; T = TempBlock.End;
@ -104,15 +54,15 @@ VOID ObfObfuscate1(POBFUSCATOR Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth)
} }
T = T->Next; T = T->Next;
} }
/*if (NewBlockStart && CurrentCount >= Obf->MinSizeForOpaqueBranch) if (NewBlockStart) //Deal with remaining instructions in the block
{ {
if (Depth >= Obf->MinDepthForRandomOpaqueBranch && (rand() % 100) <= Obf->OpaqueBranchChance && CurrentCount <= Obf->MinSizeForOpaqueBranch) if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize)
{ {
NATIVE_CODE_BLOCK NotTaken, Taken; NATIVE_CODE_BLOCK NotTaken, Taken;
ObfCreateOpaqueBranches(NewBlockStart, Block->End, &NotTaken, &Taken); ObfCreateOpaqueBranches(NewBlockStart, Block->End, &NotTaken, &Taken);
ObfObfuscate1(Obf, &NotTaken, Depth + 1); ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1);
ObfObfuscate1(Obf, &Taken, Depth + 1); ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1);
ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->GlobalBlock), NcGenUnusedLabelId(Obf->GlobalBlock)); ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock));
ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &NotTaken); ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &NotTaken);
} }
else else
@ -120,16 +70,53 @@ VOID ObfObfuscate1(POBFUSCATOR Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth)
NATIVE_CODE_BLOCK TempBlock; NATIVE_CODE_BLOCK TempBlock;
if (NcDeepCopyPartialBlock(NewBlockStart, Block->End, &TempBlock)) if (NcDeepCopyPartialBlock(NewBlockStart, Block->End, &TempBlock))
{ {
ObfObfuscate1(Obf, &TempBlock, Depth + 1); ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1);
ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &TempBlock); ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &TempBlock);
} }
} }
}*/ }
} }
}
VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block)
{
for (PNATIVE_CODE_LINK T = Block->Start; T && T != Block->End->Next;)
{
if ((T->Flags & CODE_FLAG_IS_LABEL) || (T->Flags & CODE_FLAG_DO_NOT_DIVIDE) || (T->Flags & CODE_FLAG_IS_REL_JMP))
{
T = T->Next;
continue;
}
PNATIVE_CODE_LINK RealNext = T->Next;
if ((rand() % 100) <= Obf->MutateChance)
{
PNATIVE_CODE_BLOCK PreOp = JitEmitPreRipMov(T);
PNATIVE_CODE_BLOCK PostOp = JitEmitPostRipMov(T);
PreOp->Start->Flags |= CODE_FLAG_GROUP_START;
PostOp->End->Flags |= CODE_FLAG_GROUP_END;
T->Flags |= CODE_FLAG_DO_NOT_DIVIDE;
T->Flags |= CODE_FLAG_HAS_ASM_OP;
T->AsmOperations.emplace_back((FN_INST_ASM_OP)ObfiRandomizeInstruction, (PVOID)NULL);
NcInsertBlockBefore(T, PreOp, FALSE);
NcInsertBlockAfter(T, PostOp, FALSE);
if (T == Block->End)
Block->End = PostOp->End;
if (T == Block->Start)
Block->Start = PreOp->Start;
if (Block->Start == T)
Block->Start = PreOp->Start;
if (Block->End == T)
Block->End = PostOp->End;
delete PreOp;
delete PostOp;
}
T = RealNext;
}
} }

@ -12,23 +12,26 @@
#define OBF_ATTRIBUTE_OPAQUE_BRANCHES (1<<1) #define OBF_ATTRIBUTE_OPAQUE_BRANCHES (1<<1)
#define OBF_ATTRIBUTE_RANDOMIZE_DIVISOR (1<<2) #define OBF_ATTRIBUTE_RANDOMIZE_DIVISOR (1<<2)
typedef struct _OBFUSCATOR typedef struct _OPBR_SETS
{ {
ULONG MinDepthForRandomOpaqueBranch;
ULONG MinSizeForOpaqueBranch;
UCHAR OpaqueBranchChance;
UCHAR InstructionMutateChance;
UCHAR BlockDivisionFactor;
ULONG Flags;
PNATIVE_CODE_BLOCK GlobalBlock;
ULONG MaxDepth; ULONG MaxDepth;
}OBFUSCATOR, *POBFUSCATOR; ULONG MinBranchSize;
FLOAT Divisor;
ULONG Flags;
ULONG MinDepthForBranch;
ULONG ChanceForBranch;
PNATIVE_CODE_BLOCK ParentBlock;
}OPBR_SETS, *POPBR_SETS;
BOOL ObfJitInst(); typedef struct _INSTMUT_SETS
{
ULONG MutateStart;
ULONG MutateChance;
}INSTMUT_SETS, *PINSTMUT_SETS;
//Recursive obfuscation routine using opaque branches and jit //Recursive obfuscation routine using opaque branches and jit
VOID ObfObfuscate1(POBFUSCATOR Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth = 0); VOID ObfGenerateOpaqueBranches(POPBR_SETS Obf, PNATIVE_CODE_BLOCK Block, ULONG Depth = 0);
VOID ObfMutateInstructions(PINSTMUT_SETS Obf, PNATIVE_CODE_BLOCK Block);
#endif #endif

@ -10,6 +10,7 @@
#define INLINE inline #define INLINE inline
#define STDSTRING std::string #define STDSTRING std::string
#define STDVECTOR std::vector #define STDVECTOR std::vector
#define STDPAIR std::pair
#define StdFind std::find #define StdFind std::find
/* /*

@ -1,4 +1,4 @@
Microsoft (R) Macro Assembler (x64) Version 14.29.30038.1 10/23/21 14:21:58 Microsoft (R) Macro Assembler (x64) Version 14.27.29111.0 10/26/21 20:35:01
Assembly.asm Page 1 - 1 Assembly.asm Page 1 - 1
@ -23,7 +23,7 @@ Assembly.asm Page 1 - 1
0000001E NextFunction ENDP 0000001E NextFunction ENDP
END END
Microsoft (R) Macro Assembler (x64) Version 14.29.30038.1 10/23/21 14:21:58 Microsoft (R) Macro Assembler (x64) Version 14.27.29111.0 10/26/21 20:35:01
Assembly.asm Symbols 2 - 1 Assembly.asm Symbols 2 - 1

@ -1,11 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project> <Project>
<ProjectOutputs> <ProjectOutputs>C:\$Fanta\code-virtualizer\x64\Debug\CodeVirtualizer.exe</ProjectOutputs>
<ProjectOutput> <ContentFiles></ContentFiles>
<FullPath>C:\@\Work\code-virtualizer\x64\Debug\CodeVirtualizer.exe</FullPath> <SatelliteDlls></SatelliteDlls>
</ProjectOutput> <NonRecipeFileRefs></NonRecipeFileRefs>
</ProjectOutputs>
<ContentFiles />
<SatelliteDlls />
<NonRecipeFileRefs />
</Project> </Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save