public override void CleanUp() { var badCall = RoutineVariables["resolverCall"] as Tuple <Instruction[], MethodDef>; var badRes = RoutineVariables["badRes"] as EmbeddedResource; var resolver = RoutineVariables["resolver"] as MethodDef; var asmFld = RoutineVariables["asmFld"] as FieldDef; if (badCall != null) { RemovedInstructions.Add(Tuple.Create(badCall.Item2, badCall.Item1)); foreach (var instr in badCall.Item1) { badCall.Item2.Body.Instructions.Remove(instr); } } if (badRes != null) { Ctx.UIProvider.WriteVerbose("Removed encrypted resource: {0}", 2, true, badRes.Name); Ctx.Assembly.ManifestModule.Resources.Remove(badRes); } if (resolver != null) { Ctx.UIProvider.WriteVerbose("Removed resource decryptor: {0}::{1}", 2, true, resolver.DeclaringType.Name, resolver.Name); resolver.DeclaringType.Methods.Remove(resolver); } if (asmFld != null) { Ctx.UIProvider.WriteVerbose("Removed bad field: {0}::{1}", 2, true, asmFld.DeclaringType.Name, asmFld.Name); asmFld.DeclaringType.Fields.Remove(asmFld); } }
private void DecryptConstants( List <Tuple <Decryptor, MethodDef, List <Tuple <Instruction, MethodDef> > > > demutatedDecryptors) { demutatedDecryptors.ForEach(d => { CalculateMutations(d.Item2); PopulateKeys(d.Item1, d.Item2); foreach (var @ref in d.Item3) { //var tracer = new ILEmulator(@ref.Item2.Body, // @ref.Item2.Body.Instructions.Count); //var test = tracer.TraceCallParameters(@ref.Item1).ToList(); var body = @ref.Item2.Body; var mdModifier = (uint)@ref.Item1.Previous(body).Previous(body).GetLdcI4Value(); var hashModifier = (ulong)@ref.Item1.Previous(body).GetLdcI8(); var str = d.Item1.Decrypt <string>(mdModifier, hashModifier); body.SimplifyMacros(@ref.Item2.Parameters); body.SimplifyBranches(); var removedInstructions = new[] { @ref.Item1.Previous(body), @ref.Item1.Previous(body).Previous(body), @ref.Item1 }; body.Instructions.Replace(@ref.Item1, Instruction.Create(OpCodes.Ldstr, str)); foreach (var instr in removedInstructions) { body.Instructions.Remove(instr); } body.OptimizeMacros(); body.OptimizeBranches(); body.UpdateInstructionOffsets(); RemovedInstructions.Add(Tuple.Create(@ref.Item2, removedInstructions)); Ctx.UIProvider.WriteVerbose("Restored string \"{0}\"", 2, true, str); } }); }
public override void RestoreProxyCall(Tuple <TypeDef, IMemberRef, FieldDef> resolvedProxy) { var destCall = resolvedProxy.Item1.Methods.First(x => x.IsStatic && !x.IsConstructor && x.HasBody); foreach (var @ref in destCall.FindAllReferences()) { Ctx.UIProvider.WriteVerbose("Restored proxy call [{0} -> {1}]", 2, true, destCall.Name, resolvedProxy.Item2.Name); @ref.Item2.Body.SimplifyMacros(@ref.Item2.Parameters); @ref.Item2.Body.SimplifyBranches(); RemovedInstructions.Add(Tuple.Create(@ref.Item2, new[] { @ref.Item1 })); @ref.Item2.Body.Instructions.Replace(@ref.Item1, Instruction.Create(OpCodes.Newobj, resolvedProxy.Item2 as IMethod)); @ref.Item2.Body.OptimizeBranches(); @ref.Item2.Body.OptimizeMacros(); } }
public override void CleanUp() { var badCall = RoutineVariables["badcall"] as Tuple <Instruction, MethodDef>; var badType = RoutineVariables["badtype"] as TypeDef; if (badCall != null) { Ctx.UIProvider.WriteVerbose("Removed bad call from {0}::{1}", 2, true, badCall.Item2.DeclaringType.Name, badCall.Item2.Name); RemovedInstructions.Add(Tuple.Create(badCall.Item2, new[] { badCall.Item1 })); badCall.Item2.Body.Instructions.Remove(badCall.Item1); } if (badType != null) { Ctx.UIProvider.WriteVerbose("Removed bad type {0}", 2, true, badType.Name); badType.Module.Types.Remove(badType); } }
public override void CleanUp() { var antiTamper = RoutineVariables["antiTamper"] as MethodDef; var refs = antiTamper.FindAllReferences().ToList(); if (refs.Count != 1) { Ctx.UIProvider.Write("Too many or too few references to anti-tamper module"); return; } Ctx.UIProvider.WriteVerbose("Removed call to anti-tamper from {0}::{1}", 2, true, refs[0].Item2.DeclaringType.Name, ".cctor"); RemovedInstructions.Add(Tuple.Create(refs[0].Item2, new[] { refs[0].Item1 })); refs[0].Item2.Body.Instructions.Remove(refs[0].Item1); Ctx.UIProvider.WriteVerbose("Removed bad type: {0}", 2, true, antiTamper.DeclaringType.Name); Ctx.Assembly.ManifestModule.Types.Remove(antiTamper.DeclaringType); }
public override void RestoreProxyCall(Tuple <TypeDef, IMemberRef, FieldDef> resolvedProxy, char virtIdentifier) { var destCall = resolvedProxy.Item1.Methods.First( x => x.IsStatic && !x.IsConstructor && x.HasBody && x.Body.Instructions.FindInstruction( y => y.OpCode.Code == Code.Ldsfld && y.Operand == resolvedProxy.Item3, 0) != null); var isVirtual = resolvedProxy.Item3.Name.String[0] == virtIdentifier; foreach (var @ref in destCall.FindAllReferences()) { if (resolvedProxy.Item2 == null) { continue; } Ctx.UIProvider.WriteVerbose("Restored proxy call [{0} -> {1}]", 2, true, destCall.Name, resolvedProxy.Item2.Name); @ref.Item2.Body.SimplifyMacros(@ref.Item2.Parameters); @ref.Item2.Body.SimplifyBranches(); if ((resolvedProxy.Item2 as MemberRef) == null) { return; } RemovedInstructions.Add(Tuple.Create(@ref.Item2, new[] { @ref.Item1 })); @ref.Item2.Body.Instructions.Replace(@ref.Item1, Instruction.Create((isVirtual ? OpCodes.Callvirt : OpCodes.Call), resolvedProxy.Item2 as MemberRef)); @ref.Item2.Body.OptimizeMacros(); @ref.Item2.Body.OptimizeBranches(); @ref.Item2.Body.UpdateInstructionOffsets(); } }
public void CalculateMutations(MethodDef method) { if (method == null || method.Body == null) { return; } var pattern = new List <Predicate <Instruction> > { (x => x.IsLdcI4_2()), (x => x.OpCode.Code == Code.Add), (x => x.OpCode.Code == Code.Xor), (x => x.OpCode.Code == Code.Sub), //(x => x.OpCode.Code == Code.Mul), (x => x.OpCode.Code == Code.Ldc_I8), }; var stackvals = new List <dynamic>(); var updatedValues = new List <Tuple <Instruction, Instruction[], Instruction> >(); for (var i = 0; i < method.Body.Instructions.Count; i++) { var instr = method.Body.Instructions[i]; Instruction ender; int size; if (!instr.IsLdcI4() && instr.OpCode.Code != Code.Ldc_I8) { continue; } if (!instr.FollowsPattern(method.Body, out ender, pattern, 2, out size)) { continue; } var st = new ILEmulator(method.Body, method.Body.Instructions.Count); try { st.EmulateUntil(ender.Next(method.Body), method.Body, instr); var fakedVal = false; if (st.Stack.Count > 1) { if (instr.Previous(method.Body).OpCode.StackBehaviourPush != StackBehaviour.Push1) { fakedVal = true; stackvals.Add((dynamic)st.Stack.Reverse().ToList()[0].Value); } else { continue; } } else { stackvals.Add((dynamic)st.Stack.Peek().Value); } var oldInstr = instr.Next(method.Body); var badInstrs = new Instruction[size - 1]; for (int j = i, x = 0; j < size + i - 1; j++, x++) { badInstrs[x] = oldInstr; oldInstr = oldInstr.Next(method.Body); } if (fakedVal) { dynamic val = st.Stack.ToList().Last().Value; if (val is int) { updatedValues.Add(Tuple.Create(instr, badInstrs, Instruction.CreateLdcI4(val))); } else { updatedValues.Add(Tuple.Create(instr, badInstrs, Instruction.Create(OpCodes.Ldc_I8, (long)val))); } badInstrs[badInstrs.Length - 1] = null; } else { dynamic val = st.Stack.ToList().Last().Value; if (val is int) { updatedValues.Add(Tuple.Create(instr, badInstrs, Instruction.CreateLdcI4(val))); } else if (val != null) { updatedValues.Add(Tuple.Create(instr, badInstrs, Instruction.Create(OpCodes.Ldc_I8, (long)val))); } } i += size; } catch (InvalidOperationException) { } } foreach (var @new in updatedValues) { method.Body.SimplifyBranches(); var initIdx = @new.Item1.GetInstructionIndex(method.Body.Instructions); if (@new.Item1.IsLdcI4()) { if (@new.Item1.GetLdcI4Value() == @new.Item3.GetLdcI4Value()) { continue; } } else if ((dynamic)@new.Item1.Operand == (dynamic)@new.Item3.Operand) { continue; } var removedInstructions = new Instruction[@new.Item2.Count(x => x != null) + 1]; var idx = 0; foreach (var instr in @new.Item2.Where(instr => instr != null)) { removedInstructions[idx++] = instr; method.Body.Instructions.Remove(instr); } method.Body.Instructions.Insert(initIdx, @new.Item3); method.Body.Instructions.Remove(@new.Item1); method.Body.OptimizeBranches(); removedInstructions[removedInstructions.Length - 1] = @new.Item1; RemovedInstructions.Add(Tuple.Create(method, removedInstructions)); } }