From ee7773871397945e2686494aa8e937b34e78d5ff Mon Sep 17 00:00:00 2001 From: bird_egop Date: Mon, 18 Aug 2025 21:57:18 +0300 Subject: [PATCH] remove leftovers --- ParkanPlayground.sln | 6 - X86Disassembler/PEFormat.cs | 834 ------------------------- X86Disassembler/Program.cs | 153 ----- X86Disassembler/X86Disassembler.csproj | 10 - 4 files changed, 1003 deletions(-) delete mode 100644 X86Disassembler/PEFormat.cs delete mode 100644 X86Disassembler/Program.cs delete mode 100644 X86Disassembler/X86Disassembler.csproj diff --git a/ParkanPlayground.sln b/ParkanPlayground.sln index 932cc48..c437615 100644 --- a/ParkanPlayground.sln +++ b/ParkanPlayground.sln @@ -28,8 +28,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VarsetLib", "VarsetLib\Vars EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Visualisator", "Visualisator\Visualisator.csproj", "{667A7E03-5CAA-4591-9980-F6C722911A35}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "X86Disassembler", "X86Disassembler\X86Disassembler.csproj", "{B5C2E94A-0F63-4E09-BC04-F2518E2CC1F0}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -84,9 +82,5 @@ Global {667A7E03-5CAA-4591-9980-F6C722911A35}.Debug|Any CPU.Build.0 = Debug|Any CPU {667A7E03-5CAA-4591-9980-F6C722911A35}.Release|Any CPU.ActiveCfg = Release|Any CPU {667A7E03-5CAA-4591-9980-F6C722911A35}.Release|Any CPU.Build.0 = Release|Any CPU - {B5C2E94A-0F63-4E09-BC04-F2518E2CC1F0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {B5C2E94A-0F63-4E09-BC04-F2518E2CC1F0}.Debug|Any CPU.Build.0 = Debug|Any CPU - {B5C2E94A-0F63-4E09-BC04-F2518E2CC1F0}.Release|Any CPU.ActiveCfg = Release|Any CPU - {B5C2E94A-0F63-4E09-BC04-F2518E2CC1F0}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection EndGlobal diff --git a/X86Disassembler/PEFormat.cs b/X86Disassembler/PEFormat.cs deleted file mode 100644 index a66ddc2..0000000 --- a/X86Disassembler/PEFormat.cs +++ /dev/null @@ -1,834 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; - -namespace X86Disassembler -{ - /// - /// Represents a Portable Executable (PE) file format parser - /// - public class PEFormat - { - // DOS Header constants - 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 - - // 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 - - // 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 - - // PE file data - private byte[] _fileData; - - // Parsed headers - public DOSHeader DosHeader { get; private set; } - public FileHeader FileHeader { get; private set; } - public OptionalHeader OptionalHeader { get; private set; } - public List SectionHeaders { get; private set; } - public bool Is64Bit { get; private set; } - - // Export and Import information - public ExportDirectory ExportDirectory { get; private set; } - public List ExportedFunctions { get; private set; } - public List ImportDescriptors { get; private set; } - - /// - /// Parses a PE file from the given byte array - /// - /// The raw file data - public PEFormat(byte[] fileData) - { - _fileData = fileData; - SectionHeaders = new List(); - ExportedFunctions = new List(); - ImportDescriptors = new List(); - Parse(); - } - - /// - /// Parses the PE file structure - /// - private void Parse() - { - using (MemoryStream stream = new MemoryStream(_fileData)) - using (BinaryReader reader = new BinaryReader(stream)) - { - // Parse DOS header - DosHeader = ParseDOSHeader(reader); - - // Move to PE header - reader.BaseStream.Seek(DosHeader.e_lfanew, SeekOrigin.Begin); - - // Verify PE signature - uint peSignature = reader.ReadUInt32(); - if (peSignature != PE_SIGNATURE) - { - throw new InvalidDataException("Invalid PE signature"); - } - - // Parse File Header - FileHeader = ParseFileHeader(reader); - - // Parse Optional Header - OptionalHeader = ParseOptionalHeader(reader); - - // Parse Section Headers - for (int i = 0; i < FileHeader.NumberOfSections; i++) - { - SectionHeaders.Add(ParseSectionHeader(reader)); - } - - // Parse Export Directory - if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_EXPORT && - OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress != 0) - { - ExportDirectory = ParseExportDirectory(reader, OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); - ParseExportedFunctions(reader); - } - - // Parse Import Descriptors - if (OptionalHeader.DataDirectories.Length > IMAGE_DIRECTORY_ENTRY_IMPORT && - OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress != 0) - { - ImportDescriptors = ParseImportDescriptors(reader, OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); - } - } - } - - /// - /// Parses the DOS header - /// - private DOSHeader ParseDOSHeader(BinaryReader reader) - { - DOSHeader header = new DOSHeader(); - - header.e_magic = reader.ReadUInt16(); - if (header.e_magic != DOS_SIGNATURE) - { - throw new InvalidDataException("Invalid DOS signature (MZ)"); - } - - header.e_cblp = reader.ReadUInt16(); - header.e_cp = reader.ReadUInt16(); - header.e_crlc = reader.ReadUInt16(); - header.e_cparhdr = reader.ReadUInt16(); - header.e_minalloc = reader.ReadUInt16(); - header.e_maxalloc = reader.ReadUInt16(); - header.e_ss = reader.ReadUInt16(); - header.e_sp = reader.ReadUInt16(); - header.e_csum = reader.ReadUInt16(); - header.e_ip = reader.ReadUInt16(); - header.e_cs = reader.ReadUInt16(); - header.e_lfarlc = reader.ReadUInt16(); - header.e_ovno = reader.ReadUInt16(); - - header.e_res = new ushort[4]; - for (int i = 0; i < 4; i++) - { - header.e_res[i] = reader.ReadUInt16(); - } - - header.e_oemid = reader.ReadUInt16(); - header.e_oeminfo = reader.ReadUInt16(); - - header.e_res2 = new ushort[10]; - for (int i = 0; i < 10; i++) - { - header.e_res2[i] = reader.ReadUInt16(); - } - - header.e_lfanew = reader.ReadUInt32(); - - return header; - } - - /// - /// Parses the File header - /// - private FileHeader ParseFileHeader(BinaryReader reader) - { - FileHeader header = new FileHeader(); - - header.Machine = reader.ReadUInt16(); - header.NumberOfSections = reader.ReadUInt16(); - header.TimeDateStamp = reader.ReadUInt32(); - header.PointerToSymbolTable = reader.ReadUInt32(); - header.NumberOfSymbols = reader.ReadUInt32(); - header.SizeOfOptionalHeader = reader.ReadUInt16(); - header.Characteristics = reader.ReadUInt16(); - - return header; - } - - /// - /// Parses the Optional header - /// - private OptionalHeader ParseOptionalHeader(BinaryReader reader) - { - OptionalHeader header = new OptionalHeader(); - - // Standard fields - header.Magic = reader.ReadUInt16(); - - // Determine if this is a PE32 or PE32+ file - Is64Bit = header.Magic == PE32PLUS_MAGIC; - - header.MajorLinkerVersion = reader.ReadByte(); - header.MinorLinkerVersion = reader.ReadByte(); - header.SizeOfCode = reader.ReadUInt32(); - header.SizeOfInitializedData = reader.ReadUInt32(); - header.SizeOfUninitializedData = reader.ReadUInt32(); - header.AddressOfEntryPoint = reader.ReadUInt32(); - header.BaseOfCode = reader.ReadUInt32(); - - // PE32 has BaseOfData, PE32+ doesn't - if (!Is64Bit) - { - header.BaseOfData = reader.ReadUInt32(); - } - - // Windows-specific fields - if (Is64Bit) - { - header.ImageBase = reader.ReadUInt64(); - } - else - { - header.ImageBase = reader.ReadUInt32(); - } - - header.SectionAlignment = reader.ReadUInt32(); - header.FileAlignment = reader.ReadUInt32(); - header.MajorOperatingSystemVersion = reader.ReadUInt16(); - header.MinorOperatingSystemVersion = reader.ReadUInt16(); - header.MajorImageVersion = reader.ReadUInt16(); - header.MinorImageVersion = reader.ReadUInt16(); - header.MajorSubsystemVersion = reader.ReadUInt16(); - header.MinorSubsystemVersion = reader.ReadUInt16(); - header.Win32VersionValue = reader.ReadUInt32(); - header.SizeOfImage = reader.ReadUInt32(); - header.SizeOfHeaders = reader.ReadUInt32(); - header.CheckSum = reader.ReadUInt32(); - header.Subsystem = reader.ReadUInt16(); - header.DllCharacteristics = reader.ReadUInt16(); - - // Size fields differ between PE32 and PE32+ - if (Is64Bit) - { - header.SizeOfStackReserve = reader.ReadUInt64(); - header.SizeOfStackCommit = reader.ReadUInt64(); - header.SizeOfHeapReserve = reader.ReadUInt64(); - header.SizeOfHeapCommit = reader.ReadUInt64(); - } - else - { - header.SizeOfStackReserve = reader.ReadUInt32(); - header.SizeOfStackCommit = reader.ReadUInt32(); - header.SizeOfHeapReserve = reader.ReadUInt32(); - header.SizeOfHeapCommit = reader.ReadUInt32(); - } - - header.LoaderFlags = reader.ReadUInt32(); - header.NumberOfRvaAndSizes = reader.ReadUInt32(); - - // Data directories - int numDirectories = (int)Math.Min(header.NumberOfRvaAndSizes, 16); // Maximum of 16 directories - header.DataDirectories = new DataDirectory[numDirectories]; - - for (int i = 0; i < numDirectories; i++) - { - DataDirectory dir = new DataDirectory(); - dir.VirtualAddress = reader.ReadUInt32(); - dir.Size = reader.ReadUInt32(); - header.DataDirectories[i] = dir; - } - - return header; - } - - /// - /// Parses a section header - /// - private SectionHeader ParseSectionHeader(BinaryReader reader) - { - SectionHeader header = new SectionHeader(); - - // Read section name (8 bytes) - byte[] nameBytes = reader.ReadBytes(8); - // Convert to string, removing any null characters - header.Name = Encoding.ASCII.GetString(nameBytes).TrimEnd('\0'); - - header.VirtualSize = reader.ReadUInt32(); - header.VirtualAddress = reader.ReadUInt32(); - header.SizeOfRawData = reader.ReadUInt32(); - header.PointerToRawData = reader.ReadUInt32(); - header.PointerToRelocations = reader.ReadUInt32(); - header.PointerToLinenumbers = reader.ReadUInt32(); - header.NumberOfRelocations = reader.ReadUInt16(); - header.NumberOfLinenumbers = reader.ReadUInt16(); - header.Characteristics = reader.ReadUInt32(); - - return header; - } - - /// - /// Parses the Export Directory - /// - private ExportDirectory ParseExportDirectory(BinaryReader reader, uint rva) - { - ExportDirectory directory = new ExportDirectory(); - - reader.BaseStream.Seek(RvaToOffset(rva), SeekOrigin.Begin); - - directory.Characteristics = reader.ReadUInt32(); - directory.TimeDateStamp = reader.ReadUInt32(); - directory.MajorVersion = reader.ReadUInt16(); - directory.MinorVersion = reader.ReadUInt16(); - directory.Name = reader.ReadUInt32(); - directory.Base = reader.ReadUInt32(); - directory.NumberOfFunctions = reader.ReadUInt32(); - directory.NumberOfNames = reader.ReadUInt32(); - directory.AddressOfFunctions = reader.ReadUInt32(); - directory.AddressOfNames = reader.ReadUInt32(); - directory.AddressOfNameOrdinals = reader.ReadUInt32(); - - // Read the DLL name - uint dllNameRVA = directory.Name; - reader.BaseStream.Seek(RvaToOffset(dllNameRVA), SeekOrigin.Begin); - byte[] dllNameBytes = reader.ReadBytes(256); - directory.DllName = Encoding.ASCII.GetString(dllNameBytes).TrimEnd('\0'); - - return directory; - } - - /// - /// Parses the Import Descriptors - /// - private List ParseImportDescriptors(BinaryReader reader, uint rva) - { - List descriptors = new List(); - - try - { - reader.BaseStream.Seek(RvaToOffset(rva), SeekOrigin.Begin); - - while (true) - { - ImportDescriptor descriptor = new ImportDescriptor(); - - descriptor.OriginalFirstThunk = reader.ReadUInt32(); - descriptor.TimeDateStamp = reader.ReadUInt32(); - descriptor.ForwarderChain = reader.ReadUInt32(); - descriptor.Name = reader.ReadUInt32(); - descriptor.FirstThunk = reader.ReadUInt32(); - - // Check if we've reached the end of the import descriptors - if (descriptor.OriginalFirstThunk == 0 && descriptor.Name == 0 && descriptor.FirstThunk == 0) - { - break; - } - - try - { - // Read the DLL name - uint dllNameOffset = RvaToOffset(descriptor.Name); - reader.BaseStream.Seek(dllNameOffset, SeekOrigin.Begin); - - List nameBytes = new List(); - byte b; - while ((b = reader.ReadByte()) != 0) - { - nameBytes.Add(b); - } - descriptor.DllName = Encoding.ASCII.GetString(nameBytes.ToArray()); - - // Read the imported functions (use FirstThunk if OriginalFirstThunk is 0) - uint thunkRVA = descriptor.OriginalFirstThunk != 0 ? descriptor.OriginalFirstThunk : descriptor.FirstThunk; - - if (thunkRVA != 0) - { - try - { - uint thunkOffset = RvaToOffset(thunkRVA); - uint currentThunkOffset = thunkOffset; - - while (true) - { - reader.BaseStream.Seek(currentThunkOffset, SeekOrigin.Begin); - uint thunk = reader.ReadUInt32(); - - if (thunk == 0) - { - break; - } - - ImportedFunction function = new ImportedFunction(); - function.ThunkRVA = thunkRVA + (currentThunkOffset - thunkOffset); - - // Check if the function is imported by ordinal - if ((thunk & 0x80000000) != 0) - { - function.IsOrdinal = true; - function.Ordinal = (ushort)(thunk & 0xFFFF); - function.Name = $"Ordinal_{function.Ordinal}"; - } - else - { - // Read the function name and hint - try - { - uint nameOffset = RvaToOffset(thunk); - reader.BaseStream.Seek(nameOffset, SeekOrigin.Begin); - - function.Hint = reader.ReadUInt16(); - - List funcNameBytes = new List(); - byte c; - while ((c = reader.ReadByte()) != 0) - { - funcNameBytes.Add(c); - } - function.Name = Encoding.ASCII.GetString(funcNameBytes.ToArray()); - } - catch (Exception) - { - function.Name = $"Function_at_{thunk:X8}"; - } - } - - descriptor.Functions.Add(function); - - currentThunkOffset += 4; // Move to the next thunk - } - } - catch (Exception) - { - // Skip this thunk table if there's an error - } - } - } - catch (Exception) - { - // If we can't read the DLL name, use a placeholder - descriptor.DllName = $"DLL_at_{descriptor.Name:X8}"; - } - - descriptors.Add(descriptor); - } - } - catch (Exception) - { - // Return whatever descriptors we've managed to parse - } - - return descriptors; - } - - /// - /// Parses the exported functions using the export directory information - /// - private void ParseExportedFunctions(BinaryReader reader) - { - if (ExportDirectory == null) - { - return; - } - - // Read the array of function addresses (RVAs) - uint[] functionRVAs = new uint[ExportDirectory.NumberOfFunctions]; - reader.BaseStream.Seek(RvaToOffset(ExportDirectory.AddressOfFunctions), SeekOrigin.Begin); - for (int i = 0; i < ExportDirectory.NumberOfFunctions; i++) - { - functionRVAs[i] = reader.ReadUInt32(); - } - - // Read the array of name RVAs - uint[] nameRVAs = new uint[ExportDirectory.NumberOfNames]; - reader.BaseStream.Seek(RvaToOffset(ExportDirectory.AddressOfNames), SeekOrigin.Begin); - for (int i = 0; i < ExportDirectory.NumberOfNames; i++) - { - nameRVAs[i] = reader.ReadUInt32(); - } - - // Read the array of name ordinals - ushort[] nameOrdinals = new ushort[ExportDirectory.NumberOfNames]; - reader.BaseStream.Seek(RvaToOffset(ExportDirectory.AddressOfNameOrdinals), SeekOrigin.Begin); - for (int i = 0; i < ExportDirectory.NumberOfNames; i++) - { - nameOrdinals[i] = reader.ReadUInt16(); - } - - // Create a dictionary to map ordinals to names - Dictionary ordinalToName = new Dictionary(); - for (int i = 0; i < ExportDirectory.NumberOfNames; i++) - { - // Read the function name - reader.BaseStream.Seek(RvaToOffset(nameRVAs[i]), SeekOrigin.Begin); - List nameBytes = new List(); - byte b; - while ((b = reader.ReadByte()) != 0) - { - nameBytes.Add(b); - } - string name = Encoding.ASCII.GetString(nameBytes.ToArray()); - - // Map the ordinal to the name - ordinalToName[nameOrdinals[i]] = name; - } - - // Create the exported functions - for (ushort i = 0; i < ExportDirectory.NumberOfFunctions; i++) - { - uint functionRVA = functionRVAs[i]; - if (functionRVA == 0) - { - continue; // Skip empty entries - } - - ExportedFunction function = new ExportedFunction(); - function.Ordinal = (ushort)(i + ExportDirectory.Base); - function.Address = functionRVA; - - // Check if this function has a name - if (ordinalToName.TryGetValue(i, out string name)) - { - function.Name = name; - } - else - { - function.Name = $"Ordinal_{function.Ordinal}"; - } - - // Check if this is a forwarder - uint exportDirStart = OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress; - uint exportDirEnd = exportDirStart + OptionalHeader.DataDirectories[IMAGE_DIRECTORY_ENTRY_EXPORT].Size; - - if (functionRVA >= exportDirStart && functionRVA < exportDirEnd) - { - function.IsForwarder = true; - - // Read the forwarder string - reader.BaseStream.Seek(RvaToOffset(functionRVA), SeekOrigin.Begin); - List forwarderBytes = new List(); - byte b; - while ((b = reader.ReadByte()) != 0) - { - forwarderBytes.Add(b); - } - function.ForwarderName = Encoding.ASCII.GetString(forwarderBytes.ToArray()); - } - - ExportedFunctions.Add(function); - } - } - - /// - /// Gets the raw data for a specific section - /// - /// Index of the section - /// Byte array containing the section data - public byte[] GetSectionData(int sectionIndex) - { - if (sectionIndex < 0 || sectionIndex >= SectionHeaders.Count) - { - throw new ArgumentOutOfRangeException(nameof(sectionIndex)); - } - - SectionHeader section = SectionHeaders[sectionIndex]; - byte[] sectionData = new byte[section.SizeOfRawData]; - - Array.Copy(_fileData, section.PointerToRawData, sectionData, 0, section.SizeOfRawData); - - return sectionData; - } - - /// - /// Gets the raw data for a section by name - /// - /// Name of the section - /// Byte array containing the section data - public byte[] GetSectionData(string sectionName) - { - for (int i = 0; i < SectionHeaders.Count; i++) - { - if (SectionHeaders[i].Name == sectionName) - { - return GetSectionData(i); - } - } - - throw new ArgumentException($"Section '{sectionName}' not found"); - } - - /// - /// Checks if a section contains code - /// - /// The section to check - /// True if the section contains code, false otherwise - public bool IsSectionContainsCode(SectionHeader section) - { - return (section.Characteristics & IMAGE_SCN_CNT_CODE) != 0 || - (section.Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0; - } - - /// - /// Gets all code sections - /// - /// List of section indices that contain code - public List GetCodeSections() - { - List codeSections = new List(); - - for (int i = 0; i < SectionHeaders.Count; i++) - { - if (IsSectionContainsCode(SectionHeaders[i])) - { - codeSections.Add(i); - } - } - - return codeSections; - } - - /// - /// Converts a Relative Virtual Address (RVA) to a file offset - /// - /// The RVA to convert - /// The corresponding file offset - public uint RvaToOffset(uint rva) - { - if (rva == 0) - { - return 0; - } - - foreach (var section in SectionHeaders) - { - // Check if the RVA is within this section - if (rva >= section.VirtualAddress && rva < section.VirtualAddress + section.VirtualSize) - { - // Calculate the offset within the section - uint offsetInSection = rva - section.VirtualAddress; - - // Make sure we don't exceed the raw data size - if (offsetInSection < section.SizeOfRawData) - { - return section.PointerToRawData + offsetInSection; - } - } - } - - // If the RVA is not within any section, it might be in the headers - if (rva < OptionalHeader.SizeOfHeaders) - { - return rva; - } - - throw new ArgumentException($"RVA {rva:X8} is not within any section"); - } - } - - #region PE Format Structures - - /// - /// DOS Header structure - /// - public class DOSHeader - { - public ushort e_magic; // Magic number ("MZ") - public ushort e_cblp; // Bytes on last page of file - public ushort e_cp; // Pages in file - public ushort e_crlc; // Relocations - public ushort e_cparhdr; // Size of header in paragraphs - public ushort e_minalloc; // Minimum extra paragraphs needed - public ushort e_maxalloc; // Maximum extra paragraphs needed - public ushort e_ss; // Initial (relative) SS value - public ushort e_sp; // Initial SP value - public ushort e_csum; // Checksum - public ushort e_ip; // Initial IP value - public ushort e_cs; // Initial (relative) CS value - public ushort e_lfarlc; // File address of relocation table - public ushort e_ovno; // Overlay number - public ushort[] e_res; // Reserved words - public ushort e_oemid; // OEM identifier - public ushort e_oeminfo; // OEM information - public ushort[] e_res2; // Reserved words - public uint e_lfanew; // File address of new exe header - } - - /// - /// File Header structure - /// - public class FileHeader - { - public ushort Machine; // Target machine type - public ushort NumberOfSections; // Number of sections - public uint TimeDateStamp; // Time stamp - public uint PointerToSymbolTable; // File offset of symbol table - public uint NumberOfSymbols; // Number of symbols - public ushort SizeOfOptionalHeader; // Size of optional header - public ushort Characteristics; // Characteristics - } - - /// - /// Optional Header structure - /// - public class OptionalHeader - { - // Standard fields - public ushort Magic; // Magic number (PE32 or PE32+) - public byte MajorLinkerVersion; // Major linker version - public byte MinorLinkerVersion; // Minor linker version - public uint SizeOfCode; // Size of code section - public uint SizeOfInitializedData; // Size of initialized data - public uint SizeOfUninitializedData; // Size of uninitialized data - public uint AddressOfEntryPoint; // Entry point RVA - public uint BaseOfCode; // Base of code section - public uint BaseOfData; // Base of data section (PE32 only) - - // Windows-specific fields - public dynamic ImageBase; // Preferred image base (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 dynamic SizeOfStackReserve; // Size of stack reserve (uint for PE32, ulong for PE32+) - public dynamic SizeOfStackCommit; // Size of stack commit (uint for PE32, ulong for PE32+) - public dynamic SizeOfHeapReserve; // Size of heap reserve (uint for PE32, ulong for PE32+) - public dynamic SizeOfHeapCommit; // Size of heap commit (uint for PE32, ulong for PE32+) - public uint LoaderFlags; // Loader flags - public uint NumberOfRvaAndSizes; // Number of data directories - - // Data directories - public DataDirectory[] DataDirectories; // Data directories - } - - /// - /// Data Directory structure - /// - public class DataDirectory - { - public uint VirtualAddress; // RVA of the directory - public uint Size; // Size of the directory - } - - /// - /// Section Header structure - /// - public class SectionHeader - { - public string Name; // Section name - public uint VirtualSize; // Virtual size - public uint VirtualAddress; // Virtual address (RVA) - public uint SizeOfRawData; // Size of raw data - public uint PointerToRawData; // File pointer to raw data - public uint PointerToRelocations; // File pointer to relocations - public uint PointerToLinenumbers; // File pointer to line numbers - public ushort NumberOfRelocations; // Number of relocations - public ushort NumberOfLinenumbers; // Number of line numbers - public uint Characteristics; // Characteristics - } - - #endregion - - #region Export and Import Structures - - /// - /// Export Directory structure - /// - public class ExportDirectory - { - public uint Characteristics; - public uint TimeDateStamp; - public ushort MajorVersion; - public ushort MinorVersion; - public uint Name; // RVA to the DLL name - public string DllName; // Actual DLL name - public uint Base; // Ordinal base - public uint NumberOfFunctions; // Number of exported functions - public uint NumberOfNames; // Number of exported names - public uint AddressOfFunctions; // RVA to function addresses - public uint AddressOfNames; // RVA to function names - public uint AddressOfNameOrdinals; // RVA to ordinals - } - - /// - /// Represents an exported function - /// - public class ExportedFunction - { - public string Name; // Function name - public uint Address; // Function RVA - public ushort Ordinal; // Function ordinal - public bool IsForwarder; // True if this is a forwarder - public string ForwarderName; // Name of the forwarded function (if IsForwarder is true) - } - - /// - /// Import Descriptor structure - /// - public class ImportDescriptor - { - public uint OriginalFirstThunk; // RVA to Import Lookup Table - public uint TimeDateStamp; - public uint ForwarderChain; - public uint Name; // RVA to the DLL name - public string DllName; // Actual DLL name - public uint FirstThunk; // RVA to Import Address Table - public List Functions; // List of imported functions - - public ImportDescriptor() - { - Functions = new List(); - } - } - - /// - /// Represents an imported function - /// - public class ImportedFunction - { - public bool IsOrdinal; // True if imported by ordinal - public ushort Ordinal; // Ordinal value (if IsOrdinal is true) - public string Name; // Function name (if IsOrdinal is false) - public ushort Hint; // Hint value (if IsOrdinal is false) - public uint ThunkRVA; // RVA in the Import Address Table - } - - #endregion -} diff --git a/X86Disassembler/Program.cs b/X86Disassembler/Program.cs deleted file mode 100644 index 752401a..0000000 --- a/X86Disassembler/Program.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.IO; - -namespace X86Disassembler -{ - internal class Program - { - // Path to the DLL file to disassemble - private const string DllPath = @"C:\Windows\SysWOW64\msvcrt.dll"; // Example path, replace with your target DLL - - static void Main(string[] args) - { - Console.WriteLine("X86 Disassembler and Decompiler"); - Console.WriteLine("--------------------------------"); - - Console.WriteLine($"Loading file: {DllPath}"); - - // Load the DLL file - byte[] binaryData = File.ReadAllBytes(DllPath); - - Console.WriteLine($"Successfully loaded {DllPath}"); - Console.WriteLine($"File size: {binaryData.Length} bytes"); - - // Parse the PE format - Console.WriteLine("\nParsing PE format..."); - PEFormat peFile = new PEFormat(binaryData); - - // Display basic PE information - DisplayPEInfo(peFile); - - // Display exported functions - DisplayExportedFunctions(peFile); - - // Display imported functions - DisplayImportedFunctions(peFile); - - // Find code sections for disassembly - var codeSections = peFile.GetCodeSections(); - Console.WriteLine($"\nFound {codeSections.Count} code section(s):"); - - foreach (int sectionIndex in codeSections) - { - var section = peFile.SectionHeaders[sectionIndex]; - Console.WriteLine($" - {section.Name}: Size={section.SizeOfRawData} bytes, RVA=0x{section.VirtualAddress:X8}"); - - // Get the section data for disassembly - byte[] sectionData = peFile.GetSectionData(sectionIndex); - - // TODO: Implement disassembling logic here - // This is where we would pass the section data to our disassembler - } - - Console.WriteLine("\nPress any key to exit..."); - Console.ReadKey(); - } - - private static void DisplayPEInfo(PEFormat peFile) - { - Console.WriteLine("\nPE File Information:"); - Console.WriteLine($"Architecture: {(peFile.Is64Bit ? "64-bit" : "32-bit")}"); - Console.WriteLine($"Entry Point: 0x{peFile.OptionalHeader.AddressOfEntryPoint:X8}"); - Console.WriteLine($"Image Base: 0x{peFile.OptionalHeader.ImageBase:X}"); - Console.WriteLine($"Number of Sections: {peFile.FileHeader.NumberOfSections}"); - - // Display section information - Console.WriteLine("\nSections:"); - for (int i = 0; i < peFile.SectionHeaders.Count; i++) - { - var section = peFile.SectionHeaders[i]; - string flags = ""; - - if ((section.Characteristics & 0x00000020) != 0) flags += "Code "; // IMAGE_SCN_CNT_CODE - if ((section.Characteristics & 0x20000000) != 0) flags += "Exec "; // IMAGE_SCN_MEM_EXECUTE - if ((section.Characteristics & 0x40000000) != 0) flags += "Read "; // IMAGE_SCN_MEM_READ - if ((section.Characteristics & 0x80000000) != 0) flags += "Write"; // IMAGE_SCN_MEM_WRITE - - Console.WriteLine($" {i}: {section.Name,-8} VA=0x{section.VirtualAddress:X8} Size={section.SizeOfRawData,-8} [{flags}]"); - } - } - - private static void DisplayExportedFunctions(PEFormat peFile) - { - if (peFile.ExportDirectory == null) - { - Console.WriteLine("\nNo exported functions found."); - return; - } - - Console.WriteLine("\nExported Functions:"); - Console.WriteLine($"DLL Name: {peFile.ExportDirectory.DllName}"); - Console.WriteLine($"Number of Functions: {peFile.ExportDirectory.NumberOfFunctions}"); - Console.WriteLine($"Number of Names: {peFile.ExportDirectory.NumberOfNames}"); - - // Display the first 10 exported functions (if any) - int count = Math.Min(10, peFile.ExportedFunctions.Count); - for (int i = 0; i < count; i++) - { - var function = peFile.ExportedFunctions[i]; - Console.WriteLine($" {i}: {function.Name} (Ordinal={function.Ordinal}, RVA=0x{function.Address:X8})"); - } - - if (peFile.ExportedFunctions.Count > 10) - { - Console.WriteLine($" ... and {peFile.ExportedFunctions.Count - 10} more"); - } - } - - private static void DisplayImportedFunctions(PEFormat peFile) - { - if (peFile.ImportDescriptors.Count == 0) - { - Console.WriteLine("\nNo imported functions found."); - return; - } - - Console.WriteLine("\nImported Functions:"); - Console.WriteLine($"Number of Imported DLLs: {peFile.ImportDescriptors.Count}"); - - // Display the first 5 imported DLLs and their functions - int dllCount = Math.Min(5, peFile.ImportDescriptors.Count); - for (int i = 0; i < dllCount; i++) - { - var descriptor = peFile.ImportDescriptors[i]; - Console.WriteLine($" DLL: {descriptor.DllName}"); - - // Display the first 5 functions from this DLL - int funcCount = Math.Min(5, descriptor.Functions.Count); - for (int j = 0; j < funcCount; j++) - { - var function = descriptor.Functions[j]; - if (function.IsOrdinal) - { - Console.WriteLine($" {j}: Ordinal {function.Ordinal}"); - } - else - { - Console.WriteLine($" {j}: {function.Name} (Hint={function.Hint})"); - } - } - - if (descriptor.Functions.Count > 5) - { - Console.WriteLine($" ... and {descriptor.Functions.Count - 5} more"); - } - } - - if (peFile.ImportDescriptors.Count > 5) - { - Console.WriteLine($" ... and {peFile.ImportDescriptors.Count - 5} more DLLs"); - } - } - } -} diff --git a/X86Disassembler/X86Disassembler.csproj b/X86Disassembler/X86Disassembler.csproj deleted file mode 100644 index 91b464a..0000000 --- a/X86Disassembler/X86Disassembler.csproj +++ /dev/null @@ -1,10 +0,0 @@ - - - - Exe - net8.0 - enable - enable - - -