protected override bool Deobfuscate(Block block) { this.block = block; if (!block.LastInstr.IsConditionalBranch() && block.LastInstr.OpCode.Code != Code.Switch) { return(false); } instructionEmulator.Initialize(blocks, allBlocks[0] == block); 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)); }
protected override bool Deobfuscate(Block block) { bool modified = false; instructionEmulator.Initialize(blocks, allBlocks[0] == block); 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: modified |= 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: modified |= 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(modified); }
// 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 modified = false; foreach (var source in new List <Block>(block.Sources)) { if (!isBranchBlock(source)) { continue; } instructionEmulator.Initialize(blocks, allBlocks[0] == source); instructionEmulator.Emulate(source.Instructions); var target = GetSwitchTarget(switchTargets, switchFallThrough, instructionEmulator.Pop()); if (target == null) { continue; } source.ReplaceLastNonBranchWithBranch(0, target); source.Add(new Instr(OpCodes.Pop.ToInstruction())); modified = true; } return(modified); }
protected override bool Deobfuscate(Block block) { bool modified = false; instructionEmulator.Initialize(Blocks, AllBlocks[0] == block); 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: modified |= 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: modified |= 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; case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.And: case Code.Ceq: case Code.Cgt: case Code.Cgt_Un: case Code.Clt: case Code.Clt_Un: case Code.Conv_I: case Code.Conv_I1: case Code.Conv_I2: case Code.Conv_I4: case Code.Conv_I8: case Code.Conv_Ovf_I: case Code.Conv_Ovf_I_Un: case Code.Conv_Ovf_I1: case Code.Conv_Ovf_I1_Un: case Code.Conv_Ovf_I2: case Code.Conv_Ovf_I2_Un: case Code.Conv_Ovf_I4: case Code.Conv_Ovf_I4_Un: case Code.Conv_Ovf_I8: case Code.Conv_Ovf_I8_Un: case Code.Conv_Ovf_U: case Code.Conv_Ovf_U_Un: case Code.Conv_Ovf_U1: case Code.Conv_Ovf_U1_Un: case Code.Conv_Ovf_U2: case Code.Conv_Ovf_U2_Un: case Code.Conv_Ovf_U4: case Code.Conv_Ovf_U4_Un: case Code.Conv_Ovf_U8: case Code.Conv_Ovf_U8_Un: case Code.Conv_R_Un: case Code.Conv_R4: case Code.Conv_R8: case Code.Conv_U: case Code.Conv_U1: case Code.Conv_U2: case Code.Conv_U4: case Code.Conv_U8: case Code.Div: case Code.Div_Un: case Code.Dup: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Neg: case Code.Not: case Code.Or: case Code.Rem: case Code.Rem_Un: case Code.Shl: case Code.Shr: case Code.Shr_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Xor: if (DisableNewCode) { break; } if (i + 1 < instrs.Count && instrs[i + 1].OpCode.Code == Code.Pop) { break; } if (!VerifyValidArgs(instr.Instruction)) { break; } instructionEmulator.Emulate(instr.Instruction); var tos = instructionEmulator.Peek(); Instruction newInstr = null; if (tos.IsInt32()) { var val = (Int32Value)tos; if (val.AllBitsValid()) { newInstr = Instruction.CreateLdcI4(val.Value); } } else if (tos.IsInt64()) { var val = (Int64Value)tos; if (val.AllBitsValid()) { newInstr = OpCodes.Ldc_I8.ToInstruction(val.Value); } } else if (tos.IsReal8()) { var val = (Real8Value)tos; if (val.IsValid) { newInstr = GetLoadRealInstruction(val.Value); } } if (newInstr != null) { block.Insert(i + 1, Instruction.Create(OpCodes.Pop)); block.Insert(i + 2, newInstr); i += 2; modified = true; } continue; } try { instructionEmulator.Emulate(instr.Instruction); } catch (NullReferenceException) { // Here if eg. invalid metadata token in a call instruction (operand is null) break; } } return(modified); }