Пример #1
0
func sanity() {
	goBinGo := path.Join(config.Gosrcroot, "go/bin/go")
	log.Printf("check %v as the go binary", goBinGo)
	_, err := os.Stat(goBinGo)
	if err == nil {
		config.Go = "go/bin/go"
	}
	// but does the one in go/bin/OS_ARCH exist too?
	archgo := fmt.Sprintf("bin/%s_%s/go", config.Goos, config.Arch)
	linuxBinGo := path.Join(config.Gosrcroot, archgo)
	log.Printf("check %v as the go binary", linuxBinGo)
	_, err = os.Stat(linuxBinGo)
	if err == nil {
		config.Go = archgo
		goBinGo = linuxBinGo
	}
	log.Printf("Using %v as the go command", goBinGo)
	if config.Go == "" {
		log.Fatalf("Can't find a go binary! Is GOROOT set correctly?")
	}
	f, err := elf.Open(goBinGo)
	if err != nil {
		log.Fatalf("%v is not an ELF file; don't know what to do", goBinGo)
	}
	ds := f.SectionByType(elf.SHT_DYNAMIC)
	if ds != nil {
		log.Printf("U-root requires a staticically built go tree at present. %v is dynamic.", goBinGo)
		log.Fatalf("To fix this:\ncd %v/src\nexport CGO_ENABLED=0\nGOARCH=%v ./make.bash", config.Goroot, config.Arch)
	}
}
Пример #2
0
func IsELF(fPath string) error {
	if _, err := elf.Open(fPath); err != nil {
		return err
	}

	return nil
}
Пример #3
0
func cmdMode(cmd string, args []string) error {
	f, err := elf.Open(cmd)
	if err != nil {
		return err
	}
	defer f.Close()

	// Set mem limits
	for _, p := range f.Progs {
		if p.Type != elf.PT_LOAD {
			continue
		}
		if p.Vaddr < startAddr {
			startAddr = p.Vaddr
		}
		if addr := p.Vaddr + p.Memsz; addr > endAddr {
			endAddr = addr
		}
	}

	pt, err := ForkExec(cmd, args)
	if err != nil {
		return err
	}
	if err := pt.Wait(printPC); err != nil {
		return err
	}
	return nil
}
Пример #4
0
func getDwarf(execname string) *dwarf.Data {
	e, err := elf.Open(execname)
	if err == nil {
		defer e.Close()
		d, err := e.DWARF()
		if err == nil {
			return d
		}
	}
	m, err := macho.Open(execname)
	if err == nil {
		defer m.Close()
		d, err := m.DWARF()
		if err == nil {
			return d
		}
	}
	p, err := pe.Open(execname)
	if err == nil {
		defer p.Close()
		d, err := p.DWARF()
		if err == nil {
			return d
		}
	}
	log.Fatal("can't get dwarf info from executable", err)
	return nil
}
Пример #5
0
func FindFunc(fileName string, pc uint64) (s elf.Symbol, err error) {
	file, err := elf.Open(fileName)
	if err != nil {
		return elf.Symbol{}, err
	}

	symbols, err := file.Symbols()
	if err != nil {
		return elf.Symbol{}, err
	}

	funcSymbols := make(Symbols, 0)
	for _, symbol := range symbols {
		if elf.ST_TYPE(symbol.Info) == elf.STT_FUNC {
			funcSymbols = append(funcSymbols, symbol)
		}
	}
	n := len(funcSymbols)
	if n == 0 {
		return elf.Symbol{}, &ErrNoFunctions{}
	}

	sort.Sort(funcSymbols)
	i := sort.Search(n, func(i int) bool { return funcSymbols[i].Value >= pc })
	if i != 0 || funcSymbols[i].Value <= pc {
		if i == n || (funcSymbols[i].Value != pc && i != 0) {
			i--
		}
		return funcSymbols[i], nil
	}

	return elf.Symbol{}, &ErrFunctionNotFound{}
}
Пример #6
0
func testBuildID(t *testing.T) {
	f, err := elf.Open("/proc/self/exe")
	if err != nil {
		if os.IsNotExist(err) {
			t.Skip("no /proc/self/exe")
		}
		t.Fatal("opening /proc/self/exe: ", err)
	}
	defer f.Close()

	c := 0
	for i, s := range f.Sections {
		if s.Type != elf.SHT_NOTE {
			continue
		}

		d, err := s.Data()
		if err != nil {
			t.Logf("reading data of note section %d: %v", i, err)
			continue
		}

		for len(d) > 0 {

			// ELF standards differ as to the sizes in
			// note sections.  Both the GNU linker and
			// gold always generate 32-bit sizes, so that
			// is what we assume here.

			if len(d) < 12 {
				t.Logf("note section %d too short (%d < 12)", i, len(d))
				continue
			}

			namesz := f.ByteOrder.Uint32(d)
			descsz := f.ByteOrder.Uint32(d[4:])
			typ := f.ByteOrder.Uint32(d[8:])

			an := (namesz + 3) &^ 3
			ad := (descsz + 3) &^ 3

			if int(12+an+ad) > len(d) {
				t.Logf("note section %d too short for header (%d < 12 + align(%d,4) + align(%d,4))", i, len(d), namesz, descsz)
				continue
			}

			// 3 == NT_GNU_BUILD_ID
			if typ == 3 && namesz == 4 && bytes.Equal(d[12:16], []byte("GNU\000")) {
				c++
			}

			d = d[12+an+ad:]
		}
	}

	if c > 1 {
		t.Errorf("found %d build ID notes", c)
	}
}
Пример #7
0
func main() {
	file, err := elf.Open("hello")
	if err != nil {
		log.Fatalf("failed opening file: %s", err)
	}
	defer file.Close()
	printDwarfInformation(file)
}
Пример #8
0
func main() {
	file, err := elf.Open("bash.elf")
	if err != nil {
		log.Fatalf("failed opening file: %s", err)
	}
	defer file.Close()
	printFileInformation(file)
}
Пример #9
0
func crack(file string, t *testing.T) (*elf.File, *Table) {
	// Open self
	f, err := elf.Open(file)
	if err != nil {
		t.Fatal(err)
	}
	return parse(file, f, t)
}
Пример #10
0
func main() {
	file, err := elf.Open("doozerd")
	if err != nil {
		log.Fatalf("failed opening file: %s", err)
	}
	defer file.Close()
	processGoInformation(file)
}
Пример #11
0
Файл: out.go Проект: jnwhiteh/go
func dynimport(obj string) {
	if f, err := elf.Open(obj); err == nil {
		sym, err := f.ImportedSymbols()
		if err != nil {
			fatalf("cannot load imported symbols from ELF file %s: %v", obj, err)
		}
		for _, s := range sym {
			targ := s.Name
			if s.Version != "" {
				targ += "@" + s.Version
			}
			fmt.Printf("#pragma dynimport %s %s %q\n", s.Name, targ, s.Library)
		}
		lib, err := f.ImportedLibraries()
		if err != nil {
			fatalf("cannot load imported libraries from ELF file %s: %v", obj, err)
		}
		for _, l := range lib {
			fmt.Printf("#pragma dynimport _ _ %q\n", l)
		}
		return
	}

	if f, err := macho.Open(obj); err == nil {
		sym, err := f.ImportedSymbols()
		if err != nil {
			fatalf("cannot load imported symbols from Mach-O file %s: %v", obj, err)
		}
		for _, s := range sym {
			if len(s) > 0 && s[0] == '_' {
				s = s[1:]
			}
			fmt.Printf("#pragma dynimport %s %s %q\n", s, s, "")
		}
		lib, err := f.ImportedLibraries()
		if err != nil {
			fatalf("cannot load imported libraries from Mach-O file %s: %v", obj, err)
		}
		for _, l := range lib {
			fmt.Printf("#pragma dynimport _ _ %q\n", l)
		}
		return
	}

	if f, err := pe.Open(obj); err == nil {
		sym, err := f.ImportedSymbols()
		if err != nil {
			fatalf("cannot load imported symbols from PE file %s: %v", obj, err)
		}
		for _, s := range sym {
			ss := strings.Split(s, ":", -1)
			fmt.Printf("#pragma dynimport %s %s %q\n", ss[0], ss[0], strings.ToLower(ss[1]))
		}
		return
	}

	fatalf("cannot parse %s as ELF, Mach-O or PE", obj)
}
Пример #12
0
func data2c(name string, path string) (string, error) {
	var out []byte
	var in []byte

	if elf, err := elf.Open(path); err == nil {
		elf.Close()
		cwd, err := os.Getwd()
		tmpf, err := ioutil.TempFile(cwd, name)
		if err != nil {
			log.Fatalf("%v\n", err)
		}
		args := []string{"-o", tmpf.Name(), path}
		cmd := exec.Command(toolprefix+"strip", args...)
		cmd.Env = nil
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		cmd.Stdout = os.Stdout
		log.Printf("%v", cmd.Args)
		err = cmd.Run()
		if err != nil {
			log.Fatalf("%v\n", err)
		}

		in, err = ioutil.ReadAll(tmpf)
		if err != nil {
			log.Fatalf("%v\n", err)
		}
		tmpf.Close()
		os.Remove(tmpf.Name())
	} else {
		var file *os.File
		var err error
		if file, err = os.Open(path); err != nil {
			log.Fatalf("%v", err)
		}
		in, err = ioutil.ReadAll(file)
		if err != nil {
			log.Fatalf("%v\n", err)
		}
		file.Close()
	}

	total := len(in)

	out = []byte(fmt.Sprintf("static unsigned char ramfs_%s_code[] = {\n", name))
	for len(in) > 0 {
		for j := 0; j < 16 && len(in) > 0; j++ {
			out = append(out, []byte(fmt.Sprintf("0x%02x, ", in[0]))...)
			in = in[1:]
		}
		out = append(out, '\n')
	}

	out = append(out, []byte(fmt.Sprintf("0,\n};\nint ramfs_%s_len = %v;\n", name, total))...)

	return string(out), nil
}
Пример #13
0
func HasSection(path string) bool {
	file, err := elf.Open(path)
	if err != nil {
		return false
	}
	defer file.Close()

	return file.Section("goblet") != nil
}
func main() {
	f, err := elf.Open(os.Args[0])
	if err != nil {
		fmt.Println("  ", err)
		return
	}
	fmt.Println(f.FileHeader.ByteOrder)
	f.Close()
}
Пример #15
0
func dump_elf(filename string) int {
	file, err := elf.Open(filename)
	if err != nil {
		fmt.Printf("Couldn’t open file : \"%s\" as an ELF.\n")
		return 2
	}
	dump_dynstr(file)
	dump_symbols(file)
	return 0
}
Пример #16
0
func main() {
	// len(Args)
	f, e := elf.Open(os.Args[1])
	if e != nil {
		println(e)
		return
	}

	text := f.Section(".text")

	gopclntab := f.Section(".gopclntab")
	gopclndata, e := gopclntab.Data()
	if e != nil {
		println(e)
		return
	}
	pclntab := gosym.NewLineTable(gopclndata, text.Addr)

	gosymtab := f.Section(".gosymtab")
	gosymdata, e := gosymtab.Data()
	symtab, e := gosym.NewTable(gosymdata, pclntab)
	if e != nil {
		println(e)
		return
	}

	args := make([]string, 3)
	args[0] = "/usr/bin/objdump"
	args[1] = "-D"
	args[2] = os.Args[1]
	cmd, e := exec.Run(args[0], args, os.Environ(), exec.DevNull, exec.Pipe, exec.MergeWithStdout)
	if e != nil {
		println(e)
		return
	}

	reader := bufio.NewReader(cmd.Stdout)
	for {
		line, e := reader.ReadString('\n')
		if e != nil {
			break
		}

		addr := extractAddrFromLine(line)

		function := symtab.PCToFunc(addr)
		if function != nil && function.Entry == addr {
			fmt.Printf("%08x <%s.%s>:\n", addr, function.Sym.PackageName(), function.Sym.BaseName())
		}

		print(line)
	}

	f.Close()
}
Пример #17
0
// The shared library does not have relocations against the text segment.
func TestNoTextrel(t *testing.T) {
	sopath := filepath.Join(gorootInstallDir, soname)
	f, err := elf.Open(sopath)
	if err != nil {
		t.Fatal("elf.Open failed: ", err)
	}
	defer f.Close()
	if hasDynTag(f, elf.DT_TEXTREL) {
		t.Errorf("%s has DT_TEXTREL set", soname)
	}
}
Пример #18
0
func elfData(t *testing.T, name string) *Data {
	f, err := elf.Open(name)
	if err != nil {
		t.Fatal(err)
	}

	d, err := f.DWARF()
	if err != nil {
		t.Fatal(err)
	}
	return d
}
Пример #19
0
// ExtractSymbolTable attempts to parse the DWARF section of a binary and return
// a symbol table. This currently just supports file names, and function
// definitions
func ExtractSymbolTable(binary string, offset uint64) (*SymbolTable, error) {
	files := make(SymbolTable)

	f, err := elf.Open(binary)
	if err != nil {
		return nil, err
	}
	defer f.Close()

	dwarfs, err := f.DWARF()
	if err != nil {
		return nil, err
	}

	dwarfReader := dwarfs.Reader()
	for {
		entry, _ := dwarfReader.Next()
		if entry == nil {
			break
		}

		/* TODO: This is all by value, make this references */
		// For now, all we need are files and functions
		switch entry.Tag {

		case dwarf.TagCompileUnit:
			file := extractFile(entry)
			// file.Lowpc += offset
			// file.Highpc += offset
			name := file.Filename

			if name == "" {
				continue
			}

			files[name] = file

		/* TODO: Stupid inefficient */
		case dwarf.TagSubprogram:
			fun := extractFunction(entry)
			// fun.Highpc += offset
			// fun.Lowpc += offset
			for _, v := range files {
				if contains(v, fun) {
					v.Functions[fun.Name] = fun
				}
			}
		}
	}

	return &files, nil

}
Пример #20
0
func dynStrings(t *testing.T, path string, flag elf.DynTag) []string {
	f, err := elf.Open(path)
	defer f.Close()
	if err != nil {
		t.Fatalf("elf.Open(%q) failed: %v", path, err)
	}
	dynstrings, err := f.DynString(flag)
	if err != nil {
		t.Fatalf("DynString(%s) failed on %s: %v", flag, path, err)
	}
	return dynstrings
}
Пример #21
0
func ELFAnal(input string, symbolsDump bool) ([][]int, error) {
	// An array of arrays for storing the section offsets
	var sectionData [][]int

	fmt.Printf("[+] Analyzing binary: %s\n", input)

	// Check for executable type
	elfFmt, err := elf.Open(input)
	if err != nil {
		return sectionData, err
	}
	defer elfFmt.Close()

	sections := elfFmt.Sections
	sectionCount := len(sections)

	fmt.Printf("[+] Number of sections: %d\n", sectionCount)

	for k := range sections {
		sec := sections[k]
		secName := sec.Name
		secSize := sec.Size
		secOffset := sec.Offset + 1
		secEnd := int(secOffset) + int(secSize) - 1

		fmt.Printf("\t Name: %s\n", secName)
		fmt.Printf("\t Size: %d\n", secSize)
		fmt.Printf("\t Offset: %d\n", secOffset)
		fmt.Printf("\t Section end: %d\n", secEnd)
		fmt.Println("")

		sectionData = append(sectionData, []int{int(secOffset), int(secEnd)})
	}

	symbols, err := elfFmt.ImportedSymbols()
	if err != nil {
		return sectionData, err
	}

	numberOfSymbols := len(symbols)

	fmt.Printf("[+] Found %d symbols\n", numberOfSymbols)
	if numberOfSymbols > 0 && symbolsDump {
		for k := range symbols {
			symName := symbols[k]

			fmt.Printf("\t Name: %s\n", symName)
		}
		fmt.Println("")
	}

	return sectionData, nil
}
Пример #22
0
func dynStrings(path string, flag elf.DynTag) []string {
	f, err := elf.Open(path)
	defer f.Close()
	if err != nil {
		log.Fatal("elf.Open failed: ", err)
	}
	dynstrings, err := f.DynString(flag)
	if err != nil {
		log.Fatal("dynstring failed: ", err)
	}
	return dynstrings
}
Пример #23
0
func ReadFromBinary(filename string) ([]byte, error) {
	file, err := elf.Open(os.Args[0])
	if err != nil {
		return []byte{}, err
	}

	sec := file.Section(filename)
	if sec == nil {
		return []byte{}, errors.New("no section for filename")
	}

	return sec.Data()
}
Пример #24
0
func checkPIE(t *testing.T, name string) {
	f, err := elf.Open(name)
	if err != nil {
		t.Fatal("elf.Open failed: ", err)
	}
	defer f.Close()
	if f.Type != elf.ET_DYN {
		t.Errorf("%s has type %v, want ET_DYN", name, f.Type)
	}
	if hasDynTag(f, elf.DT_TEXTREL) {
		t.Errorf("%s has DT_TEXTREL set", name)
	}
}
Пример #25
0
// gccDebug runs gcc -gdwarf-2 over the C program stdin and
// returns the corresponding DWARF data and, if present, debug data block.
func (p *Package) gccDebug(stdin []byte) (*dwarf.Data, binary.ByteOrder, []byte) {
	runGcc(stdin, p.gccCmd())

	if f, err := macho.Open(gccTmp); err == nil {
		d, err := f.DWARF()
		if err != nil {
			fatalf("cannot load DWARF output from %s: %v", gccTmp, err)
		}
		var data []byte
		if f.Symtab != nil {
			for i := range f.Symtab.Syms {
				s := &f.Symtab.Syms[i]
				// Mach-O still uses a leading _ to denote non-assembly symbols.
				if s.Name == "_"+"__cgodebug_data" {
					// Found it.  Now find data section.
					if i := int(s.Sect) - 1; 0 <= i && i < len(f.Sections) {
						sect := f.Sections[i]
						if sect.Addr <= s.Value && s.Value < sect.Addr+sect.Size {
							if sdat, err := sect.Data(); err == nil {
								data = sdat[s.Value-sect.Addr:]
							}
						}
					}
				}
			}
		}
		return d, f.ByteOrder, data
	}

	// Can skip debug data block in ELF and PE for now.
	// The DWARF information is complete.

	if f, err := elf.Open(gccTmp); err == nil {
		d, err := f.DWARF()
		if err != nil {
			fatalf("cannot load DWARF output from %s: %v", gccTmp, err)
		}
		return d, f.ByteOrder, nil
	}

	if f, err := pe.Open(gccTmp); err == nil {
		d, err := f.DWARF()
		if err != nil {
			fatalf("cannot load DWARF output from %s: %v", gccTmp, err)
		}
		return d, binary.LittleEndian, nil
	}

	fatalf("cannot parse gcc output %s as ELF, Mach-O, PE object", gccTmp)
	panic("not reached")
}
Пример #26
0
func ELFAnal(input string) ([]SectionData, []string, []string, error) {
	// An array of arrays for storing the section offsets
	var sectionData []SectionData
	var symbolsArr []string

	// Check for executable type
	elfFmt, err := elf.Open(input)
	if err != nil {
		return sectionData, []string{}, []string{}, NotValidELFFileError
	}
	defer elfFmt.Close()

	// Extract sections
	sections := elfFmt.Sections
	for k := range sections {
		sec := sections[k]
		secName := sec.Name
		secSize := sec.Size
		secOffset := sec.Offset + 1
		secEnd := secOffset + secSize - 1

		sd := SectionData{
			Name:   secName,
			Size:   int(secSize),
			Offset: int(secOffset),
			End:    int(secEnd),
		}

		sectionData = append(sectionData, sd)
	}

	// Get imported symbols
	symbols, err := elfFmt.ImportedSymbols()
	if err != nil {
		return sectionData, []string{}, []string{}, err
	}

	if len(symbols) > 0 {
		for k := range symbols {
			symbolsArr = append(symbolsArr, symbols[k].Name)
		}
	}

	// Get imported libraries
	libraries, err := elfFmt.ImportedLibraries()
	if err != nil {
		return sectionData, []string{}, []string{}, err
	}

	return sectionData, libraries, symbolsArr, nil
}
Пример #27
0
func TestElf(filename, expectedArch, expectedOs string, isVerbose bool) error {
	file, err := elf.Open(filename)

	if err != nil {
		log.Printf("File '%s' is not an ELF file: %v\n", filename, err)
		return err
	}
	defer file.Close()
	if isVerbose {
		log.Printf("File '%s' is an ELF file (arch: %s, osabi: %s)\n", filename, file.FileHeader.Machine.String(), file.FileHeader.OSABI.String())
	}
	if expectedOs == platforms.LINUX {
		if file.FileHeader.OSABI != elf.ELFOSABI_NONE && file.FileHeader.OSABI != elf.ELFOSABI_LINUX {
			return errors.New("Not a Linux executable")
		}
	}
	if expectedOs == platforms.NETBSD {
		if file.FileHeader.OSABI != elf.ELFOSABI_NETBSD {
			return errors.New("Not a NetBSD executable")
		}
	}
	if expectedOs == platforms.FREEBSD {
		if file.FileHeader.OSABI != elf.ELFOSABI_FREEBSD {
			return errors.New("Not a FreeBSD executable")
		}
	}
	if expectedOs == platforms.OPENBSD {
		if file.FileHeader.OSABI != elf.ELFOSABI_OPENBSD {
			return errors.New("Not an OpenBSD executable")
		}
	}

	if expectedArch == platforms.ARM {
		if file.FileHeader.Machine != elf.EM_ARM {
			return errors.New("Not an ARM executable")
		}
	}
	if expectedArch == platforms.X86 {
		if file.FileHeader.Machine != elf.EM_386 {
			return errors.New("Not a 386 executable")
		}

	}
	if expectedArch == platforms.AMD64 {
		if file.FileHeader.Machine != elf.EM_X86_64 {
			return errors.New("Not an AMD64 executable")
		}

	}
	return nil
}
Пример #28
0
func (v *Volume) Create() (err error) {
	if err = os.MkdirAll(v.Path, 0755); err != nil {
		return
	}
	defer func() {
		if err != nil {
			v.Remove()
		}
	}()

	for _, d := range v.dirs {
		dir := path.Join(v.Path, v.Version, d.name)
		if err := os.MkdirAll(dir, 0755); err != nil {
			return err
		}
		for _, f := range d.files {
			obj, err := elf.Open(f)
			if err != nil {
				return err
			}
			defer obj.Close()

			ok, err := blacklisted(f, obj)
			if err != nil {
				return err
			}
			if ok {
				continue
			}

			l := path.Join(dir, path.Base(f))
			if err := os.Link(f, l); err != nil {
				return err
			}
			soname, err := obj.DynString(elf.DT_SONAME)
			if err != nil {
				return err
			}
			if len(soname) > 0 {
				f = path.Join(v.Mountpoint, d.name, path.Base(f))
				l = path.Join(dir, soname[0])
				if err := os.Symlink(f, l); err != nil &&
					!os.IsExist(err.(*os.LinkError).Err) {
					return err
				}
			}
		}
	}
	return nil
}
Пример #29
0
func ExtractSection(path string) ([]byte, error) {
	file, err := elf.Open(path)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	section := file.Section("goblet")
	if section == nil {
		return nil, errors.New("no goblet section found")
	}

	return section.Data()
}
Пример #30
0
func (r *Reporter) SetExecutable(filename string) error {
	f, err := elf.Open(filename)
	if err != nil {
		return err
	}
	defer f.Close()
	symbols, err := f.Symbols()
	if err != nil {
		return err
	}
	sort.Sort(elfSymbolTable(symbols))
	r.Resolver = elfSymbolTable(symbols)
	return nil
}