Merge pull request #295 from morluto/agent/fix-managed-conformance-x64-pe

fix(managed): emit valid x64 conformance PE
This commit is contained in:
N0zoM1z0 2026-07-17 21:10:14 +09:00 committed by GitHub
commit dcd94f1472
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 85 additions and 8 deletions

View File

@ -0,0 +1,36 @@
export interface ManagedPeFixtureMethod {
readonly body?: Buffer;
readonly flags?: number;
readonly implFlags?: number;
readonly name: string;
}
export interface ManagedPeFixtureOptions {
readonly cliFlags?: number;
readonly corruptMetadataSignature?: boolean;
readonly fieldName?: string;
readonly ilBody?: Buffer;
readonly machine?: number;
readonly metadataValidMaskExtra?: bigint;
readonly methodImplFlags?: number;
readonly methodName?: string;
readonly methods?: readonly ManagedPeFixtureMethod[];
readonly mvid?: Buffer;
readonly pinvoke?: {
readonly importName?: string;
readonly mappingFlags?: number;
readonly moduleName?: string;
};
readonly readyToRun?: boolean;
readonly references?: readonly string[];
readonly resourceData?: Buffer;
readonly targetFramework?: string;
readonly typeName?: string;
readonly typeNamespace?: string;
}
export const alternateMvid: Buffer;
export function buildManagedPeFixture(
options?: ManagedPeFixtureOptions,
): Buffer;
export function buildNativePeFixture(): Buffer;

View File

@ -330,22 +330,27 @@ export const buildManagedPeFixture = (options = {}) => {
image.writeUInt32LE(0x80, 0x3c);
image.writeUInt32LE(0x0000_4550, 0x80);
const coff = 0x84;
image.writeUInt16LE(options.machine ?? 0x014c, coff);
const machine = options.machine ?? 0x014c;
const pe32Plus = machine === 0x8664 || machine === 0xaa64;
const optionalSize = pe32Plus ? 0x00f0 : 0x00e0;
const directoryOffset = pe32Plus ? 112 : 96;
image.writeUInt16LE(machine, coff);
image.writeUInt16LE(1, coff + 2);
image.writeUInt16LE(0x00e0, coff + 16);
image.writeUInt16LE(optionalSize, coff + 16);
image.writeUInt16LE(0x0102, coff + 18);
const optional = coff + 20;
image.writeUInt16LE(0x010b, optional);
image.writeUInt16LE(pe32Plus ? 0x020b : 0x010b, optional);
image.writeUInt32LE(0x2000, optional + 20);
image.writeUInt32LE(0x0040_0000, optional + 28);
if (pe32Plus) image.writeBigUInt64LE(0x0040_0000n, optional + 24);
else image.writeUInt32LE(0x0040_0000, optional + 28);
image.writeUInt32LE(0x1000, optional + 32);
image.writeUInt32LE(0x200, optional + 36);
image.writeUInt32LE(0x3000, optional + 56);
image.writeUInt32LE(0x200, optional + 60);
image.writeUInt32LE(16, optional + 92);
image.writeUInt32LE(0x2000, optional + 96 + 14 * 8);
image.writeUInt32LE(72, optional + 96 + 14 * 8 + 4);
const section = optional + 0x00e0;
image.writeUInt32LE(16, optional + directoryOffset - 4);
image.writeUInt32LE(0x2000, optional + directoryOffset + 14 * 8);
image.writeUInt32LE(72, optional + directoryOffset + 14 * 8 + 4);
const section = optional + optionalSize;
image.write(".text\0\0\0", section, "ascii");
image.writeUInt32LE(0x1000, section + 8);
image.writeUInt32LE(0x2000, section + 12);

View File

@ -0,0 +1,36 @@
import { mkdtemp, rm, writeFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import { buildManagedPeFixture } from "../scripts/lib/managed-pe-fixture.mjs";
import { parseBinaryTarget } from "../src/domain/binaryTarget.js";
const workspaces: string[] = [];
afterEach(async () => {
await Promise.all(
workspaces.splice(0).map((path) => rm(path, { recursive: true })),
);
});
describe("managed conformance fixture", () => {
it("emits PE32+ headers when the COFF machine is x86-64", async () => {
const workspace = await mkdtemp(join(tmpdir(), "rea-managed-fixture-"));
workspaces.push(workspace);
const path = join(workspace, "fixture.exe");
await writeFile(path, buildManagedPeFixture({ machine: 0x8664 }));
const parsed = await parseBinaryTarget(path);
expect(parsed).toMatchObject({
ok: true,
value: {
format: "pe",
architecture: "x86_64",
managed: true,
},
});
});
});