Skip to content

Instantly share code, notes, and snippets.

@CompeyDev
Created October 31, 2024 12:50
Show Gist options
  • Save CompeyDev/a3670adf15b07284aae0aeab61490324 to your computer and use it in GitHub Desktop.
Save CompeyDev/a3670adf15b07284aae0aeab61490324 to your computer and use it in GitHub Desktop.

Revisions

  1. CompeyDev created this gist Oct 31, 2024.
    91 changes: 91 additions & 0 deletions detect_executable.luau
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,91 @@
    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