public void Clear() { instructions = new List<Instruction>(); branchOrRet = new List<Instruction>(); afterInstr = null; fakeBranches = new List<Instruction>(); }
public void EmulateUntil(Instruction instruction, CilBody body, Instruction starter) { Snapshots.Add(new Snapshot(new Stack<StackEntry>(Stack), new Dictionary<int, LocalEntry>(_locals), instruction, _methodBody, null)); _instructionPointer = starter.GetInstructionIndex(body.Instructions) - 1; Trace(() => _methodBody.Instructions[_instructionPointer] != instruction); }
static Instruction getInstruction(IList<Instruction> instrs, Instruction source, int displ) { int sourceIndex = instrs.IndexOf(source); if (sourceIndex < 0) throw new ApplicationException("Could not find source instruction"); return instrs[sourceIndex + displ]; }
public bool Emulate(Instruction instr) { switch (instr.OpCode.Code) { case Code.Br: case Code.Br_S: return Emulate_Br(); 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; } }
void MarkAsBranchTarget(Instruction instr) { if (instr == null) return; int index = instrToIndex[instr]; GetBranchTargetList(index); // Just create the list }
public static bool FollowsPattern( this Instruction instr, CilBody body, out Instruction ender, List<Predicate<Instruction>> preds, int minPatternSize, out int patternSize) { var curInstr = instr; ender = null; var correct = 0; patternSize = 0; while (curInstr.Next(body) != null && preds.Any(p => p(curInstr.Next(body)))) { curInstr = curInstr.Next(body); correct++; } if (correct >= minPatternSize) { patternSize = correct + 1; ender = curInstr; return true; } return false; }
protected override Instruction OnAfterLoadArg(MethodDef methodToInline, Instruction instr, ref int instrIndex) { if (instr.OpCode.Code != Code.Box) return instr; if (methodToInline.MethodSig.GetGenParamCount() == 0) return instr; return DotNetUtils.GetInstruction(methodToInline.Body.Instructions, ref instrIndex); }
public static List <dnlib.DotNet.Emit.Instruction> GetInstructions(IList <dnlib.DotNet.Emit.Instruction> instrs, int index) { int stackSize = 0, end = 1; List <dnlib.DotNet.Emit.Instruction> condInstrs = new List <dnlib.DotNet.Emit.Instruction>(); if (instrs[index - 1].OpCode == OpCodes.Dup) { end = 1; } for (int i = index; i > -1; i--) { dnlib.DotNet.Emit.Instruction instr = instrs[i]; instr.CalculateStackUsage(out int push, out int pop); stackSize += push - pop; condInstrs.Add(instr); if (stackSize == end) { if (instr.OpCode != OpCodes.Dup) { break; } else { } } } condInstrs.Reverse(); return(condInstrs); }
protected override ITokenOperand ReadInlineTok(Instruction instr) { switch (reader.ReadByte()) { case 0: return imageReader.ReadTypeSig().ToTypeDefOrRef(); case 1: return imageReader.ReadFieldRef(); case 2: return imageReader.ReadMethodRef(); default: throw new ApplicationException("Unknown token type"); } }
public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg) { Tuple<MethodDef, Func<int, int>> key = GetKey(ctx, init); var repl = new List<Instruction>(); repl.AddRange(arg); repl.Add(Instruction.Create(OpCodes.Call, key.Item1)); return repl.ToArray(); }
public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg) { Tuple<Expression, Func<int, int>> key = GetKey(ctx, init); var invCompiled = new List<Instruction>(); new CodeGen(arg, ctx.Method, invCompiled).GenerateCIL(key.Item1); init.Body.MaxStack += (ushort)ctx.Depth; return invCompiled.ToArray(); }
ExInfo getExInfo(Instruction instruction) { if (instruction == null) return lastExInfo; ExInfo exInfo; if (!exInfos.TryGetValue(instruction, out exInfo)) exInfos[instruction] = exInfo = new ExInfo(); return exInfo; }
static bool checkInvokeCall(Instruction instr, string returnType, string parameters) { var method = instr.Operand as MethodDef; if (method == null) return false; if (method.Name != "Invoke") return false; return DotNetUtils.isMethod(method, returnType, parameters); }
protected static int GetInstructionSize(Instruction instr) { var opcode = instr.OpCode; if (opcode == null) return 5; // Load store/field var op = instr.Operand as SwitchTargetDisplOperand; if (op == null) return instr.GetSize(); return instr.OpCode.Size + (op.TargetDisplacements.Length + 1) * 4; }
protected bool InlineLoadMethod(int patchIndex, MethodDef methodToInline, Instruction loadInstr, int instrIndex) { if (!IsReturn(methodToInline, instrIndex)) return false; int methodArgsCount = DotNetUtils.GetArgsCount(methodToInline); for (int i = 0; i < methodArgsCount; i++) block.Insert(patchIndex++, OpCodes.Pop.ToInstruction()); block.Instructions[patchIndex] = new Instr(loadInstr.Clone()); return true; }
/// <summary> /// Gets the offset of an instruction /// </summary> /// <param name="instr">The instruction</param> /// <returns>The offset or <c>0</c> if <paramref name="instr"/> is <c>null</c> or not /// present in the list of all instructions.</returns> protected uint GetOffset(Instruction instr) { if (instr == null) { Error("Instruction is null"); return 0; } uint offset; if (offsets.TryGetValue(instr, out offset)) return offset; Error("Found some other method's instruction or a removed instruction. You probably removed an instruction that is the target of a branch instruction or an instruction that's the first/last instruction in an exception handler."); return 0; }
private bool ReplaceFormText(Instruction currentInstruction, string replacementText) { if (currentInstruction.Operand == null) return false; if (currentInstruction.Operand.ToString() != "ReplaceMe1") return false; currentInstruction.Operand = replacementText; return true; }
public static IEnumerable<Instruction> GetInstructionsBetween(this CilBody body, Instruction init, Instruction ender) { var curInstr = init; while (curInstr.Next(body) != null && curInstr.Next(body) != ender) { yield return curInstr; curInstr = curInstr.Next(body); } yield return curInstr; yield return curInstr.Next(body); }
/// <summary> /// Converts an instruction to a string /// </summary> /// <param name="instr">The instruction</param> /// <returns>The result</returns> public static string ToString(Instruction instr) { if (instr == null) return string.Empty; var sb = new StringBuilder(); sb.Append(string.Format("IL_{0:X4}: ", instr.Offset)); sb.Append(instr.OpCode.Name); AddOperandString(sb, instr, " "); return sb.ToString(); }
public Instruction[] EmitDecode(MethodDef init, RPContext ctx, Instruction[] arg) { Tuple<int, int> key = GetKey(ctx.Random, init); var ret = new List<Instruction>(); if (ctx.Random.NextBoolean()) { ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1)); ret.AddRange(arg); } else { ret.AddRange(arg); ret.Add(Instruction.Create(OpCodes.Ldc_I4, key.Item1)); } ret.Add(Instruction.Create(OpCodes.Mul)); return ret.ToArray(); }
/// <summary> /// Removes all nodes from start to end (exclusive) from this ControlStructure and moves them to the target structure. /// </summary> static HashSet<ControlFlowNode> FindNodes(ControlStructure current, Instruction startInst, Instruction endInst) { HashSet<ControlFlowNode> result = new HashSet<ControlFlowNode>(); if (startInst == null || endInst == null) return result; uint start = startInst.Offset; uint end = endInst.Offset; foreach (var node in current.Nodes.ToArray()) { if (node.Start != null && start <= node.Start.Value.Offset && node.Start.Value.Offset < end) { result.Add(node); } } return result; }
public IEnumerable<Instruction> TraceCallParameters(Instruction instruction) { EmulateUntil(instruction); var target = (instruction.Operand as MethodDef); var currentSnapshot = Snapshots[Snapshots.Count - 1]; while (currentSnapshot.ClonedStack.Count > Stack.Count - target.Parameters.Count) { yield return currentSnapshot.CurrentInstruction; currentSnapshot = currentSnapshot.Previous; } yield return instruction; }
public static int Emulate(Instruction[] code, int value) { DynamicMethod emulatore = new DynamicMethod("MER ? BUULHE", typeof(int), null); ILGenerator il = emulatore.GetILGenerator(); foreach (Instruction instr in code) { if (instr.OpCode == OpCodes.Ldarg_0) il.Emit(ReflOpCodes.Ldc_I4, value); else if (instr.Operand != null) il.Emit(instr.OpCode.ToReflectionOp(), Convert.ToInt32(instr.Operand)); else il.Emit(instr.OpCode.ToReflectionOp()); } Result ris = (Result)emulatore.CreateDelegate(typeof(Result)); return ris.Invoke(); }
// callee must have the same args as the calling method // if the callee is an instance method, the object must be placed on the stack first public static void EmitWrapperCall(this ILProcessor proc, MethodDef toCall, Instruction before = null) { //var caller = proc.Body.Method; for (ushort i = 0; i < toCall.Parameters.Count - (toCall.IsStatic ? 0 : 1); i++) if (before == null) proc.Append(toCall.Parameters.GetLdargOf(i, /*!toCall.IsStatic*/false)); else proc.InsertBefore(before, toCall.Parameters.GetLdargOf(i, /*!toCall.IsStatic*/false)); var c = toCall.IsVirtual ? OpCodes.Callvirt : OpCodes.Call; if (before == null) proc.Emit(c, toCall); else proc.InsertBefore(before, Instruction.Create(c, toCall)); }
/// <summary> /// Whether or not an instruction is an Stind instruction. /// </summary> /// <param name="instr">Instruction</param> /// <returns>true if Stind, false if not</returns> Boolean IsStind(Instruction instr) { switch (instr.OpCode.Code) { case Code.Stind_I: case Code.Stind_I1: case Code.Stind_I2: case Code.Stind_I4: case Code.Stind_I8: case Code.Stind_R4: case Code.Stind_R8: case Code.Stind_Ref: return true; default: return false; } }
public static bool getArgValue(Instruction instr, out object arg) { switch (instr.OpCode.Code) { case Code.Ldc_I4_S: arg = (int)(sbyte)instr.Operand; return true; case Code.Ldc_I4_M1: arg = -1; return true; case Code.Ldc_I4_0: arg = 0; return true; case Code.Ldc_I4_1: arg = 1; return true; case Code.Ldc_I4_2: arg = 2; return true; case Code.Ldc_I4_3: arg = 3; return true; case Code.Ldc_I4_4: arg = 4; return true; case Code.Ldc_I4_5: arg = 5; return true; case Code.Ldc_I4_6: arg = 6; return true; case Code.Ldc_I4_7: arg = 7; return true; case Code.Ldc_I4_8: arg = 8; return true; case Code.Ldnull: arg = null; return true; case Code.Ldstr: case Code.Ldc_I4: case Code.Ldc_I8: case Code.Ldc_R4: case Code.Ldc_R8: arg = instr.Operand; return true; case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldloc: case Code.Ldloc_S: case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: arg = null; return true; default: arg = null; return false; } }
public void AddJump(IList<Instruction> instrs, Instruction target) { if (!Method.Module.IsClr40 && JunkCode && !Method.DeclaringType.HasGenericParameters && !Method.HasGenericParameters && (instrs[0].OpCode.FlowControl == FlowControl.Call || instrs[0].OpCode.FlowControl == FlowControl.Next)) { switch (Random.NextInt32(3)) { case 0: instrs.Add(Instruction.Create(OpCodes.Ldc_I4_0)); instrs.Add(Instruction.Create(OpCodes.Brtrue, instrs[0])); break; case 1: instrs.Add(Instruction.Create(OpCodes.Ldc_I4_1)); instrs.Add(Instruction.Create(OpCodes.Brfalse, instrs[0])); break; case 2: // Take that, de4dot + ILSpy :) bool addDefOk = false; if (Random.NextBoolean()) { TypeDef randomType; randomType = Method.Module.Types[Random.NextInt32(Method.Module.Types.Count)]; if (randomType.HasMethods) { instrs.Add(Instruction.Create(OpCodes.Ldtoken, randomType.Methods[Random.NextInt32(randomType.Methods.Count)])); instrs.Add(Instruction.Create(OpCodes.Box, Method.Module.CorLibTypes.GetTypeRef("System", "RuntimeMethodHandle"))); addDefOk = true; } } if (!addDefOk) { instrs.Add(Instruction.Create(OpCodes.Ldc_I4, Random.NextBoolean() ? 0 : 1)); instrs.Add(Instruction.Create(OpCodes.Box, Method.Module.CorLibTypes.Int32.TypeDefOrRef)); } Instruction pop = Instruction.Create(OpCodes.Pop); instrs.Add(Instruction.Create(OpCodes.Brfalse, instrs[0])); instrs.Add(Instruction.Create(OpCodes.Ldc_I4, Random.NextBoolean() ? 0 : 1)); instrs.Add(pop); break; } } instrs.Add(Instruction.Create(OpCodes.Br, target)); }
private bool ReplaceImageByteArray(MethodDef injectedMethodDef, Instruction currentInstruction, int instructionIndex, Image replacementImage) { if (currentInstruction.OpCode != OpCodes.Ldnull) return false; var operand = injectedMethodDef.Body.Instructions[instructionIndex + 2].Operand; if (operand == null) return false; if (!operand.ToString().Contains("MemoryStream")) return false; injectedMethodDef.Body.Instructions.RemoveAt(1); var imageBytes = GetImageAsByteArray(replacementImage); var newInstructions = GetNewByteArrayInstructions(injectedMethodDef, imageBytes); for (var injectionIndex = instructionIndex; injectionIndex < instructionIndex + newInstructions.Length; injectionIndex++) injectedMethodDef.Body.Instructions.Insert(injectionIndex, newInstructions[injectionIndex - instructionIndex]); return true; }
bool InlineMethod(Instruction callInstr, int instrIndex) { var method = callInstr.Operand as MethodDef; if (method == null) { var ms = callInstr.Operand as MethodSpec; if (ms != null) method = ms.Method as MethodDef; if (method == null) return false; } if (!CanInline(method)) return false; if (instrIndex < 2) return false; var ldci4_1st = block.Instructions[instrIndex - 2]; var ldci4_2nd = block.Instructions[instrIndex - 1]; if (!ldci4_1st.IsLdcI4() || !ldci4_2nd.IsLdcI4()) return false; if (!InlineMethod(method, instrIndex, ldci4_1st.GetLdcI4Value(), ldci4_2nd.GetLdcI4Value())) return false; return true; }
static Instruction GetInstruction(IList<Instruction> instructions, IDictionary<Instruction, int> instructionToIndex, Instruction instruction) { if (instruction == null) return null; return instructions[instructionToIndex[instruction]]; }
public static void CopyBody(MethodDef method, out IList<Instruction> instructions, out IList<ExceptionHandler> exceptionHandlers) { if (method == null || !method.HasBody) { instructions = new List<Instruction>(); exceptionHandlers = new List<ExceptionHandler>(); return; } var oldInstrs = method.Body.Instructions; var oldExHandlers = method.Body.ExceptionHandlers; instructions = new List<Instruction>(oldInstrs.Count); exceptionHandlers = new List<ExceptionHandler>(oldExHandlers.Count); var oldToIndex = Utils.CreateObjectToIndexDictionary(oldInstrs); foreach (var oldInstr in oldInstrs) instructions.Add(oldInstr.Clone()); foreach (var newInstr in instructions) { var operand = newInstr.Operand; if (operand is Instruction) newInstr.Operand = instructions[oldToIndex[(Instruction)operand]]; else if (operand is IList<Instruction>) { var oldArray = (IList<Instruction>)operand; var newArray = new Instruction[oldArray.Count]; for (int i = 0; i < oldArray.Count; i++) newArray[i] = instructions[oldToIndex[oldArray[i]]]; newInstr.Operand = newArray; } } foreach (var oldEx in oldExHandlers) { var newEx = new ExceptionHandler(oldEx.HandlerType) { TryStart = GetInstruction(instructions, oldToIndex, oldEx.TryStart), TryEnd = GetInstruction(instructions, oldToIndex, oldEx.TryEnd), FilterStart = GetInstruction(instructions, oldToIndex, oldEx.FilterStart), HandlerStart = GetInstruction(instructions, oldToIndex, oldEx.HandlerStart), HandlerEnd = GetInstruction(instructions, oldToIndex, oldEx.HandlerEnd), CatchType = oldEx.CatchType, }; exceptionHandlers.Add(newEx); } }
/// <summary> /// Add an instruction's operand to <paramref name="sb"/> /// </summary> /// <param name="sb">Place result here</param> /// <param name="instr">The instruction</param> public static void AddOperandString(StringBuilder sb, Instruction instr) { AddOperandString(sb, instr, string.Empty); }
/// <summary> /// Add an instruction's operand to <paramref name="sb"/> /// </summary> /// <param name="sb">Place result here</param> /// <param name="instr">The instruction</param> /// <param name="extra">A string that will be added before the operand, if there's /// an operand.</param> public static void AddOperandString(StringBuilder sb, Instruction instr, string extra) { switch (instr.OpCode.OperandType) { case OperandType.InlineBrTarget: case OperandType.ShortInlineBrTarget: sb.Append(extra); AddInstructionTarget(sb, instr.Operand as Instruction); break; case OperandType.InlineField: case OperandType.InlineMethod: case OperandType.InlineTok: case OperandType.InlineType: sb.Append(extra); if (instr.Operand is IFullName) { sb.Append((instr.Operand as IFullName).FullName); } else if (instr.Operand != null) { sb.Append(instr.Operand.ToString()); } else { sb.Append("null"); } break; case OperandType.InlineI: case OperandType.InlineI8: case OperandType.InlineR: case OperandType.ShortInlineI: case OperandType.ShortInlineR: sb.Append(string.Format("{0}{1}", extra, instr.Operand)); break; case OperandType.InlineSig: sb.Append(extra); sb.Append(FullNameCreator.MethodFullName(null, (UTF8String)null, instr.Operand as MethodSig)); break; case OperandType.InlineString: sb.Append(extra); EscapeString(sb, instr.Operand as string, true); break; case OperandType.InlineSwitch: var targets = instr.Operand as IList <Instruction>; if (targets == null) { sb.Append("null"); } else { sb.Append('('); for (int i = 0; i < targets.Count; i++) { if (i != 0) { sb.Append(','); } AddInstructionTarget(sb, targets[i]); } sb.Append(')'); } break; case OperandType.InlineVar: case OperandType.ShortInlineVar: sb.Append(extra); if (instr.Operand == null) { sb.Append("null"); } else { sb.Append(instr.Operand.ToString()); } break; case OperandType.InlineNone: case OperandType.InlinePhi: default: break; } }
private static void Clean() { foreach (MethodDef method in methods) { methodName = method.Name; methodBytes = Strings.Initalise.GetOriginalBytes.bytesDict[method.MDToken.ToUInt32()]; for (int i = 0; i < method.Body.Instructions.Count; i++) { dnlib.DotNet.Emit.Instruction instruction = method.Body.Instructions[i]; if (instruction.OpCode != OpCodes.Call) { continue; } if (!(instruction.Operand is MethodSpec)) { continue; } if (!instruction.Operand.ToString().Contains("System.String>")) { continue; } if (instruction.Operand.ToString().Contains("(System.UInt32,System.Object)")) { List <dnlib.DotNet.Emit.Instruction> instructions = GetInstructions(method.Body.Instructions, i); CawkEmulatorV4.Emulation emu = new CawkEmulatorV4.Emulation(method); uint[] setUp = new uint[2]; emu.OnInstructionPrepared += (emulation, args) => { if (args.Instruction.IsLdloc()) { emulation.ValueStack.CallStack.Push(setUp); args.Cancel = true; } if (args.Instruction.OpCode == OpCodes.Box) { args.Cancel = true; } }; if (instructions[0].OpCode == OpCodes.Dup) { emu.ValueStack.CallStack.Push(setUp); emu.Emulate2(instructions, 0, instructions.Count - 1); } else { emu.Emulate2(instructions, 0, instructions.Count - 1); } dynamic array = emu.ValueStack.CallStack.Pop(); dynamic uintVal = emu.ValueStack.CallStack.Pop(); string decryptedString = DecryptSting(instruction.Operand as MethodSpec, (uint)uintVal, (object)array); for (int y = 0; y < instructions.Count; y++) { method.Body.Instructions[i - y].OpCode = OpCodes.Nop; } method.Body.Instructions[i].OpCode = OpCodes.Ldstr; method.Body.Instructions[i].Operand = decryptedString; } else { // throw new NotSupportedException(); } } } }