#ifndef __MACHO_UTIL_H__ #define __MACHO_UTIL_H__ #include /*! @header macho_util Handy functions for working with Mach-O files. Very rudimentary, use at your own risk. */ /*! * @define MAGIC32 * @abstract Get the 32-bit magic number from a file data pointer. * @param ptr A pointer to a file whose magic number you want to get. * @result Returns an unsigned 32-bit integer containing * the first four bytes of the file data. */ #define MAGIC32(ptr) (*((uint32_t *)(ptr))) #define ISMACHO(magic) (((magic) == MH_MAGIC) || \ ((magic) == MH_CIGAM) || \ ((magic) == MH_MAGIC_64) || \ ((magic) == MH_CIGAM_64)) #define ISSWAPPEDMACHO(magic) (((magic) == MH_CIGAM) || \ ((magic) == MH_CIGAM_64)) /******************************************************************************* * *******************************************************************************/ #define CondSwapInt32(flag, value) ((flag) ? OSSwapInt32((value)) : \ (uint32_t)(value)) /*! * @enum macho_seek_result * @abstract Results of a lookup within a Mach-O file. * @discussion This enum lists the possible return values for a Mach-O lookup. * @constant macho_seek_result_error Invalid arguments or bad Mach-O file. * @constant macho_seek_result_found The requested item was found. * @constant macho_seek_result_not_found The requested item was not found. * For functions called repeatedly (such as the macho_lc_callback), * this means the item may be found on a subsequent invocation. * @constant macho_seek_result_stop The requested item will not be found. * This is only returned by functions that may be called repeatedly, * when they can determine conclusively that the requested item does not exist. */ typedef enum { macho_seek_result_error = -1, macho_seek_result_found = 0, macho_seek_result_not_found = 1, macho_seek_result_stop = 2, } macho_seek_result; /*! * @function macho_find_symbol * @abstract Finds symbol data in a mapped Mach-O file. * @discussion * The macho_find_symbol function searches a memory-mapped Mach-O file * for a given symbol, * indirectly returning the address within that mapped file * containing the data for that symbol. * @param mach_header A pointer to the beginning of the mapped Mach-O file. * @param file_end A pointer to the end of the mapped Mach-O file. * @param symbol_name The name of the symbol to find. * @param symbol_address The address of a pointer that will be filled * with the location of the symbol's data if it is found. * @result Returns macho_seek_result_found if the symbol is found, * macho_seek_result_not_found if the symbol is not defined in the given file, * or macho_seek_result_error if an error occurs. */ macho_seek_result macho_find_symbol( const void * file_start, const void * file_end, const char * symbol_name, const void ** symbol_address); /*! * @function macho_find_symtab * @abstract Finds a mapped Mach-O file's symbol table. * @discussion * The macho_find_symtab function locates the symbol table of a Mach-O * file. Only the LC_SYMTAB load command is located, not the LC_DSYMTAB. * @param mach_header A pointer to the beginning of the mapped Mach-O file. * @param file_end A pointer to the end of the mapped Mach-O file. * @param symtab A pointer to the address of a symtab_command struct; * if provided, this is filled with the address of the file's symbol table. * @result Returns macho_seek_result_found if the symbol table is found, * macho_seek_result_not_found if a symbol table is not defined in the given file, * or macho_seek_result_error if an error occurs. */ macho_seek_result macho_find_symtab( const void * file_start, const void * file_end, struct symtab_command ** symtab); /*! * @function macho_find_section_numbered * @abstract Finds an ordinal section in a Mach-O file. * @discussion * The macho_find_section_numbered function locates an ordinally-numbered * section within a Mach-O file, which is needed for calculating proper * offsets and addresses of such things as nlist entries. * Sections are numbered in a Mach-O file starting with 1, since zero * is reserved to mean "no section". * Since you will likely be passing a section number directly from other * structure within the same Mach-O file, this should not be a problem. * @param mach_header A pointer to the beginning of the mapped Mach-O file. * @param file_end A pointer to the end of the mapped Mach-O file. * @param sect_num The ordinal number of the section to get, starting with 1. * @result Returns a pointer to the requested section struct if it exists; * otherwise returns NULL. */ struct section * macho_find_section_numbered( const void * file_start, const void * file_end, uint8_t sect_num); /*! * @typedef macho_lc_callback * @abstract The callback function used when scanning Mach-O load commands * with macho_scan_load_commands. * @discussion macho_lc_callback defines the callback function * invoked by macho_scan_load_commands for each load command it encounters. * The scan function passes a pointer to a user data struct that you can use * for search parameters, running information, and search results. * @param load_command A pointer to the Mach-O load command being processed. * @param file_end A pointer to the end of the mapped Mach-O file, * to be used for bounds checking. * @param swap A boolean flag indicating whether the Mach-O file's byte order * is opposite the host's. * If nonzero, the callback needs to swap all multibyte values * read from the Mach-O file. * @param user_data A pointer to user-defined data that is passed unaltered * across invocations of the callback function. * @result Returns macho_seek_result_found if the requested item is found, * macho_seek_result_not_found if is not found on this call, * macho_seek_result_stop if the function determined that it does not exist, * or macho_seek_result_error if an error occurs * (particularly if any data structure to be accessed * would run past the end of the file). */ typedef macho_seek_result (*macho_lc_callback)( struct load_command * load_command, const void * file_end, uint8_t swap, void * user_data ); /*! * @function macho_scan_load_commands * @abstract Iterates over the load commands of a Mach-O file using a callback. * @discussion * The macho_scan_load_commands iterates over the load commands within a * Mach-O file, invoking a user-supplied callback until that callback * returns a result indicating the scan should stop. * @param mach_header A pointer to the beginning of the mapped Mach-O file. * @param file_end A pointer to the end of the mapped Mach-O file. * @param lc_callback A function that is invoked on each load command * of the Mach-O file until the callback function * indicates the scan is finished. * @param user_data A pointer to user-defined data that is passed unaltered * across invocations of the callback function. * @result Returns a pointer to the requested section struct if it exists; * otherwise returns NULL. */ macho_seek_result macho_scan_load_commands( const void * file_start, const void * file_end, macho_lc_callback lc_callback, void * user_data); #endif /* __MACHO_UTIL_H__ */