using WhiteMagic; using WhiteMagic.Discovery; namespace WhiteMagicTest.Discovery; /// /// Tests for . /// public class PeHeaderParserTests { private static InProcessReader CreateReader() { return new InProcessReader(); } [Fact] public void EntryPoint_returns_nonzero_for_current_module() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); IntPtr entryPoint = parser.EntryPoint; // Entry point should be a valid RVA (non-zero for a valid PE) Assert.NotEqual(IntPtr.Zero, entryPoint); // Entry point should be less than module size Assert.True((nint)entryPoint < mainModule.ModuleMemorySize); } [Fact] public void Sections_enumerates_at_least_text_section() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); var sections = parser.Sections.ToList(); Assert.NotEmpty(sections); // Every PE file should have a .text section (or similar) var textSection = sections.FirstOrDefault(s => s.Name.Equals(".text", StringComparison.OrdinalIgnoreCase) || s.Name.Equals("TEXT", StringComparison.OrdinalIgnoreCase)); // May not find ".text" exactly, but should have at least some sections Assert.True(sections.Count >= 1); } [Fact] public void Sections_have_valid_properties() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); var sections = parser.Sections.ToList(); foreach (var section in sections) { // Name should not be empty Assert.False(string.IsNullOrWhiteSpace(section.Name)); // Virtual address should be within module bounds Assert.True((nint)section.VirtualAddress < mainModule.ModuleMemorySize); // Virtual size should be positive Assert.True(section.VirtualSize > 0); } } [Fact] public void Sections_have_common_names() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); var sections = parser.Sections.Select(s => s.Name).ToList(); // At least some common section names should be present var commonNames = new[] { ".text", ".data", ".rdata", ".bss" }; bool hasCommonSection = commonNames.Any(name => sections.Contains(name, StringComparer.OrdinalIgnoreCase)); // This might not always be true, but for managed EXEs it usually is // We'll just verify sections were enumerated Assert.NotEmpty(sections); } [Fact] public void EntryPoint_is_consistent_across_calls() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); IntPtr first = parser.EntryPoint; IntPtr second = parser.EntryPoint; Assert.Equal(first, second); } [Fact] public void Sections_are_consistent_across_calls() { using var reader = CreateReader(); var currentProcess = System.Diagnostics.Process.GetCurrentProcess(); var mainModule = currentProcess.MainModule; Assert.NotNull(mainModule); var parser = new PeHeaderParser(reader, mainModule.BaseAddress); var first = parser.Sections.ToList(); var second = parser.Sections.ToList(); Assert.Equal(first.Count, second.Count); for (int i = 0; i < first.Count; i++) { Assert.Equal(first[i].Name, second[i].Name); Assert.Equal(first[i].VirtualAddress, second[i].VirtualAddress); Assert.Equal(first[i].VirtualSize, second[i].VirtualSize); } } [Fact] public void Constructor_throws_on_zero_base_address() { using var reader = CreateReader(); var ex = Assert.Throws(() => new PeHeaderParser(reader, IntPtr.Zero)); Assert.Contains("Base address cannot be zero", ex.Message); } }