mirror of
https://github.com/morluto/rea.git
synced 2026-10-26 17:35:11 +00:00
refactor(pe): share optional header image and alignment facts
This commit is contained in:
1 parent
72fa15a509
commit
5c4a6c467c
4 files changed
+52
-4
No files matched your search
@@ -14,6 +14,10 @@ const header = (
|
||||
): Buffer => {
|
||||
const bytes = Buffer.alloc(byteLength);
|
||||
bytes.writeUInt16LE(format.magic);
|
||||
if (format.bits === 64) bytes.writeBigUInt64LE(0xfedcba9876540000n, 24);
|
||||
else bytes.writeUInt32LE(0x87650000, 28);
|
||||
bytes.writeUInt32LE(0x1000, 32);
|
||||
bytes.writeUInt32LE(0x200, 36);
|
||||
bytes.writeUInt32LE(0x400, 60);
|
||||
bytes.writeUInt32LE(directoryCount, format.directoryOffset - 4);
|
||||
return bytes;
|
||||
@@ -32,6 +36,9 @@ it.each(formats)(
|
||||
if (!result.ok) throw new Error(result.error.message);
|
||||
expect(result.value).toMatchObject({
|
||||
...format,
|
||||
imageBase: format.bits === 64 ? 0xfedcba9876540000n : 0x87650000n,
|
||||
sectionAlignment: 0x1000,
|
||||
fileAlignment: 0x200,
|
||||
sizeOfHeaders: 0x400,
|
||||
directoryCount: 5,
|
||||
});
|
||||
@@ -54,6 +61,9 @@ it.each(formats)(
|
||||
ok: true,
|
||||
value: {
|
||||
...format,
|
||||
imageBase: format.bits === 64 ? 0xfedcba9876540000n : 0x87650000n,
|
||||
sectionAlignment: 0x1000,
|
||||
fileAlignment: 0x200,
|
||||
sizeOfHeaders: 0xffffffff,
|
||||
directoryCount: 0,
|
||||
dataDirectories: [],
|
||||
@@ -157,6 +167,9 @@ it("honors a Uint8Array window and detaches facts from later source changes", ()
|
||||
backing.fill(0);
|
||||
expect(result.value).toEqual({
|
||||
...formats[1],
|
||||
imageBase: 0xfedcba9876540000n,
|
||||
sectionAlignment: 0x1000,
|
||||
fileAlignment: 0x200,
|
||||
sizeOfHeaders: 0x400,
|
||||
directoryCount: 1,
|
||||
dataDirectories: [{ address: 0x12345678, size: 0x90, offset: 112 }],
|
||||
|
||||
@@ -13,6 +13,9 @@ export interface PeOptionalHeaderStructure {
|
||||
readonly magic: 0x10b | 0x20b;
|
||||
readonly bits: 32 | 64;
|
||||
readonly format: "pe32" | "pe32-plus";
|
||||
readonly imageBase: bigint;
|
||||
readonly sectionAlignment: number;
|
||||
readonly fileAlignment: number;
|
||||
readonly sizeOfHeaders: number;
|
||||
readonly directoryOffset: number;
|
||||
readonly directoryCount: number;
|
||||
@@ -74,6 +77,12 @@ export const readPeOptionalHeaderStructure = (
|
||||
magic,
|
||||
bits,
|
||||
format: bits === 64 ? "pe32-plus" : "pe32",
|
||||
imageBase:
|
||||
bits === 64
|
||||
? view.getBigUint64(24, true)
|
||||
: BigInt(view.getUint32(28, true)),
|
||||
sectionAlignment: view.getUint32(32, true),
|
||||
fileAlignment: view.getUint32(36, true),
|
||||
sizeOfHeaders: view.getUint32(60, true),
|
||||
directoryOffset,
|
||||
directoryCount,
|
||||
|
||||
@@ -68,6 +68,27 @@ it.each([32, 64] as const)(
|
||||
},
|
||||
);
|
||||
|
||||
it.each([32, 64] as const)(
|
||||
"retains PE%d declared image base and alignments in native image facts",
|
||||
(bits) => {
|
||||
const { bytes } = createGoBinaryFixture({ format: "pe", bits });
|
||||
const optional = bytes.readUInt32LE(0x3c) + 24;
|
||||
const imageBase = bits === 64 ? 0xfedcba9876540000n : 0x87650000n;
|
||||
if (bits === 64) bytes.writeBigUInt64LE(imageBase, optional + 24);
|
||||
else bytes.writeUInt32LE(Number(imageBase), optional + 28);
|
||||
// These remain declarations; alignment policy belongs to image consumers.
|
||||
bytes.writeUInt32LE(0, optional + 32);
|
||||
bytes.writeUInt32LE(0xffffffff, optional + 36);
|
||||
const container = readPeImage(bytes);
|
||||
expect(container.image_base).toBe(imageBase);
|
||||
expect(container.pe_header_mapping.address).toBe(imageBase);
|
||||
expect(container.mappings[0]?.address).toBe(imageBase + 0x400n);
|
||||
expect(container.pe_section_alignment).toBe(0);
|
||||
expect(container.pe_file_alignment).toBe(0xffffffff);
|
||||
expect(container.sections[0]?.file_alignment).toBe(0xffffffff);
|
||||
},
|
||||
);
|
||||
|
||||
it("keeps Go fallback candidates when a PE section has no printable name", () => {
|
||||
const fixture = createGoBinaryFixture({ format: "pe", bits: 64 });
|
||||
const expected = readGoBinaryImage(fixture.bytes).build_info;
|
||||
|
||||
@@ -82,9 +82,14 @@ export const readPeImage = (bytes: Buffer): PeImage => {
|
||||
);
|
||||
if (!facts.ok)
|
||||
throw new BinaryFormatFailure(facts.error.kind, facts.error.message);
|
||||
const { bits, dataDirectories, sizeOfHeaders } = facts.value;
|
||||
const imageBase = reader.word(optional + (bits === 64 ? 24 : 28), bits);
|
||||
const fileAlignment = reader.u32(optional + 36);
|
||||
const {
|
||||
bits,
|
||||
dataDirectories,
|
||||
sizeOfHeaders,
|
||||
imageBase,
|
||||
sectionAlignment,
|
||||
fileAlignment,
|
||||
} = facts.value;
|
||||
const headerMapping: FileMapping = {
|
||||
address: imageBase,
|
||||
offset: 0,
|
||||
@@ -153,7 +158,7 @@ export const readPeImage = (bytes: Buffer): PeImage => {
|
||||
format: "pe",
|
||||
image_base: imageBase,
|
||||
pe_machine: machine,
|
||||
pe_section_alignment: reader.u32(optional + 32),
|
||||
pe_section_alignment: sectionAlignment,
|
||||
pe_file_alignment: fileAlignment,
|
||||
pe_data_directories: dataDirectories,
|
||||
pe_header_mapping: headerMapping,
|
||||
|
||||
Reference in new issue
Block a user