github.com/HXSecurity/DongTai-agent-go@v0.4.2/service/auxiliary.go (about) 1 package service 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "fmt" 7 "github.com/HXSecurity/DongTai-agent-go/model/request" 8 "github.com/HXSecurity/DongTai-agent-go/service/version" 9 "github.com/HXSecurity/DongTai-agent-go/utils" 10 "github.com/pkg/errors" 11 "io/fs" 12 "os" 13 "os/exec" 14 "path/filepath" 15 "runtime" 16 "strings" 17 ) 18 19 var buildInfoMagic = []byte("\xff Go buildinf:") 20 21 // An exe is a generic interface to an OS executable (ELF, Mach-O, PE, XCOFF). 22 type exe interface { 23 // Close closes the underlying file. 24 Close() error 25 26 // ReadData reads and returns up to size byte starting at virtual address addr. 27 ReadData(addr, size uint64) ([]byte, error) 28 29 // DataStart returns the writable data segment start address. 30 DataStart() uint64 31 } 32 33 // GenAQLForGolang 为golang组件生成aql 34 func GenAQLForGolang(packageName, version string) string { 35 return fmt.Sprintf("golang:%s:%s:", packageName, version) 36 } 37 38 // 获取包 39 func GetMod() ([]request.Component, string) { 40 //fmt.Println(getCurrentPath()) 41 path, _ := os.Executable() 42 return scanFile(path, true) 43 } 44 45 // 判断是否是exe文件 46 func isExe(file string, info fs.FileInfo) bool { 47 if runtime.GOOS == "windows" { 48 return strings.HasSuffix(strings.ToLower(file), ".exe") 49 } 50 return info.Mode().IsRegular() && info.Mode()&0111 != 0 51 } 52 53 // 从二进制文件读取包信息 54 func scanFile(file string, mustPrint bool) (packages []request.Component, agentVersion string) { 55 56 i, err := os.Stat(file) 57 info := i 58 59 if !isExe(file, info) { 60 if mustPrint { 61 fmt.Fprintf(os.Stderr, "%s: not executable file\n", file) 62 } 63 return 64 } 65 66 x, err := version.OpenExe(file) 67 if err != nil { 68 if mustPrint { 69 fmt.Fprintf(os.Stderr, "%s: %v\n", file, err) 70 } 71 return 72 } 73 defer x.Close() 74 75 vers, mod := findVers(x) 76 if vers == "" { 77 if mustPrint { 78 fmt.Fprintf(os.Stderr, "%s: go version not found\n", file) 79 } 80 return 81 } 82 83 li := strings.Split(mod[:len(mod)-1], "\n") 84 for i := range li { 85 licl := strings.Split(li[i], "\t") 86 if licl[0] == "dep" { 87 fmt.Printf("依赖:%s\t版本:%s\n", licl[1], licl[2]) 88 aql := GenAQLForGolang(licl[1], licl[2]) 89 if licl[1] == "github.com/HXSecurity/DongTai-agent-go" { 90 fmt.Println("当前探针版本为:" + licl[2]) 91 agentVersion = licl[2] 92 } 93 packages = append(packages, request.Component{ 94 PackageName: aql, 95 PackageAlgorithm: "SHA-1", 96 PackagePath: file, 97 PackageVersion: licl[2], 98 PackageSignature: utils.SHA1(aql), 99 }, 100 ) 101 } 102 } 103 return packages, agentVersion 104 } 105 106 // 获取服务信息 107 func getServerInfo() (server *utils.Server, err error) { 108 var s utils.Server 109 s.Os = utils.InitOS() 110 if s.Cpu, err = utils.InitCPU(); err != nil { 111 fmt.Println(err.Error()) 112 return &s, err 113 } 114 if s.Rrm, err = utils.InitRAM(); err != nil { 115 fmt.Println(err.Error()) 116 return &s, err 117 } 118 if s.Disk, err = utils.InitDisk(); err != nil { 119 fmt.Println(err.Error()) 120 return &s, err 121 } 122 123 return &s, nil 124 } 125 126 func getCurrentPath() (string, error) { 127 file, err := exec.LookPath(os.Args[0]) 128 if err != nil { 129 return "", err 130 } 131 path, err := filepath.Abs(file) 132 if err != nil { 133 return "", err 134 } 135 i := strings.LastIndex(path, "/") 136 if i < 0 { 137 i = strings.LastIndex(path, "\\") 138 } 139 if i < 0 { 140 return "", errors.New(`error: Can't find "/" or "\".`) 141 } 142 return string(path[0 : i+1]), nil 143 } 144 145 func findVers(x exe) (vers, mod string) { 146 // Read the first 64kB of text to find the build info blob. 147 text := x.DataStart() 148 data, err := x.ReadData(text, 64*1024) 149 if err != nil { 150 return 151 } 152 for ; !bytes.HasPrefix(data, buildInfoMagic); data = data[32:] { 153 if len(data) < 32 { 154 return 155 } 156 } 157 158 // Decode the blob. 159 ptrSize := int(data[14]) 160 bigEndian := data[15] != 0 161 var bo binary.ByteOrder 162 if bigEndian { 163 bo = binary.BigEndian 164 } else { 165 bo = binary.LittleEndian 166 } 167 var readPtr func([]byte) uint64 168 if ptrSize == 4 { 169 readPtr = func(b []byte) uint64 { return uint64(bo.Uint32(b)) } 170 } else { 171 readPtr = bo.Uint64 172 } 173 vers = readString(x, ptrSize, readPtr, readPtr(data[16:])) 174 if vers == "" { 175 return 176 } 177 mod = readString(x, ptrSize, readPtr, readPtr(data[16+ptrSize:])) 178 if len(mod) >= 33 && mod[len(mod)-17] == '\n' { 179 // Strip module framing. 180 mod = mod[16 : len(mod)-16] 181 } else { 182 mod = "" 183 } 184 return 185 } 186 187 // readString returns the string at address addr in the executable x. 188 func readString(x exe, ptrSize int, readPtr func([]byte) uint64, addr uint64) string { 189 hdr, err := x.ReadData(addr, uint64(2*ptrSize)) 190 if err != nil || len(hdr) < 2*ptrSize { 191 return "" 192 } 193 dataAddr := readPtr(hdr) 194 dataLen := readPtr(hdr[ptrSize:]) 195 data, err := x.ReadData(dataAddr, dataLen) 196 if err != nil || uint64(len(data)) < dataLen { 197 return "" 198 } 199 return string(data) 200 }