diff --git a/builder/Makefile.release b/builder/Makefile.release index 94e784889..d45a4e73d 100644 --- a/builder/Makefile.release +++ b/builder/Makefile.release @@ -50,7 +50,9 @@ endif OUTPUT_DIR = ./bin TAR_DIR = ecapture-$(SNAPSHOT_VERSION)-linux-$(UNAME_M) +TAR_DIR_NOCORE = ecapture-$(SNAPSHOT_VERSION)-linux-nocore TAR_DIR_ANDROID = ecapture-$(SNAPSHOT_VERSION)-android-$(UNAME_M) +TAR_DIR_ANDROID_NOCORE = ecapture-$(SNAPSHOT_VERSION)-android-$(UNAME_M)-nocore # from CLI args. RELEASE_NOTES ?= $(OUTPUT_DIR)/release_notes.txt @@ -71,7 +73,9 @@ BUILD_DIR = build # OUT_ARCHIVE := $(OUTPUT_DIR)/$(TAR_DIR).tar.gz -OUT_ARCHIVE_ANDROID := $(OUTPUT_DIR)/$(TAR_DIR_ANDROID)-nocore.tar.gz +OUT_ARCHIVE_NOCORE := $(OUTPUT_DIR)/$(TAR_DIR_NOCORE).tar.gz +OUT_ARCHIVE_ANDROID := $(OUTPUT_DIR)/$(TAR_DIR_ANDROID).tar.gz +OUT_ARCHIVE_ANDROID_NOCORE := $(OUTPUT_DIR)/$(TAR_DIR_ANDROID_NOCORE).tar.gz OUT_CHECKSUMS := $(OUTPUT_DIR)/checksum-$(SNAPSHOT_VERSION).txt @@ -183,7 +187,7 @@ snapshot: \ $(CMD_CP) $(OUTPUT_DIR)/ecapture $(TAR_DIR)/ecapture $(CMD_TAR) -czf $(OUT_ARCHIVE) $(TAR_DIR) cd $(OUTPUT_DIR) - $(CMD_CHECKSUM) $(TAR_DIR).tar.gz > ./../$(OUT_CHECKSUMS) + $(CMD_CHECKSUM) $(OUT_ARCHIVE_ANDROID) > ./../$(OUT_CHECKSUMS) cd ../ .PHONY: snapshot_android @@ -198,29 +202,29 @@ snapshot_android: \ $(MAKE) clean ANDROID=1 $(MAKE) nocore RELEASE_TAG=$(SNAPSHOT_VERSION) # create the tar ball and checksum files - $(CMD_MKDIR) -p $(TAR_DIR_ANDROID) - $(CMD_CP) LICENSE $(TAR_DIR_ANDROID)/LICENSE - $(CMD_CP) CHANGELOG.md $(TAR_DIR_ANDROID)/CHANGELOG.md - $(CMD_CP) README.md $(TAR_DIR_ANDROID)/README.md - $(CMD_CP) README_CN.md $(TAR_DIR_ANDROID)/README_CN.md - $(CMD_CP) $(OUTPUT_DIR)/ecapture $(TAR_DIR_ANDROID)/ecapture - $(CMD_TAR) -czf $(OUT_ARCHIVE_ANDROID) $(TAR_DIR_ANDROID) + $(CMD_MKDIR) -p $(TAR_DIR_ANDROID_NOCORE) + $(CMD_CP) LICENSE $(TAR_DIR_ANDROID_NOCORE)/LICENSE + $(CMD_CP) CHANGELOG.md $(TAR_DIR_ANDROID_NOCORE)/CHANGELOG.md + $(CMD_CP) README.md $(TAR_DIR_ANDROID_NOCORE)/README.md + $(CMD_CP) README_CN.md $(TAR_DIR_ANDROID_NOCORE)/README_CN.md + $(CMD_CP) $(OUTPUT_DIR)/ecapture $(TAR_DIR_ANDROID_NOCORE)/ecapture + $(CMD_TAR) -czf $(OUT_ARCHIVE_ANDROID_NOCORE) $(TAR_DIR_ANDROID_NOCORE) cd $(OUTPUT_DIR) - $(CMD_CHECKSUM) $(TAR_DIR_ANDROID).tar.gz >> ./../$(OUT_CHECKSUMS) + $(CMD_CHECKSUM) $(OUT_ARCHIVE_ANDROID_NOCORE) >> ./../$(OUT_CHECKSUMS) cd ../ .PHONY: publish publish: \ $(OUTPUT_DIR) \ $(OUT_ARCHIVE) \ - $(OUT_ARCHIVE_ANDROID) \ + $(OUT_ARCHIVE_ANDROID_NOCORE) \ $(OUT_CHECKSUMS) \ $(OUT_DEB_FILE) \ | .check_tree \ .check_$(CMD_GITHUB) # # release it! - $(CMD_GITHUB) release create $(SNAPSHOT_VERSION) $(OUT_ARCHIVE) $(OUT_ARCHIVE_ANDROID) $(OUT_DEB_FILE) $(OUT_CHECKSUMS) --title "eCapture $(SNAPSHOT_VERSION)" --notes-file $(RELEASE_NOTES) + $(CMD_GITHUB) release create $(SNAPSHOT_VERSION) $(OUT_ARCHIVE) $(OUT_ARCHIVE_ANDROID_NOCORE) $(OUT_DEB_FILE) $(OUT_CHECKSUMS) --title "eCapture $(SNAPSHOT_VERSION)" --notes-file $(RELEASE_NOTES) .PHONY: clean clean: diff --git a/kern/gotls_kern.c b/kern/gotls_kern.c index f109d8fc2..4b9e108e3 100644 --- a/kern/gotls_kern.c +++ b/kern/gotls_kern.c @@ -106,7 +106,10 @@ static __always_inline int gotls_write(struct pt_regs *ctx, len_ptr = (void *)go_get_argument(ctx, is_register_abi, 4); bpf_probe_read_kernel(&len, sizeof(len), (void *)&len_ptr); - debug_bpf_printk("gotls_write record_type:%d\n", record_type); + if (len == 0) { + return 0; + } + debug_bpf_printk("gotls_write record_type:%d, len:%d\n", record_type, len); if (record_type != recordTypeApplicationData) { return 0; } @@ -115,7 +118,7 @@ static __always_inline int gotls_write(struct pt_regs *ctx, if (!event) { return 0; } - + len = len & 0xFFFF; event->data_len = len; int ret = bpf_probe_read_user(&event->data, sizeof(event->data), (void *)str); @@ -157,7 +160,10 @@ static __always_inline int gotls_read(struct pt_regs *ctx, // Read函数的返回值第一个是int类型,存放在栈里的顺序是5 ret_len_ptr = (void *)go_get_argument_by_stack(ctx, 5); bpf_probe_read_kernel(&ret_len, sizeof(ret_len), (void *)&ret_len_ptr); - if (len == 0) { + if (len <= 0) { + return 0; + } + if (ret_len <= 0 ) { return 0; } @@ -251,7 +257,7 @@ static __always_inline int gotls_mastersecret(struct pt_regs *ctx, return 0; } - debug_bpf_printk("gotls_mastersecret read mastersecret label%s\n", + debug_bpf_printk("gotls_mastersecret read mastersecret label:%s\n", mastersecret_gotls.label); ret = bpf_probe_read_user_str(&mastersecret_gotls.client_random, sizeof(mastersecret_gotls.client_random), diff --git a/user/config/config_gotls.go b/user/config/config_gotls.go index 3f44c3131..a03024ce9 100644 --- a/user/config/config_gotls.go +++ b/user/config/config_gotls.go @@ -15,41 +15,86 @@ package config import ( + "bytes" + "debug/buildinfo" "debug/elf" + "debug/gosym" + "encoding/binary" "errors" "fmt" "os" "runtime" - - "golang.org/x/arch/arm64/arm64asm" - "golang.org/x/arch/x86/x86asm" + "strings" ) const ( - // Arm64armInstSize via : arm64/arm64asm/decode.go:Decode() size = 4 - Arm64armInstSize = 4 + GoTlsReadFunc = "crypto/tls.(*Conn).Read" + GoTlsWriteFunc = "crypto/tls.(*Conn).writeRecordLocked" + GoTlsMasterSecretFunc = "crypto/tls.(*Config).writeKeyLog" - GoTlsReadFunc = "crypto/tls.(*Conn).Read" + /* + 我是通过IDA静态分析符号发现`crypto/tls.(*Conn).Read`的地址是`46EE50`。用程序计算出来的总是比这个数字少了`0x120` ,通过分析其他多个编译的程序,发现差值总是`0x120`。 + 所以,我定义了一个常量,增加到程序计算的地址上。但是我不知道原因,如果你知道,请告诉我。更多信息见:https://github.com/gojue/ecapture/pull/512 + */ + IdaProOffset = 0x120 ) var ( - ErrorGoBINNotFound = errors.New("The executable program (compiled by Golang) was not found") - ErrorSymbolNotFound = errors.New("symbol not found") - ErrorNoRetFound = errors.New("no RET instructions found") + ErrorGoBINNotFound = errors.New("The executable program (compiled by Golang) was not found") + ErrorSymbolEmpty = errors.New("symbol is empty") + ErrorSymbolNotFound = errors.New("symbol not found") + ErrorSymbolNotFoundFromTable = errors.New("symbol not found from table") + ErrorNoRetFound = errors.New("no RET instructions found") + ErrorNoRetFoundFromSymTabFun = errors.New("no RET instructions found from golang symbol table with Fun") ) +// From go/src/debug/gosym/pclntab.go +const ( + go12magic = 0xfffffffb + go116magic = 0xfffffffa + go118magic = 0xfffffff0 + go120magic = 0xfffffff1 +) + +// Select the magic number based on the Go version +func magicNumber(goVersion string) []byte { + bs := make([]byte, 4) + var magic uint32 + if strings.Compare(goVersion, "go1.20") >= 0 { + magic = go120magic + } else if strings.Compare(goVersion, "go1.18") >= 0 { + magic = go118magic + } else if strings.Compare(goVersion, "go1.16") >= 0 { + magic = go116magic + } else { + magic = go12magic + } + binary.LittleEndian.PutUint32(bs, magic) + return bs +} + +type FuncOffsets struct { + Start uint64 + Returns []uint64 +} + // GoTLSConfig represents configuration for Go SSL probe type GoTLSConfig struct { eConfig - Path string `json:"path"` // golang application path to binary built with Go toolchain. - PcapFile string `json:"pcapFile"` // pcapFile the raw packets to file rather than parsing and printing them out. - KeylogFile string `json:"keylogFile"` // keylogFile The file stores SSL/TLS keys, and eCapture captures these keys during encrypted traffic communication and saves them to the file. - Model string `json:"model"` // model such as : text, pcapng/pcap, key/keylog. - Ifname string `json:"ifName"` // (TC Classifier) Interface name on which the probe will be attached. - PcapFilter string `json:"pcapFilter"` // pcap filter - goElfArch string // - goElf *elf.File // - ReadTlsAddrs []int + Path string `json:"path"` // golang application path to binary built with Go toolchain. + PcapFile string `json:"pcapFile"` // pcapFile the raw packets to file rather than parsing and printing them out. + KeylogFile string `json:"keylogFile"` // keylogFile The file stores SSL/TLS keys, and eCapture captures these keys during encrypted traffic communication and saves them to the file. + Model string `json:"model"` // model such as : text, pcapng/pcap, key/keylog. + Ifname string `json:"ifName"` // (TC Classifier) Interface name on which the probe will be attached. + PcapFilter string `json:"pcapFilter"` // pcap filter + goElfArch string // + goElf *elf.File // + Buildinfo *buildinfo.BuildInfo + ReadTlsAddrs []int + GoTlsWriteAddr uint64 + GoTlsMasterSecretAddr uint64 + IsPieBuildMode bool + goSymTab *gosym.Table } // NewGoTLSConfig creates a new config for Go SSL @@ -74,6 +119,12 @@ func (gc *GoTLSConfig) Check() error { return err } + // Read the build information of the Go application + gc.Buildinfo, err = buildinfo.ReadFile(gc.Path) + if err != nil { + return err + } + var goElf *elf.File goElf, err = elf.Open(gc.Path) if err != nil { @@ -102,7 +153,43 @@ func (gc *GoTLSConfig) Check() error { } gc.goElfArch = goElfArch gc.goElf = goElf - gc.ReadTlsAddrs, err = gc.findRetOffsets(GoTlsReadFunc) + // If built with PIE and stripped, gopclntab is + // unlabeled and nested under .data.rel.ro. + for _, bs := range gc.Buildinfo.Settings { + if bs.Key == "-buildmode" { + if bs.Value == "pie" { + gc.IsPieBuildMode = true + } + break + } + } + if gc.IsPieBuildMode { + gc.goSymTab, err = gc.ReadTable() + if err != nil { + return err + } + var addr uint64 + 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) + if err != nil { + return fmt.Errorf("%s symbol address error:%s", GoTlsMasterSecretFunc, err.Error()) + } + gc.GoTlsMasterSecretAddr = addr + + gc.ReadTlsAddrs, err = gc.findRetOffsetsPie(GoTlsReadFunc) + if err != nil { + return err + } + } else { + gc.ReadTlsAddrs, err = gc.findRetOffsets(GoTlsReadFunc) + if err != nil { + return err + } + } return err } @@ -118,14 +205,13 @@ func (gc *GoTLSConfig) findRetOffsets(symbolName string) ([]int, error) { if len(goSymbs) > 0 { allSymbs = append(allSymbs, goSymbs...) } - goDynamicSymbs, _ := gc.goElf.DynamicSymbols() if len(goDynamicSymbs) > 0 { allSymbs = append(allSymbs, goDynamicSymbs...) } if len(allSymbs) == 0 { - return nil, fmt.Errorf("no symbols found") + return nil, ErrorSymbolEmpty } var found bool @@ -160,29 +246,22 @@ func (gc *GoTLSConfig) findRetOffsets(symbolName string) ([]int, error) { if len(offsets) == 0 { return offsets, ErrorNoRetFound } - return offsets, nil -} -// decodeInstruction Decode into assembly instructions and identify the RET instruction to return the offset. -func (gc *GoTLSConfig) decodeInstruction(instHex []byte) ([]int, error) { - var offsets []int - for i := 0; i < len(instHex); { - if gc.goElfArch == "amd64" { - inst, err := x86asm.Decode(instHex[i:], 64) - if err != nil { - return nil, err - } - if inst.Op == x86asm.RET { - offsets = append(offsets, i) - } - i += inst.Len - } else { - inst, _ := arm64asm.Decode(instHex[i:]) // Why ignore error: https://github.com/gojue/ecapture/pull/506 - if inst.Op == arm64asm.RET { - offsets = append(offsets, i) - } - i += Arm64armInstSize + address := symbol.Value + for _, prog := range gc.goElf.Progs { + // Skip uninteresting segments. + if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 { + continue } + + if prog.Vaddr <= symbol.Value && symbol.Value < (prog.Vaddr+prog.Memsz) { + // stackoverflow.com/a/40249502 + address = symbol.Value - prog.Vaddr + prog.Off + break + } + } + for i, offset := range offsets { + offsets[i] = int(address) + offset } return offsets, nil } @@ -204,3 +283,96 @@ func (gc *GoTLSConfig) checkModel() (string, error) { } return m, e } + +func (gc *GoTLSConfig) ReadTable() (*gosym.Table, error) { + sectionLabel := ".gopclntab" + section := gc.goElf.Section(sectionLabel) + if section == nil { + // binary may be built with -pie + sectionLabel = ".data.rel.ro.gopclntab" + section = gc.goElf.Section(sectionLabel) + if section == nil { + sectionLabel = ".data.rel.ro" + section = gc.goElf.Section(sectionLabel) + if section == nil { + return nil, fmt.Errorf("could not read section %s from %s ", sectionLabel, gc.Path) + } + } + } + tableData, err := section.Data() + if err != nil { + return nil, fmt.Errorf("found section but could not read %s from %s ", sectionLabel, gc.Path) + } + // 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) + if pclntabIndex < 0 { + return nil, fmt.Errorf("could not find magic number in %s ", gc.Path) + } + tableData = tableData[pclntabIndex:] + + addr := gc.goElf.Section(".text").Addr + lineTable := gosym.NewLineTable(tableData, addr) + symTable, err := gosym.NewTable([]byte{}, lineTable) + if err != nil { + return nil, ErrorSymbolNotFoundFromTable + } + return symTable, nil +} + +func (gc *GoTLSConfig) findRetOffsetsPie(lfunc string) ([]int, error) { + var offsets []int + var address uint64 + var err error + address, err = gc.findPieSymbolAddr(lfunc) + if err != nil { + return offsets, err + } + f := gc.goSymTab.LookupFunc(lfunc) + funcLen := f.End - f.Entry + for _, prog := range gc.goElf.Progs { + if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 { + continue + } + data := make([]byte, funcLen) + _, err = prog.ReadAt(data, int64(address)) + if err != nil { + return offsets, fmt.Errorf("finding function return: %w", err) + } + offsets, err = gc.decodeInstruction(data) + if err != nil { + return offsets, fmt.Errorf("finding function return: %w", err) + } + for i, offset := range offsets { + offsets[i] = int(address) + offset + } + return offsets, nil + } + return offsets, errors.New("cant found gotls symbol offsets.") +} + +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.") + } + var err error + for _, prog := range gc.goElf.Progs { + if prog.Type != elf.PT_LOAD || (prog.Flags&elf.PF_X) == 0 { + continue + } + // For more info on this calculation: stackoverflow.com/a/40249502 + if prog.Vaddr <= f.Value && f.Value < (prog.Vaddr+prog.Memsz) { + funcLen := f.End - f.Entry + data := make([]byte, funcLen) + address := f.Value - prog.Vaddr + prog.Off + IdaProOffset + _, err = prog.ReadAt(data, int64(address)) + if err != nil { + return 0, fmt.Errorf("search function return: %w", err) + } + return address, nil + } + } + return 0, ErrorNoRetFoundFromSymTabFun +} diff --git a/user/config/go_instructions_amd64.go b/user/config/go_instructions_amd64.go new file mode 100644 index 000000000..f2d9c7c8d --- /dev/null +++ b/user/config/go_instructions_amd64.go @@ -0,0 +1,21 @@ +package config + +import ( + "golang.org/x/arch/x86/x86asm" +) + +// decodeInstruction Decode into assembly instructions and identify the RET instruction to return the offset. +func (gc *GoTLSConfig) decodeInstruction(instHex []byte) ([]int, error) { + var offsets []int + for i := 0; i < len(instHex); { + inst, err := x86asm.Decode(instHex[i:], 64) + if err != nil { + return nil, err + } + if inst.Op == x86asm.RET { + offsets = append(offsets, i) + } + i += inst.Len + } + return offsets, nil +} diff --git a/user/config/go_instructions_arm64.go b/user/config/go_instructions_arm64.go new file mode 100644 index 000000000..ac4c20a6b --- /dev/null +++ b/user/config/go_instructions_arm64.go @@ -0,0 +1,23 @@ +package config + +import ( + "golang.org/x/arch/arm64/arm64asm" +) + +const ( + // Arm64armInstSize via : arm64/arm64asm/decode.go:Decode() size = 4 + Arm64armInstSize = 4 +) + +// decodeInstruction Decode into assembly instructions and identify the RET instruction to return the offset. +func (gc *GoTLSConfig) decodeInstruction(instHex []byte) ([]int, error) { + var offsets []int + for i := 0; i < len(instHex); { + inst, _ := arm64asm.Decode(instHex[i:]) // Why ignore error: https://github.com/gojue/ecapture/pull/506 + if inst.Op == arm64asm.RET { + offsets = append(offsets, i) + } + i += Arm64armInstSize + } + return offsets, nil +} diff --git a/user/event/event_gotls.go b/user/event/event_gotls.go index ae1392053..23f5c3988 100644 --- a/user/event/event_gotls.go +++ b/user/event/event_gotls.go @@ -32,6 +32,8 @@ func (ge *GoTLSEvent) Decode(payload []byte) error { if err = binary.Read(r, binary.LittleEndian, &ge.Data); err != nil { return err } + } else { + ge.Len = 0 } decodedKtime, err := DecodeKtime(int64(ge.TimestampNS), true) if err == nil { diff --git a/user/module/probe_gotls.go b/user/module/probe_gotls.go index c11479316..d7ad4b65e 100644 --- a/user/module/probe_gotls.go +++ b/user/module/probe_gotls.go @@ -29,11 +29,6 @@ func init() { Register(mod) } -const ( - goTlsWriteFunc = "crypto/tls.(*Conn).writeRecordLocked" - goTlsMasterSecretFunc = "crypto/tls.(*Config).writeKeyLog" -) - var NotGoCompiledBin = errors.New("It is not a program compiled in the Go language.") // GoTLSProbe represents a probe for Go SSL @@ -261,6 +256,8 @@ func (g *GoTLSProbe) saveMasterSecret(secretEvent *event.MasterSecretGotlsEvent) g.logger.Fatalf("%s: save masterSecrets to pcapng error:%s", secretEvent.String(), e.Error()) return } + default: + g.logger.Fatalf("unhandled default case with eBPF Program type:%d", g.eBPFProgramType) } } diff --git a/user/module/probe_gotls_keylog.go b/user/module/probe_gotls_keylog.go index 244e5fd73..4ff477ef8 100644 --- a/user/module/probe_gotls_keylog.go +++ b/user/module/probe_gotls_keylog.go @@ -15,18 +15,35 @@ package module import ( + "ecapture/user/config" "ecapture/user/event" "errors" "github.com/cilium/ebpf" manager "github.com/gojue/ebpfmanager" "golang.org/x/sys/unix" "math" + "strings" ) func (g *GoTLSProbe) setupManagersKeylog() error { - - g.logger.Printf("%s\tHOOK type:golang elf, binrayPath:%s\n", g.Name(), g.path) - g.logger.Printf("%s\tHook masterKey function:%s\n", g.Name(), goTlsMasterSecretFunc) + var gotlsConf = g.conf.(*config.GoTLSConfig) + var buildInfo = new(strings.Builder) + for _, setting := range gotlsConf.Buildinfo.Settings { + if setting.Value == "" { + continue + } + buildInfo.WriteString(" ") + buildInfo.WriteString(setting.Key) + buildInfo.WriteString("=") + buildInfo.WriteString(setting.Value) + } + g.logger.Printf("%s\tHOOK type:Golang elf, binrayPath:%s\n", g.Name(), g.path) + g.logger.Printf("%s\tGolang buildInfo version:%s, Params: %s\n", g.Name(), gotlsConf.Buildinfo.GoVersion, buildInfo.String()) + if gotlsConf.IsPieBuildMode { + // buildmode pie is enabled. + g.logger.Printf("%s\tGolang elf buildmode with pie\n", g.Name()) + } + g.logger.Printf("%s\tHook masterKey function:%s, Address:%x \n", g.Name(), config.GoTlsMasterSecretFunc, gotlsConf.GoTlsMasterSecretAddr) var ( sec string @@ -47,9 +64,10 @@ func (g *GoTLSProbe) setupManagersKeylog() error { { Section: sec, EbpfFuncName: fn, - AttachToFuncName: goTlsMasterSecretFunc, + AttachToFuncName: config.GoTlsMasterSecretFunc, BinaryPath: g.path, UID: "uprobe_gotls_master_secret", + UAddress: g.conf.(*config.GoTLSConfig).GoTlsMasterSecretAddr, }, }, diff --git a/user/module/probe_gotls_pcap.go b/user/module/probe_gotls_pcap.go index 2f80813c9..3d65f382f 100644 --- a/user/module/probe_gotls_pcap.go +++ b/user/module/probe_gotls_pcap.go @@ -55,7 +55,7 @@ func (g *GoTLSProbe) setupManagersPcap() error { g.logger.Printf("%s\tHOOK type:golang elf, binrayPath:%s\n", g.Name(), g.path) g.logger.Printf("%s\tPcapFilter: %s\n", g.Name(), pcapFilter) g.logger.Printf("%s\tIfname: %s, Ifindex: %d\n", g.Name(), g.ifName, g.ifIdex) - g.logger.Printf("%s\tHook masterKey function: %s\n", g.Name(), goTlsMasterSecretFunc) + g.logger.Printf("%s\tHook masterKey function: %s, Address:%x \n", g.Name(), config.GoTlsMasterSecretFunc, g.conf.(*config.GoTLSConfig).GoTlsMasterSecretAddr) // create pcapng writer netIfs, err := net.Interfaces() @@ -106,9 +106,10 @@ func (g *GoTLSProbe) setupManagersPcap() error { { Section: sec, EbpfFuncName: fn, - AttachToFuncName: goTlsMasterSecretFunc, + AttachToFuncName: config.GoTlsMasterSecretFunc, BinaryPath: g.path, UID: "uprobe_gotls_master_secret", + UAddress: g.conf.(*config.GoTLSConfig).GoTlsMasterSecretAddr, }, }, diff --git a/user/module/probe_gotls_text.go b/user/module/probe_gotls_text.go index 2fe0112fd..b21513e13 100644 --- a/user/module/probe_gotls_text.go +++ b/user/module/probe_gotls_text.go @@ -23,6 +23,7 @@ import ( manager "github.com/gojue/ebpfmanager" "golang.org/x/sys/unix" "math" + "strings" ) func (g *GoTLSProbe) setupManagersText() error { @@ -42,14 +43,32 @@ func (g *GoTLSProbe) setupManagersText() error { readSec = "uprobe/gotls_read_stack" readFn = "gotls_read_stack" } + var gotlsConf = g.conf.(*config.GoTLSConfig) + var buildInfo = new(strings.Builder) + for _, setting := range gotlsConf.Buildinfo.Settings { + if setting.Value == "" { + continue + } + buildInfo.WriteString(" ") + buildInfo.WriteString(setting.Key) + buildInfo.WriteString("=") + buildInfo.WriteString(setting.Value) + } g.logger.Printf("%s\teBPF Function Name:%s, isRegisterABI:%t\n", g.Name(), fn, g.isRegisterABI) + g.logger.Printf("%s\tGolang buildInfo version:%s, Params: %s\n", g.Name(), gotlsConf.Buildinfo.GoVersion, buildInfo.String()) + + if g.conf.(*config.GoTLSConfig).IsPieBuildMode { + // buildmode pie is enabled. + g.logger.Printf("%s\tGolang elf buildmode with pie\n", g.Name()) + } g.bpfManager = &manager.Manager{ Probes: []*manager.Probe{ { Section: sec, EbpfFuncName: fn, - AttachToFuncName: goTlsWriteFunc, + AttachToFuncName: config.GoTlsWriteFunc, BinaryPath: g.path, + UAddress: g.conf.(*config.GoTLSConfig).GoTlsWriteAddr, }, }, Maps: []*manager.Map{ @@ -69,8 +88,9 @@ func (g *GoTLSProbe) setupManagersText() error { EbpfFuncName: readFn, AttachToFuncName: config.GoTlsReadFunc, BinaryPath: g.path, - UprobeOffset: uint64(v), - UID: uid, + //UprobeOffset: uint64(v), + UAddress: uint64(v), + UID: uid, }) } g.bpfManagerOptions = manager.Options{