From 0ce529af4e0280fcbd4e647d0fcb0a9ca9f3496e Mon Sep 17 00:00:00 2001 From: Rudy Mizrahi Celekli <47457359+rudycelekli@users.noreply.github.com> Date: Mon, 5 Oct 2026 14:09:00 -0400 Subject: [PATCH] fix(managed): recognize PE Thumb and ARMNT machines (#605) Signed-off-by: Rudy Celekli <47457359+rudycelekli@users.noreply.github.com> --- src/domain/binaryTarget.ts | 2 + src/domain/peInspection.ts | 1 + src/dotnet/ManagedPeReader.ts | 2 + .../managed/managedArmMachine.test.ts | 50 +++++++++++++++++++ 4 files changed, 55 insertions(+) create mode 100644 tests/boundary/providers/managed/managedArmMachine.test.ts diff --git a/src/domain/binaryTarget.ts b/src/domain/binaryTarget.ts index 2dce8c592..101b857df 100644 --- a/src/domain/binaryTarget.ts +++ b/src/domain/binaryTarget.ts @@ -237,6 +237,8 @@ const peArchitecture = (machine: number): BinaryArchitecture | undefined => { case 0x8664: return "x86_64"; case 0x1c0: + case 0x1c2: + case 0x1c4: return "arm"; case 0xaa64: return "arm64"; diff --git a/src/domain/peInspection.ts b/src/domain/peInspection.ts index 907f12656..9e58dea0b 100644 --- a/src/domain/peInspection.ts +++ b/src/domain/peInspection.ts @@ -132,6 +132,7 @@ export function parseMachineType(machine: number): PeMachineType { case 0x8664: return "x64"; case 0x01c0: + case 0x01c2: case 0x01c4: return "arm"; case 0xaa64: diff --git a/src/dotnet/ManagedPeReader.ts b/src/dotnet/ManagedPeReader.ts index 1c68850d2..84e3ce5b6 100644 --- a/src/dotnet/ManagedPeReader.ts +++ b/src/dotnet/ManagedPeReader.ts @@ -106,6 +106,8 @@ const architectureFor = (machine: number): ManagedPeLayout["architecture"] => { case 0x8664: return "x86_64"; case 0x01c0: + case 0x01c2: + case 0x01c4: return "arm"; case 0xaa64: return "arm64"; diff --git a/tests/boundary/providers/managed/managedArmMachine.test.ts b/tests/boundary/providers/managed/managedArmMachine.test.ts new file mode 100644 index 000000000..0436c631d --- /dev/null +++ b/tests/boundary/providers/managed/managedArmMachine.test.ts @@ -0,0 +1,50 @@ +import { writeFile } from "node:fs/promises"; +import { join } from "node:path"; +import { expect, it } from "vitest"; +import { createTestTempDirectory } from "../../../fixtures/temporaryDirectory.js"; +import { parseBinaryTarget } from "../../../../src/application/BinaryTargetResolver.js"; +import { parseMachineType } from "../../../../src/domain/peInspection.js"; +import { buildManagedPeFixture } from "../../../../src/dotnet/ManagedPe.fixture.js"; +import { ManagedStaticProvider } from "../../../../src/dotnet/ManagedStaticProvider.js"; + +it.each([0x01c0, 0x01c2, 0x01c4])( + "opens and inspects managed PE ARM machine 0x%s through the public path", + async (machine) => { + const bytes = buildManagedPeFixture({ cliFlags: 0 }); + bytes.writeUInt16LE(machine, bytes.readUInt32LE(0x3c) + 4); + const directory = await createTestTempDirectory("rea-managed-arm-"); + const path = join(directory, "fixture.exe"); + await writeFile(path, bytes); + const parsed = await parseBinaryTarget(path); + expect(parsed.ok).toBe(true); + if (!parsed.ok) throw parsed.error; + expect(parsed.value).toMatchObject({ + kind: "executable", + format: "pe", + architecture: "arm", + managed: true, + }); + expect(parseMachineType(machine)).toBe("arm"); + const client = new ManagedStaticProvider().createClient(parsed.value); + try { + for (const operation of [ + "inspect_managed_artifact", + "inspect_managed_members", + "inspect_managed_native_boundaries", + ] as const) { + const observed = await client.execute(operation, {}); + expect(observed.ok).toBe(true); + if (!observed.ok) throw observed.error; + expect(observed.value.subject).toMatchObject({ + path, + sha256: parsed.value.sha256, + }); + expect(observed.value.result).toMatchObject({ + module: { name: "Fixture.dll" }, + }); + } + } finally { + await client.close(); + } + }, +);