Exemple #1
0
const struct section_64 *
getsectbyname(
    const char *segname,
    const char *sectname)
{
    struct mach_header_64 *mhp = _NSGetMachExecuteHeader();

    return(getsectbynamefromheader_64(mhp, segname, sectname));
}
GSList*
mono_w32process_get_modules (pid_t pid)
{
	GSList *ret = NULL;
	MonoW32ProcessModule *mod;
	guint32 count;
	int i = 0;

	if (pid != getpid ())
		return NULL;

	count = _dyld_image_count ();
	for (i = 0; i < count; i++) {
#if SIZEOF_VOID_P == 8
		const struct mach_header_64 *hdr;
		const struct section_64 *sec;
#else
		const struct mach_header *hdr;
		const struct section *sec;
#endif
		const char *name;

		name = _dyld_get_image_name (i);
#if SIZEOF_VOID_P == 8
		hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
		sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
#else
		hdr = _dyld_get_image_header (i);
		sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
#endif

		/* Some dynlibs do not have data sections on osx (#533893) */
		if (sec == 0)
			continue;

		mod = g_new0 (MonoW32ProcessModule, 1);
		mod->address_start = GINT_TO_POINTER (sec->addr);
		mod->address_end = GINT_TO_POINTER (sec->addr+sec->size);
		mod->perms = g_strdup ("r--p");
		mod->address_offset = 0;
		mod->device = makedev (0, 0);
		mod->inode = i;
		mod->filename = g_strdup (name);

		if (g_slist_find_custom (ret, mod, mono_w32process_module_equals) == NULL) {
			ret = g_slist_prepend (ret, mod);
		} else {
			mono_w32process_module_free (mod);
		}
	}

	return g_slist_reverse (ret);
}
Exemple #3
0
/*
 * This routine returns the a pointer to the data for the named section in the
 * named segment if it exist in the 64-bit mach header passed to it.  Also it
 * returns the size of the section data indirectly through the pointer size.
 * Otherwise it returns zero for the pointer and the size.
 */
char *
getsectdatafromheader_64(
    struct mach_header_64 *mhp,
    const char *segname,
    const char *sectname,
    unsigned long *size)
{
    const struct section_64 *sp;

    sp = getsectbynamefromheader_64(mhp, segname, sectname);
    if(sp == NULL) {
        *size = 0;
        return(NULL);
    }
    *size = sp->size;
    return((char *)((uintptr_t)(sp->addr)));
}
Exemple #4
0
/*
 * This routine returns the a pointer to the data for the named section in the
 * named segment if it exist in the named Framework.  Also it returns the size
 * of the section data indirectly through the pointer size.  Otherwise it
 * returns zero for the pointer and the size.  The last component of the path
 * of the Framework is passed as FrameworkName.
 */
void *
getsectdatafromFramework(
    const char *FrameworkName,
    const char *segname,
    const char *sectname,
    unsigned long *size)
{
    uint32_t i, n;
    uintptr_t vmaddr_slide;
#ifndef __LP64__
    struct mach_header *mh;
    const struct section *s;
#else /* defined(__LP64__) */
    struct mach_header_64 *mh;
    const struct section_64 *s;
#endif /* defined(__LP64__) */
    char *name, *p;

    n = _dyld_image_count();
    for(i = 0; i < n ; i++) {
        name = _dyld_get_image_name(i);
        p = strrchr(name, '/');
        if(p != NULL && p[1] != '\0')
            name = p + 1;
        if(strcmp(name, FrameworkName) != 0)
            continue;
        mh = _dyld_get_image_header(i);
        vmaddr_slide = _dyld_get_image_vmaddr_slide(i);
#ifndef __LP64__
        s = getsectbynamefromheader(mh, segname, sectname);
#else /* defined(__LP64__) */
        s = getsectbynamefromheader_64(mh, segname, sectname);
#endif /* defined(__LP64__) */
        if(s == NULL) {
            *size = 0;
            return(NULL);
        }
        *size = s->size;
        return((void *)(s->addr + vmaddr_slide));
    }
    *size = 0;
    return(NULL);
}
Exemple #5
0
/*
 * iterate over __cstring section to find location of m3u and m3u8 strings, and patch'em!
 * could be better :-)
 */
int
find_and_patch_addresses(struct header_info *hi)
{
    // get pointer to the __cstring section
    const struct section_64 *cstring_section = getsectbynamefromheader_64(hi->mh, "__TEXT", "__cstring");
    // header values do not have ASLR slide so fix it
    mach_vm_address_t cstring_addr = cstring_section->addr + hi->aslr_slide;
	// search for the addresses of the right strings to be patched
    char *cstring_mem = (char*)cstring_addr;
    int index = 0;
    
	for (uint64_t w = 0 ; w < cstring_section->size; w++)
	{   
		// match m3u
		if (*(int*)cstring_mem == 0x0075336d)
		{
            mach_vm_address_t patch_addr = cstring_addr + w;
            hi->patch_addresses[index++] = patch_addr;
            DEBUG_MSG("Found m3u address to be patched %p\n", (void*)patch_addr);
            if (patchmemory(patch_addr) != 0)
            {
                ERROR_MSG("Failed to patch m3u.");
                return -1;
            }
			
		}
		// match first bytes of m3u8
		else if (*(int*)cstring_mem == 0x3875336d)
		{
            mach_vm_address_t patch_addr = cstring_addr + w;
            hi->patch_addresses[index++] = patch_addr;
            DEBUG_MSG("Found m3u8 address to be patched %p\n", (void*)patch_addr);
            if (patchmemory(patch_addr) != 0)
            {
                ERROR_MSG("Failed to patch m3u8.");
                return -1;
            }
		}
		// move to the next byte in the array
		cstring_mem++;
	}
    return 0;
}
primitiveExecutableModulesAndOffsets(void)
{
    const struct mach_header *h;
    const struct mach_header_64 *h64;
    sqInt i;
    const char *name;
    char *nameObjData;
    sqInt nimages;
    sqInt resultObj;
    const struct section *s;
    const struct section_64 *s64;
    usqIntptr_t size;
    usqIntptr_t slide;
    usqIntptr_t start;
    sqInt valueObj;

	
#  if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4

	/* _dyld_present was deprecated in 10.5 */
	if (!(_dyld_present())) {
		return primitiveFail();
	}

#  endif /* MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4 */

	nimages = _dyld_image_count();
	resultObj = instantiateClassindexableSize(classArray(), nimages * 4);
	if (resultObj == 0) {
		return primitiveFail();
	}
	pushRemappableOop(resultObj);
	for (i = 0; i < nimages; i += 1) {

		/* impossible start & size */
		start = (size = -1);
		name = _dyld_get_image_name(i);
		slide = _dyld_get_image_vmaddr_slide(i);
		
#    if __x86_64__
		h64 = (const struct mach_header_64 *)_dyld_get_image_header(i);
		if (!(h64 == null)) {
			s64 = getsectbynamefromheader_64(h64,SEG_TEXT,SECT_TEXT);
			if (!(s64 == null)) {
				start = s64->addr;
				size = s64->size;
			}
		}

#    else /* __x86_64__ */
		h = _dyld_get_image_header(i);
		if (!(h == null)) {
			s = getsectbynamefromheader(h,SEG_TEXT,SECT_TEXT);
			if (!(s == null)) {
				start = s->addr;
				size = s->size;
			}
		}

#    endif /* __x86_64__ */

		valueObj = instantiateClassindexableSize(classString(), strlen(name));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue(i * 4, topRemappableOop(), valueObj);
		nameObjData = arrayValueOf(valueObj);
		memcpy(nameObjData, name, strlen(name));
		valueObj = (BytesPerWord == 8
			? signed64BitIntegerFor(slide)
			: signed32BitIntegerFor(slide));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 1, topRemappableOop(), valueObj);
		/* begin positiveMachineIntegerFor: */
		valueObj = (BytesPerWord == 8
			? positive64BitIntegerFor(start)
			: positive32BitIntegerFor(start));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 2, topRemappableOop(), valueObj);
		/* begin positiveMachineIntegerFor: */
		valueObj = (BytesPerWord == 8
			? positive64BitIntegerFor(size)
			: positive32BitIntegerFor(size));
		if (failed()) {
			popRemappableOop();
			return primitiveFail();
		}
		storePointerofObjectwithValue((i * 4) + 3, topRemappableOop(), valueObj);
	}
	resultObj = popRemappableOop();
	return popthenPush(1, resultObj);
}
Exemple #7
0
void loaderMach(Desasembleur* desas, Fichier* fichier) {
    
    char* chemin = fichier->chemin;
    int fd = open(chemin, O_RDONLY);
    struct stat stat_buf;
    fstat(fd, &stat_buf);
    size_t size = stat_buf.st_size;
    /*============================= chargement en mémoire====================*/
    void* debutReel = mmap(0, size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, 0);
    
    DISASM* prog = desas->disasm;
    
    
    
    struct fat_header* fat = (struct fat_header*) debutReel;
    if (fat->magic == FAT_CIGAM) { // du coup ça m apprend que mon processeur est un little-endian
                                   // en effet, apres recherche, les intels sont little-endien, les motorola sont big-endian
        printf("c est un fat binary : je ne peux de le desassembler\n(dans un prochaine version sans doute...)\n");
        exit(EXIT_FAILURE);
    }
    
//    unsigned long addr = (unsigned long) debutReel;
//
//    // The first bytes of a Mach-O file comprise its header
////    struct mach_header_64 *mh = (struct mach_header_64 *) addr;
//
//    // Load commands follow the header
//    addr += sizeof (struct mach_header_64);
//
////    printf("There are %d load commands\n", mh->ncmds);
//
//    int fini = 0;
//    unsigned long debutVirtuel;
//    unsigned long taille;
//    while (!fini) {
//        struct load_command *lc = (struct load_command *) addr;
//        if (lc->cmd == LC_SEGMENT_64) {
//            struct segment_command_64 *sc = (struct segment_command_64 *) addr;
//            if (strcmp(sc->segname, "__TEXT") == 0) {
//                unsigned long addrSec = addr + sizeof (struct segment_command_64);
//                while (!fini) { // il y a forcement un __text dans ce cas
//                    struct section_64* sec = (struct section_64*) addrSec;
//                    addrSec += sizeof (struct section_64);
//                    if (strcmp(sec->sectname, "__text") == 0) {
//                        fini = 1;
//                        debutVirtuel = 0x100000000 + sec->offset; // /*+ sizeof (struct mach_header_64)*/ + (unsigned long) debutReel;
////                        printf("début du bloc : 0x%lx\n", debutVirtuel);
//                        taille = sec->size;
////                        printf("taille du bloc : 0x%lx\n", taille);
//                    }
//                }
//            }
//        }
//        //avance a la prochaine load_command
//        addr += lc->cmdsize;
//    }
    
    //===============================================================
    
    const struct section_64* section = getsectbynamefromheader_64(debutReel, "__TEXT", "__text");
    unsigned long debutVirtuel = section->addr;
    unsigned long taille = section->size;
    desas->debutVirtuel = debutVirtuel;
    
    unsigned long pev;
    unsigned long addr = (unsigned long) debutReel + sizeof (struct mach_header_64);
    int fini = 0;
    while (!fini) {
        struct load_command *lc = (struct load_command *) addr;
        if (lc->cmd == LC_UNIXTHREAD) {
            struct lecteurRegistre* t = (struct lecteurRegistre*) addr;
            pev = t->state.uts.ts64.__rip;
            initialiseRegistre(desas->proc, t->state);
            fini = 1;
        }
        addr += lc->cmdsize;
    }
    
    
    unsigned long per = ((unsigned long) debutReel) + pev - (debutVirtuel - section->offset);
    
    prog->EIP = (UIntPtr) per;
    prog->Archi = 64;
    prog->Options = Tabulation + NasmSyntax + PrefixedNumeral + ShowSegmentRegs;
    prog->VirtualAddr = pev;
    prog->SecurityBlock = (unsigned int) (taille - (pev - debutVirtuel));

//    printf("\nDone.\n\n");
    close(fd);
    return;
}