Skip to content

Commit 4ec45e2

Browse files
authored
Merge 53ce68e into f929c68
2 parents f929c68 + 53ce68e commit 4ec45e2

10 files changed

Lines changed: 497 additions & 99 deletions

File tree

internal/output/writers/keylog_writer.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,9 @@ func NewPcapKeylogWriter(pw *PcapWriter) *PcapKeylogWriter {
3434
}
3535

3636
func (w *PcapKeylogWriter) Write(p []byte) (n int, err error) {
37-
return len(p), w.PcapWriter.WriteKeyLog(p)
37+
// Create a copy to avoid modifying the provided buffer
38+
data := make([]byte, len(p)+1)
39+
copy(data, p)
40+
data[len(p)] = '\n'
41+
return len(p), w.PcapWriter.WriteKeyLog(data)
3842
}

internal/probe/base/handlers/keylog_handler.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ func (h *KeylogHandler) handleTLS12(event MasterSecretEvent) error {
150150
}
151151

152152
// Format: CLIENT_RANDOM <client_random> <master_secret>
153-
line := fmt.Sprintf("%s %x %x\n",
153+
line := fmt.Sprintf("%s %x %x",
154154
KeyLogLabelTLS12,
155155
clientRandom[:Ssl3RandomSize],
156156
masterKey[:MasterSecretMaxLen])
@@ -199,7 +199,7 @@ func (h *KeylogHandler) handleGoTLS(event GoTLSMasterSecretEvent) error {
199199

200200
// Format: LABEL <client_random_hex> <secret_hex>
201201
// This is the standard NSS Key Log Format used by Wireshark
202-
line := fmt.Sprintf("%s %x %x\n", label, clientRandom, secret)
202+
line := fmt.Sprintf("%s %x %x", label, clientRandom, secret)
203203

204204
// Use label+client_random as dedup key to avoid multiple captures
205205
dedupKey := fmt.Sprintf("%s_%x", label, clientRandom)
@@ -250,7 +250,7 @@ func (h *KeylogHandler) handleTLS13(event MasterSecretEvent) error {
250250
continue // Already written this secret type for this connection
251251
}
252252

253-
line := fmt.Sprintf("%s %s %x\n", secret.label, clientRandomHex, secret.data)
253+
line := fmt.Sprintf("%s %s %x", secret.label, clientRandomHex, secret.data)
254254

255255
// Write to output
256256
if _, err := h.writer.Write([]byte(line)); err != nil {

internal/probe/bash/bash_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,6 @@ func TestNewProbe(t *testing.T) {
133133
if err != nil {
134134
t.Fatalf("NewProbe() error = %v", err)
135135
}
136-
if probe == nil {
137-
t.Fatal("NewProbe() returned nil")
138-
}
139136
if probe.Name() != "Bash" {
140137
t.Errorf("expected name 'bash', got %s", probe.Name())
141138
}

internal/probe/gotls/config_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,6 @@ import (
2525

2626
func TestNewConfig(t *testing.T) {
2727
cfg := NewConfig()
28-
if cfg == nil {
29-
t.Fatal("NewConfig() returned nil")
30-
}
3128

3229
if cfg.CaptureMode != "text" {
3330
t.Errorf("expected default CaptureMode='text', got '%s'", cfg.CaptureMode)

internal/probe/mysql/mysql_test.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,6 @@ func TestEvent_Methods(t *testing.T) {
224224

225225
func TestProbe_Creation(t *testing.T) {
226226
probe := NewProbe()
227-
if probe == nil {
228-
t.Fatal("NewProbe() returned nil")
229-
}
230227

231228
if probe.Name() != "MySQL" {
232229
t.Errorf("Probe.Name() = %v, want %v", probe.Name(), "MySQL")

internal/probe/openssl/config.go

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -170,10 +170,7 @@ func (c *Config) validateCaptureMode() error {
170170

171171
// IsSupportedVersion checks if the detected version is supported.
172172
func (c *Config) IsSupportedVersion() bool {
173-
if c.SslVersion != "" {
174-
return true
175-
}
176-
return false
173+
return c.SslVersion != ""
177174
}
178175

179176
// GetBPFFileName returns the eBPF object file name for the detected version.
@@ -326,9 +323,6 @@ func (c *Config) getSslBpfFile(soPath, sslVersion string) error {
326323
//c.Logger().Warn().Err(err).Str("soPath", soPath).Str("imported", libcryptoName).Msgf("OpenSSL(libcrypto.so.3) version not found.%s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux))
327324
return err
328325
}
329-
if goerrors.Is(err, ErrProbeOpensslVerNotFound) {
330-
//c.Logger().Info().Str("soPath", soPath).Str("imported", libcryptoName).Str("version", verString).Msg("OpenSSL/BoringSSL version found from imported libcrypto.so")
331-
}
332326
}
333327
}
334328

@@ -354,9 +348,8 @@ func (c *Config) getSslBpfFile(soPath, sslVersion string) error {
354348
c.SslBpfFile = bpfFile
355349
//c.Logger().Info().Bool("Android", isAndroid).Str("library version", bpfFileKey).Msg("OpenSSL/BoringSSL version found")
356350
return nil
357-
} else {
358-
//c.Logger().Warn().Str("version", bpfFileKey).Err(ErrProbeOpensslVerBytecodeNotFound).Msg("Please send an issue to https://github.com/gojue/ecapture/issues")
359351
}
352+
//c.Logger().Warn().Str("version", bpfFileKey).Err(ErrProbeOpensslVerBytecodeNotFound).Msg("Please send an issue to https://github.com/gojue/ecapture/issues")
360353
}
361354

362355
bpfFile = c.autoDetectBytecode(bpfFileKey, soPath, isAndroid)
@@ -484,13 +477,12 @@ func (c *Config) autoDetectBytecode(ver, soPath string, isAndroid bool) string {
484477
}
485478

486479
// auto downgrade openssl version
487-
var isDowngrade bool
488-
bpfFile, isDowngrade = c.downgradeOpensslVersion(ver, soPath)
489-
if isDowngrade {
490-
//c.Logger().Error().Str("OpenSSL Version", ver).Str("bpfFile", bpfFile).Msgf("OpenSSL/BoringSSL version not found, used downgrade version. %s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux))
491-
} else {
492-
//c.Logger().Error().Str("OpenSSL Version", ver).Str("bpfFile", bpfFile).Msgf("OpenSSL/BoringSSL version not found, used default version. %s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux))
493-
}
480+
//var isDowngrade bool
481+
bpfFile, _ = c.downgradeOpensslVersion(ver, soPath)
482+
//if isDowngrade {
483+
//c.Logger().Error().Str("OpenSSL Version", ver).Str("bpfFile", bpfFile).Msgf("OpenSSL/BoringSSL version not found, used downgrade version. %s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux))
484+
//}
485+
//c.Logger().Error().Str("OpenSSL Version", ver).Str("bpfFile", bpfFile).Msgf("OpenSSL/BoringSSL version not found, used default version. %s", fmt.Sprintf(OpensslNoticeUsedDefault, OpensslNoticeVersionGuideLinux))
494486

495487
return bpfFile
496488
}

internal/probe/openssl/event.go

Lines changed: 152 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import (
2020
"fmt"
2121
"time"
2222

23+
"golang.org/x/sys/unix"
24+
2325
"github.com/gojue/ecapture/internal/domain"
2426
"github.com/gojue/ecapture/internal/errors"
2527
)
@@ -31,31 +33,91 @@ const (
3133

3234
// MaxDataSize is the maximum TLS data size from eBPF
3335
// Increased to 16KB, fix: https://github.com/gojue/ecapture/issues/740
34-
MaxDataSize = 1024 * 16
35-
36+
MaxDataSize = 1024 * 16
3637
ChunkSize = 32
3738
ChunkSizeHalf = ChunkSize / 2
3839
)
3940

41+
type AttachType int64
42+
43+
const (
44+
ProbeEntry AttachType = iota
45+
ProbeRet
46+
)
47+
48+
const (
49+
Ssl2Version = 0x0002
50+
Ssl3Version = 0x0300
51+
Tls1Version = 0x0301
52+
Tls11Version = 0x0302
53+
Tls12Version = 0x0303
54+
Tls13Version = 0x0304
55+
Dtls1Version = 0xFEFF
56+
Dtls12Version = 0xFEFD
57+
)
58+
59+
type TlsVersion struct {
60+
Version int32
61+
}
62+
63+
func (t TlsVersion) String() string {
64+
switch t.Version {
65+
case Ssl2Version:
66+
return "SSL2_VERSION"
67+
case Ssl3Version:
68+
return "SSL3_VERSION"
69+
case Tls1Version:
70+
return "TLS1_VERSION"
71+
case Tls11Version:
72+
return "TLS1_1_VERSION"
73+
case Tls12Version:
74+
return "TLS1_2_VERSION"
75+
case Tls13Version:
76+
return "TLS1_3_VERSION"
77+
case Dtls1Version:
78+
return "DTLS1_VERSION"
79+
case Dtls12Version:
80+
return "DTLS1_2_VERSION"
81+
}
82+
return fmt.Sprintf("TLS_VERSION_UNKNOWN_%d", t.Version)
83+
}
84+
85+
/*
86+
struct ssl_data_event_t {
87+
enum ssl_data_event_type type;
88+
u64 timestamp_ns;
89+
u32 pid;
90+
u32 tid;
91+
char data[MAX_DATA_SIZE_OPENSSL];
92+
s32 data_len;
93+
char comm[TASK_COMM_LEN];
94+
u32 fd;
95+
s32 version;
96+
u32 bio_type;
97+
};
98+
*/
4099
// Event represents an OpenSSL TLS data event from eBPF.
41100
type Event struct {
42-
Timestamp uint64 `json:"timestamp"` // Nanosecond timestamp
43-
Pid uint32 `json:"pid"` // Process ID
44-
Tid uint32 `json:"tid"` // Thread ID
45-
DataLen int32 `json:"dataLen"` // Length of actual data
46-
PayloadType uint8 `json:"payloadType"`
47-
Data [MaxDataSize]byte `json:"data"` // TLS data payload
48-
Comm [16]byte `json:"comm"` // Process name
49-
50-
DataType uint8 `json:"dataType"`
51-
Fd uint32 `json:"fd"`
52-
Version uint32 `json:"version"` // TLS version (e.g., 771 for TLS 1.2)
101+
DataType int64 `json:"dataType"`
102+
Timestamp uint64 `json:"timestamp"` // Nanosecond timestamp
103+
Pid uint32 `json:"pid"` // Process ID
104+
Tid uint32 `json:"tid"` // Thread ID
105+
Data [MaxDataSize]byte `json:"data"` // TLS data payload
106+
DataLen int32 `json:"dataLen"` // Length of actual data
107+
Comm [TaskCommLen]byte `json:"comm"` // Process name
108+
Fd uint32 `json:"fd"`
109+
Version int32 `json:"version"` // TLS version (e.g., 771 for TLS 1.2)
110+
Tuple string
111+
BioType uint32
112+
Sock uint64
53113
}
54114

55115
// DecodeFromBytes deserializes the event from raw eBPF data.
56116
func (e *Event) DecodeFromBytes(data []byte) error {
57117
buf := bytes.NewBuffer(data)
58-
118+
if err := binary.Read(buf, binary.LittleEndian, &e.DataType); err != nil {
119+
return errors.NewEventDecodeError("openssl.DataType", err)
120+
}
59121
// Read fields in order matching the eBPF structure
60122
if err := binary.Read(buf, binary.LittleEndian, &e.Timestamp); err != nil {
61123
return errors.NewEventDecodeError("openssl.Timestamp", err)
@@ -66,26 +128,25 @@ func (e *Event) DecodeFromBytes(data []byte) error {
66128
if err := binary.Read(buf, binary.LittleEndian, &e.Tid); err != nil {
67129
return errors.NewEventDecodeError("openssl.Tid", err)
68130
}
69-
if err := binary.Read(buf, binary.LittleEndian, &e.DataLen); err != nil {
70-
return errors.NewEventDecodeError("openssl.DataLen", err)
71-
}
72-
if err := binary.Read(buf, binary.LittleEndian, &e.PayloadType); err != nil {
73-
return errors.NewEventDecodeError("openssl.PayloadType", err)
74-
}
75131
if err := binary.Read(buf, binary.LittleEndian, &e.Data); err != nil {
76132
return errors.NewEventDecodeError("openssl.Data", err)
77133
}
134+
if err := binary.Read(buf, binary.LittleEndian, &e.DataLen); err != nil {
135+
return errors.NewEventDecodeError("openssl.DataLen", err)
136+
}
78137
if err := binary.Read(buf, binary.LittleEndian, &e.Comm); err != nil {
79138
return errors.NewEventDecodeError("openssl.Comm", err)
80139
}
81-
82-
if err := binary.Read(buf, binary.LittleEndian, &e.Comm); err != nil {
140+
if err := binary.Read(buf, binary.LittleEndian, &e.Fd); err != nil {
141+
return errors.NewEventDecodeError("openssl.Fd", err)
142+
}
143+
if err := binary.Read(buf, binary.LittleEndian, &e.Version); err != nil {
83144
return errors.NewEventDecodeError("openssl.Version", err)
84145
}
85-
86-
if e.Timestamp == 0 {
87-
e.Timestamp = uint64(time.Now().UnixNano())
146+
if err := binary.Read(buf, binary.LittleEndian, &e.BioType); err != nil {
147+
return errors.NewEventDecodeError("openssl.BioType", err)
88148
}
149+
89150
return nil
90151
}
91152

@@ -96,11 +157,22 @@ func (e *Event) String() string {
96157
direction = "READ"
97158
}
98159

99-
ts := time.Unix(0, int64(e.Timestamp))
160+
// 2. 获取时间偏移量
161+
offsetNs, err := getClockOffset()
162+
if err != nil {
163+
panic(err)
164+
}
165+
// 3. 计算绝对时间戳(纳秒)
166+
absoluteTimeNs := int64(e.Timestamp) + offsetNs
167+
168+
// 4. 将纳秒转换为 Go 的 time.Time 对象
169+
// time.Unix(sec, nsec)
170+
eventTime := time.Unix(0, absoluteTimeNs)
171+
100172
dataStr := string(e.GetData())
101173

102174
return fmt.Sprintf("[%s] PID:%d TID:%d Comm:%s FD:%d %s (%d bytes):\n%s",
103-
ts.Format("2006-01-02 15:04:05.000"),
175+
eventTime.Format("2006-01-02 15:04:05.000"),
104176
e.Pid,
105177
e.Tid,
106178
e.GetComm(),
@@ -118,7 +190,7 @@ func (e *Event) StringHex() string {
118190
direction = "READ"
119191
}
120192

121-
ts := time.Unix(0, int64(e.Timestamp))
193+
ts := time.Unix(int64(e.Timestamp), 0)
122194

123195
hexData := dumpByteSlice(e.GetData(), "")
124196

@@ -134,6 +206,25 @@ func (e *Event) StringHex() string {
134206
)
135207
}
136208

209+
func (e *Event) BaseInfo() string {
210+
addr := "[TODO]"
211+
if e.Tuple != "" {
212+
addr = e.Tuple
213+
}
214+
var connInfo string
215+
switch AttachType(e.DataType) {
216+
case ProbeEntry:
217+
connInfo = fmt.Sprintf("Received %d bytes from %s", e.DataLen, addr)
218+
case ProbeRet:
219+
connInfo = fmt.Sprintf("Send %d bytes to %s", e.DataLen, addr)
220+
default:
221+
connInfo = fmt.Sprintf("UNKNOWN_%d", e.DataType)
222+
}
223+
v := TlsVersion{Version: e.Version}
224+
s := fmt.Sprintf("PID:%d, Comm:%s, TID:%d, Version:%s, %s", e.Pid, commStr(e.Comm[:]), e.Tid, v.String(), connInfo)
225+
return s
226+
}
227+
137228
// Clone creates a new instance of the event.
138229
func (e *Event) Clone() domain.Event {
139230
clone := *e
@@ -213,17 +304,17 @@ func commToString(data []byte) string {
213304
return string(data)
214305
}
215306

216-
// Decode implements domain.EventDecoder interface for TLS data events.
217-
func (e *Event) Decode(data []byte) (domain.Event, error) {
218-
event := &Event{}
219-
if err := event.DecodeFromBytes(data); err != nil {
220-
return nil, err
221-
}
222-
if err := event.Validate(); err != nil {
223-
return nil, err
224-
}
225-
return event, nil
226-
}
307+
//// Decode implements domain.EventDecoder interface for TLS data events.
308+
//func (e *Event) Decode(data []byte) (domain.Event, error) {
309+
// event := &Event{}
310+
// if err := event.DecodeFromBytes(data); err != nil {
311+
// return nil, err
312+
// }
313+
// if err := event.Validate(); err != nil {
314+
// return nil, err
315+
// }
316+
// return event, nil
317+
//}
227318

228319
func dumpByteSlice(b []byte, prefix string) *bytes.Buffer {
229320
var a [ChunkSize]byte
@@ -267,3 +358,25 @@ func dumpByteSlice(b []byte, prefix string) *bytes.Buffer {
267358
}
268359
return bb
269360
}
361+
362+
// getClockOffset 计算 CLOCK_REALTIME (绝对时间) 和 CLOCK_MONOTONIC (单调时间) 之间的差值。
363+
// 这个差值实际上就是系统的启动时间 (Boot Time)。
364+
func getClockOffset() (int64, error) {
365+
var tsReal, tsMono unix.Timespec
366+
367+
// 获取当前墙上时间 (绝对时间)
368+
if err := unix.ClockGettime(unix.CLOCK_REALTIME, &tsReal); err != nil {
369+
return 0, fmt.Errorf("failed to get CLOCK_REALTIME: %w", err)
370+
}
371+
372+
// 获取当前单调时间 (自启动以来的时间)
373+
if err := unix.ClockGettime(unix.CLOCK_MONOTONIC, &tsMono); err != nil {
374+
return 0, fmt.Errorf("failed to get CLOCK_MONOTONIC: %w", err)
375+
}
376+
377+
// 转换为纳秒并计算差值
378+
realNs := tsReal.Sec*1e9 + tsReal.Nsec
379+
monoNs := tsMono.Sec*1e9 + tsMono.Nsec
380+
381+
return realNs - monoNs, nil
382+
}

0 commit comments

Comments
 (0)