public static ExportTable Load(PEImage image)
        {
            if (image == null)
            {
                return(null);
            }

            var dd = image.Directories[DataDirectories.ExportTable];

            if (dd.IsNull)
            {
                return(null);
            }

            var table = new ExportTable();

            using (var accessor = image.OpenImageToSectionData(dd.RVA))
            {
                Load(accessor, image, table);
            }

            return(table);
        }
        private static unsafe void Load(IBinaryAccessor accessor, PEImage image, ExportTable table)
        {
            ExportTableHeader header;

            fixed(byte *pBuff = accessor.ReadBytes(sizeof(ExportTableHeader)))
            {
                header = *(ExportTableHeader *)pBuff;
            }

            table._ordinalBase   = (int)header.Base;
            table._timeDateStamp = ConvertUtils.ToDateTime(header.TimeDateStamp);

            // Name
            accessor.Position = image.ResolvePositionToSectionData(header.Name);
            table._dllName    = accessor.ReadNullTerminatedString(Encoding.ASCII);

            if (header.AddressOfFunctions != 0)
            {
                // Export Address Table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfFunctions);
                uint[] arrayOfExportRVA = new uint[header.NumberOfFunctions];
                for (int i = 0; i < header.NumberOfFunctions; i++)
                {
                    arrayOfExportRVA[i] = accessor.ReadUInt32();
                }

                // Name pointer table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfNames);
                uint[] arrayOfNameRVA = new uint[header.NumberOfNames];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    arrayOfNameRVA[i] = accessor.ReadUInt32();
                }

                // Ordinal table
                accessor.Position = image.ResolvePositionToSectionData(header.AddressOfNameOrdinals);
                ushort[] arrayOfOrdinals = new ushort[header.NumberOfNames];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    arrayOfOrdinals[i] = accessor.ReadUInt16();
                }

                // Read names and map against export rva
                string[] names = new string[header.NumberOfFunctions];
                for (int i = 0; i < header.NumberOfNames; i++)
                {
                    accessor.Position = image.ResolvePositionToSectionData(arrayOfNameRVA[i]);
                    string name = accessor.ReadNullTerminatedString(Encoding.ASCII);

                    int ordinal = arrayOfOrdinals[i];
                    names[ordinal] = name;
                }

                var exportDirectory = image.Directories[DataDirectories.ExportTable];

                // Build entries
                for (int i = 0; i < header.NumberOfFunctions; i++)
                {
                    uint   exportRVA = arrayOfExportRVA[i];
                    string name      = names[i];

                    ExportEntry entry;

                    // Each entry in the export address table is a field that uses one of two formats in the
                    // following table. If the address specified is not within the export section (as defined
                    // by the address and length that are indicated in the optional header), the field is an
                    // export RVA, which is an actual address in code or data. Otherwise, the field is a
                    // forwarder RVA, which names a symbol in another DLL.
                    if (exportDirectory.Contains(exportRVA))
                    {
                        accessor.Position = image.ResolvePositionToSectionData(exportRVA);
                        string forwarder = accessor.ReadNullTerminatedString(Encoding.ASCII);
                        entry = new ExportForwarderEntry(name, forwarder);
                    }
                    else
                    {
                        entry = new ExportRVAEntry(name, exportRVA);
                    }

                    entry._parent = table;
                    table._list.Add(entry);
                }
            }
        }