Skip to content

Commit

Permalink
backup
Browse files Browse the repository at this point in the history
  • Loading branch information
SeeFlowerX committed Dec 21, 2023
1 parent 973d197 commit f0dbdaf
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 63 deletions.
20 changes: 16 additions & 4 deletions src/syscall.c
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {

for (int i = 0; i < op_count; i++) {
u32 op_key = point_args->op_key_list[i];
bpf_printk("[stackplz] index:%d op_key:%d\n", i, op_key);
// bpf_printk("[stackplz] index:%d op_key:%d\n", i, op_key);
op_config_t* op = bpf_map_lookup_elem(&op_list, &op_key);
// make ebpf verifier happy
if (unlikely(op == NULL)) return 0;

bpf_printk("[stackplz] op_key:%d code:%d value:%ld\n", op_key, op->code, op->value);
// bpf_printk("[stackplz] op_key:%d code:%d value:%ld\n", op_key, op->code, op->value);

// 一旦 break_flag 置 1 那么跳过所有操作直到出现 OP_RESET_BREAK
if (op_ctx->break_flag == 1) {
Expand Down Expand Up @@ -266,6 +266,7 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
op_ctx->read_len = op_ctx->reg_value;
}
case OP_SET_READ_LEN_POINTER_VALUE:
// bpf_printk("[stackplz] OP_SET_READ_LEN_POINTER_VALUE old_len:%d new_len:%d\n", op_ctx->read_len, op_ctx->pointer_value);
if (op_ctx->read_len > op_ctx->pointer_value) {
op_ctx->read_len = op_ctx->pointer_value;
}
Expand All @@ -274,9 +275,11 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
op_ctx->read_len *= op->value;
break;
case OP_ADD_OFFSET:
// bpf_printk("[stackplz] OP_ADD_OFFSET ptr:0x%lx add:%d\n", op_ctx->read_addr, op->value);
op_ctx->read_addr += op->value;
break;
case OP_SUB_OFFSET:
// bpf_printk("[stackplz] OP_SUB_OFFSET ptr:0x%lx sub:%d\n", op_ctx->read_addr, op->value);
op_ctx->read_addr -= op->value;
break;
case OP_MOVE_REG_VALUE:
Expand All @@ -295,8 +298,14 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
op_ctx->break_count = op_ctx->reg_value;
break;
case OP_SET_BREAK_COUNT_POINTER_VALUE:
// bpf_printk("[stackplz] OP_SET_BREAK_COUNT_POINTER_VALUE count:%d\n", op_ctx->pointer_value);
op_ctx->break_count = op_ctx->pointer_value;
break;
case OP_SAVE_ADDR:
// bpf_printk("[stackplz] OP_SAVE_ADDR val:0x%lx idx:%d\n", op_ctx->read_addr, op_ctx->save_index);
save_to_submit_buf(p.event, (void *)&op_ctx->read_addr, sizeof(op_ctx->read_addr), op_ctx->save_index);
op_ctx->save_index += 1;
break;
case OP_READ_REG:
// make ebpf verifier happy
if (op_ctx->reg_index >= REG_ARM64_MAX) {
Expand All @@ -305,14 +314,16 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
op_ctx->reg_value = READ_KERN(regs->regs[op_ctx->reg_index]);
break;
case OP_SAVE_REG:
save_to_submit_buf(p.event, (void *)&op_ctx->reg_value, sizeof(op_ctx->reg_value), (u8)op_ctx->save_index);
save_to_submit_buf(p.event, (void *)&op_ctx->reg_value, sizeof(op_ctx->reg_value), op_ctx->save_index);
op_ctx->save_index += 1;
break;
case OP_READ_POINTER:
bpf_probe_read_user(&op_ctx->pointer_value, sizeof(op_ctx->pointer_value), (void*)op_ctx->read_addr);
// bpf_printk("[stackplz] OP_READ_POINTER ptr:0x%lx val:0x%lx\n", op_ctx->read_addr, op_ctx->pointer_value);
break;
case OP_SAVE_POINTER:
save_to_submit_buf(p.event, (void *) &op_ctx->pointer_value, sizeof(op_ctx->pointer_value), op_ctx->save_index);
// bpf_printk("[stackplz] OP_SAVE_POINTER val:0x%lx idx:%d\n", op_ctx->pointer_value, op_ctx->save_index);
save_to_submit_buf(p.event, (void *)&op_ctx->pointer_value, sizeof(op_ctx->pointer_value), op_ctx->save_index);
op_ctx->save_index += 1;
break;
case OP_READ_STRUCT:
Expand All @@ -323,6 +334,7 @@ int next_raw_syscalls_sys_enter(struct bpf_raw_tracepoint_args* ctx) {
if (op_ctx->read_len > MAX_BYTES_ARR_SIZE) {
op_ctx->read_len = MAX_BYTES_ARR_SIZE;
}
// bpf_printk("[stackplz] OP_SAVE_STRUCT ptr:0x%lx len:%d\n", op_ctx->read_addr, op_ctx->read_len);
int status = save_bytes_to_buf(p.event, (void *)(op_ctx->read_addr), op_ctx->read_len, op_ctx->save_index);
if (status == 0) {
// 保存失败的情况 比如是一个非法的地址 那么就填一个空的 buf
Expand Down
1 change: 1 addition & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ enum op_code_e
OP_SET_TMP_VALUE,
OP_SET_BREAK_COUNT_REG_VALUE,
OP_SET_BREAK_COUNT_POINTER_VALUE,
OP_SAVE_ADDR,
OP_READ_REG,
OP_SAVE_REG,
OP_READ_POINTER,
Expand Down
29 changes: 20 additions & 9 deletions user/config/config_struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,12 +390,11 @@ type Arg_Iovec_Fix_t struct {

func (this *Arg_Iovec_Fix_t) Format() string {
var fields []string
fields = append(fields, fmt.Sprintf("index=%d", this.Index))
fields = append(fields, fmt.Sprintf("len=%d", this.Len))
fields = append(fields, fmt.Sprintf("base=0x%x", this.Base))
fields = append(fields, fmt.Sprintf("len=0x%x", this.BufLen))
fields = append(fields, fmt.Sprintf("buf=(%s)", util.PrettyByteSlice(this.Payload)))
return fmt.Sprintf("{%s}", strings.Join(fields, ", "))
// fields = append(fields, fmt.Sprintf("index=%d", this.Index))
// fields = append(fields, fmt.Sprintf("len=%d", this.Len))
fields = append(fields, fmt.Sprintf("base=0x%x(%s)", this.Base, util.PrettyByteSlice(this.Payload)))
fields = append(fields, fmt.Sprintf("buflen=0x%x", this.BufLen))
return fmt.Sprintf("(%s)", strings.Join(fields, ", "))
}

type Arg_Iovec_t struct {
Expand Down Expand Up @@ -502,12 +501,24 @@ func (this *Arg_Msghdr) Format() string {
var fields []string
fields = append(fields, fmt.Sprintf("name=0x%x", this.Name))
fields = append(fields, fmt.Sprintf("namelen=0x%x", this.Namelen))
fields = append(fields, fmt.Sprintf("iov=0x%x", this.Iov))
fields = append(fields, fmt.Sprintf("*iov=0x%x", this.Iov))
fields = append(fields, fmt.Sprintf("iovlen=0x%x", this.Iovlen))
fields = append(fields, fmt.Sprintf("control=0x%x", this.Control))
fields = append(fields, fmt.Sprintf("*control=0x%x", this.Control))
fields = append(fields, fmt.Sprintf("controllen=0x%x", this.Controllen))
fields = append(fields, fmt.Sprintf("flags=0x%x", this.Flags))
return fmt.Sprintf("{%s}", strings.Join(fields, ", "))
return fmt.Sprintf("(%s)", strings.Join(fields, ", "))
}

func (this *Arg_Msghdr) FormatFull(iov_fmt, control_fmt string) string {
var fields []string
fields = append(fields, fmt.Sprintf("name=0x%x", this.Name))
fields = append(fields, fmt.Sprintf("namelen=0x%x", this.Namelen))
fields = append(fields, fmt.Sprintf("*iov=0x%x%s", this.Iov, iov_fmt))
fields = append(fields, fmt.Sprintf("iovlen=0x%x", this.Iovlen))
fields = append(fields, fmt.Sprintf("*control=0x%x%s", this.Control, control_fmt))
fields = append(fields, fmt.Sprintf("controllen=0x%x", this.Controllen))
fields = append(fields, fmt.Sprintf("flags=0x%x", this.Flags))
return fmt.Sprintf("(%s)", strings.Join(fields, ", "))
}

type Arg_ItTmerspec struct {
Expand Down
64 changes: 46 additions & 18 deletions user/config/config_syscall_aarch64.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ const (
OP_SET_TMP_VALUE
OP_SET_BREAK_COUNT_REG_VALUE
OP_SET_BREAK_COUNT_POINTER_VALUE
OP_SAVE_ADDR
OP_READ_REG
OP_SAVE_REG
OP_READ_POINTER
Expand Down Expand Up @@ -193,6 +194,7 @@ var OPC_MOVE_TMP_VALUE = ROPC(OP_MOVE_TMP_VALUE)
var OPC_SET_TMP_VALUE = ROPC(OP_SET_TMP_VALUE)
var OPC_SET_BREAK_COUNT_REG_VALUE = ROPC(OP_SET_BREAK_COUNT_REG_VALUE)
var OPC_SET_BREAK_COUNT_POINTER_VALUE = ROPC(OP_SET_BREAK_COUNT_POINTER_VALUE)
var OPC_SAVE_ADDR = ROPC(OP_SAVE_ADDR)
var OPC_READ_REG = ROPC(OP_READ_REG)
var OPC_SAVE_REG = ROPC(OP_SAVE_REG)
var OPC_READ_POINTER = ROPC(OP_READ_POINTER)
Expand Down Expand Up @@ -295,7 +297,7 @@ func R(nr uint32, name string, configs ...*ArgOpConfig) {
ops = append(ops, op_key)
}
}
fmt.Println("len(ops)", len(ops))
// fmt.Println("len(ops)", len(ops))
// 检查操作数上限
op_key_config := OpKeyConfig{}
if len(ops) > len(op_key_config.OpKeyList) {
Expand Down Expand Up @@ -329,44 +331,70 @@ func init() {
}
// 对一些复杂结构体的读取配置进行补充

// 读取 iov 数据
// 读取 iov 注意 OPA_IOV 第一步会执行 OPC_SAVE_STRUCT
// 将 op_ctx->read_addr 指向 iovec->iov_len
OPA_IOV.AddOp(OPC_ADD_OFFSET, 8)
// 读取 iovec->iov_len
OPA_IOV.AddOpC(OP_READ_POINTER)
// 设置 op_ctx->read_len 为默认的单次最大读取长度
OPA_IOV.AddOp(OPC_SET_READ_LEN, uint64(MAX_BUF_READ_SIZE))
// 修正 op_ctx->read_len
OPA_IOV.AddOpC(OP_SET_READ_LEN_POINTER_VALUE)
// 将 op_ctx->read_addr 重新指向 iovec 起始处
OPA_IOV.AddOp(OPC_SUB_OFFSET, 8)
// 读取 iovec->iov_base
OPA_IOV.AddOpC(OP_READ_POINTER)
// 转移 iovec->iov_base 到 op_ctx->read_addr
OPA_IOV.AddOpC(OP_MOVE_POINTER_VALUE)
// 读取 op_ctx->read_addr 处 op_ctx->read_len 长度的数据
OPA_IOV.AddOpC(OP_SAVE_STRUCT)

// 将读取地址指向 iovlen
// 将 op_ctx->read_addr 保存到 op_ctx->tmp_value 也就是 msghdr 的地址
OPA_MSGHDR.AddOpC(OP_SET_TMP_VALUE)
// 将 op_ctx->read_addr 指向 msghdr->controllen
OPA_MSGHDR.AddOp(OPC_ADD_OFFSET, 8+4+4+8+8+8)
// 读取 msghdr->controllen
OPA_MSGHDR.AddOpC(OP_READ_POINTER)
// 设置 op_ctx->read_len 为默认的单次最大读取长度
OPA_MSGHDR.AddOp(OPC_SET_READ_LEN, uint64(MAX_BUF_READ_SIZE))
// 修正 op_ctx->read_len
OPA_MSGHDR.AddOpC(OP_SET_READ_LEN_POINTER_VALUE)
// 将 op_ctx->read_addr 指向 msghdr->control 起始处
OPA_MSGHDR.AddOp(OPC_SUB_OFFSET, 8)
// 读取 msghdr->control
OPA_MSGHDR.AddOpC(OP_READ_POINTER)
// 转移 msghdr->control 到 op_ctx->read_addr
OPA_MSGHDR.AddOpC(OP_MOVE_POINTER_VALUE)
// 读取 op_ctx->read_addr 处 op_ctx->read_len 长度的数据
OPA_MSGHDR.AddOpC(OP_SAVE_STRUCT)
// 恢复 op_ctx->tmp_value 也就是 op_ctx->read_addr 重新指向 msghdr
OPA_MSGHDR.AddOpC(OP_MOVE_TMP_VALUE)

// 将 op_ctx->read_addr 指向 msghdr->iovlen
OPA_MSGHDR.AddOp(OPC_ADD_OFFSET, 8+4+4+8)
// 读取 iovlen
// 读取 msghdr->iovlen
OPA_MSGHDR.AddOpC(OP_READ_POINTER)
// 将 iovlen 设置为循环次数上限
OPA_MSGHDR.AddOpC(OP_SET_BREAK_COUNT_POINTER_VALUE)
// 将读取地址指向 iov
// 将读取地址指向 msghdr->iov
OPA_MSGHDR.AddOp(OPC_SUB_OFFSET, 8)
// 取出 iov 指针
// 读取 msghdr->iov 指针
OPA_MSGHDR.AddOpC(OP_READ_POINTER)
// 保存 iov 指针
OPA_MSGHDR.AddOpC(OP_SAVE_POINTER)
// 将读取地址指向取出的 iov 指针
// 将 op_ctx->read_addr 指向 msghdr->iov 指针
OPA_MSGHDR.AddOpC(OP_MOVE_POINTER_VALUE)
// 将读取地址放一份到临时变量中
OPA_MSGHDR.AddOpC(OP_SET_TMP_VALUE)
// 读取 iov 结构体 设置最多读取6次
// 读取 msghdr->iov 最多读取 6 次 最少 msghdr->iovlen 次
for i := 0; i < 6; i++ {
OPA_MSGHDR.AddOp(OPC_FOR_BREAK, uint64(i))
OPA_MSGHDR.AddOpC(OP_READ_POINTER)
OPA_MSGHDR.AddOpC(OP_MOVE_POINTER_VALUE)
// 保存 iov 指针
OPA_MSGHDR.AddOpC(OP_SAVE_ADDR)
// 将读取地址放一份到临时变量中
OPA_MSGHDR.AddOpC(OP_SET_TMP_VALUE)
// 读取 iov 数据
OPA_MSGHDR.AddOpA(OPA_IOV)
// 恢复临时变量结果到 读取地址
OPA_MSGHDR.AddOpC(OP_MOVE_TMP_VALUE)
// 将 读取地址 偏移一个指针大小
OPA_MSGHDR.AddOp(OPC_ADD_OFFSET, 8)
// 更新临时变量
OPA_MSGHDR.AddOpC(OP_SET_TMP_VALUE)
// 将 读取地址 偏移到下一个 iov 指针处
OPA_MSGHDR.AddOp(OPC_ADD_OFFSET, 16)
}
OPA_MSGHDR.AddOpC(OP_RESET_BREAK)

Expand Down
83 changes: 51 additions & 32 deletions user/event/event_raw_syscalls.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,83 +27,90 @@ type SyscallEvent struct {
type Arg_bytes = config.Arg_str

func (this *SyscallEvent) ParseContextSysEnterNext() (err error) {
if this.mconf.Next {
this.logger.Printf("ParseContextSysEnterNext RawSample:\n%s", util.HexDump(this.rec.RawSample, util.COLORRED))
}
this.logger.Printf("nr:%s", this.nr.Format())
// 输出json会更方便分析 next
// if this.mconf.Next {
// this.logger.Printf("ParseContextSysEnterNext RawSample:\n%s", util.HexDump(this.rec.RawSample, util.COLORRED))
// }
if err = binary.Read(this.buf, binary.LittleEndian, &this.lr); err != nil {
panic(err)
}
this.logger.Printf("lr:%s", this.lr.Format())
if err = binary.Read(this.buf, binary.LittleEndian, &this.pc); err != nil {
panic(err)
}
this.logger.Printf("pc:%s", this.pc.Format())
if err = binary.Read(this.buf, binary.LittleEndian, &this.sp); err != nil {
panic(err)
}
this.logger.Printf("sp:%s", this.sp.Format())
// 根据调用号解析剩余参数
this.nr_point_next = config.GetSyscallPointByNR(this.nr.Value)
if this.nr_point_next.Name != "sendmsg" {
panic("only sendmsg now")
}
var results []string
for arg_index, point_arg := range this.nr_point_next.Args {
for _, point_arg := range this.nr_point_next.Args {
var ptr config.Arg_reg
if err = binary.Read(this.buf, binary.LittleEndian, &ptr); err != nil {
panic(err)
}
this.logger.Printf("arg_index:%d ptr:%s", arg_index, ptr.Format())
switch point_arg.AliasType {
case config.TYPE_MSGHDR:
var arg_msghdr config.Arg_Msghdr
if err = binary.Read(this.buf, binary.LittleEndian, &arg_msghdr.Index); err != nil {
if err = binary.Read(this.buf, binary.LittleEndian, &arg_msghdr); err != nil {
panic(err)
}
this.logger.Printf("index=%d", arg_msghdr.Index)
results = append(results, fmt.Sprintf("index=%d", arg_msghdr.Index))
if err = binary.Read(this.buf, binary.LittleEndian, &arg_msghdr.Len); err != nil {
var control_buf config.Arg_str
if err = binary.Read(this.buf, binary.LittleEndian, &control_buf); err != nil {
panic(err)
}
this.logger.Printf("len=%d", arg_msghdr.Len)
results = append(results, fmt.Sprintf("len=%d", arg_msghdr.Len))
if err = binary.Read(this.buf, binary.LittleEndian, &arg_msghdr.Msghdr); err != nil {
panic(err)
control_payload := []byte{}
if control_buf.Len > 0 {
control_payload = make([]byte, control_buf.Len)
if err = binary.Read(this.buf, binary.LittleEndian, &control_payload); err != nil {
panic(err)
}
}
this.logger.Printf("msghdr={%s}", arg_msghdr.Format())
results = append(results, arg_msghdr.Format())

// this.logger.Printf("control_buf=%s", control_buf.Format(control_payload))

iov_len := arg_msghdr.Iovlen
if iov_len > 6 {
iov_len = 6
}
this.logger.Printf("iov_len={%d}", iov_len)
for i := 0; i < int(iov_len); i++ {
this.logger.Printf("iov_index=%d", i)

var iov_ptr config.Arg_reg
if err = binary.Read(this.buf, binary.LittleEndian, &iov_ptr); err != nil {
var iov_results []string
for iov_index := 0; iov_index < int(iov_len); iov_index++ {
var iov_value config.Arg_reg
if err = binary.Read(this.buf, binary.LittleEndian, &iov_value); err != nil {
panic(err)
}
this.logger.Printf("iov_ptr:%s", iov_ptr.Format())
// this.logger.Printf("iov_value:%s", iov_value.Format())

var arg_iovec config.Arg_Iovec_Fix_t
if err = binary.Read(this.buf, binary.LittleEndian, &arg_iovec.Arg_Iovec_Fix); err != nil {
panic(err)
}
this.logger.Printf("index:%d iovec={%s}", arg_iovec.Index, arg_iovec.Format())
// this.logger.Printf("index:%d iovec={%s}", arg_iovec.Index, arg_iovec.Format())

var iov_buf config.Arg_str
if err = binary.Read(this.buf, binary.LittleEndian, &iov_buf); err != nil {
panic(err)
}
payload := make([]byte, iov_buf.Len)
if err = binary.Read(this.buf, binary.LittleEndian, &payload); err != nil {
panic(err)
// this.logger.Printf("index:%d iov_buf.Len={%d}", iov_buf.Index, iov_buf.Len)
payload := []byte{}
if iov_buf.Len > 0 {
payload = make([]byte, iov_buf.Len)
if err = binary.Read(this.buf, binary.LittleEndian, &payload); err != nil {
panic(err)
}
}
arg_iovec.Payload = payload
this.logger.Printf("payload={%s}", arg_iovec.Format())
results = append(results, arg_iovec.Format())
// this.logger.Printf("payload={%s}", arg_iovec.Format())
iov_results = append(iov_results, fmt.Sprintf("iov_%d=%s", iov_index, arg_iovec.Format()))
}
iov_results_str := "[\n\t" + strings.Join(iov_results, ", \n\t") + "\n]"
results = append(results, fmt.Sprintf("%s=%s", point_arg.ArgName, arg_msghdr.FormatFull(iov_results_str, control_buf.Format(control_payload))))
case config.TYPE_INT32:
results = append(results, fmt.Sprintf("%s=%d", point_arg.ArgName, int32(ptr.Address)))
default:
results = append(results, fmt.Sprintf("%s=0x%x", point_arg.ArgName, ptr.Address))
}
}
this.arg_str = "(" + strings.Join(results, ", ") + ")"
Expand Down Expand Up @@ -280,7 +287,19 @@ func (this *SyscallEvent) JsonString(stack_str string) string {
}
}

func (this *SyscallEvent) NextString() string {
var base_str string
base_str = fmt.Sprintf("[%s] nr:%s%s", this.GetUUID(), this.nr_point_next.Name, this.arg_str)
lr_str := fmt.Sprintf("LR:0x%x", this.lr.Address)
pc_str := fmt.Sprintf("PC:0x%x", this.pc.Address)
base_str = fmt.Sprintf("%s %s %s SP:0x%x", base_str, lr_str, pc_str, this.sp.Address)
return base_str
}

func (this *SyscallEvent) String() string {
if this.mconf.Next {
return this.NextString()
}
stack_str := ""
if this.EventId == SYSCALL_ENTER {
stack_str = this.GetStackTrace(stack_str)
Expand Down

0 comments on commit f0dbdaf

Please sign in to comment.