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);
		}
Exemple #2
0
        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);
        }