コード例 #1
0
        internal static MethodSignatureInfoV2 ParseMethodSignature(uint signature, DotNetFile file, string FunctionName)
        {
            MethodSignatureInfoV2 ret = new MethodSignatureInfoV2();
            string sig = "";
            var    blobStreamReader = new BinaryReader(new MemoryStream(file.Backend.BlobStream));

            blobStreamReader.BaseStream.Seek(signature, SeekOrigin.Begin);
            var length    = IlDecompiler.ParseNumber(blobStreamReader);
            var type      = IlDecompiler.ParseNumber(blobStreamReader);
            var parmaters = IlDecompiler.ParseNumber(blobStreamReader); //This field becomes "generic parameters" if type & 10 != 0

            if ((type & 0x10) != 0)
            {
                ret.AmountOfGenericParams = (int)parmaters;
                //The "real" generic param amount
                parmaters = IlDecompiler.ParseNumber(blobStreamReader);
            }


            var returnVal = ReadParam(blobStreamReader, file); //read return value

            ret.ReturnVal = returnVal;

            if (type == 0)
            {
                //Static method
                sig         += "static ";
                ret.IsStatic = true;
            }
            if ((type & 0x20) != 0)
            {
                ret.HasThis = true;
            }
            sig += returnVal.TypeInString;
            sig += " " + FunctionName;
            sig += "(";
            for (ulong i = 0; i < parmaters; i++)
            {
                var parm = ReadParam(blobStreamReader, file);
                ret.Params.Add(parm);
                sig += parm.TypeInString + ", ";
                ret.AmountOfParms++;
            }
            if (parmaters > 0)
            {
                sig = sig.Substring(0, sig.Length - 2); //Remove the last ,
            }
            sig          += ");";
            ret.Signature = sig;
            return(ret);
        }
コード例 #2
0
        internal static MethodSignatureParam ReadParam(BinaryReader r, DotNetFile file)
        {
            string sig;
            var    parm = r.ReadByte();
            MethodSignatureParam ret = new MethodSignatureParam();

            switch (parm)
            {
            case 0x00:
            {
                //end of list
                sig      = "End of list";
                ret.type = StackItemType.Array;         //array maybe?
                break;
            }

            case 0x01:
            {
                sig      = "void";
                ret.type = StackItemType.None;
                break;
            }

            case 0x02:
            {
                sig      = "bool";
                ret.type = StackItemType.Boolean;
                break;
            }

            case 0x03:
            {
                sig      = "char";
                ret.type = StackItemType.Char;
                break;
            }

            case 0x04:
            {
                sig      = "sbyte";
                ret.type = StackItemType.SByte;
                break;
            }

            case 0x05:
            {
                sig      = "byte";
                ret.type = StackItemType.Byte;
                break;
            }

            case 0x06:
            {
                sig      = "short";
                ret.type = StackItemType.Int16;
                break;
            }

            case 0x07:
            {
                sig      = "ushort";
                ret.type = StackItemType.UInt16;
                break;
            }

            case 0x08:
            {
                sig      = "int";
                ret.type = StackItemType.Int32;
                break;
            }

            case 0x09:
            {
                sig      = "uint";
                ret.type = StackItemType.UInt32;
                break;
            }

            case 0x0A:
            {
                sig      = "long";
                ret.type = StackItemType.Int64;
                break;
            }

            case 0x0B:
            {
                sig      = "ulong";
                ret.type = StackItemType.UInt64;
                break;
            }

            case 0x0C:
            {
                sig      = "float";
                ret.type = StackItemType.Float32;
                break;
            }

            case 0x0D:
            {
                sig      = "double";
                ret.type = StackItemType.Float64;
                break;
            }

            case 0x0E:
            {
                sig      = "string";
                ret.type = StackItemType.String;
                break;
            }

            case 0xF:
                //Pointer* (followed by type)
            {
                sig      = ReadParam(r, file).TypeInString + "*";
                ret.type = StackItemType.Int32;
                break;
            }

            case 0x10:
                //byref* //followed by type
            {
                sig      = "ref " + ReadParam(r, file).TypeInString;
                ret.type = StackItemType.Int32;
                break;
            }

            case 0x11:
                //valve type (followed by typedef or typeref token)
            {
                var t = IlDecompiler.ParseNumber(r);         //type of the type
                IlDecompiler.DecodeTypeDefOrRef(t, out uint rowType, out uint index);
                string name;
                string Namespace;
                ret.type    = StackItemType.Object;
                ret.IsClass = true;
                if (rowType == 0)
                {
                    //typedef
                    var tt = file.Backend.Tabels.TypeDefTabel[(int)(index - 1)];
                    name      = file.Backend.ClrStringsStream.GetByOffset(tt.Name);
                    Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.Namespace);

                    //resolve it
                    foreach (var item in file.Types)
                    {
                        if (item.NameSpace == Namespace && item.Name == name)
                        {
                            ret.ClassType = item;
                        }
                    }
                }
                else if (rowType == 1)
                {
                    //typeref
                    var tt = file.Backend.Tabels.TypeRefTabel[(int)(index - 1)];
                    name      = file.Backend.ClrStringsStream.GetByOffset(tt.TypeName);
                    Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.TypeNamespace);
                }
                else
                {
                    throw new NotImplementedException();
                }
                if (!string.IsNullOrEmpty(Namespace))
                {
                    sig = $"{Namespace}.{name}";
                }
                else
                {
                    sig = $"{name}";
                }
                break;
            }

            case 0x12:
                //class followed by typedef or typeref token
            {
                var t = IlDecompiler.ParseNumber(r);         //type of the type
                IlDecompiler.DecodeTypeDefOrRef(t, out uint rowType, out uint index);
                string name;
                string Namespace;
                ret.type    = StackItemType.Object;
                ret.IsClass = true;
                if (rowType == 0)
                {
                    //typedef
                    var tt = file.Backend.Tabels.TypeDefTabel[(int)(index - 1)];
                    name      = file.Backend.ClrStringsStream.GetByOffset(tt.Name);
                    Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.Namespace);

                    //resolve it
                    foreach (var item in file.Types)
                    {
                        if (item.NameSpace == Namespace && item.Name == name)
                        {
                            ret.ClassType = item;
                        }
                    }
                }
                else if (rowType == 1)
                {
                    //typeref
                    var tt = file.Backend.Tabels.TypeRefTabel[(int)(index - 1)];
                    name      = file.Backend.ClrStringsStream.GetByOffset(tt.TypeName);
                    Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.TypeNamespace);
                }
                else
                {
                    throw new NotImplementedException();
                }
                if (!string.IsNullOrEmpty(Namespace))
                {
                    sig = $"{Namespace}.{name}";
                }
                else
                {
                    sig = $"{name}";
                }
                break;
            }

            case 0x13:
                //GENERIC_PARM
            {
                var b = IlDecompiler.ParseNumber(r);
                sig      = "T";
                ret.type = StackItemType.Any;
                break;
            }

            case 0x14:
            {
                sig      = "[][]";
                ret.type = StackItemType.Array;
                break;
            }

            case 0x15:
            {
                //ELEMENT_TYPE_GENERICINST
                var t = IlDecompiler.ParseNumber(r);         //type of the generic type
                var c = IlDecompiler.ParseNumber(r);         //generic type (TypeDefOrRefEncoded)
                var d = IlDecompiler.ParseNumber(r);         //Count of generic args
                IlDecompiler.DecodeTypeDefOrRef((uint)c, out uint rowType, out uint index);
                ret.IsGeneric = true;
                ret.type      = StackItemType.Object;
                List <MethodSignatureParam> @params = new List <MethodSignatureParam>();
                for (ulong i = 0; i < d; i++)
                {
                    @params.Add(ReadParam(r, file));
                }


                if (rowType == 0)
                {
                    //typedef
                    var tt        = file.Backend.Tabels.TypeDefTabel[(int)(index - 1)];
                    var name      = file.Backend.ClrStringsStream.GetByOffset(tt.Name);
                    var Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.Namespace);

                    if (!string.IsNullOrEmpty(Namespace))
                    {
                        sig = $"{Namespace}.{name}<";
                    }
                    else
                    {
                        sig = $"{name}<";
                    }

                    ret.GenericClassNamespace = Namespace;
                    ret.GenericClassName      = name;
                }
                else if (rowType == 1)
                {
                    //typeref
                    var tt        = file.Backend.Tabels.TypeRefTabel[(int)(index - 1)];
                    var name      = file.Backend.ClrStringsStream.GetByOffset(tt.TypeName);
                    var Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.TypeNamespace);

                    if (!string.IsNullOrEmpty(Namespace))
                    {
                        sig = $"{Namespace}.{name}<";
                    }
                    else
                    {
                        sig = $"{name}<";
                    }

                    ret.GenericClassNamespace = Namespace;
                    ret.GenericClassName      = name;
                }
                else
                {
                    throw new NotImplementedException();
                }

                foreach (var item in @params)
                {
                    sig += item.TypeInString + ", ";
                }
                sig  = sig.Substring(0, sig.Length - 2);
                sig += ">";
                break;
            }

            case 0x16:
            {
                //TypedRefrerence structure
                sig      = "TypedReference";
                ret.type = StackItemType.Object;
                break;
            }

            case 0x18:
            {
                //IntPtr
                sig      = "IntPtr";
                ret.type = StackItemType.IntPtr;
                break;
            }

            case 0x19:
            {
                //UIntPtr
                sig      = "UIntPtr";
                ret.type = StackItemType.UIntPtr;
                break;
            }

            case 0x1B:
            {
                sig      = "func ptr";
                ret.type = StackItemType.MethodPtr;
                break;
            }

            case 0x1C:
            {
                sig      = "object";
                ret.type = StackItemType.Object;
                break;
            }

            case 0x1D:
            {
                ret.ArrayType = ReadParam(r, file);
                sig           = ret.ArrayType.TypeInString + "[]";
                ret.type      = StackItemType.Array;
                ret.IsArray   = true;
                break;
            }

            case 0x1E:
                //MVar
                var num = IlDecompiler.ParseNumber(r);
                sig = "T" + num;

                break;

            case 0x20:
                var num2 = IlDecompiler.ParseNumber(r);
                IlDecompiler.DecodeTypeDefOrRef((uint)num2, out uint rowType2, out uint index2);
                sig = "TODO: 0x20";
                break;

            default:
                throw new System.NotImplementedException("Unknown byte: 0x" + parm.ToString("X"));
            }

            ret.TypeInString = sig;
            return(ret);
        }