Example #1
0
func NewMachOLoader(r io.ReaderAt, archHint string) (models.Loader, error) {
	var (
		file    *macho.File
		fatFile *macho.FatFile
		err     error
	)
	magic := getMagic(r)
	if bytes.Equal(magic, fatMagic) {
		fatFile, err = macho.NewFatFile(r)
		if fatFile != nil {
			for _, arch := range fatFile.Arches {
				if machineName, ok := machoCpuMap[arch.Cpu]; ok {
					if machineName == archHint || archHint == "any" {
						file = arch.File
						break
					}
				}
			}
			if file == nil {
				return nil, fmt.Errorf("Could not find Mach-O fat binary entry for arch '%s'.", archHint)
			}
		}
	} else {
		file, err = macho.NewFile(r)
	}
	if err != nil {
		return nil, err
	}
	var bits int
	switch file.Magic {
	case macho.Magic32:
		bits = 32
	case macho.Magic64:
		bits = 64
	default:
		return nil, errors.New("Unknown ELF class.")
	}
	machineName, ok := machoCpuMap[file.Cpu]
	if !ok {
		return nil, fmt.Errorf("Unsupported CPU: %s", file.Cpu)
	}
	entry, err := findEntry(file, bits)
	if err != nil {
		return nil, err
	}
	return &MachOLoader{
		LoaderHeader: LoaderHeader{
			arch:  machineName,
			bits:  bits,
			os:    "darwin",
			entry: entry,
		},
		file: file,
	}, nil
}
Example #2
0
func (fq *findQueue) worker() {
	for fp := range fq.queue {
		blacklisted := false
		for _, re := range blacklistRegexps {
			blacklisted = blacklisted || re.MatchString(fp)
		}
		if blacklisted {
			continue
		}

		f, err := os.Open(fp)
		if err != nil {
			log.Printf("%s: %v", fp, err)
			continue
		}

		fatFile, err := macho.NewFatFile(f)
		if err == nil {
			// The file is fat, so dump its architectures.
			for _, fatArch := range fatFile.Arches {
				fq.dumpMachOFile(fp, fatArch.File)
			}
			fatFile.Close()
		} else if err == macho.ErrNotFat {
			// The file isn't fat but may still be MachO.
			thinFile, err := macho.NewFile(f)
			if err != nil {
				log.Printf("%s: %v", fp, err)
				continue
			}
			fq.dumpMachOFile(fp, thinFile)
			thinFile.Close()
		} else {
			f.Close()
		}
	}
}