1/* 2 * Copyright (c) 2006-2008, 2012 Apple Inc. All rights reserved. 3 * 4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. The rights granted to you under the License 10 * may not be used to create, or enable the creation or redistribution of, 11 * unlawful or unlicensed copies of an Apple operating system, or to 12 * circumvent, violate, or enable the circumvention or violation of, any 13 * terms of an Apple operating system software license agreement. 14 * 15 * Please obtain a copy of the License at 16 * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 * 18 * The Original Code and all software distributed under the License are 19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 * Please see the License for the specific language governing rights and 24 * limitations under the License. 25 * 26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 */ 28#ifndef __MACHO_UTIL_H__ 29#define __MACHO_UTIL_H__ 30 31#include <mach-o/loader.h> 32#include <mach-o/nlist.h> 33#include <uuid/uuid.h> 34 35/******************************************************************************* 36******************************************************************************** 37** DO NOT USE THIS API. IT IS VOLATILE. ** 38******************************************************************************** 39*******************************************************************************/ 40 41/*! @header macho_util 42Handy functions for working with Mach-O files. Very rudimentary, use at your 43own risk. 44*/ 45 46/*! 47 * @define MAGIC32 48 * @abstract Get the 32-bit magic number from a file data pointer. 49 * @param ptr A pointer to a file whose magic number you want to get. 50 * @result Returns an unsigned 32-bit integer containing 51 * the first four bytes of the file data. 52 */ 53#define MAGIC32(ptr) (*((uint32_t *)(ptr))) 54 55#define ISMACHO(magic) (((magic) == MH_MAGIC) || \ 56 ((magic) == MH_CIGAM) || \ 57 ((magic) == MH_MAGIC_64) || \ 58 ((magic) == MH_CIGAM_64)) 59#define ISSWAPPEDMACHO(magic) (((magic) == MH_CIGAM) || \ 60 ((magic) == MH_CIGAM_64)) 61#define ISMACHO64(magic) (((magic) == MH_MAGIC_64) || \ 62 ((magic) == MH_CIGAM_64)) 63 64/******************************************************************************* 65* 66*******************************************************************************/ 67#define CondSwapInt32(flag, value) ((flag) ? OSSwapInt32((value)) : \ 68 (uint32_t)(value)) 69#define CondSwapInt64(flag, value) ((flag) ? OSSwapInt64((value)) : \ 70 (uint64_t)(value)) 71/*! 72 * @enum macho_seek_result 73 * @abstract Results of a lookup within a Mach-O file. 74 * @discussion This enum lists the possible return values for a Mach-O lookup. 75 * @constant macho_seek_result_error Invalid arguments or bad Mach-O file. 76 * @constant macho_seek_result_found The requested item was found. 77 * @constant macho_seek_result_not_found The requested item was not found. 78 * For functions called repeatedly (such as the macho_lc_callback), 79 * this means the item may be found on a subsequent invocation. 80 * @constant macho_seek_result_stop The requested item will not be found. 81 * This is only returned by functions that may be called repeatedly, 82 * when they can determine conclusively that the requested item does not exist. 83 */ 84typedef enum { 85 macho_seek_result_error = -1, 86 macho_seek_result_found = 0, 87 macho_seek_result_found_no_value = 1, 88 macho_seek_result_not_found = 2, 89 macho_seek_result_stop = 3, 90} macho_seek_result; 91 92/*! 93 * @function macho_find_symbol 94 * @abstract Finds symbol data in a mapped Mach-O file. 95 * @discussion 96 * The macho_find_symbol function searches a memory-mapped Mach-O file 97 * for a given symbol, 98 * indirectly returning the address within that mapped file 99 * containing the data for that symbol. 100 * Only symbols of type N_SECT, N_UNDF result in an address; 101 * for N_ABS and N_INDR the result will be macho_seek_result_found_no_value. 102 * @param file_start A pointer to the beginning of the mapped Mach-O file. 103 * @param file_end A pointer to the end of the mapped Mach-O file. 104 * @param name The name of the symbol to find. 105 * @param nlist_type The address of a uint8_t that will be filled with the type 106 * of the located symbol. 107 * @param symbol_address The address of a pointer that will be filled 108 * with the location of the symbol's data in the mapped file, 109 * if the address can be calculated. 110 * @result Returns macho_seek_result_found if the symbol is found, 111 * macho_seek_result_not_found if the symbol is not defined in the given file, 112 * or macho_seek_result_error if an error occurs. 113 */ 114macho_seek_result macho_find_symbol( 115 const void * file_start, 116 const void * file_end, 117 const char * name, 118 uint8_t * nlist_type, 119 const void ** symbol_address); 120 121/*! 122 * @function macho_find_symtab 123 * @abstract Finds a mapped Mach-O file's symbol table. 124 * @discussion 125 * The macho_find_symtab function locates the symbol table of a Mach-O 126 * file. Only the LC_SYMTAB load command is located, not the LC_DSYMTAB. 127 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 128 * @param file_end A pointer to the end of the mapped Mach-O file. 129 * @param symtab A pointer to the address of a symtab_command struct; 130 * if provided, this is filled with the address of the file's symbol table. 131 * @result Returns macho_seek_result_found if the symbol table is found, 132 * macho_seek_result_not_found if a symbol table is not defined in the given file, 133 * or macho_seek_result_error if an error occurs. 134 */ 135macho_seek_result macho_find_symtab( 136 const void * file_start, 137 const void * file_end, 138 struct symtab_command ** symtab); 139 140/*! 141 * @function macho_find_dysymtab 142 * @abstract Finds a mapped Mach-O file's dynamic link-edit symbol table info. 143 * @discussion 144 * The macho_find_dysymtab function locates the dynamic link-edit symbol 145 * table of a Mach-O file. Only the LC_DYSYMTAB load command is located, 146 * not the LC_SYMTAB. 147 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 148 * @param file_end A pointer to the end of the mapped Mach-O file. 149 * @param dysymtab A pointer to the address of a dysymtab_command struct; 150 * if provided, this is filled with the address of the file's symbol table. 151 * @result Returns macho_seek_result_found if the symbol table is found, 152 * macho_seek_result_not_found if a symbol table is not defined in the given file, 153 * or macho_seek_result_error if an error occurs. 154 */ 155macho_seek_result macho_find_dysymtab( 156 const void * file_start, 157 const void * file_end, 158 struct dysymtab_command ** dysymtab); 159 160/*! 161 * @function macho_find_uuid 162 * @abstract Finds a mapped Mach-O file's UUID. 163 * @discussion 164 * The macho_find_uuid function locates the UUID of a Mach-O file. 165 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 166 * @param file_end A pointer to the end of the mapped Mach-O file. 167 * @param uuid A pointer to the start of the UUID bytes; 168 * if provided, this is filled with the address of the UUID bytes. 169 * @result Returns macho_seek_result_found if the UUID is found, 170 * macho_seek_result_not_found if a UUID is not defined in the given file, 171 * or macho_seek_result_error if an error occurs. 172 */ 173macho_seek_result macho_find_uuid( 174 const void * file_start, 175 const void * file_end, 176 char **uuid); 177 178/*! 179 * @function macho_find_section_numbered 180 * @abstract Finds an ordinal section in a Mach-O file. 181 * @discussion 182 * The macho_find_section_numbered function locates an ordinally-numbered 183 * section within a Mach-O file, which is needed for calculating proper 184 * offsets and addresses of such things as nlist entries. 185 * Sections are numbered in a Mach-O file starting with 1, since zero 186 * is reserved to mean "no section". 187 * Since you will likely be passing a section number directly from other 188 * structure within the same Mach-O file, this should not be a problem. 189 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 190 * @param file_end A pointer to the end of the mapped Mach-O file. 191 * @param sect_num The ordinal number of the section to get, starting with 1. 192 * @result Returns a pointer to the requested section struct if it exists; 193 * otherwise returns NULL. 194 */ 195// cast to (struct section[_64] *) 196void * macho_find_section_numbered( 197 const void * file_start, 198 const void * file_end, 199 uint8_t sect_num); 200 201/*! 202 * @typedef macho_lc_callback 203 * @abstract The callback function used when scanning Mach-O load commands 204 * with macho_scan_load_commands. 205 * @discussion macho_lc_callback defines the callback function 206 * invoked by macho_scan_load_commands for each load command it encounters. 207 * The scan function passes a pointer to a user data struct that you can use 208 * for search parameters, running information, and search results. 209 * @param load_command A pointer to the Mach-O load command being processed. 210 * @param file_end A pointer to the end of the mapped Mach-O file, 211 * to be used for bounds checking. 212 * @param swap A boolean flag indicating whether the Mach-O file's byte order 213 * is opposite the host's. 214 * If nonzero, the callback needs to swap all multibyte values 215 * read from the Mach-O file. 216 * @param user_data A pointer to user-defined data that is passed unaltered 217 * across invocations of the callback function. 218 * @result Returns macho_seek_result_found if the requested item is found, 219 * macho_seek_result_not_found if is not found on this call, 220 * macho_seek_result_stop if the function determined that it does not exist, 221 * or macho_seek_result_error if an error occurs 222 * (particularly if any data structure to be accessed 223 * would run past the end of the file). 224 */ 225typedef macho_seek_result (*macho_lc_callback)( 226 struct load_command * load_command, 227 const void * file_end, 228 uint8_t swap, 229 void * user_data 230); 231 232/*! 233 * @function macho_find_source_version 234 * @abstract Finds a mapped Mach-O file's LC_SOURCE_VERSION. 235 * @discussion 236 * The macho_find_source_version function locates the source version 237 * load command of a Mach-O file. 238 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 239 * @param file_end A pointer to the end of the mapped Mach-O file. 240 * @param version A pointer to a uint64_t variable into which to store the 241 * contents of the 'version' field of the LC_SOURCE_VERSION load 242 * command from the mach-o header. 243 * @result Returns macho_seek_result_found if the source version is found, 244 * macho_seek_result_not_found if a source version is not defined in the 245 * given file, or macho_seek_result_error if an error occurs. 246 */ 247macho_seek_result macho_find_source_version( 248 const void * file_start, 249 const void * file_end, 250 uint64_t * version); 251 252/*! 253 * @function macho_scan_load_commands 254 * @abstract Iterates over the load commands of a Mach-O file using a callback. 255 * @discussion 256 * The macho_scan_load_commands iterates over the load commands within a 257 * Mach-O file, invoking a user-supplied callback until that callback 258 * returns a result indicating the scan should stop. 259 * @param mach_header A pointer to the beginning of the mapped Mach-O file. 260 * @param file_end A pointer to the end of the mapped Mach-O file. 261 * @param lc_callback A function that is invoked on each load command 262 * of the Mach-O file until the callback function 263 * indicates the scan is finished. 264 * @param user_data A pointer to user-defined data that is passed unaltered 265 * across invocations of the callback function. 266 * @result Returns a pointer to the requested section struct if it exists; 267 * otherwise returns NULL. 268 */ 269macho_seek_result macho_scan_load_commands( 270 const void * file_start, 271 const void * file_end, 272 macho_lc_callback lc_callback, 273 void * user_data); 274 275boolean_t macho_swap( 276 u_char * file); 277 278boolean_t macho_unswap( 279 u_char * file); 280 281struct segment_command * macho_get_segment_by_name( 282 struct mach_header * mach_header, 283 const char * segname); 284 285struct segment_command_64 * macho_get_segment_by_name_64( 286 struct mach_header_64 * mach_header, 287 const char * segname); 288 289struct section * macho_get_section_by_name( 290 struct mach_header * mach_header, 291 const char * segname, 292 const char * sectname); 293 294struct section_64 * macho_get_section_by_name_64( 295 struct mach_header_64 * mach_header, 296 const char * segname, 297 const char * sectname); 298 299boolean_t macho_remove_linkedit( 300 u_char * macho, 301 u_long * linkedit_size); 302 303boolean_t macho_trim_linkedit( 304 u_char *macho, 305 u_long *amount_trimmed); 306 307#endif /* __MACHO_UTIL_H__ */ 308