void DecryptMethodsOld(MDTable methodDefTable, ref DumpedMethods dumpedMethods) { dumpedMethods = new DumpedMethods(); var decrypter = new Decrypter10(peImage, codeHeader.decryptionKey); for (uint rid = 1; rid <= methodDefTable.Rows; rid++) { var dm = new DumpedMethod(); var method = (MethodDef)module.ResolveMethod(rid); if (method == null || method.DeclaringType == module.GlobalType) { continue; } peImage.ReadMethodTableRowTo(dm, rid); if (dm.mdRVA == 0) { continue; } uint bodyOffset = peImage.RvaToOffset(dm.mdRVA); var mbHeader = decrypter.Decrypt(bodyOffset, out dm.code, out dm.extraSections); peImage.UpdateMethodHeaderInfo(dm, mbHeader); dumpedMethods.Add(dm); } }
public SymbolMethod ReadMethodSymbolInfo(int methodMetadataToken) { var rid = MDToken.ToRID(methodMetadataToken); var mdMethod = _module.ResolveMethod(rid); return(_symbolReader.GetMethod(mdMethod, version: 1)); }
public static IEnumerable <MethodDef> EnumerateAllMethodDefs(this ModuleDefMD moduleDefMd) { var methodTableLength = moduleDefMd.TablesStream.MethodTable.Rows; for (uint rid = 1; rid <= methodTableLength; rid++) { yield return(moduleDefMd.ResolveMethod(rid)); } }
// Not working for all tokens ! /*public static IEnumerable<Tuple<Instruction, MethodDef>> FindAllReferences(this MethodDef mDef) * { * foreach ( * var method in * mDef.Module.Assembly.FindMethods(x => x.HasBody)) * { * for (var i = 0; i < method.Body.Instructions.Count; i++) * { * if (method.Body.Instructions[i].OpCode == OpCodes.Call) * if ((method.Body.Instructions[i].Operand as MethodSpec) != null) * { * var a = method.Body.Instructions[i].Operand as MethodSpec; * if (a.Method == mDef) * yield return Tuple.Create(method.Body.Instructions[i], method); * } * else if ((method.Body.Instructions[i].Operand as MethodDef) != null) * { * var a = method.Body.Instructions[i].Operand as MethodDef; * if (a == mDef) * yield return Tuple.Create(method.Body.Instructions[i], method); * } * else if ((method.Body.Instructions[i].Operand as MemberRef != null)) * { * var a = method.Body.Instructions[i].Operand as MemberRef; * if (a.ResolveMethod() != null) * yield return Tuple.Create(method.Body.Instructions[i], method); * } * } * } * }*/ // Somehow the other method skipped some references // Now we resolve every method by its token and check the instructions, it works this way (but isn't as clean as the other) public static IEnumerable <Instruction> FindAllReferences(this MethodDef mDef, ModuleDefMD module) { var returnList = new List <Instruction>(); var totalMethods2 = new List <MethodDef>(); // TODO: Read count dynamically for (var i = 1; i < 0x10000; i++) { var resolved = module.ResolveMethod((uint)i); if (resolved == null) { continue; } if (resolved.HasBody) { totalMethods2.Add(resolved); } } foreach ( var method in totalMethods2) { if (!method.HasBody) { continue; } for (var i = 0; i < method.Body.Instructions.Count; i++) { if (method.Body.Instructions[i].OpCode == OpCodes.Call) { var currentMethod = method.Body.Instructions[i].Operand as MethodDef; if (currentMethod != null && currentMethod.MDToken.ToInt32() == mDef.MDToken.ToInt32()) { returnList.Add(method.Body.Instructions[i]); } var currentMethodSpec = method.Body.Instructions[i].Operand as MethodSpec; if (currentMethodSpec != null && currentMethodSpec.MDToken.ToInt32() == mDef.MDToken.ToInt32()) { returnList.Add(method.Body.Instructions[i]); } } } } return(returnList); }
// Token: 0x0600001A RID: 26 RVA: 0x00002D9C File Offset: 0x00000F9C public void Analyze(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { ModuleDefMD module = def as ModuleDefMD; if (module == null) { return; } MDTable table = module.TablesStream.Get(Table.Method); uint len = table.Rows; for (uint i = 1u; i <= len; i += 1u) { MethodDef methodDef = module.ResolveMethod(i); foreach (MethodOverride ov in methodDef.Overrides) { this.ProcessMemberRef(context, service, module, ov.MethodBody); this.ProcessMemberRef(context, service, module, ov.MethodDeclaration); } if (methodDef.HasBody) { foreach (Instruction instr in methodDef.Body.Instructions) { if (instr.Operand is MemberRef || instr.Operand is MethodSpec) { this.ProcessMemberRef(context, service, module, (IMemberRef)instr.Operand); } } } } table = module.TablesStream.Get(Table.TypeRef); len = table.Rows; for (uint j = 1u; j <= len; j += 1u) { TypeRef typeRef = module.ResolveTypeRef(j); TypeDef typeDef = typeRef.ResolveTypeDefThrow(); if (typeDef.Module != module && context.Modules.Contains((ModuleDefMD)typeDef.Module)) { service.AddReference <TypeDef>(typeDef, new TypeRefReference(typeRef, typeDef)); } } }
private static void *[] LoadMethodHandles(Module module, ModuleDefMD moduleDef) { void *[] methodHandles; ModuleHandle moduleHandle; methodHandles = new void *[moduleDef.TablesStream.MethodTable.Rows]; moduleHandle = module.ModuleHandle; for (int i = 0; i < methodHandles.Length; i++) { MethodDef methodDef; methodDef = moduleDef.ResolveMethod((uint)i + 1); if (!methodDef.HasBody) { continue; } methodHandles[i] = (void *)moduleHandle.ResolveMethodHandle(0x06000001 + i).Value; } return(methodHandles); }
public MethodSymbol ReadMethodSymbol(int token) { var method = _moduleDefMd.ResolveMethod((uint)(token & 0x00FFFFFF)); var stateClassType = GetStateClassType(method); if (stateClassType != null) { var sequencePoints = new List <SequencePoint>(); if (stateClassType != null) { foreach (var typeMethod in stateClassType.Methods) { sequencePoints.AddRange(GetSequencePointsFromMethodBody(typeMethod)); } } sequencePoints.AddRange(GetSequencePointsFromMethodBody(method)); sequencePoints.Sort((sp1, sp2) => Comparer <int> .Default.Compare(sp1.StartLine, sp2.StartLine)); return(new MethodSymbol(token, sequencePoints.ToArray())); } return(new MethodSymbol(token, GetSequencePointsFromMethodBody(method).ToArray())); }
unsafe DumpedMethod decryptMethod(uint token) { if (!canDecryptMethods()) { throw new ApplicationException("Can't decrypt methods since compileMethod() isn't hooked yet"); } ctx = new DecryptContext(); ctx.dm = new DumpedMethod(); ctx.dm.token = token; ctx.method = dnlibModule.ResolveMethod(MDToken.ToRID(token)); if (ctx.method == null) { throw new ApplicationException(string.Format("Could not find method {0:X8}", token)); } byte *mh = (byte *)hInstModule + (uint)ctx.method.RVA; byte *code; if (mh == (byte *)hInstModule) { ctx.dm.mhMaxStack = 0; ctx.dm.mhCodeSize = 0; ctx.dm.mhFlags = 0; ctx.dm.mhLocalVarSigTok = 0; code = null; } else if ((*mh & 3) == 2) { uint headerSize = 1; ctx.dm.mhMaxStack = 8; ctx.dm.mhCodeSize = (uint)(*mh >> 2); ctx.dm.mhFlags = 2; ctx.dm.mhLocalVarSigTok = 0; code = mh + headerSize; } else { uint headerSize = (uint)((mh[1] >> 4) * 4); ctx.dm.mhMaxStack = *(ushort *)(mh + 2); ctx.dm.mhCodeSize = *(uint *)(mh + 4); ctx.dm.mhFlags = *(ushort *)mh; ctx.dm.mhLocalVarSigTok = *(uint *)(mh + 8); code = mh + headerSize; } CORINFO_METHOD_INFO info = default(CORINFO_METHOD_INFO); info.ILCode = new IntPtr(code); info.ILCodeSize = ctx.dm.mhCodeSize; info.maxStack = ctx.dm.mhMaxStack; info.scope = moduleToDecryptScope; initializeOurComp(); if (code == null) { ctx.dm.code = new byte[0]; updateFromMethodDefTableRow(); } else { callMethodDelegate(*(IntPtr *)jitterVtbl, jitterInstance, ourCompMem, new IntPtr(&info), 0, new IntPtr(0x12345678), new IntPtr(0x3ABCDEF0)); } var dm = ctx.dm; ctx = null; return(dm); }
public static IEnumerable <Instruction> FindAllReferences(this MethodDef mDef, ModuleDefMD module) { List <Instruction> instructionList = new List <Instruction>(); List <MethodDef> methodDefList = new List <MethodDef>(); for (int index = 1; index < 65536; ++index) { MethodDef methodDef = module.ResolveMethod((uint)index); if (methodDef != null && methodDef.HasBody) { methodDefList.Add(methodDef); } } foreach (MethodDef methodDef in methodDefList) { if (methodDef.HasBody) { for (int index = 0; index < methodDef.Body.Instructions.Count; ++index) { if (methodDef.Body.Instructions[index].OpCode == OpCodes.Call) { MethodDef operand1 = methodDef.Body.Instructions[index].Operand as MethodDef; MDToken mdToken; int num1; if (operand1 != null) { mdToken = operand1.MDToken; int int32_1 = mdToken.ToInt32(); mdToken = mDef.MDToken; int int32_2 = mdToken.ToInt32(); num1 = int32_1 == int32_2 ? 1 : 0; } else { num1 = 0; } if (num1 != 0) { instructionList.Add(methodDef.Body.Instructions[index]); } MethodSpec operand2 = methodDef.Body.Instructions[index].Operand as MethodSpec; int num2; if (operand2 != null) { mdToken = operand2.MDToken; int int32_1 = mdToken.ToInt32(); mdToken = mDef.MDToken; int int32_2 = mdToken.ToInt32(); num2 = int32_1 == int32_2 ? 1 : 0; } else { num2 = 0; } if (num2 != 0) { instructionList.Add(methodDef.Body.Instructions[index]); } } } } } return((IEnumerable <Instruction>)instructionList); }
static void ParseMethods(TypeDef clazz) { foreach (var rid in currentModule.Metadata.GetMethodRidList(clazz.Rid)) { var method = currentModule.ResolveMethod(rid); if (method == null || method.IsConstructor || method.IsStaticConstructor) { continue; } var methodName = method.Name.Replace("::", "_").Replace("<", "").Replace(">", "").Replace(".", "_").Replace("`", "_"); if (methodName.Equals("auto") || methodName.Equals("register")) { methodName += "_"; } var methodType = Il2CppTypeToCppType(method.ReturnType); var methodOffset = GetMethodOffset(method); string methodKey = clazz.Namespace + clazz.FullName + method.Name; if (m_DuplicateMethodTable.ContainsKey(methodKey)) { methodName += "_" + m_DuplicateMethodTable[methodKey]++; } else { m_DuplicateMethodTable.Add(methodKey, 1); } List <string> methodParams = new List <string>(); List <string> paramTypes = new List <string>(); List <string> paramNames = new List <string>(); foreach (var param in method.Parameters) { if (param.IsNormalMethodParameter) { var paramType = Il2CppTypeToCppType(param.Type); if (param.HasParamDef) { if (param.ParamDef.IsOut) { paramType += "*"; } } if (param.Name.Equals("auto") || param.Name.Equals("register")) { param.Name += "_"; } paramTypes.Add(paramType); paramNames.Add(param.Name); methodParams.Add(paramType + " " + param.Name); } } currentFile.Write(string.Format("\ttemplate <typename T = {0}>", methodType)); currentFile.WriteLine(string.Format(" {0}{1} {2}({3}) {{", (method.IsStatic ? "static " : ""), "T", methodName, string.Join(", ", methodParams))); if (!method.IsStatic) { if (methodParams.Count > 0) { currentFile.WriteLine("\t\treturn (({0} (*)({1}*, {2}))(Il2CppBase() + {3}))(this, {4});", "T", FormatToValidClassname(clazz.Name), string.Join(", ", paramTypes), methodOffset, string.Join(", ", paramNames)); } else { currentFile.WriteLine("\t\treturn (({0} (*)({1}*))(Il2CppBase() + {3}))(this);", "T", FormatToValidClassname(clazz.Name), string.Join(", ", paramTypes), methodOffset); } } else { if (methodParams.Count > 0) { currentFile.WriteLine("\t\treturn (({0} (*)(void *, {1}))(Il2CppBase() + {2}))(0, {3});", "T", string.Join(", ", paramTypes), methodOffset, string.Join(", ", paramNames)); } else { currentFile.WriteLine("\t\treturn (({0} (*)(void *))(Il2CppBase() + {2}))(0);", "T", string.Join(", ", paramTypes), methodOffset, string.Join(", ", paramNames)); } } currentFile.WriteLine("\t}"); } }
public void DecryptString(ref int amount) { //Checking if the method of decryption list is not empty if (DecryptionMeth.Count == 0) { Console.WriteLine("No decryption method found, please input token of meth : "); } try { //Removing 0x string corrected = Console.ReadLine().Remove(0, 2); //Converting token to rid by substracting 0x06000000 MethodDef found = module.ResolveMethod(uint.Parse(corrected, System.Globalization.NumberStyles.HexNumber) - 0x06000000); Console.WriteLine("Found decryption method : {0}", found.Name); //If the method wasn't found, we ask to the use to input one DecryptionMeth.Add(found); } catch (Exception ex) { Console.WriteLine(ex.Message); } //Looping through the type foreach (TypeDef type in module.Types) { //Looping through the methods foreach (MethodDef method in type.Methods) { //Checking if method.HasBody if (method.HasBody) { //Now we loop through each instruction for (int i = 0; i < method.Body.Instructions.Count; i++) { /* * [*] First check -> checking if argument is ldstr (most of the time, ldstr become int * so you have to adapt this part * [*] Second check -> checking if next instr is call (sometimes, the ldstr is not right * after the ldstr, see my toolYano deobfuscator for a more stable version * [*] Third check -> checking if the call is a methoddef * [*] Fourth check -> checking if the method is a decryption method */ if (method.Body.Instructions[i].OpCode == OpCodes.Ldstr && method.Body.Instructions[i + 1].OpCode == OpCodes.Call && method.Body.Instructions[i + 1].Operand is MethodDef && DecryptionMeth.Contains((MethodDef)method.Body.Instructions[i + 1].Operand)) { //Getting the encrypted string string argument = method.Body.Instructions[i].Operand.ToString(); string resolved; if (mode == Mode.Static) { //decrypting the string //STATIC APPROACH resolved = DecryptString(argument); } else { //DYNAMIC APPROACH //We grab the methodDef to get its mdtoken MethodDef toinvoke = (MethodDef)method.Body.Instructions[i + 1].Operand; //Then we invoke the methodofdecryption to get the string //It's more reliable but can be dangerous as it loads the assembly which //may contains virus resolved = (string)asm.ManifestModule.ResolveMethod(toinvoke.MDToken.ToInt32()).Invoke(null, new object[] { argument }); } //Replacing the decrypted string //Here you can use resolve or resolved2, they should be the same method.Body.Instructions[i].Operand = resolved; //Nop the call !! not deleting it ! method.Body.Instructions[i + 1].OpCode = OpCodes.Nop; //Printing the decrypted strings amount++; Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine("Decrypted : {0}", resolved); Console.ForegroundColor = ConsoleColor.White; } } } } } }
PdbAsyncMethod CreateAsyncMethod(ModuleDefMD module, MethodDef method, CilBody body, ISymbolMethod2 symMethod) { var kickoffToken = new MDToken(symMethod.KickoffMethod); if (kickoffToken.Table != MD.Table.Method) { return(null); } var kickoffMethod = module.ResolveMethod(kickoffToken.Rid); var rawStepInfos = symMethod.GetAsyncStepInfos(); var asyncMethod = new PdbAsyncMethod(rawStepInfos.Length); asyncMethod.KickoffMethod = kickoffMethod; var catchHandlerILOffset = symMethod.CatchHandlerILOffset; if (catchHandlerILOffset != null) { asyncMethod.CatchHandlerInstruction = GetInstruction(body, catchHandlerILOffset.Value); Debug.Assert(asyncMethod.CatchHandlerInstruction != null); } foreach (var rawInfo in rawStepInfos) { var yieldInstruction = GetInstruction(body, rawInfo.YieldOffset); Debug.Assert(yieldInstruction != null); if (yieldInstruction == null) { continue; } MethodDef breakpointMethod; Instruction breakpointInstruction; if (method.MDToken.Raw == rawInfo.BreakpointMethod) { breakpointMethod = method; breakpointInstruction = GetInstruction(body, rawInfo.BreakpointOffset); } else { var breakpointMethodToken = new MDToken(rawInfo.BreakpointMethod); Debug.Assert(breakpointMethodToken.Table == MD.Table.Method); if (breakpointMethodToken.Table != MD.Table.Method) { continue; } breakpointMethod = module.ResolveMethod(breakpointMethodToken.Rid); Debug.Assert(breakpointMethod != null); if (breakpointMethod == null) { continue; } breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); } Debug.Assert(breakpointInstruction != null); if (breakpointInstruction == null) { continue; } asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); } return(asyncMethod); }
// Token: 0x0600002B RID: 43 RVA: 0x00003AAC File Offset: 0x00001CAC public void Analyze(ConfuserContext context, INameService service, ProtectionParameters parameters, IDnlibDef def) { ModuleDefMD module = def as ModuleDefMD; if (module == null) { return; } MDTable table = module.TablesStream.Get(Table.Method); uint len = table.Rows; IEnumerable <MethodDef> methods = from rid in Enumerable.Range(1, (int)len) select module.ResolveMethod((uint)rid); foreach (MethodDef method in methods) { foreach (MethodOverride methodImpl in method.Overrides) { if (methodImpl.MethodBody is MemberRef) { this.AnalyzeMemberRef(context, service, (MemberRef)methodImpl.MethodBody); } if (methodImpl.MethodDeclaration is MemberRef) { this.AnalyzeMemberRef(context, service, (MemberRef)methodImpl.MethodDeclaration); } } if (method.HasBody) { foreach (Instruction instr in method.Body.Instructions) { if (instr.Operand is MemberRef) { this.AnalyzeMemberRef(context, service, (MemberRef)instr.Operand); } else if (instr.Operand is MethodSpec) { MethodSpec spec = (MethodSpec)instr.Operand; if (spec.Method is MemberRef) { this.AnalyzeMemberRef(context, service, (MemberRef)spec.Method); } } } } } table = module.TablesStream.Get(Table.CustomAttribute); len = table.Rows; IEnumerable <CustomAttribute> attrs = (from rid in Enumerable.Range(1, (int)len) select module.ResolveHasCustomAttribute(module.TablesStream.ReadCustomAttributeRow((uint)rid).Parent)).Distinct <IHasCustomAttribute>().SelectMany((IHasCustomAttribute owner) => owner.CustomAttributes); foreach (CustomAttribute attr in attrs) { if (attr.Constructor is MemberRef) { this.AnalyzeMemberRef(context, service, (MemberRef)attr.Constructor); } foreach (CAArgument arg in attr.ConstructorArguments) { this.AnalyzeCAArgument(context, service, arg); } foreach (CANamedArgument arg2 in attr.Fields) { this.AnalyzeCAArgument(context, service, arg2.Argument); } foreach (CANamedArgument arg3 in attr.Properties) { this.AnalyzeCAArgument(context, service, arg3.Argument); } TypeDef attrType = attr.AttributeType.ResolveTypeDefThrow(); if (context.Modules.Contains((ModuleDefMD)attrType.Module)) { foreach (CANamedArgument fieldArg in attr.Fields) { FieldDef field = attrType.FindField(fieldArg.Name, new FieldSig(fieldArg.Type)); if (field == null) { context.Logger.WarnFormat("Failed to resolve CA field '{0}::{1} : {2}'.", new object[] { attrType, fieldArg.Name, fieldArg.Type }); } else { service.AddReference <IDnlibDef>(field, new CAMemberReference(fieldArg, field)); } } foreach (CANamedArgument propertyArg in attr.Properties) { PropertyDef property = attrType.FindProperty(propertyArg.Name, new PropertySig(true, propertyArg.Type)); if (property == null) { context.Logger.WarnFormat("Failed to resolve CA property '{0}::{1} : {2}'.", new object[] { attrType, propertyArg.Name, propertyArg.Type }); } else { service.AddReference <IDnlibDef>(property, new CAMemberReference(propertyArg, property)); } } } } }