#include "Obfuscator.h" BOOL ObfiRandomizeInstruction(PNATIVE_CODE_LINK Link, PUCHAR ToMutate, PVOID Context) { for (ULONG i = 0; i < Link->RawDataSize; i++) ToMutate[i] = RndGetRandomInt(0, 255); return TRUE; } VOID ObfGenOpaqueBranch(PNATIVE_CODE_BLOCK Block, FLOAT BranchSizePercentage) { ULONG BlockSize = NcCountInstructions(Block, TRUE); ULONG BranchSize = (FLOAT)BlockSize * BranchSizePercentage; ULONG BranchStartPos = RndGetRandomInt(0, BlockSize - 1 - BranchSize); PNATIVE_CODE_LINK BranchStart = BranchStartPos ? NULL : 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 (BranchStartPos) { --BranchStartPos; if (BranchStartPos == 0) BranchStart = T; T = T->Next; continue; } if (BranchSize) { --BranchSize; T = T->Next; continue; } NATIVE_CODE_BLOCK NotTaken, Taken; ObfCreateOpaqueBranches(BranchStart, T, &NotTaken, &Taken); ObfCombineOpaqueBranches(&NotTaken, &Taken, NcGenUnusedLabelId(Block), NcGenUnusedLabelId(Block)); NcInsertBlockStartToEnd(BranchStart, T, &NotTaken); return; } } ULONG ObfMutateInstructions(PNATIVE_CODE_BLOCK Block, ULONG MutateChance, BOOL MutateFirst, BOOL MutateOnlyFirst) { ULONG MutatedInstructions = 0; 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 (RndGetRandomInt(0, 100) <= MutateChance || MutateFirst) { MutateFirst = FALSE; 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; MutatedInstructions++; if (MutateOnlyFirst) return MutatedInstructions; } T = RealNext; } return MutatedInstructions; }