From 67f4911ab8fc6add5e852454e4b49a96e546d72b Mon Sep 17 00:00:00 2001 From: Alexander O'Mara Date: Mon, 20 Jan 2025 14:07:32 -0500 Subject: [PATCH] Added MachOImage --- macho/machoimage.test.ts | 31 +++++++++++++++++++++++++++++ macho/machoimage.ts | 42 ++++++++++++++++++++++++++++++++++++++++ macho/mod.ts | 1 + 3 files changed, 74 insertions(+) create mode 100644 macho/machoimage.test.ts create mode 100644 macho/machoimage.ts diff --git a/macho/machoimage.test.ts b/macho/machoimage.test.ts new file mode 100644 index 0000000..38f8c98 --- /dev/null +++ b/macho/machoimage.test.ts @@ -0,0 +1,31 @@ +import { assertEquals, assertStrictEquals } from '@std/assert'; +import { MH_MAGIC } from '../const.ts'; +import { LoadCommand } from '../mach/loadcommand.ts'; +import { MachHeader } from '../mach/machheader.ts'; +import { MachOImage } from './machoimage.ts'; + +Deno.test('constructor', () => { + const buffer = new ArrayBuffer( + MachHeader.BYTE_LENGTH + LoadCommand.BYTE_LENGTH, + ); + const header = new MachHeader(buffer); + header.magic = MH_MAGIC; + header.ncmds = 1; + header.sizeofcmds = LoadCommand.BYTE_LENGTH; + + { + const macho = new MachOImage(buffer); + const address = macho.address(); + assertEquals(address.byteOffset, 0); + assertStrictEquals(address.buffer, buffer); + } + + { + const data = new Uint8Array(buffer.byteLength + 2); + data.subarray(1).set(new Uint8Array(buffer)); + const macho = new MachOImage(data.subarray(1)); + const address = macho.address(); + assertEquals(address.byteOffset, 1); + assertStrictEquals(address.buffer, data.buffer); + } +}); diff --git a/macho/machoimage.ts b/macho/machoimage.ts new file mode 100644 index 0000000..cefe7f7 --- /dev/null +++ b/macho/machoimage.ts @@ -0,0 +1,42 @@ +import type { ArrayBufferReal, BufferPointer } from '@hqtsm/struct'; +import { MachOBase } from './machobase.ts'; + +/** + * A Mach-O binary over a buffer. + */ +export class MachOImage extends MachOBase { + declare public readonly ['constructor']: Omit; + + /** + * Construct a Mach-O binary over a buffer. + * + * @param address Buffer pointer. + */ + constructor(address: ArrayBufferReal | BufferPointer) { + super(); + + this.initHeader(address); + + let buffer; + let byteOffset = this.headerSize(); + if ('buffer' in address) { + buffer = address.buffer; + byteOffset += address.byteOffset; + } else { + buffer = address; + } + this.initCommands({ + buffer, + byteOffset, + }); + } + + /** + * Get address of Mach-O. + * + * @returns Pionter to Mach-O header. + */ + public address(): BufferPointer { + return this.header()!; + } +} diff --git a/macho/mod.ts b/macho/mod.ts index 429bdbf..5e4f36e 100644 --- a/macho/mod.ts +++ b/macho/mod.ts @@ -1,4 +1,5 @@ export * from './architecture.ts'; export * from './macho.ts'; export * from './machobase.ts'; +export * from './machoimage.ts'; export * from './universal.ts';