using System.Runtime.InteropServices; namespace BinaryObjectScanner.Models.PortableExecutable { /// /// The symbol table in this section is inherited from the traditional /// COFF format. It is distinct from Microsoft Visual C++ debug information. /// A file can contain both a COFF symbol table and Visual C++ debug /// information, and the two are kept separate. Some Microsoft tools use /// the symbol table for limited but important purposes, such as /// communicating COMDAT information to the linker. Section names and file /// names, as well as code and data symbols, are listed in the symbol table. /// /// The location of the symbol table is indicated in the COFF header. /// /// The symbol table is an array of records, each 18 bytes long. Each record /// is either a standard or auxiliary symbol-table record. A standard record /// defines a symbol or name. /// /// public sealed class COFFSymbolTableEntry { #region Standard COFF Symbol Table Entry #region Symbol Name /// /// An array of 8 bytes. This array is padded with nulls on the right if /// the name is less than 8 bytes long. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] public byte[] ShortName; /// /// A field that is set to all zeros if the name is longer than 8 bytes. /// public uint Zeroes; /// /// An offset into the string table. /// public uint Offset; #endregion /// /// The value that is associated with the symbol. The interpretation of this /// field depends on SectionNumber and StorageClass. A typical meaning is the /// relocatable address. /// public uint Value; /// /// The signed integer that identifies the section, using a one-based index /// into the section table. Some values have special meaning. /// public ushort SectionNumber; /// /// A number that represents type. Microsoft tools set this field to 0x20 /// (function) or 0x0 (not a function). /// public SymbolType SymbolType; /// /// An enumerated value that represents storage class. /// public StorageClass StorageClass; /// /// The number of auxiliary symbol table entries that follow this record. /// public byte NumberOfAuxSymbols; #endregion #region Auxiliary Symbol Records // Auxiliary symbol table records always follow, and apply to, some standard // symbol table record. An auxiliary record can have any format that the tools // can recognize, but 18 bytes must be allocated for them so that symbol table // is maintained as an array of regular size. Currently, Microsoft tools // recognize auxiliary formats for the following kinds of records: function // definitions, function begin and end symbols (.bf and .ef), weak externals, // file names, and section definitions. // // The traditional COFF design also includes auxiliary-record formats for arrays // and structures.Microsoft tools do not use these, but instead place that // symbolic information in Visual C++ debug format in the debug sections. #region Auxiliary Format 1: Function Definitions // A symbol table record marks the beginning of a function definition if it // has all of the following: a storage class of EXTERNAL (2), a Type value // that indicates it is a function (0x20), and a section number that is // greater than zero. Note that a symbol table record that has a section // number of UNDEFINED (0) does not define the function and does not have // an auxiliary record. Function-definition symbol records are followed by // an auxiliary record in the format described below: /// /// The symbol-table index of the corresponding .bf (begin function) /// symbol record. /// public uint AuxFormat1TagIndex; /// /// The size of the executable code for the function itself. If the function /// is in its own section, the SizeOfRawData in the section header is greater /// or equal to this field, depending on alignment considerations. /// public uint AuxFormat1TotalSize; /// /// The file offset of the first COFF line-number entry for the function, or /// zero if none exists. /// public uint AuxFormat1PointerToLinenumber; /// /// The symbol-table index of the record for the next function. If the function /// is the last in the symbol table, this field is set to zero. /// public uint AuxFormat1PointerToNextFunction; /// /// Unused /// public ushort AuxFormat1Unused; #endregion #region Auxiliary Format 2: .bf and .ef Symbols // For each function definition in the symbol table, three items describe // the beginning, ending, and number of lines. Each of these symbols has // storage class FUNCTION (101): // // A symbol record named .bf (begin function). The Value field is unused. // // A symbol record named .lf (lines in function). The Value field gives the // number of lines in the function. // // A symbol record named .ef (end of function). The Value field has the same // number as the Total Size field in the function-definition symbol record. // // The .bf and .ef symbol records (but not .lf records) are followed by an // auxiliary record with the following format: /// /// Unused /// public uint AuxFormat2Unused1; /// /// The actual ordinal line number (1, 2, 3, and so on) within the source file, /// corresponding to the .bf or .ef record. /// public ushort AuxFormat2Linenumber; /// /// Unused /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] public byte[] AuxFormat2Unused2; /// /// The symbol-table index of the next .bf symbol record. If the function is the /// last in the symbol table, this field is set to zero. It is not used for /// .ef records. /// public uint AuxFormat2PointerToNextFunction; /// /// Unused /// public ushort AuxFormat2Unused3; #endregion #region Auxiliary Format 3: Weak Externals // "Weak externals" are a mechanism for object files that allows flexibility at // link time. A module can contain an unresolved external symbol (sym1), but it // can also include an auxiliary record that indicates that if sym1 is not // present at link time, another external symbol (sym2) is used to resolve // references instead. // // If a definition of sym1 is linked, then an external reference to the symbol // is resolved normally. If a definition of sym1 is not linked, then all references // to the weak external for sym1 refer to sym2 instead. The external symbol, sym2, // must always be linked; typically, it is defined in the module that contains // the weak reference to sym1. // // Weak externals are represented by a symbol table record with EXTERNAL storage // class, UNDEF section number, and a value of zero. The weak-external symbol // record is followed by an auxiliary record with the following format: /// /// The symbol-table index of sym2, the symbol to be linked if sym1 is not found. /// public uint AuxFormat3TagIndex; /// /// A value of IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY indicates that no library search /// for sym1 should be performed. /// A value of IMAGE_WEAK_EXTERN_SEARCH_LIBRARY indicates that a library search for /// sym1 should be performed. /// A value of IMAGE_WEAK_EXTERN_SEARCH_ALIAS indicates that sym1 is an alias for sym2. /// public uint AuxFormat3Characteristics; /// /// Unused /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] public byte[] AuxFormat3Unused; #endregion #region Auxiliary Format 4: Files // This format follows a symbol-table record with storage class FILE (103). // The symbol name itself should be .file, and the auxiliary record that // follows it gives the name of a source-code file. /// /// An ANSI string that gives the name of the source file. This is padded /// with nulls if it is less than the maximum length. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 18)] public byte[] AuxFormat4FileName; #endregion #region Auxiliary Format 5: Section Definitions // This format follows a symbol-table record that defines a section. Such a // record has a symbol name that is the name of a section (such as .text or // .drectve) and has storage class STATIC (3). The auxiliary record provides // information about the section to which it refers. Thus, it duplicates some // of the information in the section header. /// /// The size of section data; the same as SizeOfRawData in the section header. /// public uint AuxFormat5Length; /// /// The number of relocation entries for the section. /// public ushort AuxFormat5NumberOfRelocations; /// /// The number of line-number entries for the section. /// public ushort AuxFormat5NumberOfLinenumbers; /// /// The checksum for communal data. It is applicable if the IMAGE_SCN_LNK_COMDAT /// flag is set in the section header. /// public uint AuxFormat5CheckSum; /// /// One-based index into the section table for the associated section. This is /// used when the COMDAT selection setting is 5. /// public ushort AuxFormat5Number; /// /// The COMDAT selection number. This is applicable if the section is a /// COMDAT section. /// public byte AuxFormat5Selection; /// /// Unused /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3)] public byte[] AuxFormat5Unused; #endregion #region Auxiliary Format 6: CLR Token Definition (Object Only) // This auxiliary symbol generally follows the IMAGE_SYM_CLASS_CLR_TOKEN. It is // used to associate a token with the COFF symbol table's namespace. /// /// Must be IMAGE_AUX_SYMBOL_TYPE_TOKEN_DEF (1). /// public byte AuxFormat6AuxType; /// /// Reserved, must be zero. /// public byte AuxFormat6Reserved1; /// /// The symbol index of the COFF symbol to which this CLR token definition refers. /// public uint AuxFormat6SymbolTableIndex; /// /// Reserved, must be zero. /// [MarshalAs(UnmanagedType.ByValArray, SizeConst = 12)] public byte[] AuxFormat6Reserved2; #endregion #endregion } }