Skip to content

Commit

Permalink
Merge pull request HXSecurity#40 from piexlmax/main
Browse files Browse the repository at this point in the history
Package compatible 1.16
  • Loading branch information
奇淼(piexlmax authored Jun 7, 2022
2 parents f6b8c98 + c7874cb commit 4afd12f
Show file tree
Hide file tree
Showing 6 changed files with 1,644 additions and 11 deletions.
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,5 @@ require (
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
moul.io/http2curl v1.0.0 // indirect
)


108 changes: 97 additions & 11 deletions service/auxiliary.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package service

import (
"debug/buildinfo"
"bytes"
"encoding/binary"
"fmt"
"github.com/HXSecurity/DongTai-agent-go/model/request"
"github.com/HXSecurity/DongTai-agent-go/service/version"
"github.com/HXSecurity/DongTai-agent-go/utils"
"github.com/pkg/errors"
"io/fs"
Expand All @@ -14,6 +16,20 @@ import (
"strings"
)

var buildInfoMagic = []byte("\xff Go buildinf:")

// An exe is a generic interface to an OS executable (ELF, Mach-O, PE, XCOFF).
type exe interface {
// Close closes the underlying file.
Close() error

// ReadData reads and returns up to size byte starting at virtual address addr.
ReadData(addr, size uint64) ([]byte, error)

// DataStart returns the writable data segment start address.
DataStart() uint64
}

// GenAQLForGolang 为golang组件生成aql
func GenAQLForGolang(packageName, version string) string {
return fmt.Sprintf("golang:%s:%s:", packageName, version)
Expand All @@ -36,20 +52,33 @@ func isExe(file string, info fs.FileInfo) bool {

// 从二进制文件读取包信息
func scanFile(file string, mustPrint bool) (packages []request.Component, agentVersion string) {
bi, err := buildinfo.ReadFile(file)

i, err := os.Stat(file)
info := i

if !isExe(file, info) {
if mustPrint {
fmt.Fprintf(os.Stderr, "%s: not executable file\n", file)
}
return
}

x, err := version.OpenExe(file)
if err != nil {
if mustPrint {
if pathErr := (*os.PathError)(nil); errors.As(err, &pathErr) && filepath.Clean(pathErr.Path) == filepath.Clean(file) {
fmt.Fprintf(os.Stderr, "%v\n", file)
} else {
fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
}
fmt.Fprintf(os.Stderr, "%s: %v\n", file, err)
}
return
}
defer x.Close()

vers, mod := findVers(x)
if vers == "" {
if mustPrint {
fmt.Fprintf(os.Stderr, "%s: go version not found\n", file)
}
return packages, agentVersion
return
}
fmt.Printf("%s: %s\n", file, bi.GoVersion)
bi.GoVersion = "" // suppress printing go version again
mod := bi.String()

li := strings.Split(mod[:len(mod)-1], "\n")
for i := range li {
Expand Down Expand Up @@ -112,3 +141,60 @@ func getCurrentPath() (string, error) {
}
return string(path[0 : i+1]), nil
}

func findVers(x exe) (vers, mod string) {
// Read the first 64kB of text to find the build info blob.
text := x.DataStart()
data, err := x.ReadData(text, 64*1024)
if err != nil {
return
}
for ; !bytes.HasPrefix(data, buildInfoMagic); data = data[32:] {
if len(data) < 32 {
return
}
}

// Decode the blob.
ptrSize := int(data[14])
bigEndian := data[15] != 0
var bo binary.ByteOrder
if bigEndian {
bo = binary.BigEndian
} else {
bo = binary.LittleEndian
}
var readPtr func([]byte) uint64
if ptrSize == 4 {
readPtr = func(b []byte) uint64 { return uint64(bo.Uint32(b)) }
} else {
readPtr = bo.Uint64
}
vers = readString(x, ptrSize, readPtr, readPtr(data[16:]))
if vers == "" {
return
}
mod = readString(x, ptrSize, readPtr, readPtr(data[16+ptrSize:]))
if len(mod) >= 33 && mod[len(mod)-17] == '\n' {
// Strip module framing.
mod = mod[16 : len(mod)-16]
} else {
mod = ""
}
return
}

// readString returns the string at address addr in the executable x.
func readString(x exe, ptrSize int, readPtr func([]byte) uint64, addr uint64) string {
hdr, err := x.ReadData(addr, uint64(2*ptrSize))
if err != nil || len(hdr) < 2*ptrSize {
return ""
}
dataAddr := readPtr(hdr)
dataLen := readPtr(hdr[ptrSize:])
data, err := x.ReadData(dataAddr, dataLen)
if err != nil || uint64(len(data)) < dataLen {
return ""
}
return string(data)
}
Loading

0 comments on commit 4afd12f

Please sign in to comment.