From 45f77d2c8a8bfef1aa865fa7d82fde35ace6ac6b Mon Sep 17 00:00:00 2001 From: Sam Carlton Date: Mon, 18 Jul 2022 18:06:00 -0500 Subject: [PATCH] Add MachoNode parser --- helpers/scanner/parsers/macho.js | 81 +++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) diff --git a/helpers/scanner/parsers/macho.js b/helpers/scanner/parsers/macho.js index 8271bf2..7817635 100644 --- a/helpers/scanner/parsers/macho.js +++ b/helpers/scanner/parsers/macho.js @@ -1,5 +1,81 @@ +import { Buffer } from 'buffer'; +// Tends to not support universal architecture +// but support some MachoManiac doesn't and fails faster +// so we run it first +// https://github.com/indutny/macho +export class MachoNode { + constructor ({ machoFileInstance, FileApi }) { + this.machoFileInstance = machoFileInstance + this.FileApi = FileApi + } + + // MachNode cpu types mapped to MachoManiac cpu types + // MachoNode types - https://github.com/indutny/macho/blob/c9d02419b36a468ebb4dcef66d0f9b98b6f22dbd/lib/macho/constants.js#L9 + // MachoManiac types - https://github.com/MTJailed/MachoManiac/blob/98d2d31d38d3ea3c911468181eed6e5f445eb556/macho.cpu.js#L13 + cpuMap = new Map([ + ['vax', 'VAX'], + ['mc680x0', 'MC680'], + // https://superuser.com/a/74354/412612 + ['i386', 'X86'], + ['x86_64', 'X86'], + ['mc98000', 'MC98000'], + ['hppa', 'HPPA'], + ['arm', 'ARM'], + ['arm64', 'ARM64'], + // arm64_32 is a variant of arm64 with 32-bit pointer sizes, used on Apple Watch Series 4 and later. + // https://stackoverflow.com/a/68248923/1397641 + ['arm64_32', 'ARM64'], + ['mc88000', 'MC88000'], + ['sparc', 'SPARC'], + ['i860', 'I860'], + // ['alpha', '???'] + ['powerpc', 'POWERPC'], + ['powerpc64', 'POWERPC64'] + ]) + + fileBuffer () { + const machoBuffer = new Buffer.alloc( this.machoFileInstance.buffer.byteLength ) + + for (var i = 0; i < this.machoFileInstance.buffer.length; i++) + machoBuffer[i] = this.machoFileInstance.buffer[i]; + + // console.log( 'this.machoFileInstance', this.machoFileInstance.buffer.byteLength ) + + return machoBuffer + } + + mapNodeMetaTOManiacMeta ( machoNodeMeta ) { + + return { + // Single entry since MachoNode doesn't support universal architectures + architectures: [{ + bits: machoNodeMeta.bits, + fileType: machoNodeMeta.filetype, + // header: architecture.header, + // loadCommandsInfo: architecture.loadCommandsInfo, + magic: machoNodeMeta.magic, + // offset: architecture.offset, + processorSubType: machoNodeMeta.subtype, + processorType: this.cpuMap.get( machoNodeMeta.cpu.type ), + }] + } + } + + async run () { + const { parse } = await import( 'macho' ) + + const machoNodeMeta = parse( this.fileBuffer() ) + + // console.log( 'machoNodeMeta', machoNodeMeta.cpu ) + + return this.mapNodeMetaTOManiacMeta( machoNodeMeta ) + } +} + + +// https://github.com/MTJailed/MachoManiac export class MachoManiac { constructor ({ machoFileInstance, FileApi }) { this.machoFileInstance = machoFileInstance @@ -19,6 +95,7 @@ export class MachoManiac { export async function extractMachoMeta ({ machoFileInstance, FileApi = null }) { const parsers = [ + MachoNode, MachoManiac ] @@ -34,7 +111,9 @@ export async function extractMachoMeta ({ machoFileInstance, FileApi = null }) { return meta } catch ( err ) { - // console.log( 'err', err ) + console.log( 'Macho parser failed', Parser, err ) + + // throw new Error( 'Macho parser failed' ) } }