Ejemplo n.º 1
0
        public IlDecompiler(DotNetMethod method)
        {
            if (method == null)
            {
                throw new ArgumentException("method");
            }

            m        = method;
            mainFile = m.File;
            code     = m.GetBody();
            AddReference(m.Parent.File);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Makes things much easier for the DoStartMethod() function
        /// </summary>
        /// <param name="m"></param>
        /// <param name="args"></param>
        // All of the Opcodes that have additional parameters have to be processed here.
        private void ProcessMethod(DotNetMethod m, params string[] args)
        {
            byte[] code = m.GetBody();
            List <ILInstruction> inr = new List <ILInstruction>();

            for (int i = 0; i < code.Length; i++)
            {
                byte opCode = code[i];

                if (opCode == (byte)OpCodes.Ldstr)
                {
                    //Decode the number
                    byte   first = code[i + 1]; //1st index
                    byte   sec   = code[i + 2]; //2nd
                    byte   third = code[i + 3];
                    byte   forth = code[i + 4];
                    byte[] num   = new byte[] { first, sec, third, 0 };
                    var    numb  = BitConverter.ToInt32(num, 0);

                    //Get the string
                    string s;

                    //Microsoft does really good documentation on front-end things. For example: Windows Apis, and the dot net framework.
                    //But, They don't do backend documentation, for example: Decoding this string token.
                    //I have to go through 100,000+ lines of code in the .NET Clr to figure out how these string tokens work and still didnt figure it out.

                    if (forth != 112)
                    {
                        //Will this ever be in the String Stream?
                        s = file.Backend.ClrStringsStream.GetByOffset((uint)numb);
                    }
                    else
                    {
                        //US stream

                        //This is only a temp. hack
                        s = file.Backend.ClrUsStream.GetByOffset((uint)numb);
                    }
                    int rid = numb & 0x00ffffff; //Not sure weather this is needed, but I found it in the CLR
                    i += 4;                      //skip past the string

                    inr.Add(new ILInstruction()
                    {
                        OpCode  = OpCodes.Ldstr,
                        Operand = s
                    });
                }
                else if (opCode == OpCodes.Call)
                {
                    try
                    {
                        byte   fi   = code[i + 1];
                        byte   s    = code[i + 2];
                        byte   t    = code[i + 3];
                        byte   f    = code[i + 4];
                        byte[] num  = new byte[] { fi, s, t, f };
                        short  numb = BitConverter.ToInt16(num, 0); //Method Token


                        //Get the method that we are calling
                        var c = file.Backend.tabels.MemberRefTabelRow[numb - 1]; //is the -1 needed?

                        i += 4;                                                  //skip past the string
                        #region Decode
                        //Decode the class bytes
                        uint tabel;
                        uint row;
                        DecodeMemberRefParent(c.Class, out tabel, out row);


                        var    funcName = file.Backend.ClrStringsStream.GetByOffset(c.Name);
                        string classs;
                        string Namespace;

                        //TYPE def
                        if (tabel == 02)
                        {
                            var tt = file.Backend.tabels.TypeDefTabel[(int)row - 1];

                            classs    = file.Backend.ClrStringsStream.GetByOffset(tt.Name);
                            Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.Namespace);
                        }
                        //Type REF
                        else if (tabel == 01)
                        {
                            var tt = file.Backend.tabels.TypeRefTabel[(int)row - 1];

                            classs    = file.Backend.ClrStringsStream.GetByOffset(tt.TypeName);
                            Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.TypeNamespace);
                        }
                        //Module Ref
                        else if (tabel == 26)
                        {
                            //var tt = file.Backend.MetaDataStreamTablesHeader.Tables.ModuleRef[(int)row - 1];

                            //classs = file.Backend.ClrStringsStream.GetByOffset(tt.Name);
                            //Namespace = file.Backend.ClrStringsStream.GetByOffset(tt.Namespace);
                            Console.WriteLine("Module Ref not supported!");
                            classs    = "<Module Ref>";
                            Namespace = "<Module Ref>";
                        }
                        //Unknown
                        else
                        {
                            classs    = "<unknown>";
                            Namespace = "<unknown>";
                        }
                        #endregion
                        var inst = new ILInstruction()
                        {
                            OpCode = OpCodes.Call,
                            DecompilerExtraData = numb
                        };
                        inst.Operand = new CallMethodDataHolder()
                        {
                            ClassName = classs, NameSpace = Namespace, FunctionName = funcName
                        };


                        inr.Add(inst);
                    }
                    catch { }
                }
                else
                {
                    inr.Add(new ILInstruction()
                    {
                        OpCode = opCode
                    });
                }
            }
            //After decoding, start the method
            DoStartMethod(inr, args);
        }