From: Robert Pengelly Date: Tue, 28 Oct 2025 19:09:03 +0000 (+0000) Subject: Generate Mach-O symbols X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=000fed1f165e1c93c24f6339fdbd0b6fa12bcb49;p=sar.git Generate Mach-O symbols --- diff --git a/macho.h b/macho.h new file mode 100644 index 0000000..3225e89 --- /dev/null +++ b/macho.h @@ -0,0 +1,101 @@ +/****************************************************************************** + * @file macho.h + *****************************************************************************/ +#ifndef _MACHO_H +#define _MACHO_H + +struct macho_header_64 { + + unsigned char magic[4]; + unsigned char cpu_type[4]; + unsigned char cpu_subtype[4]; + unsigned char file_type[4]; + unsigned char num_cmds[4]; + unsigned char sizeof_cmds[4]; + unsigned char flags[4]; + unsigned char reserved[4]; + +}; + +#define MH_MAGIC_64 0xFEEDFACF + +#define MH_CPU_TYPE_AMD64 0x01000007 +#define MH_CPU_TYPE_ARM64 0x0100000C + +#define MH_CPU_SUBTYPE_I386_ALL 3 +#define MH_OBJECT 1 + +struct load_command { + + unsigned char command[4]; + unsigned char command_size[4]; + +}; + +#define LC_SEGMENT_64 0x19 +#define LC_SYMTAB 0x02 + +struct segment_command_64 { + + unsigned char command[4]; + unsigned char command_size[4]; + + char seg_name[16]; + + unsigned char vm_addr[8]; + unsigned char vm_size[8]; + unsigned char file_off[8]; + unsigned char file_size[8]; + + unsigned char max_prot[4]; + unsigned char init_prot[4]; + unsigned char num_sects[4]; + unsigned char flags[4]; + +}; + +struct section_64 { + + char sect_name[16]; + char seg_name[16]; + + unsigned char addr[8]; + unsigned char size[8]; + + unsigned char offset[4]; + unsigned char align[4]; + unsigned char rel_off[4]; + unsigned char num_reloc[4]; + + unsigned char flags[4]; + + unsigned char reserved1[4]; + unsigned char reserved2[4]; + unsigned char reserved3[4]; + +}; + +struct symtab_command { + + unsigned char command[4]; + unsigned char command_size[4]; + unsigned char symbol_offset[4]; + unsigned char num_symbols[4]; + unsigned char string_offset[4]; + unsigned char string_size[4]; + +}; + +#define MACHO_N_EXT 0x01 + +struct nlist_64 { + + unsigned char n_strx[4]; + unsigned char n_type[1]; + unsigned char n_sect[1]; + unsigned char n_desc[2]; + unsigned char n_value[8]; + +}; + +#endif /* _MACHO_H */ diff --git a/ranlib.c b/ranlib.c index 61eec68..7b26ca5 100644 --- a/ranlib.c +++ b/ranlib.c @@ -13,6 +13,7 @@ #include "elf.h" #include "elks.h" #include "lib.h" +#include "macho.h" #include "report.h" #include "stdint.h" @@ -505,6 +506,96 @@ static void hunk_get_symbols (void *object, uint64_t bytes, int64_t offset) { } +static void macho_get_symbols (void *object, int64_t offset) { + + unsigned char *pos = (unsigned char *) object; + + struct macho_header_64 *header; + struct strtab *strtab; + + struct symtab_command *symtab_cmd; + struct load_command *load_command; + + unsigned long cpu_type, num_commands, num_syms; + unsigned long i, j; + + unsigned char *sym_pos; + char *string_table, *symbol_name; + + struct nlist_64 *nlist_64; + unsigned long n_strx; + + header = (struct macho_header_64 *) pos; + pos += sizeof (*header); + + cpu_type = array_to_integer (header->cpu_type, 4, 0); + + if (cpu_type != MH_CPU_TYPE_AMD64 && cpu_type != MH_CPU_TYPE_ARM64) { + return; + } + + if (array_to_integer (header->file_type, 4, 0) != MH_OBJECT) { + return; + } + + num_commands = array_to_integer (header->num_cmds, 4, 0); + + for (i = 0; i < num_commands; i++) { + + load_command = (struct load_command *) pos; + + if (array_to_integer (load_command->command, 4, 0) == LC_SYMTAB) { + + symtab_cmd = (struct symtab_command *) pos; + + if (!(num_syms = array_to_integer (symtab_cmd->num_symbols, 4, 0))) { + + pos += array_to_integer (load_command->command_size, 4, 0); + continue; + + } + + string_table = (char *) object + array_to_integer (symtab_cmd->string_offset, 4, 0); + sym_pos = (unsigned char *) object + array_to_integer (symtab_cmd->symbol_offset, 4, 0); + + for (j = 0; j < num_syms; j++) { + + nlist_64 = (struct nlist_64 *) (sym_pos + j * sizeof (*nlist_64)); + + if ((n_strx = array_to_integer (nlist_64->n_strx, 4, 0)) < array_to_integer (symtab_cmd->string_size, 4, 0)) { + + if (string_table[n_strx] != '\0') { + + symbol_name = xstrdup (string_table + n_strx); + + if (nlist_64->n_type[0] & MACHO_N_EXT) { + + strtab = xmalloc (sizeof (*strtab)); + strtab->offset = offset; + + strtab->name = symbol_name; + strtab->length = strlen (strtab->name); + + add_strtab (&gstrtab, strtab); + + } + + } + + } + + } + + break; + + } + + pos += array_to_integer (load_command->command_size, 4, 0); + + } + +} + #define RECORD_TYPE_EXTDEF 0x8C #define RECORD_TYPE_PUBDEF 0x90 @@ -693,13 +784,15 @@ void ranlib (FILE *arfp) { } else if (object[0] == 0x7F && memcmp (object + 1, "ELF", 3) == 0) { int endianess = (object[5] == 2); - + if (object[4] == 2) { elf64_get_symbols (object, offset + 8, endianess); } else { elf32_get_symbols (object, offset + 8, endianess); } + } else if (object[0] == 0xCF && object[1] == 0xFA && object[2] == 0xED && object[3] == 0xFE) { + macho_get_symbols (object, offset + 8); } else if (object[0] == 0x80) { char filename[17] = { 0 };