Created
October 31, 2024 12:50
-
-
Save CompeyDev/a3670adf15b07284aae0aeab61490324 to your computer and use it in GitHub Desktop.
A simple Lune script to detect the architecture and OS of a binary.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local process = require("@lune/process") | |
| type Arch = process.Arch | "arm" | "x86" | |
| return function(binaryContents: buffer): { | |
| os: process.OS?, | |
| arch: Arch?, | |
| }? | |
| -- Windows PE | |
| do | |
| local DOS_HEADER = "MZ" | |
| local PE_HEADER_OFFSET = 0x3c | |
| local PE_MAGIC_SIGNATURE = "PE\x00\x00" | |
| local PE_MACHINE_TYPES: { [number]: Arch } = { | |
| [0x8664] = "x86_64", | |
| [0x01c0] = "arm", | |
| [0xaa64] = "aarch64", | |
| [0x014c] = "x86", | |
| } | |
| if buffer.readstring(binaryContents, 0, 2) == DOS_HEADER then | |
| -- File was a DOS executable, jump to PE header to get the magic offset | |
| local signatureOffset = buffer.readu8(binaryContents, PE_HEADER_OFFSET) | |
| -- Check if the value at the magic offset was the PE magic signature | |
| if buffer.readstring(binaryContents, signatureOffset, 4) == PE_MAGIC_SIGNATURE then | |
| -- After the first 4 magic bytes, the next 2 bytes are architecture information | |
| local machineType = buffer.readu16(binaryContents, signatureOffset + 4) | |
| return { | |
| os = "windows", | |
| arch = PE_MACHINE_TYPES[machineType], | |
| } | |
| end | |
| end | |
| end | |
| -- Linux ELF | |
| do | |
| local ELF_MAGIC_START = 0x7f | |
| local ELF_MAGIC_SIGNATURE = "ELF" | |
| local ELF_MACHINE_TYPES: { [number]: Arch } = { | |
| [0x3e] = "x86_64", | |
| [0x28] = "arm", | |
| [0xb7] = "aarch64", | |
| [0x03] = "x86", | |
| } | |
| -- ELF files have a magic signature of [0x7f, 'E', 'L', 'F'] | |
| if | |
| buffer.readu8(binaryContents, 0) == ELF_MAGIC_START | |
| and buffer.readstring(binaryContents, 1, 3) == ELF_MAGIC_SIGNATURE | |
| then | |
| -- Machine type is located after 16 bytes of ident and 2 bytes of type | |
| local machineType = buffer.readu16(binaryContents, 18) | |
| return { | |
| os = "linux", | |
| arch = ELF_MACHINE_TYPES[machineType], | |
| } | |
| end | |
| end | |
| -- macOS Mach-O | |
| do | |
| local MACHO_MAGIC_32 = 0xFEEDFACE | |
| local MACHO_MAGIC_64 = 0xFEEDFACF | |
| local MACHO_CPU_TYPES = { | |
| x86 = 0x7, | |
| arm = 0xc, | |
| } | |
| -- First 4 bytes are the magic depending on 32 or 64 bit | |
| -- Next 2 bytes are the CPU type | |
| local headerStart = buffer.readu32(binaryContents, 0) | |
| local cpuType = buffer.readu16(binaryContents, 4) | |
| local is64bit = headerStart == MACHO_MAGIC_64 | |
| local is32bit = headerStart == MACHO_MAGIC_32 | |
| return { | |
| os = "macos", | |
| --stylua: ignore | |
| arch = ( | |
| if is64bit and cpuType == MACHO_CPU_TYPES.x86 then "x86_64" | |
| elseif is64bit and cpuType == MACHO_CPU_TYPES.arm then "aarch64" | |
| elseif is32bit and cpuType == MACHO_CPU_TYPES.x86 then "x86" | |
| elseif is32bit and cpuType == MACHO_CPU_TYPES.arm then "arm" | |
| else nil | |
| ), | |
| } | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
+1 - is cool