Files
ImHex-Patterns/patterns/macho.hexpat
2023-01-02 13:15:51 +01:00

383 lines
8.0 KiB
Rust

#pragma MIME application/x-mach-binary
#include <type/size.pat>
enum Magic : u32 {
_32BitMagic = 0xFEEDFACE,
_64BitMagic = 0xFEEDFACF
};
enum CpuType : u32 {
VAX = 1,
ROMP = 2,
BS32032 = 4,
BS32332 = 5,
MC680x0 = 6,
I386 = 7,
X86_64 = CpuType::I386 | 0x100'0000,
MIPS = 8,
NS32532 = 9,
HPPA = 11,
ARM = 12,
MC88000 = 13,
SPARC = 14,
I860 = be u32(15),
I860_LITTLE = 16,
RS6000 = 17,
MC980000 = 18,
POWERPC = 18,
POWERPC64 = CpuType::POWERPC | 0x100'0000,
VEO = 255
};
enum SubCpuTypeVAX : u24 {
ALL = 0,
VAX780 = 1,
VAX785 = 2,
VAX750 = 3,
VAX730 = 4,
UVAXI = 5,
UVAXII = 6,
VAX8200 = 7,
VAX8500 = 8,
VAX8600 = 9,
VAX8650 = 10,
VAX8800 = 11,
UVAXIII = 12
};
enum SubCpuTypeROMP : u24 {
ALL = 0,
PC = 1,
APC = 2,
_135 = 3
};
enum SubCpuType32XXX : u24 {
ALL = 0,
MMAX_DPC = 1,
SQT = 2,
MMAX_APC_FPU = 3,
MMAX_APC_FPA = 4,
MMAX_XPC = 5
};
enum SubCpuTypeI386 : u24 {
_386 = 3,
_486 = 4,
_486SX = SubCpuTypeI386::_486 + 128,
_586 = 5,
IntelPentium = 5 + (0 << 4),
IntelPentiumPro = 6 + (1 << 4),
IntelPentiumIIM3 = 6 + (3 << 4),
IntelPentiumIIM5 = 6 + (5 << 4),
IntelPentium4 = 10 + (0 << 4),
};
enum SubCpuTypeMips : u24 {
ALL = 0,
R2300 = 1,
R2600 = 2,
R2800 = 3,
R2000a = 4
};
enum SubCpuType680x0 : u24 {
ALL = 1,
MC68030 = 1,
MC68040 = 2,
MC68030_Only = 3
};
enum SubCpuTypeHPPA : u24 {
ALL = 0,
_7100 = 0,
_7100LC = 1
};
enum SubCpuTypeARM : u24 {
ALL = 0,
A500_ARCH = 1,
A500 = 2,
A440 = 3,
M4 = 4,
V4T = 5,
V6 = 6,
V5TEJ = 7,
XSCALE = 8,
V7 = 9,
V7F = 10, /* Cortex A9 */
V7S = 11, /* Swift */
V7K = 12 /* Kirkwood40 */
};
enum SubCpuTypeMC88000 : u24 {
ALL = 0,
MMAX_JPC = 1,
MC88100 = 1,
MC88110 = 2
};
enum SubCpuTypeMC98000 : u24 {
ALL = 0,
MC98601 = 1
};
enum SubCpuTypeI860 : u24 {
ALL = 0,
_860 = 1
};
enum SubCpuTypeI860Little : u24 {
ALL = 0 ... 1
};
enum SubCpuTypeRS6000 : u24 {
ALL = 0 ... 1
};
enum SubCpuTypeSparc : u24 {
ALL = 0,
_260 = 1,
_110 = 2
};
enum SubCpuTypePowerPC : u24 {
ALL = 0,
_601 = 1,
_602 = 2,
_603 = 3,
_603e = 4,
_603ev = 5,
_604 = 6,
_604e = 7,
_620 = 8,
_750 = 9,
_7400 = 10,
_7450 = 11,
_970 = 100
};
enum SubCpuTypeVEO : u24 {
_1 = 1,
_2 = 2,
_3 = 3,
_4 = 4,
ALL = SubCpuTypeVEO::_2
};
bitfield Capabilities {
padding : 7;
lib64 : 1;
} [[right_to_left]];
enum FileType : u32 {
Object = 1,
Execute = 2,
FVMLib = 3,
Core = 4,
Preload = 5,
DyLib = 6,
DyLinker = 7,
Bundle = 8,
DyLibStub = 9,
DSym = 10,
KExtBundle = 11,
};
bitfield Flags {
noUndefs : 1;
incrLink : 1;
dyldLink : 1;
binDatLoad : 1;
prebound : 1;
splitSegs : 1;
lazyInit : 1;
twoLevel : 1;
forceFlat : 1;
noMultiDefs : 1;
noFixPrebinding : 1;
prebindable : 1;
allModsBound : 1;
subSectionsViaSymbols : 1;
canonical : 1;
weakDefines : 1;
bindsToWeak : 1;
allowStackExecution : 1;
rootSafe : 1;
setuidSafe : 1;
noReexportedDylibs : 1;
pie : 1;
deadStrippableDylib : 1;
hasTlvDescriptors : 1;
noHeapExecution : 1;
appExtensionSafe : 1;
nlistOutOfSyncWithDyldinof : 1;
simSupport : 1;
} [[right_to_left]];
struct Header {
Magic magic;
CpuType cpuType;
if (cpuType == CpuType::VAX) SubCpuTypeVAX subCpuType;
else if (cpuType == CpuType::ROMP) SubCpuTypeROMP subCpuType;
else if (cpuType == CpuType::BS32032 || cpuType == CpuType::BS32332 || cpuType == CpuType::NS32532) SubCpuType32XXX subCpuType;
else if (cpuType == CpuType::I386 || cpuType == CpuType::X86_64) SubCpuTypeI386 subCpuType;
else if (cpuType == CpuType::MIPS) SubCpuTypeMips subCpuType;
else if (cpuType == CpuType::HPPA) SubCpuTypeHPPA subCpuType;
else if (cpuType == CpuType::ARM) SubCpuTypeARM subCpuType;
else if (cpuType == CpuType::MC88000) SubCpuTypeMC88000 subCpuType;
else if (cpuType == CpuType::MC98000) SubCpuTypeMC98000 subCpuType;
else if (cpuType == CpuType::I860 || cpuType == CpuType::I860_LITTLE) SubCpuTypeI860 subCpuType;
else if (cpuType == CpuType::SPARC) SubCpuTypeSparc subCpuType;
else if (cpuType == CpuType::POWERPC || cpuType == CpuType::POWERPC64) SubCpuTypePowerPC subCpuType;
else if (cpuType == CpuType::VEO) SubCpuTypeVEO subCpuType;
else u24 subCpuType;
Capabilities capabilities;
FileType fileType;
u32 numCommands;
type::Size<u32> sizeOfCommands;
Flags flags;
if (magic == Magic::_64BitMagic) padding[sizeof(u32)];
};
enum Command : u32 {
ReqDyLd = 0x8000'0000,
Segment = 0x01,
SymTab = 0x02,
SymSeg = 0x03,
Thread = 0x04,
UnixThread = 0x05,
LoadFVMLib = 0x06,
IdFVMLib = 0x07,
Ident = 0x08,
FVMFile = 0x09,
PrePage = 0x0A,
DySymTab = 0x0B,
LoadDyLib = 0x0C,
IdDyLib = 0x0D,
LoadDyLinker = 0x0E,
IdDyLinker = 0x0F,
PreboundDyLib = 0x10,
Routines = 0x11,
SubFramework = 0x12,
SubUmbrella = 0x13,
SubClient = 0x14,
SubLibrary = 0x15,
TwoLevelHints = 0x16,
PrebindCksum = 0x17,
LoadWeakDyLib = 0x18 | Command::ReqDyLd,
Segment64 = 0x19,
Routines64 = 0x1A,
UUID = 0x1B,
RPath = 0x1C | 0x8000'0000,
CodeSignature = 0x1D,
SegmentSplitInfo = 0x1E,
ReExportDyLib = 0x1F | Command::ReqDyLd,
LazyLoadDyLib = 0x20,
EncryptionInfo = 0x21,
DyLdInfo = 0x22,
DyLdInfoOnly = 0x22 | Command::ReqDyLd,
LoadUpwardDyLib = 0x23 | Command::ReqDyLd,
VersionMinMacOSX = 0x24,
VersionMinIPhoneOS = 0x25,
FunctionStarts = 0x26,
DyLdEnvironment = 0x27,
Main = 0x28 | Command::ReqDyLd,
DataInCode = 0x29,
SourceVersion = 0x2A,
DyLibCodeSignDRS = 0x2B
};
struct CommandUUID {
u128 uuid;
};
struct Section {
char sectionName[16];
char segmentName[16];
u32 address;
type::Size<u32> size;
u32 offset;
u32 align;
u32 reloff;
u32 numRelocs;
u32 flags;
padding[8];
if (offset > 0)
u8 data[size] @ offset [[sealed]];
};
struct CommandSegment {
char segmentName[16];
u32 vmAddress;
type::Size<u32> vmSize;
u32 fileOffset;
type::Size<u32> fileSize;
u32 maxProtection;
u32 initProtection;
u32 numSections;
u32 flags;
Section sections[numSections];
if (fileOffset > 0)
u8 data[fileSize] @ fileOffset [[sealed]];
};
struct Section64 {
char sectionName[16];
char segmentName[16];
u64 address;
type::Size<u64> size;
u32 offset;
u32 align;
u32 reloff;
u32 numRelocs;
u32 flags;
padding[12];
if (offset > 0)
u8 data[size] @ offset [[sealed]];
};
struct CommandSegment64 {
char segmentName[16];
u64 vmAddress;
type::Size<u64> vmSize;
u64 fileOffset;
type::Size<u64> fileSize;
u32 maxProtection;
u32 initProtection;
u32 numSections;
u32 flags;
Section64 sections[numSections];
if (fileOffset > 0)
u8 data[fileSize] @ fileOffset [[sealed]];
};
struct LoadCommand {
Command command;
type::Size<u32> commandSize;
if (command == Command::UUID)
CommandUUID data;
else if (command == Command::Segment)
CommandSegment data;
else if (command == Command::Segment64)
CommandSegment64 data;
else
u8 data[commandSize - 8] [[sealed]];
};
struct MachO {
Header header;
LoadCommand loadCommands[header.numCommands];
};
MachO macho @ 0x00;