forked from pkujhd/goloader
-
Notifications
You must be signed in to change notification settings - Fork 0
/
readobj.go
93 lines (86 loc) · 2.42 KB
/
readobj.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package goloader
import (
"cmd/objfile/sys"
"fmt"
"os"
"strings"
"github.com/pkujhd/goloader/obj"
)
func Parse(f *os.File, pkgpath *string) ([]string, error) {
pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: *pkgpath}
symbols := make([]string, 0)
if err := pkg.Symbols(); err != nil {
return symbols, err
}
for _, sym := range pkg.Syms {
symbols = append(symbols, sym.Name)
}
return symbols, nil
}
func readObj(pkg *obj.Pkg, linker *Linker) error {
if pkg.PkgPath == EmptyString {
pkg.PkgPath = DefaultPkgPath
}
if err := pkg.Symbols(); err != nil {
return fmt.Errorf("read error: %v", err)
}
if linker.Arch != nil && linker.Arch.Name != pkg.Arch {
return fmt.Errorf("read obj error: Arch %s != Arch %s", linker.Arch.Name, pkg.Arch)
} else {
linker.Arch = getArch(pkg.Arch)
}
switch linker.Arch.Name {
case sys.ArchARM.Name, sys.ArchARM64.Name:
copy(linker.pclntable, obj.ModuleHeadarm)
linker.pclntable[len(obj.ModuleHeadarm)-1] = PtrSize
}
for _, sym := range pkg.Syms {
for index, loc := range sym.Reloc {
if !strings.HasPrefix(sym.Reloc[index].Sym.Name, TypeStringPrefix) {
sym.Reloc[index].Sym.Name = strings.Replace(loc.Sym.Name, EmptyPkgPath, pkg.PkgPath, -1)
}
}
if sym.Type != EmptyString {
sym.Type = strings.Replace(sym.Type, EmptyPkgPath, pkg.PkgPath, -1)
}
if sym.Func != nil {
for index, FuncData := range sym.Func.FuncData {
sym.Func.FuncData[index] = strings.Replace(FuncData, EmptyPkgPath, pkg.PkgPath, -1)
}
}
}
for _, sym := range pkg.Syms {
linker.objsymbolMap[sym.Name] = sym
}
linker.initFuncs = append(linker.initFuncs, getInitFuncName(pkg.PkgPath))
return nil
}
func ReadObj(f *os.File, pkgpath *string) (*Linker, error) {
linker := initLinker()
pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: *pkgpath}
if err := readObj(&pkg, linker); err != nil {
return nil, err
}
if err := linker.addSymbols(); err != nil {
return nil, err
}
return linker, nil
}
func ReadObjs(files []string, pkgPath []string) (*Linker, error) {
linker := initLinker()
for i, file := range files {
f, err := os.Open(file)
if err != nil {
return nil, err
}
defer f.Close()
pkg := obj.Pkg{Syms: make(map[string]*obj.ObjSymbol, 0), F: f, PkgPath: pkgPath[i]}
if err := readObj(&pkg, linker); err != nil {
return nil, err
}
}
if err := linker.addSymbols(); err != nil {
return nil, err
}
return linker, nil
}