protected override bool deobfuscate(Block block) { this.block = block; if (!block.LastInstr.isConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch) { return(false); } instructionEmulator.init(blocks); var instructions = block.Instructions; if (instructions.Count == 0) { return(false); } try { for (int i = 0; i < instructions.Count - 1; i++) { var instr = instructions[i].Instruction; instructionEmulator.emulate(instr); } } catch (NullReferenceException) { // Here if eg. invalid metadata token in a call instruction (operand is null) return(false); } return(branchEmulator.emulate(block.LastInstr.Instruction)); }
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); }
protected override bool deobfuscate(Block block) { this.block = block; if (!DotNetUtils.isConditionalBranch(block.LastInstr.OpCode.Code) && block.LastInstr.OpCode.Code != Code.Switch) return false; instructionEmulator.init(blocks); var instructions = block.Instructions; if (instructions.Count == 0) return false; try { for (int i = 0; i < instructions.Count - 1; i++) { var instr = instructions[i].Instruction; instructionEmulator.emulate(instr); } } catch (NullReferenceException) { // Here if eg. invalid metadata token in a call instruction (operand is null) return false; } switch (block.LastInstr.OpCode.Code) { case Code.Beq: case Code.Beq_S: return emulate_Beq(); case Code.Bge: case Code.Bge_S: return emulate_Bge(); case Code.Bge_Un: case Code.Bge_Un_S: return emulate_Bge_Un(); case Code.Bgt: case Code.Bgt_S: return emulate_Bgt(); case Code.Bgt_Un: case Code.Bgt_Un_S: return emulate_Bgt_Un(); case Code.Ble: case Code.Ble_S: return emulate_Ble(); case Code.Ble_Un: case Code.Ble_Un_S: return emulate_Ble_Un(); case Code.Blt: case Code.Blt_S: return emulate_Blt(); case Code.Blt_Un: case Code.Blt_Un_S: return emulate_Blt_Un(); case Code.Bne_Un: case Code.Bne_Un_S: return emulate_Bne_Un(); case Code.Brfalse: case Code.Brfalse_S:return emulate_Brfalse(); case Code.Brtrue: case Code.Brtrue_S: return emulate_Brtrue(); case Code.Switch: return emulate_Switch(); default: return false; } }
// Switch deobfuscation when block uses stloc N, ldloc N to load switch constant // blk1: // ldc.i4 X // br swblk // swblk: // stloc N // ldloc N // switch (......) bool deobfuscateStLdloc(IList <Block> switchTargets, Block switchFallThrough, Block block) { 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.pop()); if (target == null) { continue; } source.replaceLastNonBranchWithBranch(0, target); source.add(new Instr(Instruction.Create(OpCodes.Pop))); changed = true; } return(changed); }
public void init(Blocks blocks, Block block) { this.blocks = blocks; this.block = block; instructionEmulator.init(blocks); }