Unmangles methods and data objects whose names have been mangled using Microsoft's mangling algorithm.
Microsoft doesn't document the mangling format, but reverse engineering has been done, resulting in: http://www.kegel.com/mangle.html http://www.agner.org/optimize/calling_conventions.pdf
Exemplo n.º 1
0
 public static Tuple <string, DataType, SerializedType> InferTypeFromName(string fnName, TypeLibraryDeserializer loader, IPlatform platform)
 {
     if (fnName[0] == '?')
     {
         // Microsoft-mangled signatures begin with '?'
         var pmnp = new MsMangledNameParser(fnName);
         Tuple <string, SerializedType, SerializedType> field = null;
         try
         {
             field = pmnp.Parse();
         }
         catch (Exception ex)
         {
             Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message);
             return(null);
         }
         var sproc = field.Item2 as SerializedSignature;
         if (sproc != null)
         {
             var sser = platform.CreateProcedureSerializer(loader, sproc.Convention);
             var sig  = sser.Deserialize(sproc, platform.Architecture.CreateFrame());   //$BUGBUG: catch dupes?
             return(new Tuple <string, DataType, SerializedType>(
                        field.Item1,
                        sig,
                        field.Item3));
         }
         else
         {
             var dt = field.Item2.Accept(loader);
             return(Tuple.Create(field.Item1, dt, field.Item3));
         }
     }
     return(null);
 }
Exemplo n.º 2
0
 /// <summary>
 /// Guesses the signature of a procedure based on its name.
 /// </summary>
 /// <param name="fnName"></param>
 /// <param name="loader"></param>
 /// <param name="arch"></param>
 /// <returns></returns>
 public static ExternalProcedure SignatureFromName(string fnName, TypeLibraryDeserializer loader, IPlatform platform)
 {
     int argBytes;
     if (fnName[0] == '_')
     {
         // Win32 prefixes cdecl and stdcall functions with '_'. Stdcalls will have @<nn> 
         // where <nn> is the number of bytes pushed on the stack. If 0 bytes are pushed
         // the result is indistinguishable from the corresponding cdecl call, which is OK.
         int lastAt = fnName.LastIndexOf('@');
         if (lastAt < 0)
             return CdeclSignature(fnName.Substring(1), platform.Architecture);
         string name = fnName.Substring(1, lastAt - 1);
         if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
             return CdeclSignature(name, platform.Architecture);
         else
             return StdcallSignature(name, argBytes, platform.Architecture);
     }
     else if (fnName[0] == '@')
     {
         // Win32 prefixes fastcall functions with '@'.
         int lastAt = fnName.LastIndexOf('@');
         if (lastAt <= 0)
             return CdeclSignature(fnName.Substring(1), platform.Architecture);
         string name = fnName.Substring(1, lastAt - 1);
         if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
             return CdeclSignature(name, platform.Architecture);
         else
             return FastcallSignature(name, argBytes, platform.Architecture);
     }
     else if (fnName[0] == '?')
     {
         // Microsoft-mangled signatures begin with '?'
         var pmnp = new MsMangledNameParser(fnName);
         StructField_v1 field = null;
         try
         {
             field = pmnp.Parse();
         }
         catch (Exception ex)
         {
             Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message);
             return null;
         }
         var sproc = field.Type as SerializedSignature;
         if (sproc != null)
         {
             var sser = platform.CreateProcedureSerializer(loader, sproc.Convention);
             var sig = sser.Deserialize(sproc, platform.Architecture.CreateFrame());    //$BUGBUG: catch dupes?
             return new ExternalProcedure(field.Name, sig)
             {
                 EnclosingType = sproc.EnclosingType
             };
         }
     }
     return null;
 }
Exemplo n.º 3
0
 public static (string?, SerializedType?, SerializedType?) InferTypeFromName(string fnName)
 {
     if (fnName[0] == '?')
     {
         // Microsoft-mangled signatures begin with '?'
         var pmnp = new MsMangledNameParser(fnName);
         try
         {
             var field = pmnp.Parse();
             return(field);
         }
         catch (Exception ex)
         {
             Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message);
             return(null, null, null);
         }
     }
     return(null, null, null);
 }
Exemplo n.º 4
0
 public TemplateParser(MsMangledNameParser outer)
 {
     this.outer = outer;
 }
Exemplo n.º 5
0
 public TemplateParser(MsMangledNameParser outer)
 {
     this.outer = outer;
 }
Exemplo n.º 6
0
        /// <summary>
        /// Guesses the signature of a procedure based on its name.
        /// </summary>
        /// <param name="fnName"></param>
        /// <param name="loader"></param>
        /// <param name="arch"></param>
        /// <returns></returns>
        public static ProcedureBase_v1?SignatureFromName(string fnName, IPlatform platform)
        {
            int argBytes;

            if (fnName[0] == '_')
            {
                // Win32 prefixes cdecl and stdcall functions with '_'. Stdcalls will have @<nn>
                // where <nn> is the number of bytes pushed on the stack. If 0 bytes are pushed
                // the result is indistinguishable from the corresponding cdecl call, which is OK.
                int lastAt = fnName.LastIndexOf('@');
                if (lastAt < 0)
                {
                    return(CdeclSignature(fnName.Substring(1), platform.Architecture));
                }
                string name = fnName.Substring(1, lastAt - 1);
                if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
                {
                    return(CdeclSignature(name, platform.Architecture));
                }
                else
                {
                    return(StdcallSignature(name, argBytes, platform.Architecture));
                }
            }
            else if (fnName[0] == '@')
            {
                // Borland-mangled signatures begin with '@'.
                var bmnp  = new BorlandMangledNamedParser(fnName);
                var field = bmnp.Parse();
                if (field.Item1 != null)
                {
                    var sproc = field.Item2 as SerializedSignature;
                    if (sproc != null)
                    {
                        return(new Procedure_v1
                        {
                            Name = field.Item1,
                            Signature = sproc,
                        });
                    }
                    throw new NotImplementedException();
                }
                // Win32 prefixes fastcall functions with '@'.
                int lastAt = fnName.LastIndexOf('@');
                if (lastAt <= 0)
                {
                    return(CdeclSignature(fnName.Substring(1), platform.Architecture));
                }
                string name = fnName.Substring(1, lastAt - 1);
                if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
                {
                    return(CdeclSignature(fnName, platform.Architecture));
                }
                else
                {
                    return(FastcallSignature(name, argBytes, platform.Architecture));
                }
            }
            else if (fnName[0] == '?')
            {
                // Microsoft-mangled signatures begin with '?'
                var pmnp = new MsMangledNameParser(fnName);
                (string?, SerializedType?, SerializedType?)field;
                try
                {
                    field = pmnp.Parse();
                }
                catch (Exception ex)
                {
                    Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message);
                    return(null);
                }
                var sproc = field.Item2 as SerializedSignature;
                if (sproc != null)
                {
                    return(new Procedure_v1 {
                        Name = field.Item1,
                        Signature = sproc,
                    });
                }
            }
            return(null);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Guesses the signature of a procedure based on its name.
        /// </summary>
        /// <param name="fnName"></param>
        /// <param name="loader"></param>
        /// <param name="arch"></param>
        /// <returns></returns>
        public static ExternalProcedure SignatureFromName(string fnName, TypeLibraryDeserializer loader, IPlatform platform)
        {
            int argBytes;

            if (fnName[0] == '_')
            {
                // Win32 prefixes cdecl and stdcall functions with '_'. Stdcalls will have @<nn>
                // where <nn> is the number of bytes pushed on the stack. If 0 bytes are pushed
                // the result is indistinguishable from the corresponding cdecl call, which is OK.
                int lastAt = fnName.LastIndexOf('@');
                if (lastAt < 0)
                {
                    return(CdeclSignature(fnName.Substring(1), platform.Architecture));
                }
                string name = fnName.Substring(1, lastAt - 1);
                if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
                {
                    return(CdeclSignature(name, platform.Architecture));
                }
                else
                {
                    return(StdcallSignature(name, argBytes, platform.Architecture));
                }
            }
            else if (fnName[0] == '@')
            {
                // Win32 prefixes fastcall functions with '@'.
                int lastAt = fnName.LastIndexOf('@');
                if (lastAt <= 0)
                {
                    return(CdeclSignature(fnName.Substring(1), platform.Architecture));
                }
                string name = fnName.Substring(1, lastAt - 1);
                if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes))
                {
                    return(CdeclSignature(name, platform.Architecture));
                }
                else
                {
                    return(FastcallSignature(name, argBytes, platform.Architecture));
                }
            }
            else if (fnName[0] == '?')
            {
                // Microsoft-mangled signatures begin with '?'
                var            pmnp  = new MsMangledNameParser(fnName);
                StructField_v1 field = null;
                try
                {
                    field = pmnp.Parse();
                }
                catch (Exception ex)
                {
                    Debug.Print("*** Error parsing {0}. {1}", fnName, ex.Message);
                    return(null);
                }
                var sproc = field.Type as SerializedSignature;
                if (sproc != null)
                {
                    var sser = platform.CreateProcedureSerializer(loader, sproc.Convention);
                    var sig  = sser.Deserialize(sproc, platform.Architecture.CreateFrame());   //$BUGBUG: catch dupes?
                    return(new ExternalProcedure(field.Name, sig)
                    {
                        EnclosingType = sproc.EnclosingType
                    });
                }
            }
            return(null);
        }