Exemple #1
0
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**>(
		getsectdata(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*>(
		getsectdata(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 CFStringRef _CFBundleDYLDCopyLoadedImagePathForPointer(void *p) {
    CFStringRef result = NULL;
#if USE_DYLD_PRIV
    const char *name = dyld_image_path_containing_address(p);
    if (name) result = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, name);
#else /* USE_DYLD_PRIV */
    if (!result) {
        uint32_t i, j, n = _dyld_image_count();
        Boolean foundIt = false;
        const char *name;
#if TARGET_RT_64_BIT
#define MACH_HEADER_TYPE struct mach_header_64
#define MACH_SEGMENT_CMD_TYPE struct segment_command_64
#define MACH_SEGMENT_FLAVOR LC_SEGMENT_64
#else
#define MACH_HEADER_TYPE struct mach_header
#define MACH_SEGMENT_CMD_TYPE struct segment_command
#define MACH_SEGMENT_FLAVOR LC_SEGMENT
#endif
        for (i = 0; !foundIt && i < n; i++) {
            const MACH_HEADER_TYPE *mh = (const MACH_HEADER_TYPE *)_dyld_get_image_header(i);
            uintptr_t addr = (uintptr_t)p - _dyld_get_image_vmaddr_slide(i);
            if (mh) {
                struct load_command *lc = (struct load_command *)((char *)mh + sizeof(MACH_HEADER_TYPE));
                for (j = 0; !foundIt && j < mh->ncmds; j++, lc = (struct load_command *)((char *)lc + lc->cmdsize)) {
                    if (MACH_SEGMENT_FLAVOR == lc->cmd && ((MACH_SEGMENT_CMD_TYPE *)lc)->vmaddr <= addr && addr < ((MACH_SEGMENT_CMD_TYPE *)lc)->vmaddr + ((MACH_SEGMENT_CMD_TYPE *)lc)->vmsize) {
                        foundIt = true;
                        name = _dyld_get_image_name(i);
                        if (name) result = CFStringCreateWithFileSystemRepresentation(kCFAllocatorSystemDefault, name);
                    }
                }
            }
        }
#undef MACH_HEADER_TYPE
#undef MACH_SEGMENT_CMD_TYPE
#undef MACH_SEGMENT_FLAVOR
    }
#endif /* USE_DYLD_PRIV */
#if LOG_BUNDLE_LOAD
    printf("dyld image path for pointer %p is %p\n", p, result);
#endif /* LOG_BUNDLE_LOAD */
    return result;
}