Fix InputSimulator wParam, PeHeaderParser double-parse, and other review issues
Bug fixes: - InputSimulator: Pass correct button state (MK_LBUTTON/MK_RBUTTON) in wParam for button-down messages instead of 0. - PeHeaderParser: ParseOptionalHeader now reads only the optional header, not section headers (fixes double-parse waste). - EntryPoint: Removed useless isPe32Plus branch (AddressOfEntryPoint is at offset 16 in both PE32 and PE32+). - RemoteWindow: Handle null foreground window case in Activate to avoid calling GetWindowThreadProcessId with HWND 0. - RemotePointer: Remove dead null-conditional operators (encoding ??) since encoding is non-nullable. Constants added: - SystemMethods: MkLButton (0x0001) and MkRButton (0x0002) for mouse button state flags. Tests: 199 passing, 4 integration/interactive skipped.
This commit is contained in:
@@ -64,21 +64,8 @@ public sealed class PeHeaderParser
|
||||
if (optionalHeader is null)
|
||||
return IntPtr.Zero;
|
||||
|
||||
// Entry point is at different offsets for PE32 vs PE32+
|
||||
bool isPe32Plus = IsPe32Plus();
|
||||
|
||||
if (isPe32Plus)
|
||||
{
|
||||
// PE32+: AddressOfEntryPoint is at offset 16 in OPTIONAL_HEADER (64-bit)
|
||||
return (IntPtr)BitConverter.ToUInt32(
|
||||
optionalHeader.AsSpan(16, 4));
|
||||
}
|
||||
else
|
||||
{
|
||||
// PE32: AddressOfEntryPoint is at offset 16 in OPTIONAL_HEADER (32-bit)
|
||||
return (IntPtr)BitConverter.ToUInt32(
|
||||
optionalHeader.AsSpan(16, 4));
|
||||
}
|
||||
// Entry point RVA is at offset 16 in the optional header (both PE32 and PE32+)
|
||||
return (IntPtr)BitConverter.ToUInt32(optionalHeader.AsSpan(16, 4));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +172,46 @@ public sealed class PeHeaderParser
|
||||
/// </summary>
|
||||
private (byte[]? OptionalHeader, byte[][]? SectionHeaders) ParseOptionalHeader()
|
||||
{
|
||||
return ParseOptionalHeaderAndSectionHeaders();
|
||||
// Read DOS header (first 64 bytes)
|
||||
byte[] dosHeader = _memory.ReadBytes(_baseAddress, 64);
|
||||
if (dosHeader.Length < 64)
|
||||
throw new InvalidDataException("Failed to read DOS header.");
|
||||
|
||||
// Verify DOS signature "MZ"
|
||||
if (dosHeader[0] != 0x4D || dosHeader[1] != 0x5A)
|
||||
throw new InvalidDataException("Invalid DOS signature (not a PE file).");
|
||||
|
||||
// PE header offset is at 0x3C in DOS header
|
||||
int peOffset = BitConverter.ToInt32(dosHeader, 0x3C);
|
||||
if (peOffset < 0 || peOffset > 0x1000) // Sanity check
|
||||
throw new InvalidDataException($"Invalid PE offset: {peOffset}");
|
||||
|
||||
// Read PE signature (4 bytes: "PE\0\0")
|
||||
IntPtr peSigAddr = _baseAddress + peOffset;
|
||||
byte[] peSignature = _memory.ReadBytes(peSigAddr, 4);
|
||||
if (peSignature.Length < 4)
|
||||
throw new InvalidDataException("Failed to read PE signature.");
|
||||
|
||||
if (peSignature[0] != 0x50 || peSignature[1] != 0x45 ||
|
||||
peSignature[2] != 0x00 || peSignature[3] != 0x00)
|
||||
throw new InvalidDataException("Invalid PE signature.");
|
||||
|
||||
// COFF header follows PE signature (20 bytes)
|
||||
IntPtr coffAddr = peSigAddr + 4;
|
||||
byte[] coffHeader = _memory.ReadBytes(coffAddr, 20);
|
||||
if (coffHeader.Length < 20)
|
||||
throw new InvalidDataException("Failed to read COFF header.");
|
||||
|
||||
// SizeOfOptionalHeader is at offset 16 in COFF header
|
||||
ushort sizeOfOptionalHeader = BitConverter.ToUInt16(coffHeader, 16);
|
||||
|
||||
// Optional header follows COFF header
|
||||
IntPtr optAddr = coffAddr + 20;
|
||||
byte[] optionalHeader = _memory.ReadBytes(optAddr, sizeOfOptionalHeader);
|
||||
if (optionalHeader.Length < sizeOfOptionalHeader)
|
||||
throw new InvalidDataException("Failed to read optional header.");
|
||||
|
||||
return (optionalHeader, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user