void Decrypt(IBinaryReader reader, int delegateTypeToken, ISimpleDeobfuscator simpleDeobfuscator) { var delegateType = module.ResolveToken(delegateTypeToken) as TypeDef; if (delegateType == null) throw new ApplicationException("Couldn't find delegate type"); int delToken, encMethToken, encDeclToken; if (!GetTokens(delegateType, out delToken, out encMethToken, out encDeclToken)) throw new ApplicationException("Could not find encrypted method tokens"); if (delToken != delegateTypeToken) throw new ApplicationException("Invalid delegate type token"); var encType = module.ResolveToken(encDeclToken) as ITypeDefOrRef; if (encType == null) throw new ApplicationException("Invalid declaring type token"); var encMethod = module.ResolveToken(encMethToken) as MethodDef; if (encMethod == null) throw new ApplicationException("Invalid encrypted method token"); var bodyReader = new MethodBodyReader(module, reader); bodyReader.Read(encMethod); bodyReader.RestoreMethod(encMethod); Logger.v("Restored method {0} ({1:X8}). Instrs:{2}, Locals:{3}, Exceptions:{4}", Utils.RemoveNewlines(encMethod.FullName), encMethod.MDToken.ToInt32(), encMethod.Body.Instructions.Count, encMethod.Body.Variables.Count, encMethod.Body.ExceptionHandlers.Count); delegateTypes.Add(delegateType); simpleDeobfuscator.MethodModified(encMethod); }
private static Assembly[] EmitModifiedMethod(MethodBuilder methodBuilder, MethodInfo methodInfo, object target) { // methodinfos var deseri = (typeof(SimpleJson)).GetMethods() .Where(x => x.Name == "DeserializeObject") .Where(x => x.GetParameters().Count() == 1) .First(x => !x.ContainsGenericParameters); var obgetv = typeof(JsonObject).GetMethod("GetValue", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(string) }, null); var tkval = typeof(JsonObject).GetMethod("ToObject", BindingFlags.Public | BindingFlags.Instance, null, new[] { typeof(Type) }, null); var gttype = (typeof(Type)).GetMethod("GetType", BindingFlags.Static | BindingFlags.Public, null, new[] { typeof(string) }, null); // init method builder var jsonObj = SimpleJson.SerializeObject(target); var reader = MethodBodyReader.Read(methodInfo); var writer = new MethodBodyBuilder(methodBuilder); // init method locals var locals = reader.Locals.Select(lc => lc.LocalType).Concat(new[] { typeof(JsonObject) }); writer.DeclareLocals(locals); writer.DeclareExceptionHandlers(reader.ExceptionHandlers); // serialize static container class into method var gen = writer.Generator; gen.Emit(OpCodes.Ldstr, jsonObj); gen.Emit(OpCodes.Call, deseri); gen.Emit(OpCodes.Stloc, locals.Count() - 1); // emit the original IL with the exception that ldarg.0 needs to load our JObject // instead of the delegate container class. var oldBody = reader.Instructions; List <Instruction> newBody = new List <Instruction>(); for (int index = 0; index < oldBody.Length; index++) { var ins = oldBody[index]; var name = ins.OpCode.Name; if (name.StartsWith("ldarg")) { int loc; int sepIndex = name.IndexOf('.'); if (sepIndex > 0) { var tmp = name.Substring(sepIndex + 1); if (!int.TryParse(tmp, out loc)) { throw new NotSupportedException("Unexpected Opcode: " + name); } } else if (ins.Operand is int) { loc = (int)ins.Operand; } else { throw new NotSupportedException("Unexpected Opcode: " + name); } if (loc == 0) { if (oldBody.Length < index + 1 || oldBody[index + 1].OpCode.Name != "ldfld") { throw new NotSupportedException("Unsupported case: ldarg.0 but no ldfld afterwards."); } var field = (FieldInfo)oldBody[index + 1].Operand; newBody.Add(new Instruction(-1, OpCodes.Ldloc) { Operand = locals.Count() - 1 }); newBody.Add(new Instruction(-1, OpCodes.Ldstr) { Operand = field.Name }); newBody.Add(new Instruction(-1, OpCodes.Callvirt) { Operand = obgetv }); newBody.Add(new Instruction(-1, OpCodes.Ldstr) { Operand = field.FieldType.AssemblyQualifiedName }); newBody.Add(new Instruction(-1, OpCodes.Call) { Operand = gttype }); newBody.Add(new Instruction(-1, OpCodes.Callvirt) { Operand = tkval }); if (field.FieldType.IsValueType) { newBody.Add(new Instruction(-1, OpCodes.Unbox_Any) { Operand = field.FieldType }); } else { newBody.Add(new Instruction(-1, OpCodes.Castclass) { Operand = field.FieldType }); } index++; } else { ins.OpCode = OpCodes.Ldarg; ins.Operand = loc - 1; newBody.Add(ins); } } else { newBody.Add(ins); } } writer.EmitBody(newBody); return(writer.ReferencedAssemblies); }