You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
122 lines
3.7 KiB
122 lines
3.7 KiB
#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)
|
|
{
|
|
if (Depth > Obf->MaxDepth)
|
|
return;
|
|
|
|
ULONG InstructionCount = NcCountInstructions(Block, TRUE);
|
|
if (InstructionCount > Obf->MinBranchSize)
|
|
{
|
|
ULONG TargetCount = (ULONG)((FLOAT)InstructionCount / Obf->Divisor);
|
|
ULONG CurrentCount = 0;
|
|
PNATIVE_CODE_LINK NewBlockStart = Block->Start;
|
|
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_GROUP_END)))
|
|
{
|
|
T = T->Next;
|
|
continue;
|
|
}
|
|
|
|
if (++CurrentCount >= TargetCount)
|
|
{
|
|
if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize)
|
|
{
|
|
NATIVE_CODE_BLOCK NotTaken, Taken;
|
|
ObfCreateOpaqueBranches(NewBlockStart, T, &NotTaken, &Taken);
|
|
ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1);
|
|
ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1);
|
|
ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock));
|
|
ObfInsertOpaqueBranchBlock(NewBlockStart, T, &NotTaken);
|
|
T = NotTaken.End;
|
|
}
|
|
else
|
|
{
|
|
NATIVE_CODE_BLOCK TempBlock;
|
|
if (NcDeepCopyPartialBlock(NewBlockStart, T, &TempBlock))
|
|
{
|
|
ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1);
|
|
ObfInsertOpaqueBranchBlock(NewBlockStart, T, &TempBlock);
|
|
}
|
|
T = TempBlock.End;
|
|
}
|
|
NewBlockStart = T->Next;
|
|
CurrentCount = 0;
|
|
}
|
|
T = T->Next;
|
|
}
|
|
if (NewBlockStart) //Deal with remaining instructions in the block
|
|
{
|
|
if (Depth >= Obf->MinDepthForBranch && (rand() % 100) <= Obf->ChanceForBranch && CurrentCount >= Obf->MinBranchSize)
|
|
{
|
|
NATIVE_CODE_BLOCK NotTaken, Taken;
|
|
ObfCreateOpaqueBranches(NewBlockStart, Block->End, &NotTaken, &Taken);
|
|
ObfGenerateOpaqueBranches(Obf, &NotTaken, Depth + 1);
|
|
ObfGenerateOpaqueBranches(Obf, &Taken, Depth + 1);
|
|
ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Obf->ParentBlock), NcGenUnusedLabelId(Obf->ParentBlock));
|
|
ObfInsertOpaqueBranchBlock(NewBlockStart, Block->End, &NotTaken);
|
|
}
|
|
else
|
|
{
|
|
NATIVE_CODE_BLOCK TempBlock;
|
|
if (NcDeepCopyPartialBlock(NewBlockStart, Block->End, &TempBlock))
|
|
{
|
|
ObfGenerateOpaqueBranches(Obf, &TempBlock, Depth + 1);
|
|
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;
|
|
}
|
|
} |