// Switch deobfuscation when block uses ldloc N to load switch constant // blk1: // ldc.i4 X // stloc N // br swblk / bcc swblk // swblk: // ldloc N // switch (......) bool deobfuscateLdloc(IList <Block> switchTargets, Block switchFallThrough, Block block, Local switchVariable) { bool changed = false; foreach (var source in new List <Block>(block.Sources)) { if (isBranchBlock(source)) { instructionEmulator.init(blocks); instructionEmulator.emulate(source.Instructions); var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.getLocal(switchVariable)); if (target == null) { continue; } source.replaceLastNonBranchWithBranch(0, target); changed = true; } else if (isBccBlock(source)) { instructionEmulator.init(blocks); instructionEmulator.emulate(source.Instructions); var target = getSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.getLocal(switchVariable)); if (target == null) { continue; } if (source.Targets[0] == block) { source.setNewTarget(0, target); changed = true; } if (source.FallThrough == block) { source.setNewFallThrough(target); changed = true; } } } return(changed); }
public bool deobfuscate() { bool changed = false; foreach (var block in allBlocks) { instructionEmulator.init(blocks); var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; switch (instr.OpCode.Code) { case Code.Ldarg: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarg_S: changed |= fixLoadInstruction(block, i, instructionEmulator.getArg(DotNetUtils.getParameter(args, instr.Instruction))); break; case Code.Ldloc: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldloc_S: changed |= fixLoadInstruction(block, i, instructionEmulator.getLocal(DotNetUtils.getLocalVar(blocks.Locals, instr.Instruction))); break; case Code.Ldarga: case Code.Ldarga_S: instructionEmulator.makeArgUnknown((ParameterDefinition)instr.Operand); break; case Code.Ldloca: case Code.Ldloca_S: instructionEmulator.makeLocalUnknown((VariableDefinition)instr.Operand); break; } try { instructionEmulator.emulate(instr.Instruction); } catch (System.NullReferenceException) { // Here if eg. invalid metadata token in a call instruction (operand is null) break; } } } return(changed); }
protected override bool deobfuscate(Block block) { bool changed = false; instructionEmulator.init(blocks); var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; switch (instr.OpCode.Code) { case Code.Ldarg: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarg_S: changed |= fixLoadInstruction(block, i, instructionEmulator.getArg(instr.Instruction.GetParameter(args))); break; case Code.Ldloc: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldloc_S: changed |= fixLoadInstruction(block, i, instructionEmulator.getLocal(instr.Instruction.GetLocal(blocks.Locals))); break; case Code.Ldarga: case Code.Ldarga_S: instructionEmulator.makeArgUnknown((Parameter)instr.Operand); break; case Code.Ldloca: case Code.Ldloca_S: instructionEmulator.makeLocalUnknown((Local)instr.Operand); break; } try { instructionEmulator.emulate(instr.Instruction); } catch (NullReferenceException) { // Here if eg. invalid metadata token in a call instruction (operand is null) break; } } return(changed); }
// Switch deobfuscation when block uses ldloc N to load switch constant // blk1: // ldc.i4 X // stloc N // br swblk // swblk: // ldloc N // switch (......) bool deobfuscateLdloc(IList <Block> switchTargets, Block switchFallThrough, Block block, VariableDefinition switchVariable) { bool changed = false; foreach (var source in new List <Block>(block.Sources)) { if (!isBranchBlock(source)) { continue; } instructionEmulator.init(blocks); instructionEmulator.emulate(source.Instructions); var target = getSwitchTarget(switchTargets, switchFallThrough, source, instructionEmulator.getLocal(switchVariable)); if (target == null) { continue; } source.replaceLastNonBranchWithBranch(0, target); changed = true; } return(changed); }