| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  | using System; | 
					
						
							|  |  |  | using System.IO; | 
					
						
							|  |  |  | using System.Text; | 
					
						
							|  |  |  | using System.Collections.Generic; | 
					
						
							|  |  |  | using X86Disassembler.PE; | 
					
						
							|  |  |  | using X86Disassembler.X86; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  | namespace X86Disassembler; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /// <summary> | 
					
						
							|  |  |  | /// Main program class | 
					
						
							|  |  |  | /// </summary> | 
					
						
							|  |  |  | public class Program | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |     // Hardcoded file path for testing | 
					
						
							|  |  |  |     private const string FilePath = @"C:\Program Files (x86)\Nikita\Iron Strategy\Terrain.dll"; | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |      | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |     /// <summary> | 
					
						
							|  |  |  |     /// Main entry point | 
					
						
							|  |  |  |     /// </summary> | 
					
						
							|  |  |  |     /// <param name="args">Command line arguments</param> | 
					
						
							|  |  |  |     public static void Main(string[] args) | 
					
						
							| 
									
										
										
										
											2025-04-12 18:23:18 +03:00
										 |  |  |     { | 
					
						
							|  |  |  |         Console.WriteLine("X86 Disassembler and Decompiler"); | 
					
						
							|  |  |  |         Console.WriteLine("--------------------------------"); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Load the file | 
					
						
							|  |  |  |         Console.WriteLine($"Loading file: {FilePath}"); | 
					
						
							|  |  |  |         byte[] fileBytes = File.ReadAllBytes(FilePath); | 
					
						
							|  |  |  |         Console.WriteLine($"Successfully loaded {FilePath}"); | 
					
						
							|  |  |  |         Console.WriteLine($"File size: {fileBytes.Length} bytes\n"); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Parse the PE format | 
					
						
							|  |  |  |         Console.WriteLine("Parsing PE format...\n"); | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         PeFile peFile = new PeFile(fileBytes); | 
					
						
							|  |  |  |         peFile.Parse(); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Print PE file information | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |         Console.WriteLine("PE File Information:"); | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         Console.WriteLine($"Architecture: {(peFile.OptionalHeader.Is64Bit() ? "64-bit" : "32-bit")}"); | 
					
						
							|  |  |  |         Console.WriteLine($"Entry Point: 0x{peFile.OptionalHeader.AddressOfEntryPoint:X8}"); | 
					
						
							|  |  |  |         Console.WriteLine($"Image Base: 0x{peFile.OptionalHeader.ImageBase:X8}"); | 
					
						
							|  |  |  |         Console.WriteLine($"Number of Sections: {peFile.FileHeader.NumberOfSections}"); | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         Console.WriteLine(); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Print section information | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         PrintPeSections(peFile); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Print export information | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         PrintPeExports(peFile); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Print import information | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         PrintPeImports(peFile); | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |         // Find code sections | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         var codeSections = peFile.SectionHeaders.FindAll(s => s.ContainsCode()); | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         Console.WriteLine($"Found {codeSections.Count} code section(s):"); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |         foreach (var section in codeSections) | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |             Console.WriteLine($"  - {section.Name}: Size={section.VirtualSize} bytes, RVA=0x{section.VirtualAddress:X8}"); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |         Console.WriteLine(); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |         // Disassemble the first code section | 
					
						
							|  |  |  |         if (codeSections.Count > 0) | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |         { | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |             var section = codeSections[0]; | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |             byte[] codeBytes = peFile.GetSectionData(peFile.SectionHeaders.IndexOf(section)); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |             Console.WriteLine($"Disassembling section {section.Name} at RVA 0x{section.VirtualAddress:X8}:"); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |             // Create a disassembler for the code section | 
					
						
							|  |  |  |             Disassembler disassembler = new Disassembler(codeBytes, section.VirtualAddress); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |             // Disassemble all instructions | 
					
						
							|  |  |  |             var instructions = disassembler.Disassemble(); | 
					
						
							| 
									
										
										
										
											2025-04-13 03:56:39 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |             var unknownIndex = instructions.FindIndex( | 
					
						
							|  |  |  |                 x => x.ToString() | 
					
						
							|  |  |  |                     .Contains("??") || x.ToString() | 
					
						
							|  |  |  |                     .Contains("TODO") | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |             if (unknownIndex != -1) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 _ = 5; | 
					
						
							|  |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |              | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |             // Print the first 100 instructions | 
					
						
							|  |  |  |             int count = Math.Min(100, instructions.Count); | 
					
						
							|  |  |  |             for (int i = 0; i < count; i++) | 
					
						
							| 
									
										
										
										
											2025-04-12 18:23:18 +03:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |                 Console.WriteLine(instructions[i]); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:41:40 +03:00
										 |  |  |             } | 
					
						
							|  |  |  |              | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |             // Print a summary of how many more instructions there are | 
					
						
							|  |  |  |             if (instructions.Count > count) | 
					
						
							| 
									
										
										
										
											2025-04-12 18:23:18 +03:00
										 |  |  |             { | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |                 Console.WriteLine($"... ({instructions.Count - count} more instructions not shown)"); | 
					
						
							| 
									
										
										
										
											2025-04-12 18:23:18 +03:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |         } | 
					
						
							| 
									
										
										
										
											2025-04-12 19:57:42 +03:00
										 |  |  |          | 
					
						
							| 
									
										
										
										
											2025-04-13 00:21:01 +03:00
										 |  |  |         // Console.WriteLine("\nPress Enter to exit..."); | 
					
						
							|  |  |  |         // Console.ReadLine(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static void PrintPeImports(PeFile peFile) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Console.WriteLine("Imported Functions:"); | 
					
						
							|  |  |  |         Console.WriteLine($"Number of Imported DLLs: {peFile.ImportDescriptors.Count}"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         foreach (var import in peFile.ImportDescriptors) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             Console.WriteLine($"  DLL: {import.DllName}"); | 
					
						
							|  |  |  |                  | 
					
						
							|  |  |  |             for (int i = 0; i < import.Functions.Count; i++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 var function = import.Functions[i]; | 
					
						
							|  |  |  |                 if (function.IsOrdinal) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     Console.WriteLine($"    {i}: Ordinal {function.Ordinal}"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 else | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     Console.WriteLine($"    {i}: {function.Name} (Hint={function.Hint})"); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Console.WriteLine(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static void PrintPeExports(PeFile peFile) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Console.WriteLine("Exported Functions:"); | 
					
						
							|  |  |  |         Console.WriteLine($"DLL Name: {peFile.ExportDirectory.DllName}"); | 
					
						
							|  |  |  |         Console.WriteLine($"Number of Functions: {peFile.ExportDirectory.NumberOfFunctions}"); | 
					
						
							|  |  |  |         Console.WriteLine($"Number of Names: {peFile.ExportDirectory.NumberOfNames}"); | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |         for (int i = 0; i < peFile.ExportedFunctions.Count; i++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             var export = peFile.ExportedFunctions[i]; | 
					
						
							|  |  |  |             Console.WriteLine($"  {i}: {export.Name} (Ordinal={export.Ordinal}, RVA=0x{export.AddressRva:X8})"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Console.WriteLine(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     private static void PrintPeSections(PeFile peFile) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         Console.WriteLine("Sections:"); | 
					
						
							|  |  |  |         foreach (var section in peFile.SectionHeaders) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             string flags = ""; | 
					
						
							|  |  |  |             if (section.ContainsCode()) flags += "Code "; | 
					
						
							|  |  |  |             if (section.IsExecutable()) flags += "Exec "; | 
					
						
							|  |  |  |             if (section.IsReadable()) flags += "Read "; | 
					
						
							|  |  |  |             if (section.IsWritable()) flags += "Write"; | 
					
						
							|  |  |  |              | 
					
						
							|  |  |  |             Console.WriteLine($"  {peFile.SectionHeaders.IndexOf(section)}: {section.Name,-8} VA=0x{section.VirtualAddress:X8} Size={section.VirtualSize,-8} [{flags}]"); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         Console.WriteLine(); | 
					
						
							| 
									
										
										
										
											2025-04-12 16:42:44 +03:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2025-04-12 18:23:18 +03:00
										 |  |  | } |