/// <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 ProcedureSignature SignatureFromName(string fnName, TypeLibraryLoader loader, IProcessorArchitecture arch) { 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), arch); string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) return CdeclSignature(name, arch); else return StdcallSignature(name, argBytes, arch); } else if (fnName[0] == '@') { // Win32 prefixes fastcall functions with '@'. int lastAt = fnName.LastIndexOf('@'); if (lastAt <= 0) return CdeclSignature(fnName.Substring(1), arch); string name = fnName.Substring(1, lastAt - 1); if (!Int32.TryParse(fnName.Substring(lastAt + 1), out argBytes)) return CdeclSignature(name, arch); else return FastcallSignature(name, argBytes, arch); } 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); pmnp.ToString(); return null; } var sproc = field.Type as SerializedSignature; if (sproc != null) { var sser = arch.CreateProcedureSerializer(loader, "__cdecl"); return sser.Deserialize(sproc, arch.CreateFrame()); //$BUGBUG: catch dupes? } } return null; }
public TemplateParser(MsMangledNameParser outer) { this.outer = outer; }