Пример #1
0
func hasDynTag(f *elf.File, tag elf.DynTag) bool {
	ds := f.SectionByType(elf.SHT_DYNAMIC)
	if ds == nil {
		return false
	}
	d, err := ds.Data()
	if err != nil {
		return false
	}
	for len(d) > 0 {
		var t elf.DynTag
		switch f.Class {
		case elf.ELFCLASS32:
			t = elf.DynTag(f.ByteOrder.Uint32(d[0:4]))
			d = d[8:]
		case elf.ELFCLASS64:
			t = elf.DynTag(f.ByteOrder.Uint64(d[0:8]))
			d = d[16:]
		}
		if t == tag {
			return true
		}
	}
	return false
}
Пример #2
0
func hasDynTag(t *testing.T, f *elf.File, tag elf.DynTag) bool {
	ds := f.SectionByType(elf.SHT_DYNAMIC)
	if ds == nil {
		t.Error("no SHT_DYNAMIC section")
		return false
	}
	d, err := ds.Data()
	if err != nil {
		t.Errorf("can't read SHT_DYNAMIC contents: %v", err)
		return false
	}
	for len(d) > 0 {
		var t elf.DynTag
		switch f.Class {
		case elf.ELFCLASS32:
			t = elf.DynTag(f.ByteOrder.Uint32(d[:4]))
			d = d[8:]
		case elf.ELFCLASS64:
			t = elf.DynTag(f.ByteOrder.Uint64(d[:8]))
			d = d[16:]
		}
		if t == tag {
			return true
		}
	}
	return false
}
Пример #3
0
// The shared library contains a note containing the ABI hash that is mapped into
// memory and there is a local symbol called go.link.abihashbytes that points 16
// bytes into it.
func testABIHashNote(t *testing.T, f *elf.File, note *note) {
	if note.section.Flags != elf.SHF_ALLOC {
		t.Errorf("abi hash section has flags %v", note.section.Flags)
	}
	if !isOffsetLoaded(f, note.section.Offset) {
		t.Errorf("abihash section not contained in PT_LOAD segment")
	}
	var hashbytes elf.Symbol
	symbols, err := f.Symbols()
	if err != nil {
		t.Errorf("error reading symbols %v", err)
		return
	}
	for _, sym := range symbols {
		if sym.Name == "go.link.abihashbytes" {
			hashbytes = sym
		}
	}
	if hashbytes.Name == "" {
		t.Errorf("no symbol called go.link.abihashbytes")
		return
	}
	if elf.ST_BIND(hashbytes.Info) != elf.STB_LOCAL {
		t.Errorf("%s has incorrect binding %v", hashbytes.Name, elf.ST_BIND(hashbytes.Info))
	}
	if f.Sections[hashbytes.Section] != note.section {
		t.Errorf("%s has incorrect section %v", hashbytes.Name, f.Sections[hashbytes.Section].Name)
	}
	if hashbytes.Value-note.section.Addr != 16 {
		t.Errorf("%s has incorrect offset into section %d", hashbytes.Name, hashbytes.Value-note.section.Addr)
	}
}
Пример #4
0
func haveDynTag(file *elf.File, tag elf.DynTag) bool {

	if section := file.Section(".dynamic"); section != nil {

		reader := io.NewSectionReader(section, 0, int64(section.Size))
		switch file.Machine {

		case elf.EM_X86_64:
			for {
				var entry elf.Dyn64
				if err := binary.Read(reader, binary.LittleEndian, &entry); err != io.EOF {
					if elf.DynTag(entry.Tag) == tag {
						return true
					}
				} else {
					break
				}
			}

		case elf.EM_386:
			for {
				var entry elf.Dyn32
				if err := binary.Read(reader, binary.LittleEndian, &entry); err != io.EOF {
					if elf.DynTag(entry.Tag) == tag {
						return true
					}
				} else {
					break
				}
			}
		}
	}
	return false
}
Пример #5
0
func dump_symbols(file *elf.File) {
	fmt.Printf("Symbols:\n")
	symbols, _ := file.Symbols()
	for _, e := range symbols {
		if !strings.EqualFold(e.Name, "") {
			fmt.Printf("\t%s\n", e.Name)
		}
	}
}
Пример #6
0
func producer(debugfile *elf.File, dwzfile *elf.File, debug_package string, debug_file string) []string {
	var output []string

	// iterate over all CUs present in debugfile
	d, e := debugfile.DWARF() // increases memory usage by 2x to 3x!

	if e != nil {
		log.Println(e, debug_package, debug_file)
		return output
	}

	reader := d.Reader()
	for {
		entry, err := reader.Next()
		if err != nil {
			log.Println(err, debug_file, debug_package)
			break
		}

		if entry == nil {
			break
		}

		if entry.Tag == dwarf.TagCompileUnit {
			for _, f := range entry.Field {
				if f.Attr == dwarf.AttrName {
					switch f.Val.(type) {
					case string:
						output = append(output, f.Val.(string))
					case dwarf.OffsetStrpAlt:
						output = append(output, (string)(f.Val.(dwarf.OffsetStrpAlt)))
					case dwarf.OffsetRefAlt:
						log.Panic("DW_FORM_GNU_ref_alt handling missing for dwarf.AttrName ;(")
					default:
						panic("form unhandled for dwarf.AttrName, expect the unexpected ;(")
					}
				} else if f.Attr == dwarf.AttrProducer {
					switch f.Val.(type) {
					case string:
						output = append(output, f.Val.(string))
					case dwarf.OffsetStrpAlt:
						output = append(output, dwzparser(dwzfile, (int64)(f.Val.(dwarf.OffsetStrpAlt)), debug_package, debug_file))
					case dwarf.OffsetRefAlt:
						log.Panic("DW_FORM_GNU_ref_alt handling missing for dwarf.AttrProducer ;(")
					default:
						panic("form unhandled for dwarf.AttrProducer, expect the unexpected ;(")
					}

				}
			}
		}
	}

	// log.Println(output)
	return output
}
Пример #7
0
func getSectionData(f *elf.File, name string) []byte {
	section := f.Section(name)
	if section == nil {
		log.Fatalf("failed getting section %s", name)
	}
	data, err := section.Data()
	if err != nil {
		log.Fatalf("failed getting section %s data: %s", name, err)
	}
	return data
}
Пример #8
0
Файл: elf.go Проект: eqv/indika
func GetSymbols(e *elf.File) map[ds.Range]*ds.Symbol {
	res := make(map[ds.Range]*ds.Symbol)
	symbols, err := e.Symbols()
	if err != nil {
		log.WithFields(log.Fields{"error": err}).Info("Failed to Parse Symbols")
		return res
	}
	for _, sym := range symbols {
		sym_type := elfSymbolTypeToSymbolType(uint(sym.Info))
		symbol := ds.NewSymbol(sym.Name, sym_type)
		res[ds.NewRange(sym.Value, sym.Value+sym.Size)] = symbol
	}
	return res
}
Пример #9
0
func processGoInformation(f *elf.File) {
	gosymtab := getSectionData(f, ".gosymtab")
	gopclntab := getSectionData(f, ".gopclntab")

	lineTable := gosym.NewLineTable(gopclntab, f.Section(".text").Addr)
	table, err := gosym.NewTable(gosymtab, lineTable)
	if err != nil {
		log.Fatalf("failed making table: %s", err)
	}

	printSyms(table.Syms)
	printFuncs(table.Funcs)
	printFiles(table.Files)
}
Пример #10
0
func (dbp *Process) parseDebugLineInfo(exe *elf.File, wg *sync.WaitGroup) {
	defer wg.Done()

	if sec := exe.Section(".debug_line"); sec != nil {
		debugLine, err := exe.Section(".debug_line").Data()
		if err != nil {
			fmt.Println("could not get .debug_line section", err)
			os.Exit(1)
		}
		dbp.lineInfo = line.Parse(debugLine)
	} else {
		fmt.Println("could not find .debug_line section in binary")
		os.Exit(1)
	}
}
Пример #11
0
func (dbp *Process) parseDebugFrame(exe *elf.File, wg *sync.WaitGroup) {
	defer wg.Done()

	if sec := exe.Section(".debug_frame"); sec != nil {
		debugFrame, err := exe.Section(".debug_frame").Data()
		if err != nil {
			fmt.Println("could not get .debug_frame section", err)
			os.Exit(1)
		}
		dbp.frameEntries = frame.Parse(debugFrame)
	} else {
		fmt.Println("could not find .debug_frame section in binary")
		os.Exit(1)
	}
}
Пример #12
0
func dwzparser(dwzfile *elf.File, offset int64, debug_package string, debug_file string) string {
	if section := dwzfile.Section(".debug_str"); section != nil {
		reader := io.NewSectionReader(section, 0, int64(section.Size))
		reader.Seek(offset, 1)
		bufreader := bufio.NewReader(reader)
		// http://golang.org/pkg/bufio/#Reader.ReadString
		str, err := bufreader.ReadString('\x00')
		if err != nil {
			log.Println(err, debug_package, debug_file)
		}

		return strings.TrimSuffix(str, "\x00")
	}
	panic("dwzparser ran into problems ;(")
}
Пример #13
0
func canary(file *elf.File) string {

	if symbols, e := file.Symbols(); e == nil {
		for _, sym := range symbols {
			if bytes.HasPrefix([]byte(sym.Name), []byte(STACK_CHK)) {
				return ENABLED
			}
		}
	}

	if importedSymbols, e := file.ImportedSymbols(); e == nil {
		for _, imp := range importedSymbols {
			if bytes.HasPrefix([]byte(imp.Name), []byte(STACK_CHK)) {
				return ENABLED
			}
		}
	}

	return DISABLED
}
Пример #14
0
func elfGoSyms(f *elf.File) (*gosym.Table, os.Error) {
	text := f.Section(".text")
	symtab := f.Section(".gosymtab")
	pclntab := f.Section(".gopclntab")
	if text == nil || symtab == nil || pclntab == nil {
		return nil, nil
	}

	symdat, err := symtab.Data()
	if err != nil {
		return nil, err
	}
	pclndat, err := pclntab.Data()
	if err != nil {
		return nil, err
	}

	pcln := gosym.NewLineTable(pclndat, text.Addr)
	tab, err := gosym.NewTable(symdat, pcln)
	if err != nil {
		return nil, err
	}

	return tab, nil
}
Пример #15
0
func (dbp *Process) obtainGoSymbols(exe *elf.File, wg *sync.WaitGroup) {
	defer wg.Done()

	var (
		symdat  []byte
		pclndat []byte
		err     error
	)

	if sec := exe.Section(".gosymtab"); sec != nil {
		symdat, err = sec.Data()
		if err != nil {
			fmt.Println("could not get .gosymtab section", err)
			os.Exit(1)
		}
	}

	if sec := exe.Section(".gopclntab"); sec != nil {
		pclndat, err = sec.Data()
		if err != nil {
			fmt.Println("could not get .gopclntab section", err)
			os.Exit(1)
		}
	}

	pcln := gosym.NewLineTable(pclndat, exe.Section(".text").Addr)
	tab, err := gosym.NewTable(symdat, pcln)
	if err != nil {
		fmt.Println("could not get initialize line table", err)
		os.Exit(1)
	}

	dbp.goSymTable = tab
}
Пример #16
0
func blacklisted(file string, obj *elf.File) (bool, error) {
	lib := regexp.MustCompile(`^.*/lib([\w-]+)\.so[\d.]*$`)
	glcore := regexp.MustCompile(`libnvidia-e?glcore\.so`)
	gldispatch := regexp.MustCompile(`libGLdispatch\.so`)

	if m := lib.FindStringSubmatch(file); m != nil {
		switch m[1] {

		// Blacklist EGL/OpenGL libraries issued by other vendors
		case "EGL":
			fallthrough
		case "GLESv1_CM":
			fallthrough
		case "GLESv2":
			fallthrough
		case "GL":
			deps, err := obj.DynString(elf.DT_NEEDED)
			if err != nil {
				return false, err
			}
			for _, d := range deps {
				if glcore.MatchString(d) || gldispatch.MatchString(d) {
					return false, nil
				}
			}
			return true, nil

		// Blacklist TLS libraries using the old ABI (!= 2.3.99)
		case "nvidia-tls":
			const abi = 0x6300000003
			s, err := obj.Section(".note.ABI-tag").Data()
			if err != nil {
				return false, err
			}
			return binary.LittleEndian.Uint64(s[24:]) != abi, nil
		}
	}
	return false, nil
}
Пример #17
0
func printFileInformation(f *elf.File) {
	printHeader(&f.FileHeader)
	printSections(f.Sections)
	printProgs(f.Progs)
	printImportedLibraries(f.ImportedLibraries())
	printSymbols(f.Symbols())
	printImportedSymbols(f.ImportedSymbols())
}
Пример #18
0
func printDwarfInformation(f *elf.File) {
	dwarf, err := f.DWARF()
	if err != nil {
		log.Printf("failed getting DWARF info: %s", err)
		return
	}

	rd := dwarf.Reader()
	for {
		entry, err := rd.Next()
		if err != nil {
			log.Printf("failed getting next DWARF entry: %s", err)
			return
		}
		if entry == nil {
			// All done
			return
		}
		log.Printf("got entry with tag: %s, and offset %d", entry.Tag, entry.Offset)
		for _, field := range entry.Field {
			log.Printf("\t%s: %v", field.Attr, field.Val)
		}
	}
}
Пример #19
0
func dump_dynstr(file *elf.File) {
	fmt.Printf("DynStrings:\n")
	dynstrs, _ := file.DynString(elf.DT_NEEDED)
	for _, e := range dynstrs {
		fmt.Printf("\t%s\n", e)
	}
	dynstrs, _ = file.DynString(elf.DT_SONAME)
	for _, e := range dynstrs {
		fmt.Printf("\t%s\n", e)
	}
	dynstrs, _ = file.DynString(elf.DT_RPATH)
	for _, e := range dynstrs {
		fmt.Printf("\t%s\n", e)
	}
	dynstrs, _ = file.DynString(elf.DT_RUNPATH)
	for _, e := range dynstrs {
		fmt.Printf("\t%s\n", e)
	}
}
Пример #20
0
func parse(file string, f *elf.File, t *testing.T) (*elf.File, *Table) {
	symdat, err := f.Section(".gosymtab").Data()
	if err != nil {
		f.Close()
		t.Fatalf("reading %s gosymtab: %v", file, err)
	}
	pclndat, err := f.Section(".gopclntab").Data()
	if err != nil {
		f.Close()
		t.Fatalf("reading %s gopclntab: %v", file, err)
	}

	pcln := NewLineTable(pclndat, f.Section(".text").Addr)
	tab, err := NewTable(symdat, pcln)
	if err != nil {
		f.Close()
		t.Fatalf("parsing %s gosymtab: %v", file, err)
	}

	return f, tab
}
Пример #21
0
func producer(debugfile *elf.File, dwzfile *elf.File, debug_package string, debug_file string) []string {
	var output []string

	// iterate over all CUs present in debugfile
	d, e := debugfile.DWARF() // increases memory usage by 2x to 3x!

	if e != nil {
		log.Println(e, debug_package, debug_file)
		return output
	}

	reader := d.Reader()
	for {
		entry, err := reader.Next()
		if err != nil {
			log.Println(err, debug_file, debug_package)
			break
		}

		if entry == nil {
			break
		}

		if entry.Tag == dwarf.TagCompileUnit {
			for _, f := range entry.Field {
				if f.Attr == dwarf.AttrName {
					switch f.Val.(type) {
					case string:
						output = append(output, f.Val.(string))
					default:
						// distinguish between dwarf.OffsetStrpAlt, and dwarf.OffsetRefAlt
						switch f.Class {
						case dwarf.ClassStringAlt:
							output = append(output, dwzparser(dwzfile, (int64)(f.Val.(int64)), debug_package, debug_file)) // this are filenames!
							dummy := 0
							_ = dummy

							// panic("dwarf.ClassStringAlt is not handled currently in dwarf.AttrName, expect the unexpected ;(")
						case dwarf.ClassReferenceAlt:
							panic("dwarf.ClassReferenceAlt is not handled currently in dwarf.AttrName, expect the unexpected ;(")
						default:
							panic("form unhandled for dwarf.AttrName, expect the unexpected ;(")
						}
					}
				} else if f.Attr == dwarf.AttrProducer {
					switch f.Val.(type) {
					case string:
						output = append(output, f.Val.(string))
					default:
						// distinguish between dwarf.OffsetStrpAlt, and dwarf.OffsetRefAlt
						switch f.Class {
						case dwarf.ClassStringAlt:
							output = append(output, dwzparser(dwzfile, (int64)(f.Val.(int64)), debug_package, debug_file))
						case dwarf.ClassReferenceAlt:
							panic("dwarf.ClassReferenceAlt is not handled currently in dwarf.AttrProducer, expect the unexpected ;(")
						default:
							panic("form unhandled for dwarf.AttrProducer, expect the unexpected ;(")
						}
					}
				}
			}
		}
	}

	// log.Println(output)
	return output
}