const unsigned char *get_blocks_dat_start(int testnet) { size_t size; if (testnet) return getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size); else return getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size); }
size_t get_blocks_dat_size(int testnet) { size_t size; if (testnet) getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size); else getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size); return size; }
void ProcessImageLoad(const struct mach_header* mh, intptr_t slide) { unsigned long size; std::vector<const char*> classNames; void* dataPtr = nullptr; #ifdef OBJC_ABI_2 const class_t** classes; ProcessProtocolsNew(mh, slide); classes = reinterpret_cast<const class_t**>( getsectiondata(mh, SEG_OBJC_CLASSLIST_NEW, SECT_OBJC_CLASSLIST_NEW, &size) ); if (classes) { classNames = ProcessClassesNew(mh, slide, classes, size); dataPtr = (void*)*classes; } ProcessCategoriesNew(mh, slide); #else module_info* modinfo; ProcessProtocolsOld(mh, slide); modinfo = reinterpret_cast<module_info*>( getsectiondata(mh, SEG_OBJC_MODINFO_OLD, SECT_OBJC_MODINFO_OLD, &size) ); if (modinfo && modinfo->symtab) { classNames = ProcessClassesOld(mh, slide, modinfo); dataPtr = modinfo; ProcessCategoriesOld(mh, slide, modinfo); } #endif UpdateClassRefs(mh); UpdateSelectors(mh, slide); // Do this only for dynamic libs (slide > 0) if (!classNames.empty() && slide > 0) { // Generate a NSFramework_XXXX class for GNUstep's NSBundle const char* path = dyld_image_path_containing_address(dataPtr); assert(path != nullptr); //RegisterFramework(&classNames[0], classNames.size(), path); } static SEL selInit = sel_getUid("load"); while (!g_pendingInitClasses.empty()) { auto pair = g_pendingInitClasses.front(); g_pendingInitClasses.pop(); pair.second(reinterpret_cast<objc_object*>(pair.first), selInit); } }
static bool getResourceFromMappedFile(const char * filename, const byte * start_addr, MemoryBuffer &data, const char * type, unsigned id) { #if defined(_WIN32) || defined (_USE_BINUTILS) throwUnexpected(); #elif defined(__APPLE__) VStringBuffer sectname("%s_%u", type, id); // The first bytes are the Mach-O header const struct mach_header_64 *mh = (const struct mach_header_64 *) start_addr; if (mh->magic != MH_MAGIC_64) { DBGLOG("Failed to extract resource %s: Does not appear to be a Mach-O 64-bit binary", filename); return false; } unsigned long len = 0; unsigned char *data2 = getsectiondata(mh, "__TEXT", sectname.str(), &len); data.append(len, data2); return true; #else // The first bytes are the ELF header const Elf64_Ehdr * hdr = (const Elf64_Ehdr *) start_addr; if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0) { DBGLOG("Failed to extract resource %s: Does not appear to be a ELF binary", filename); return false; } if (hdr->e_ident[EI_CLASS] != ELFCLASS64) { DBGLOG("Failed to extract resource %s: Does not appear to be a ELF 64-bit binary", filename); return false; } //Check that there is a symbol table for the sections. if (hdr->e_shstrndx == SHN_UNDEF) { DBGLOG("Failed to extract resource %s: Does not include a section symbol table", filename); return false; } //Now walk the sections comparing the section names Elf64_Half numSections = hdr->e_shnum; const Elf64_Shdr * sectionHeaders = reinterpret_cast<const Elf64_Shdr *>(start_addr + hdr->e_shoff); const Elf64_Shdr & symbolTableSection = sectionHeaders[hdr->e_shstrndx]; const char * symbolTable = (const char *)start_addr + symbolTableSection.sh_offset; VStringBuffer sectname("%s_%u", type, id); for (unsigned iSect= 0; iSect < numSections; iSect++) { const Elf64_Shdr & section = sectionHeaders[iSect]; const char * sectionName = symbolTable + section.sh_name; if (streq(sectionName, sectname)) { data.append(section.sh_size, start_addr + section.sh_offset); return true; } } DBGLOG("Failed to extract resource %s: Does not include a matching entry", filename); return false; #endif }
static os_redirect_t _os_find_log_redirect_func(os_mach_header *hdr) { os_redirect_t result = NULL; char name[128]; unsigned long size = 0; uint8_t *data = getsectiondata(hdr, OS_ASSUMES_REDIRECT_SEG, OS_ASSUMES_REDIRECT_SECT, &size); if (!data) { data = getsectiondata(hdr, "__TEXT", OSX_ASSUMES_LOG_REDIRECT_SECT_NAME, &size); if (data && size < sizeof(name) - 2) { (void)strlcpy(name, (const char *)data, size + 1); result = dlsym(RTLD_DEFAULT, name); } } else if (size == sizeof(struct _os_redirect_assumes_s)) { struct _os_redirect_assumes_s *redirect = (struct _os_redirect_assumes_s *)data; result = redirect->redirect; } return result; }
void UpdateClassRefs(const struct mach_header* mh) { clsref* class_refs; unsigned long refsize; class_refs = reinterpret_cast<clsref*>( getsectiondata(mh, SEG_OBJC_CLASSREFS_OLD, SECT_OBJC_CLASSREFS_OLD, &refsize) ); if (class_refs) { for (size_t i = 0; i < refsize / sizeof(clsref); i++) { Class c = (Class) objc_getClass(class_refs[i].clsName); LOG << "ObjC fixup classref @" << &class_refs[i].cls << ": " << class_refs[i].cls << " -> " << c << std::endl; class_refs[i].cls = c; } } }