0
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-06-19 16:08:02 +03:00

clarify rva members

This commit is contained in:
bird_egop
2025-04-12 18:49:23 +03:00
parent d73cccd3c5
commit 60f63c2c06
10 changed files with 132 additions and 101 deletions

19
.windsurfrules Normal file
View File

@ -0,0 +1,19 @@
when creating or edditing code, adjust namespace declaration style to oneliner, e.g. "namespace MyNamespace;".
always separate usings, namespaces, type declarations, methods and properties with empty line.
always add comments to the code, when the code is not trivial.
always put classes into separate files.
always try to build the project you've edited.
always summarize the changes you've made.
always add changes to git with descriptive comment, but be concise.
never use terminal commands to edit code. In case of a failure, write it to user and stop execution.
never address compiler warnings yourself. If you see a warning, suggest to address it.
when working with RVA variables, always add that to variable name, e.g. "nameRVA".

View File

@ -9,8 +9,8 @@ public class ExportDirectory
public uint TimeDateStamp; // Time and date stamp public uint TimeDateStamp; // Time and date stamp
public ushort MajorVersion; // Major version public ushort MajorVersion; // Major version
public ushort MinorVersion; // Minor version public ushort MinorVersion; // Minor version
public uint Name; // RVA of the name of the DLL public uint DllNameRva; // RVA of the name of the DLL
public string DllName; // The actual name of the DLL public string DllName; // The actual name of the DLL
public uint Base; // Ordinal base public uint Base; // Ordinal base
public uint NumberOfFunctions; // Number of functions public uint NumberOfFunctions; // Number of functions
public uint NumberOfNames; // Number of names public uint NumberOfNames; // Number of names

View File

@ -7,7 +7,7 @@ public class ExportedFunction
{ {
public string Name; // Function name public string Name; // Function name
public ushort Ordinal; // Function ordinal public ushort Ordinal; // Function ordinal
public uint Address; // Function RVA public uint AddressRva; // Function RVA
public bool IsForwarder; // True if this is a forwarder public bool IsForwarder; // True if this is a forwarder
public string ForwarderName; // Name of the forwarded function public string ForwarderName; // Name of the forwarded function

View File

@ -5,12 +5,12 @@ namespace X86Disassembler.PE;
/// </summary> /// </summary>
public class ImportDescriptor public class ImportDescriptor
{ {
public uint OriginalFirstThunk; // RVA to original first thunk public uint OriginalFirstThunkRva; // RVA to original first thunk
public uint TimeDateStamp; // Time and date stamp public uint TimeDateStamp; // Time and date stamp
public uint ForwarderChain; // Forwarder chain public uint ForwarderChain; // Forwarder chain
public uint Name; // RVA to the name of the DLL public uint DllNameRva; // RVA to the name of the DLL
public string DllName; // The actual name of the DLL public string DllName; // The actual name of the DLL
public uint FirstThunk; // RVA to first thunk public uint FirstThunkRva; // RVA to first thunk
public List<ImportedFunction> Functions { get; } = new List<ImportedFunction>(); public List<ImportedFunction> Functions { get; } = new List<ImportedFunction>();

View File

@ -9,7 +9,7 @@ public class ImportedFunction
public ushort Hint; // Hint value public ushort Hint; // Hint value
public bool IsOrdinal; // True if imported by ordinal public bool IsOrdinal; // True if imported by ordinal
public ushort Ordinal; // Ordinal value (if imported by ordinal) public ushort Ordinal; // Ordinal value (if imported by ordinal)
public uint ThunkRVA; // RVA of the thunk for this function public uint ThunkRva; // RVA of the thunk for this function
/// <summary> /// <summary>
/// Initializes a new instance of the ImportedFunction class /// Initializes a new instance of the ImportedFunction class

View File

@ -21,27 +21,27 @@ public class OptionalHeader
public uint BaseOfData; // Base of data section (PE32 only) public uint BaseOfData; // Base of data section (PE32 only)
// Windows-specific fields // Windows-specific fields
public ulong ImageBase; // Image base address (uint for PE32, ulong for PE32+) public ulong ImageBase; // Image base address (uint for PE32, ulong for PE32+)
public uint SectionAlignment; // Section alignment public uint SectionAlignment; // Section alignment
public uint FileAlignment; // File alignment public uint FileAlignment; // File alignment
public ushort MajorOperatingSystemVersion; // Major OS version public ushort MajorOperatingSystemVersion; // Major OS version
public ushort MinorOperatingSystemVersion; // Minor OS version public ushort MinorOperatingSystemVersion; // Minor OS version
public ushort MajorImageVersion; // Major image version public ushort MajorImageVersion; // Major image version
public ushort MinorImageVersion; // Minor image version public ushort MinorImageVersion; // Minor image version
public ushort MajorSubsystemVersion; // Major subsystem version public ushort MajorSubsystemVersion; // Major subsystem version
public ushort MinorSubsystemVersion; // Minor subsystem version public ushort MinorSubsystemVersion; // Minor subsystem version
public uint Win32VersionValue; // Win32 version value public uint Win32VersionValue; // Win32 version value
public uint SizeOfImage; // Size of image public uint SizeOfImage; // Size of image
public uint SizeOfHeaders; // Size of headers public uint SizeOfHeaders; // Size of headers
public uint CheckSum; // Checksum public uint CheckSum; // Checksum
public ushort Subsystem; // Subsystem public ushort Subsystem; // Subsystem
public ushort DllCharacteristics; // DLL characteristics public ushort DllCharacteristics; // DLL characteristics
public ulong SizeOfStackReserve; // Size of stack reserve (uint for PE32, ulong for PE32+) public ulong SizeOfStackReserve; // Size of stack reserve (uint for PE32, ulong for PE32+)
public ulong SizeOfStackCommit; // Size of stack commit (uint for PE32, ulong for PE32+) public ulong SizeOfStackCommit; // Size of stack commit (uint for PE32, ulong for PE32+)
public ulong SizeOfHeapReserve; // Size of heap reserve (uint for PE32, ulong for PE32+) public ulong SizeOfHeapReserve; // Size of heap reserve (uint for PE32, ulong for PE32+)
public ulong SizeOfHeapCommit; // Size of heap commit (uint for PE32, ulong for PE32+) public ulong SizeOfHeapCommit; // Size of heap commit (uint for PE32, ulong for PE32+)
public uint LoaderFlags; // Loader flags public uint LoaderFlags; // Loader flags
public uint NumberOfRvaAndSizes; // Number of RVA and sizes public uint NumberOfRvaAndSizes; // Number of RVA and sizes
public DataDirectory[] DataDirectories; // Data directories public DataDirectory[] DataDirectories; // Data directories
@ -58,7 +58,7 @@ public class OptionalHeader
SizeOfHeapCommit = 0u; SizeOfHeapCommit = 0u;
// Initialize array to avoid nullability warning // Initialize array to avoid nullability warning
DataDirectories = new DataDirectory[0]; DataDirectories = [];
} }
/// <summary> /// <summary>

View File

@ -8,39 +8,39 @@ namespace X86Disassembler.PE;
public class PEFormat public class PEFormat
{ {
// DOS Header constants // DOS Header constants
private const ushort DOS_SIGNATURE = 0x5A4D; // 'MZ' private const ushort DOS_SIGNATURE = 0x5A4D; // 'MZ'
private const uint PE_SIGNATURE = 0x00004550; // 'PE\0\0' private const uint PE_SIGNATURE = 0x00004550; // 'PE\0\0'
// Optional Header Magic values // Optional Header Magic values
private const ushort PE32_MAGIC = 0x10B; // 32-bit executable private const ushort PE32_MAGIC = 0x10B; // 32-bit executable
private const ushort PE32PLUS_MAGIC = 0x20B; // 64-bit executable private const ushort PE32PLUS_MAGIC = 0x20B; // 64-bit executable
// Section characteristics flags // Section characteristics flags
private const uint IMAGE_SCN_CNT_CODE = 0x00000020; // Section contains code private const uint IMAGE_SCN_CNT_CODE = 0x00000020; // Section contains code
private const uint IMAGE_SCN_MEM_EXECUTE = 0x20000000; // Section is executable private const uint IMAGE_SCN_MEM_EXECUTE = 0x20000000; // Section is executable
private const uint IMAGE_SCN_MEM_READ = 0x40000000; // Section is readable private const uint IMAGE_SCN_MEM_READ = 0x40000000; // Section is readable
private const uint IMAGE_SCN_MEM_WRITE = 0x80000000; // Section is writable private const uint IMAGE_SCN_MEM_WRITE = 0x80000000; // Section is writable
// Data directories // Data directories
private const int IMAGE_DIRECTORY_ENTRY_EXPORT = 0; // Export Directory private const int IMAGE_DIRECTORY_ENTRY_EXPORT = 0; // Export Directory
private const int IMAGE_DIRECTORY_ENTRY_IMPORT = 1; // Import Directory private const int IMAGE_DIRECTORY_ENTRY_IMPORT = 1; // Import Directory
private const int IMAGE_DIRECTORY_ENTRY_RESOURCE = 2; // Resource Directory private const int IMAGE_DIRECTORY_ENTRY_RESOURCE = 2; // Resource Directory
private const int IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3; // Exception Directory private const int IMAGE_DIRECTORY_ENTRY_EXCEPTION = 3; // Exception Directory
private const int IMAGE_DIRECTORY_ENTRY_SECURITY = 4; // Security Directory private const int IMAGE_DIRECTORY_ENTRY_SECURITY = 4; // Security Directory
private const int IMAGE_DIRECTORY_ENTRY_BASERELOC = 5; // Base Relocation Table private const int IMAGE_DIRECTORY_ENTRY_BASERELOC = 5; // Base Relocation Table
private const int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; // Debug Directory private const int IMAGE_DIRECTORY_ENTRY_DEBUG = 6; // Debug Directory
private const int IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7; // Architecture Specific Data private const int IMAGE_DIRECTORY_ENTRY_ARCHITECTURE = 7; // Architecture Specific Data
private const int IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8; // RVA of GP private const int IMAGE_DIRECTORY_ENTRY_GLOBALPTR = 8; // RVA of GP
private const int IMAGE_DIRECTORY_ENTRY_TLS = 9; // TLS Directory private const int IMAGE_DIRECTORY_ENTRY_TLS = 9; // TLS Directory
private const int IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10; // Load Configuration Directory private const int IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG = 10; // Load Configuration Directory
private const int IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11; // Bound Import Directory private const int IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT = 11; // Bound Import Directory
private const int IMAGE_DIRECTORY_ENTRY_IAT = 12; // Import Address Table private const int IMAGE_DIRECTORY_ENTRY_IAT = 12; // Import Address Table
private const int IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13; // Delay Load Import Descriptors private const int IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT = 13; // Delay Load Import Descriptors
private const int IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14; // COM Runtime descriptor private const int IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR = 14; // COM Runtime descriptor
// PE file data // PE file data
private byte[] _fileData; private byte[] _fileData;
// Parser instances // Parser instances
private readonly DOSHeaderParser _dosHeaderParser; private readonly DOSHeaderParser _dosHeaderParser;
private readonly FileHeaderParser _fileHeaderParser; private readonly FileHeaderParser _fileHeaderParser;
@ -49,19 +49,19 @@ public class PEFormat
private PEUtility _peUtility; private PEUtility _peUtility;
private ExportDirectoryParser _exportDirectoryParser; private ExportDirectoryParser _exportDirectoryParser;
private ImportDescriptorParser _importDescriptorParser; private ImportDescriptorParser _importDescriptorParser;
// Parsed headers // Parsed headers
public DOSHeader DosHeader { get; private set; } public DOSHeader DosHeader { get; private set; }
public FileHeader FileHeader { get; private set; } public FileHeader FileHeader { get; private set; }
public OptionalHeader OptionalHeader { get; private set; } public OptionalHeader OptionalHeader { get; private set; }
public List<SectionHeader> SectionHeaders { get; private set; } public List<SectionHeader> SectionHeaders { get; private set; }
public bool Is64Bit { get; private set; } public bool Is64Bit { get; private set; }
// Export and Import information // Export and Import information
public ExportDirectory ExportDirectory { get; private set; } public ExportDirectory ExportDirectory { get; private set; }
public List<ExportedFunction> ExportedFunctions { get; private set; } public List<ExportedFunction> ExportedFunctions { get; private set; }
public List<ImportDescriptor> ImportDescriptors { get; private set; } public List<ImportDescriptor> ImportDescriptors { get; private set; }
/// <summary> /// <summary>
/// Initializes a new instance of the PEFormat class /// Initializes a new instance of the PEFormat class
/// </summary> /// </summary>
@ -72,25 +72,25 @@ public class PEFormat
SectionHeaders = new List<SectionHeader>(); SectionHeaders = new List<SectionHeader>();
ExportedFunctions = new List<ExportedFunction>(); ExportedFunctions = new List<ExportedFunction>();
ImportDescriptors = new List<ImportDescriptor>(); ImportDescriptors = new List<ImportDescriptor>();
// Initialize parsers // Initialize parsers
_dosHeaderParser = new DOSHeaderParser(); _dosHeaderParser = new DOSHeaderParser();
_fileHeaderParser = new FileHeaderParser(); _fileHeaderParser = new FileHeaderParser();
_optionalHeaderParser = new OptionalHeaderParser(); _optionalHeaderParser = new OptionalHeaderParser();
_sectionHeaderParser = new SectionHeaderParser(); _sectionHeaderParser = new SectionHeaderParser();
// Initialize properties to avoid nullability warnings // Initialize properties to avoid nullability warnings
DosHeader = new DOSHeader(); DosHeader = new DOSHeader();
FileHeader = new FileHeader(); FileHeader = new FileHeader();
OptionalHeader = new OptionalHeader(); OptionalHeader = new OptionalHeader();
ExportDirectory = new ExportDirectory(); ExportDirectory = new ExportDirectory();
// These will be initialized during Parse() // These will be initialized during Parse()
_peUtility = null!; _peUtility = null!;
_exportDirectoryParser = null!; _exportDirectoryParser = null!;
_importDescriptorParser = null!; _importDescriptorParser = null!;
} }
/// <summary> /// <summary>
/// Parses the PE file structure /// Parses the PE file structure
/// </summary> /// </summary>
@ -104,55 +104,60 @@ public class PEFormat
{ {
// Parse DOS header // Parse DOS header
DosHeader = _dosHeaderParser.Parse(reader); DosHeader = _dosHeaderParser.Parse(reader);
// Move to PE header // Move to PE header
reader.BaseStream.Seek(DosHeader.e_lfanew, SeekOrigin.Begin); reader.BaseStream.Seek(DosHeader.e_lfanew, SeekOrigin.Begin);
// Verify PE signature // Verify PE signature
uint peSignature = reader.ReadUInt32(); uint peSignature = reader.ReadUInt32();
if (peSignature != PE_SIGNATURE) if (peSignature != PE_SIGNATURE)
{ {
throw new InvalidDataException("Invalid PE signature"); throw new InvalidDataException("Invalid PE signature");
} }
// Parse File Header // Parse File Header
FileHeader = _fileHeaderParser.Parse(reader); FileHeader = _fileHeaderParser.Parse(reader);
// Parse Optional Header // Parse Optional Header
OptionalHeader = _optionalHeaderParser.Parse(reader); OptionalHeader = _optionalHeaderParser.Parse(reader);
Is64Bit = OptionalHeader.Is64Bit(); Is64Bit = OptionalHeader.Is64Bit();
// Parse Section Headers // Parse Section Headers
for (int i = 0; i < FileHeader.NumberOfSections; i++) for (int i = 0; i < FileHeader.NumberOfSections; i++)
{ {
SectionHeaders.Add(_sectionHeaderParser.Parse(reader)); SectionHeaders.Add(_sectionHeaderParser.Parse(reader));
} }
// Initialize utility after section headers are parsed // Initialize utility after section headers are parsed
_peUtility = new PEUtility(SectionHeaders, OptionalHeader.SizeOfHeaders); _peUtility = new PEUtility(SectionHeaders, OptionalHeader.SizeOfHeaders);
_exportDirectoryParser = new ExportDirectoryParser(_peUtility); _exportDirectoryParser = new ExportDirectoryParser(_peUtility);
_importDescriptorParser = new ImportDescriptorParser(_peUtility); _importDescriptorParser = new ImportDescriptorParser(_peUtility);
// Parse Export Directory // Parse Export Directory
if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_EXPORT && if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_EXPORT &&
OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != 0) OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != 0)
{ {
uint exportDirRva = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; uint exportDirRva = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
uint exportDirSize = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; uint exportDirSize = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
ExportDirectory = _exportDirectoryParser.Parse(reader, exportDirRva); ExportDirectory = _exportDirectoryParser.Parse(reader, exportDirRva);
ExportedFunctions = _exportDirectoryParser.ParseExportedFunctions(reader, ExportDirectory, exportDirRva, exportDirSize); ExportedFunctions = _exportDirectoryParser.ParseExportedFunctions(
reader,
ExportDirectory,
exportDirRva,
exportDirSize
);
} }
// Parse Import Descriptors // Parse Import Descriptors
if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_IMPORT && if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_IMPORT &&
OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != 0) OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != 0)
{ {
uint importDirRva = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; uint importDirRva = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
ImportDescriptors = _importDescriptorParser.Parse(reader, importDirRva); ImportDescriptors = _importDescriptorParser.Parse(reader, importDirRva);
} }
} }
return true; return true;
} }
catch (Exception ex) catch (Exception ex)
@ -161,7 +166,7 @@ public class PEFormat
return false; return false;
} }
} }
/// <summary> /// <summary>
/// Gets the raw data for a specific section /// Gets the raw data for a specific section
/// </summary> /// </summary>
@ -173,15 +178,21 @@ public class PEFormat
{ {
throw new ArgumentOutOfRangeException(nameof(sectionIndex)); throw new ArgumentOutOfRangeException(nameof(sectionIndex));
} }
SectionHeader section = SectionHeaders[sectionIndex]; SectionHeader section = SectionHeaders[sectionIndex];
byte[] sectionData = new byte[section.SizeOfRawData]; byte[] sectionData = new byte[section.SizeOfRawData];
Array.Copy(_fileData, section.PointerToRawData, sectionData, 0, section.SizeOfRawData); Array.Copy(
_fileData,
section.PointerToRawData,
sectionData,
0,
section.SizeOfRawData
);
return sectionData; return sectionData;
} }
/// <summary> /// <summary>
/// Gets the raw data for a section by name /// Gets the raw data for a section by name
/// </summary> /// </summary>
@ -196,10 +207,10 @@ public class PEFormat
return GetSectionData(i); return GetSectionData(i);
} }
} }
throw new ArgumentException($"Section '{sectionName}' not found"); throw new ArgumentException($"Section '{sectionName}' not found");
} }
/// <summary> /// <summary>
/// Gets all code sections /// Gets all code sections
/// </summary> /// </summary>
@ -207,18 +218,19 @@ public class PEFormat
public List<int> GetCodeSections() public List<int> GetCodeSections()
{ {
List<int> codeSections = new List<int>(); List<int> codeSections = new List<int>();
for (int i = 0; i < SectionHeaders.Count; i++) for (int i = 0; i < SectionHeaders.Count; i++)
{ {
if (SectionHeaders[i].ContainsCode()) if (SectionHeaders[i]
.ContainsCode())
{ {
codeSections.Add(i); codeSections.Add(i);
} }
} }
return codeSections; return codeSections;
} }
/// <summary> /// <summary>
/// Checks if a section contains code /// Checks if a section contains code
/// </summary> /// </summary>

View File

@ -30,7 +30,7 @@ public class ExportDirectoryParser
directory.TimeDateStamp = reader.ReadUInt32(); directory.TimeDateStamp = reader.ReadUInt32();
directory.MajorVersion = reader.ReadUInt16(); directory.MajorVersion = reader.ReadUInt16();
directory.MinorVersion = reader.ReadUInt16(); directory.MinorVersion = reader.ReadUInt16();
directory.Name = reader.ReadUInt32(); directory.DllNameRva = reader.ReadUInt32();
directory.Base = reader.ReadUInt32(); directory.Base = reader.ReadUInt32();
directory.NumberOfFunctions = reader.ReadUInt32(); directory.NumberOfFunctions = reader.ReadUInt32();
directory.NumberOfNames = reader.ReadUInt32(); directory.NumberOfNames = reader.ReadUInt32();
@ -41,7 +41,7 @@ public class ExportDirectoryParser
// Read the DLL name // Read the DLL name
try try
{ {
uint dllNameRVA = directory.Name; uint dllNameRVA = directory.DllNameRva;
uint dllNameOffset = _utility.RvaToOffset(dllNameRVA); uint dllNameOffset = _utility.RvaToOffset(dllNameRVA);
reader.BaseStream.Seek(dllNameOffset, SeekOrigin.Begin); reader.BaseStream.Seek(dllNameOffset, SeekOrigin.Begin);
@ -134,7 +134,7 @@ public class ExportDirectoryParser
ExportedFunction function = new ExportedFunction(); ExportedFunction function = new ExportedFunction();
function.Ordinal = (ushort)(i + directory.Base); function.Ordinal = (ushort)(i + directory.Base);
function.Address = functionRVA; function.AddressRva = functionRVA;
// Check if this function has a name // Check if this function has a name
if (ordinalToName.TryGetValue(i, out string? name)) if (ordinalToName.TryGetValue(i, out string? name))

View File

@ -50,11 +50,11 @@ public class ImportDescriptorParser
ImportDescriptor descriptor = new ImportDescriptor ImportDescriptor descriptor = new ImportDescriptor
{ {
OriginalFirstThunk = originalFirstThunk, OriginalFirstThunkRva = originalFirstThunk,
TimeDateStamp = timeDateStamp, TimeDateStamp = timeDateStamp,
ForwarderChain = forwarderChain, ForwarderChain = forwarderChain,
Name = nameRva, DllNameRva = nameRva,
FirstThunk = firstThunk, FirstThunkRva = firstThunk,
DllName = "Unknown" // Default name in case we can't read it DllName = "Unknown" // Default name in case we can't read it
}; };
@ -111,7 +111,7 @@ public class ImportDescriptorParser
try try
{ {
// Use OriginalFirstThunk if available, otherwise use FirstThunk // Use OriginalFirstThunk if available, otherwise use FirstThunk
uint thunkRva = descriptor.OriginalFirstThunk != 0 ? descriptor.OriginalFirstThunk : descriptor.FirstThunk; uint thunkRva = descriptor.OriginalFirstThunkRva != 0 ? descriptor.OriginalFirstThunkRva : descriptor.FirstThunkRva;
if (thunkRva == 0) if (thunkRva == 0)
{ {
@ -133,7 +133,7 @@ public class ImportDescriptorParser
ImportedFunction function = new ImportedFunction ImportedFunction function = new ImportedFunction
{ {
ThunkRVA = thunkRva + (uint)(functionCount * 4) ThunkRva = thunkRva + (uint)(functionCount * 4)
}; };
// Check if imported by ordinal (high bit set) // Check if imported by ordinal (high bit set)

View File

@ -99,7 +99,7 @@ internal class Program
for (int i = 0; i < peFormat.ExportedFunctions.Count; i++) for (int i = 0; i < peFormat.ExportedFunctions.Count; i++)
{ {
var function = peFormat.ExportedFunctions[i]; var function = peFormat.ExportedFunctions[i];
Console.WriteLine($" {i}: {function.Name} (Ordinal={function.Ordinal}, RVA=0x{function.Address:X8})"); Console.WriteLine($" {i}: {function.Name} (Ordinal={function.Ordinal}, RVA=0x{function.AddressRva:X8})");
} }
} }