Skip to content

Commit

Permalink
test:check docker binary file symbol address
Browse files Browse the repository at this point in the history
  • Loading branch information
wlingze committed Apr 2, 2024
1 parent f1930dc commit 0f69ac9
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 12 deletions.
Binary file added tests/docker_binary/arm64
Binary file not shown.
58 changes: 58 additions & 0 deletions tests/docker_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package main

import (
"ecapture/user/config"
"testing"
)

// readelf -sW ./testdata/docker_aarch64/docker | grep $FUNCTION
// 6649: 0000000000635cb0 928 FUNC LOCAL DEFAULT 6 crypto/tls.(*Conn).Read

// in ida:
// .text:0000000000635CB0
// .text:0000000000635CB0
// .text:0000000000635CB0 ; retval_635CB0 __golang crypto_tls__ptr_Conn_Read(crypto_tls_Conn_0 *c, _slice_uint8 b)
// .text:0000000000635CB0 crypto_tls._ptr_Conn.Read ; CODE XREF: crypto_tls._ptr_Conn.Read+390↓j
// .text:0000000000635CB0

const readFuncAddress = 0x0000000000635cb0

func TestDockerSymbol_ByElfSymbol(t *testing.T) {
path := "./docker_binary/arm64"
gotls := config.NewGoTLSConfig()
gotls.Path = path
if err := gotls.Init(); err != nil {
t.Fatal("init error:", err)
}
symbol, err := gotls.GetSymbol(config.GoTlsReadFunc)
if err != nil {
t.Fatalf("get symbol %s error: %v", config.GoTlsReadFunc, err)
}
if symbol.Value != readFuncAddress {
t.Fatalf("error symbol address: got[0x%08x] vs want[0x%08x]", symbol.Value, readFuncAddress)
}
}

func TestDockerSymbol_BySymbolTable(t *testing.T) {
path := "./docker_binary/arm64"
gotls := config.NewGoTLSConfig()
gotls.Path = path
if err := gotls.Init(); err != nil {
t.Fatal("init error:", err)
}
// i think this error will in this function.
goSymTab, err := gotls.ReadTable()
if err != nil {
t.Fatalf("build symbTable error: %v", err)
}
// when this symTab builded, this function address is error,
// this functino index = 6626,
// you can set condition breakpoint in `/usr/lib/go/src/debug/gosym/pclntab.go:308` this code build this functino.
f := goSymTab.LookupFunc(config.GoTlsReadFunc)
if f == nil {
t.Fatalf("con't looup symbol %s", config.GoTlsReadFunc)
}
if f.Value != readFuncAddress {
t.Fatalf("error symbol address: got[0x%08x] vs want[0x%08x], dec: 0x%08x", f.Value, readFuncAddress, readFuncAddress-f.Value)
}
}
41 changes: 29 additions & 12 deletions user/config/config_gotls.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"errors"
"fmt"
"os"
"runtime"
"strings"
)

Expand Down Expand Up @@ -103,8 +102,14 @@ func NewGoTLSConfig() *GoTLSConfig {
gc.PerCpuMapSize = DefaultMapSizePerCpu
return gc
}

func (gc *GoTLSConfig) Check() error {
if err := gc.Init(); err != nil {
return err
}
return gc.FindAddress()
}

func (gc *GoTLSConfig) Init() error {
var err error
if gc.Path == "" {
return ErrorGoBINNotFound
Expand Down Expand Up @@ -141,10 +146,10 @@ func (gc *GoTLSConfig) Check() error {
goElfArch = "unsupport_arch"
}

if goElfArch != runtime.GOARCH {
err = fmt.Errorf("Go Application not match, want:%s, have:%s", runtime.GOARCH, goElfArch)
return err
}
// if goElfArch != runtime.GOARCH {
// err = fmt.Errorf("Go Application not match, want:%s, have:%s", runtime.GOARCH, goElfArch)
// return err
// }
switch goElfArch {
case "amd64":
case "arm64":
Expand All @@ -163,18 +168,22 @@ func (gc *GoTLSConfig) Check() error {
break
}
}
return nil
}
func (gc *GoTLSConfig) FindAddress() error {
var err error
if gc.IsPieBuildMode {
gc.goSymTab, err = gc.ReadTable()
if err != nil {
return err
}
var addr uint64
addr, err = gc.findPieSymbolAddr(GoTlsWriteFunc)
addr, err = gc.FindPieSymbolAddr(GoTlsWriteFunc)
if err != nil {
return fmt.Errorf("%s symbol address error:%s", GoTlsWriteFunc, err.Error())
}
gc.GoTlsWriteAddr = addr
addr, err = gc.findPieSymbolAddr(GoTlsMasterSecretFunc)
addr, err = gc.FindPieSymbolAddr(GoTlsMasterSecretFunc)
if err != nil {
return fmt.Errorf("%s symbol address error:%s", GoTlsMasterSecretFunc, err.Error())
}
Expand All @@ -197,7 +206,7 @@ func (gc *GoTLSConfig) Check() error {
// the instruction set associated with the specified symbol in an ELF program.
// It is used for mounting uretprobe programs for Golang programs,
// which are actually mounted via uprobe on these addresses.
func (gc *GoTLSConfig) findRetOffsets(symbolName string) ([]int, error) {
func (gc *GoTLSConfig) GetSymbol(symbolName string) (*elf.Symbol, error) {
var err error
var allSymbs []elf.Symbol

Expand Down Expand Up @@ -227,6 +236,14 @@ func (gc *GoTLSConfig) findRetOffsets(symbolName string) ([]int, error) {
if !found {
return nil, ErrorSymbolNotFound
}
return &symbol, err
}

func (gc *GoTLSConfig) findRetOffsets(symbolName string) ([]int, error) {
symbol, err := gc.GetSymbol(symbolName)
if err != nil {
return nil, err
}

section := gc.goElf.Sections[symbol.Section]

Expand Down Expand Up @@ -306,7 +323,7 @@ func (gc *GoTLSConfig) ReadTable() (*gosym.Table, error) {
// Find .gopclntab by magic number even if there is no section label
magic := magicNumber(gc.Buildinfo.GoVersion)
pclntabIndex := bytes.Index(tableData, magic)
//fmt.Printf("Buildinfo :%v, magic:%x, pclntabIndex:%d offset:%x , section:%v \n", gc.Buildinfo, magic, pclntabIndex, section.Offset, section)
// fmt.Printf("Buildinfo :%v, magic:%x, pclntabIndex:%d offset:%x , section:%v \n", gc.Buildinfo, magic, pclntabIndex, section.Offset, section)
if pclntabIndex < 0 {
return nil, fmt.Errorf("could not find magic number in %s ", gc.Path)
}
Expand All @@ -325,7 +342,7 @@ func (gc *GoTLSConfig) findRetOffsetsPie(lfunc string) ([]int, error) {
var offsets []int
var address uint64
var err error
address, err = gc.findPieSymbolAddr(lfunc)
address, err = gc.FindPieSymbolAddr(lfunc)
if err != nil {
return offsets, err
}
Expand All @@ -352,7 +369,7 @@ func (gc *GoTLSConfig) findRetOffsetsPie(lfunc string) ([]int, error) {
return offsets, errors.New("cant found gotls symbol offsets.")
}

func (gc *GoTLSConfig) findPieSymbolAddr(lfunc string) (uint64, error) {
func (gc *GoTLSConfig) FindPieSymbolAddr(lfunc string) (uint64, error) {
f := gc.goSymTab.LookupFunc(lfunc)
if f == nil {
return 0, errors.New("Cant found symbol address on pie model.")
Expand Down

0 comments on commit 0f69ac9

Please sign in to comment.