this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Add 'elfdep' tool for printing the ELF dependencies of Mach-O files

+184
+2
src/buildtools/CMakeLists.txt
··· 3 3 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 4 4 5 5 add_executable(getuuid getuuid.c) 6 + add_executable(elfdep elfdep.c) 6 7 8 + #add_subdirectory(Rez)
+182
src/buildtools/elfdep.c
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2018-2020 Lubos Dolezel 5 + 6 + Darling is free software: you can redistribute it and/or modify 7 + it under the terms of the GNU General Public License as published by 8 + the Free Software Foundation, either version 3 of the License, or 9 + (at your option) any later version. 10 + 11 + Darling is distributed in the hope that it will be useful, 12 + but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + GNU General Public License for more details. 15 + 16 + You should have received a copy of the GNU General Public License 17 + along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include <stdio.h> 20 + #include <unistd.h> 21 + #include <fcntl.h> 22 + #include <sys/mman.h> 23 + #include <stdint.h> 24 + #include <stdbool.h> 25 + #include <stdlib.h> 26 + #include <mach-o/loader.h> 27 + #include <mach-o/fat.h> 28 + #include <string.h> 29 + #include <errno.h> 30 + 31 + bool printElfdepAny(const void* mem); 32 + bool printElfdepMH(const struct mach_header* mhdr); 33 + bool printElfdepMH64(const struct mach_header_64* mhdr); 34 + bool printFat(const struct fat_header* fhdr); 35 + bool printTaf(const struct fat_header* fhdr); 36 + 37 + int main(int argc, const char** argv) 38 + { 39 + if (argc != 2) 40 + { 41 + fprintf(stderr, "elfdep: Prints the ELF dependency (SONAME) of a Mach-O file, if any\n"); 42 + fprintf(stderr, "Usage: elfdep <macho-file>\n"); 43 + return EXIT_FAILURE; 44 + } 45 + 46 + int fd = open(argv[1], O_RDONLY); 47 + if (fd == -1) 48 + { 49 + fprintf(stderr, "Cannot open %s: %s", argv[1], strerror(errno)); 50 + return EXIT_FAILURE; 51 + } 52 + 53 + size_t length = lseek(fd, 0, SEEK_END); 54 + 55 + void* mem = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0); 56 + if (mem == MAP_FAILED) 57 + { 58 + perror("mmap"); 59 + return EXIT_FAILURE; 60 + } 61 + 62 + close(fd); 63 + 64 + printElfdepAny(mem); 65 + 66 + munmap(mem, length); 67 + 68 + return EXIT_SUCCESS; 69 + } 70 + 71 + bool printElfdepAny(const void* mem) 72 + { 73 + const struct mach_header* mhdr = (struct mach_header*) mem; 74 + 75 + if (mhdr->magic == MH_MAGIC) 76 + return printElfdepMH(mhdr); 77 + else if (mhdr->magic == MH_MAGIC_64) 78 + return printElfdepMH64((struct mach_header_64*) mhdr); 79 + else if (mhdr->magic == FAT_MAGIC) 80 + return printFat((struct fat_header*) mhdr); 81 + else if (mhdr->magic == FAT_CIGAM) 82 + return printTaf((struct fat_header*) mhdr); 83 + else 84 + { 85 + fprintf(stderr, "File format not recognized\n"); 86 + exit(1); 87 + } 88 + } 89 + 90 + bool printElfdep(const struct load_command* lc, const void* base) 91 + { 92 + if (lc->cmd == LC_SEGMENT) 93 + { 94 + const struct segment_command* sc = (const struct segment_command*) lc; 95 + 96 + if (strcmp(sc->segname, "__TEXT") == 0) 97 + { 98 + const struct section* sect = (const struct section*)(sc+1); 99 + for (int i = 0; i < sc->nsects; i++) 100 + { 101 + if (strcmp(sect->sectname, "__elfname") == 0) 102 + { 103 + printf("%s\n", ((const char*)base) + sect->offset); 104 + return true; 105 + } 106 + sect++; 107 + } 108 + } 109 + } 110 + else if (lc->cmd == LC_SEGMENT_64) 111 + { 112 + const struct segment_command_64* sc = (const struct segment_command_64*) lc; 113 + 114 + if (strcmp(sc->segname, "__TEXT") == 0) 115 + { 116 + const struct section_64* sect = (const struct section_64*)(sc+1); 117 + for (int i = 0; i < sc->nsects; i++) 118 + { 119 + if (strcmp(sect->sectname, "__elfname") == 0) 120 + { 121 + printf("%s\n", ((const char*)base) + sect->offset); 122 + return true; 123 + } 124 + sect++; 125 + } 126 + } 127 + } 128 + return false; 129 + } 130 + 131 + bool printElfdepMH(const struct mach_header* mhdr) 132 + { 133 + const uint8_t* command = (const uint8_t*)(mhdr + 1); 134 + for (uint32_t i = 0; i < mhdr->ncmds; i++) 135 + { 136 + if (printElfdep((const struct load_command*) command, mhdr)) 137 + return true; 138 + else 139 + command += ((const struct load_command*)command)->cmdsize; 140 + } 141 + return false; 142 + } 143 + 144 + bool printElfdepMH64(const struct mach_header_64* mhdr) 145 + { 146 + const uint8_t* command = (const uint8_t*)(mhdr + 1); 147 + for (uint32_t i = 0; i < mhdr->ncmds; i++) 148 + { 149 + if (printElfdep((const struct load_command*) command, mhdr)) 150 + return true; 151 + else 152 + command += ((const struct load_command*)command)->cmdsize; 153 + } 154 + return false; 155 + } 156 + 157 + bool printFat(const struct fat_header* fhdr) 158 + { 159 + const struct fat_arch* fa = ((const struct fat_arch*) (fhdr+1)); 160 + 161 + for (uint32_t i = 0; i < fhdr->nfat_arch; i++) 162 + { 163 + if (printElfdepAny(((char*) fhdr) + fa[i].offset)) 164 + return true; 165 + } 166 + 167 + return false; 168 + } 169 + 170 + bool printTaf(const struct fat_header* fhdr) 171 + { 172 + const struct fat_arch* fa = ((const struct fat_arch*) (fhdr+1)); 173 + 174 + for (uint32_t i = 0; i < __builtin_bswap32(fhdr->nfat_arch); i++) 175 + { 176 + if (printElfdepAny(((char*) fhdr) + __builtin_bswap32(fa[i].offset))) 177 + return true; 178 + } 179 + 180 + return false; 181 + } 182 +