Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <inttypes.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/stat.h>
- #include <sys/mman.h>
- #include <err.h>
- #include <string.h>
- #include <mach-o/arch.h>
- #include <mach-o/loader.h>
- #include <mach-o/nlist.h>
- typedef struct macho_input {
- const void *data;
- size_t length;
- } macho_input_t;
- struct _dyld {
- const struct dyld_info_command *dyld_cmd;
- char *name;
- };
- /// Verify that the given range is within bounds
- static const void *macho_read (macho_input_t *input, const void *address, size_t length) {
- if ((((uint8_t *) address) - ((uint8_t *) input->data)) + length > input->length) {
- warnx("Short read parsing Mach-O input");
- return NULL;
- }
- return address;
- }
- // Verify that address + offset + length is within bounds.
- static const void *macho_offset (macho_input_t *input, const void *address, size_t offset, size_t length) {
- void *result = ((uint8_t *) address) + offset;
- return macho_read(input, result, length);
- }
- uintptr_t get_dyld_count(macho_input_t *input, const struct mach_header_64 *header, const struct load_command *cmd) {
- uintptr_t ndyld = 0;
- for (uintptr_t i = 0; i < header->ncmds; i++) {
- uint32_t cmdsize = cmd->cmdsize;
- cmd = macho_read(input, cmd, cmdsize);
- switch(cmd->cmd) {
- case LC_ID_DYLIB:
- case LC_LOAD_WEAK_DYLIB:
- case LC_REEXPORT_DYLIB:
- case LC_LOAD_DYLIB: {
- ndyld++;
- }
- }
- cmd = macho_offset(input, cmd, cmdsize, sizeof(struct load_command));
- if (cmd == NULL)
- break;
- }
- return ndyld;
- }
- uint32_t mask_opcode(uint32_t op) {
- return (op - (op & 0x0f));
- }
- uintptr_t read_uleb128(uintptr_t i, unsigned char *sym) {
- do {
- i++;
- } while(sym[i-1] & 0x80);
- i++;
- return i;
- }
- uintptr_t get_dyld_index(unsigned char *sym) {
- uintptr_t dyld_index = 0;
- for(uintptr_t i = 0; i < strlen((char *)sym); i++) {
- if(mask_opcode(sym[i]) == 0x40) {
- if(mask_opcode(sym[i-1]) == 0x90) {
- dyld_index = 0;
- break;
- }
- if(sym[i-2] == 0x20) {
- dyld_index = sym[i-1];
- break;
- }
- if(mask_opcode(sym[i-1]) == 0x10) {
- dyld_index = sym[i-1] - mask_opcode(sym[i-1]);
- break;
- }
- }
- }
- return dyld_index;
- }
- uintptr_t get_sym_name_start(unsigned char *sym) {
- uintptr_t i;
- for(i = 0; i < strlen((char*)sym); i++) {
- switch(sym[i]) {
- case 0x80: {
- i = read_uleb128(i, sym);
- break;
- }
- case 0xA0: {
- i = read_uleb128(i, sym);
- break;
- }
- }
- if(sym[i] == 0x40 || sym[i] == 0x41) {
- i++;
- break;
- }
- }
- return i;
- }
- void get_sym_name(unsigned char *sym) {
- uintptr_t start_index = get_sym_name_start(sym);
- if(start_index) {
- int q = 0;
- for(uintptr_t i = start_index; i < strlen((char*)sym); i++) {
- sym[q] = sym[i];
- q++;
- }
- sym[q] = '