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 ushort MajorVersion; // Major version
public ushort MinorVersion; // Minor version
public uint Name; // RVA of the name of the DLL
public string DllName; // The actual name of the DLL
public uint DllNameRva; // RVA of the name of the DLL
public string DllName; // The actual name of the DLL
public uint Base; // Ordinal base
public uint NumberOfFunctions; // Number of functions
public uint NumberOfNames; // Number of names

View File

@ -7,7 +7,7 @@ public class ExportedFunction
{
public string Name; // Function name
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 string ForwarderName; // Name of the forwarded function

View File

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

View File

@ -9,7 +9,7 @@ public class ImportedFunction
public ushort Hint; // Hint value
public bool IsOrdinal; // True 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>
/// 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)
// Windows-specific fields
public ulong ImageBase; // Image base address (uint for PE32, ulong for PE32+)
public uint SectionAlignment; // Section alignment
public uint FileAlignment; // File alignment
public ushort MajorOperatingSystemVersion; // Major OS version
public ushort MinorOperatingSystemVersion; // Minor OS version
public ushort MajorImageVersion; // Major image version
public ushort MinorImageVersion; // Minor image version
public ushort MajorSubsystemVersion; // Major subsystem version
public ushort MinorSubsystemVersion; // Minor subsystem version
public uint Win32VersionValue; // Win32 version value
public uint SizeOfImage; // Size of image
public uint SizeOfHeaders; // Size of headers
public uint CheckSum; // Checksum
public ushort Subsystem; // Subsystem
public ushort DllCharacteristics; // DLL characteristics
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 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 uint LoaderFlags; // Loader flags
public uint NumberOfRvaAndSizes; // Number of RVA and sizes
public ulong ImageBase; // Image base address (uint for PE32, ulong for PE32+)
public uint SectionAlignment; // Section alignment
public uint FileAlignment; // File alignment
public ushort MajorOperatingSystemVersion; // Major OS version
public ushort MinorOperatingSystemVersion; // Minor OS version
public ushort MajorImageVersion; // Major image version
public ushort MinorImageVersion; // Minor image version
public ushort MajorSubsystemVersion; // Major subsystem version
public ushort MinorSubsystemVersion; // Minor subsystem version
public uint Win32VersionValue; // Win32 version value
public uint SizeOfImage; // Size of image
public uint SizeOfHeaders; // Size of headers
public uint CheckSum; // Checksum
public ushort Subsystem; // Subsystem
public ushort DllCharacteristics; // DLL characteristics
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 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 uint LoaderFlags; // Loader flags
public uint NumberOfRvaAndSizes; // Number of RVA and sizes
public DataDirectory[] DataDirectories; // Data directories
@ -58,7 +58,7 @@ public class OptionalHeader
SizeOfHeapCommit = 0u;
// Initialize array to avoid nullability warning
DataDirectories = new DataDirectory[0];
DataDirectories = [];
}
/// <summary>

View File

@ -8,35 +8,35 @@ namespace X86Disassembler.PE;
public class PEFormat
{
// DOS Header constants
private const ushort DOS_SIGNATURE = 0x5A4D; // 'MZ'
private const uint PE_SIGNATURE = 0x00004550; // 'PE\0\0'
private const ushort DOS_SIGNATURE = 0x5A4D; // 'MZ'
private const uint PE_SIGNATURE = 0x00004550; // 'PE\0\0'
// Optional Header Magic values
private const ushort PE32_MAGIC = 0x10B; // 32-bit executable
private const ushort PE32PLUS_MAGIC = 0x20B; // 64-bit executable
private const ushort PE32_MAGIC = 0x10B; // 32-bit executable
private const ushort PE32PLUS_MAGIC = 0x20B; // 64-bit executable
// Section characteristics flags
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_READ = 0x40000000; // Section is readable
private const uint IMAGE_SCN_MEM_WRITE = 0x80000000; // Section is writable
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_READ = 0x40000000; // Section is readable
private const uint IMAGE_SCN_MEM_WRITE = 0x80000000; // Section is writable
// Data directories
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_RESOURCE = 2; // Resource 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_BASERELOC = 5; // Base Relocation Table
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_GLOBALPTR = 8; // RVA of GP
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_BOUND_IMPORT = 11; // Bound Import Directory
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_COM_DESCRIPTOR = 14; // COM Runtime descriptor
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_RESOURCE = 2; // Resource 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_BASERELOC = 5; // Base Relocation Table
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_GLOBALPTR = 8; // RVA of GP
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_BOUND_IMPORT = 11; // Bound Import Directory
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_COM_DESCRIPTOR = 14; // COM Runtime descriptor
// PE file data
private byte[] _fileData;
@ -141,7 +141,12 @@ public class PEFormat
uint exportDirSize = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
ExportDirectory = _exportDirectoryParser.Parse(reader, exportDirRva);
ExportedFunctions = _exportDirectoryParser.ParseExportedFunctions(reader, ExportDirectory, exportDirRva, exportDirSize);
ExportedFunctions = _exportDirectoryParser.ParseExportedFunctions(
reader,
ExportDirectory,
exportDirRva,
exportDirSize
);
}
// Parse Import Descriptors
@ -177,7 +182,13 @@ public class PEFormat
SectionHeader section = SectionHeaders[sectionIndex];
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;
}
@ -210,7 +221,8 @@ public class PEFormat
for (int i = 0; i < SectionHeaders.Count; i++)
{
if (SectionHeaders[i].ContainsCode())
if (SectionHeaders[i]
.ContainsCode())
{
codeSections.Add(i);
}

View File

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

View File

@ -50,11 +50,11 @@ public class ImportDescriptorParser
ImportDescriptor descriptor = new ImportDescriptor
{
OriginalFirstThunk = originalFirstThunk,
OriginalFirstThunkRva = originalFirstThunk,
TimeDateStamp = timeDateStamp,
ForwarderChain = forwarderChain,
Name = nameRva,
FirstThunk = firstThunk,
DllNameRva = nameRva,
FirstThunkRva = firstThunk,
DllName = "Unknown" // Default name in case we can't read it
};
@ -111,7 +111,7 @@ public class ImportDescriptorParser
try
{
// 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)
{
@ -133,7 +133,7 @@ public class ImportDescriptorParser
ImportedFunction function = new ImportedFunction
{
ThunkRVA = thunkRva + (uint)(functionCount * 4)
ThunkRva = thunkRva + (uint)(functionCount * 4)
};
// 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++)
{
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})");
}
}