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, instructionEmulator.pop()); if (target == null) { continue; } source.replaceLastNonBranchWithBranch(0, target); source.add(new Instr(OpCodes.Pop.ToInstruction())); changed = true; } return(changed); }
// Returns true if code was updated, false otherwise public bool deobfuscate() { 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 (System.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); } }
public static Value[] getInitializedArray(int arraySize, MethodDef method, ref int newarrIndex, Code stelemOpCode) { var resultValueArray = new Value[arraySize]; var emulator = new InstructionEmulator(method); var theArray = new UnknownValue(); emulator.push(theArray); var instructions = method.Body.Instructions; int i; for (i = newarrIndex + 1; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.FlowControl != FlowControl.Next) break; if (instr.OpCode.Code == Code.Newarr) break; switch (instr.OpCode.Code) { case Code.Newarr: case Code.Newobj: goto done; case Code.Stloc: case Code.Stloc_S: case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Starg: case Code.Starg_S: case Code.Stsfld: case Code.Stfld: if (emulator.peek() == theArray && i != newarrIndex + 1 && i != newarrIndex + 2) goto done; break; } if (instr.OpCode.Code == stelemOpCode) { var value = emulator.pop(); var index = emulator.pop() as Int32Value; var array = emulator.pop(); if (ReferenceEquals(array, theArray) && index != null && index.allBitsValid()) { if (0 <= index.value && index.value < resultValueArray.Length) resultValueArray[index.value] = value; } } else emulator.emulate(instr); } done: if (i != newarrIndex + 1) i--; newarrIndex = i; return resultValueArray; }
public static byte[] getInitializedArray(int arraySize, MethodDefinition method, ref int newarrIndex) { var resultValueArray = new Value[arraySize]; var emulator = new InstructionEmulator(method.HasThis, false, method.Parameters, method.Body.Variables); var theArray = new UnknownValue(); emulator.push(theArray); var instructions = method.Body.Instructions; int i; for (i = newarrIndex + 1; i < instructions.Count; i++) { var instr = instructions[i]; if (instr.OpCode.FlowControl != FlowControl.Next) break; if (instr.OpCode.Code == Code.Newarr) break; if (instr.OpCode.Code == Code.Stelem_I1) { var value = emulator.pop(); var index = emulator.pop() as Int32Value; var array = emulator.pop(); if (ReferenceEquals(array, theArray) && index != null && index.allBitsValid()) { if (0 <= index.value && index.value < resultValueArray.Length) resultValueArray[index.value] = value; } } else emulator.emulate(instr); } if (i != newarrIndex + 1) i--; newarrIndex = i; byte[] resultArray = new byte[resultValueArray.Length]; for (i = 0; i < resultArray.Length; i++) { var intValue = resultValueArray[i] as Int32Value; if (intValue == null || !intValue.allBitsValid()) return null; resultArray[i] = (byte)intValue.value; } return resultArray; }