Skip to content

Commit

Permalink
example: add kprobe, asm and eBPF bytecode examples
Browse files Browse the repository at this point in the history
Signed-off-by: Shuyi Cheng <chengshuyi@linux.alibaba.com>
  • Loading branch information
chengshuyi committed Feb 19, 2024
1 parent 7d45f39 commit 088bbb0
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 3 deletions.
14 changes: 14 additions & 0 deletions src/coolbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <pthread.h>
#include <signal.h>
#include <sys/resource.h>
#include <sys/utsname.h>
#include <linux/version.h>

#include "coolbpf.h"
uint32_t coolbpf_major_version(void)
Expand Down Expand Up @@ -160,4 +162,16 @@ int bump_memlock_rlimit(void)

return setrlimit(RLIMIT_MEMLOCK, &rlim_new);
}

unsigned int get_kernel_version(void)
{
__u32 major, minor, patch, version;
struct utsname info;

uname(&info);
if (sscanf(info.release, "%u.%u.%u", &major, &minor, &patch) != 3)
return 0;

return KERNEL_VERSION(major, minor, patch);
}
#endif
7 changes: 7 additions & 0 deletions src/coolbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,13 @@ COOLBPF_API int kill_perf_thread(pthread_t thread);
*/
int bump_memlock_rlimit(void);

/**
* @brief get kernel version number
*
* @return unsigned int
*/
unsigned int get_kernel_version(void);

#endif

#endif
6 changes: 3 additions & 3 deletions tools/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@

add_subdirectory(asm)
add_subdirectory(kprobe)
add_subdirectory(raw_bytecode)
add_subdirectory(syscall)


9 changes: 9 additions & 0 deletions tools/examples/asm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

include(${PROJECT_SOURCE_DIR}/scripts/cmake/genskel.cmake)

genskel(asm)

add_executable(asm asm.c)
target_include_directories(asm PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(asm asm_skel)
target_link_libraries(asm PRIVATE coolbpf)
48 changes: 48 additions & 0 deletions tools/examples/asm/asm.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@


#include <vmlinux.h>
#include <coolbpf/coolbpf.h>

#define __clobber_all "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "memory"

SEC("kprobe/tcp_sendmsg")
__attribute__((naked)) void kprobe_tcp_sendmsg(void)
{

asm volatile(" \
r6 = *(u64 *)(r1 +96); \
call %[pid]; \
r7 = r0; \
r7 >>= 32; \
r8 = r10; \
r8 += -16; \
r1 = r8; \
r2 = 16; \
call %[comm]; \
r1 = 175334772; \
*(u32 *)(r10 -24) = r1; \
r1 = %[str1] ll; \
*(u64 *)(r10 -32) = r1; \
r1 = %[str2] ll; \
*(u64 *)(r10 -40) = r1; \
r1 = 0; \
*(u8 *)(r10 -20) = r1; \
r1 = r10; \
r1 += -40; \
r2 = %[fmt_size]; \
r3 = r7; \
r4 = r8; \
r5 = r6; \
call %[print]; \
r0 = 0; \
exit; \
"
:
: [pid] "i"(bpf_get_current_pid_tgid),
[comm] "i"(bpf_get_current_comm),
[print] "i"(bpf_trace_printk),
[fmt_size] "i"(sizeof("%d/%s send %d bytes\n")),
[str1] "i"(0x796220642520646e),
[str2] "i"(0x65732073252f6425)
: __clobber_all);
}
14 changes: 14 additions & 0 deletions tools/examples/asm/asm.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#include <unistd.h>
#include <coolbpf/coolbpf.h>
#include "asm.skel.h"

int main()
{
bump_memlock_rlimit();
coolbpf_set_loglevel(LOG_DEBUG);
struct coolbpf_object *cb = coolbpf_object_new(asm);
while (1)
sleep(3);
return 0;
}
9 changes: 9 additions & 0 deletions tools/examples/kprobe/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

include(${PROJECT_SOURCE_DIR}/scripts/cmake/genskel.cmake)

genskel(kprobe)

add_executable(kprobe kprobe.c)
target_include_directories(kprobe PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
add_dependencies(kprobe kprobe_skel)
target_link_libraries(kprobe PRIVATE coolbpf)
14 changes: 14 additions & 0 deletions tools/examples/kprobe/kprobe.bpf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@


#include <vmlinux.h>
#include <coolbpf/coolbpf.h>

SEC("kprobe/tcp_sendmsg")
int BPF_KPROBE(tcp_sendmsg, struct sock *sk, struct msghdr *msg, size_t size)
{
int pid = pid();
char command[16];
comm(command);
bpf_printk("%d/%s send %d bytes\n", pid, command, size);
return 0;
}
14 changes: 14 additions & 0 deletions tools/examples/kprobe/kprobe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

#include <unistd.h>
#include <coolbpf/coolbpf.h>
#include "kprobe.skel.h"

int main()
{
bump_memlock_rlimit();
coolbpf_set_loglevel(LOG_INFO);
struct coolbpf_object *cb = coolbpf_object_new(kprobe);
while (1)
sleep(3);
return 0;
}
3 changes: 3 additions & 0 deletions tools/examples/raw_bytecode/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
add_executable(raw_bytecode raw_bytecode.c)
target_include_directories(raw_bytecode PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
target_link_libraries(raw_bytecode PRIVATE coolbpf)
85 changes: 85 additions & 0 deletions tools/examples/raw_bytecode/raw_bytecode.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#include <linux/filter.h>
#include <asm/unistd.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/perf_event.h>
#include <coolbpf/coolbpf.h>

int main(void)
{
bump_memlock_rlimit();
LIBBPF_OPTS(bpf_prog_load_opts, load_opts, .kern_version = get_kernel_version());
char bpf_func_name[] = "kprobe_tcp_sendmsg";
char func_name[] = "tcp_sendmsg";

struct bpf_insn insns[] = {
BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 96),
BPF_EMIT_CALL(BPF_FUNC_get_current_pid_tgid),
BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
BPF_ALU64_IMM(BPF_RSH, BPF_REG_7, 32),
BPF_MOV64_REG(BPF_REG_8, BPF_REG_10),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_8, -16),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
BPF_MOV64_IMM(BPF_REG_2, 16),
BPF_EMIT_CALL(BPF_FUNC_get_current_comm),
BPF_MOV64_IMM(BPF_REG_1, 175334772),
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -24),
BPF_LD_IMM64(BPF_REG_1, 0x796220642520646e),
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -32),
BPF_LD_IMM64(BPF_REG_1, 0x65732073252f6425),
BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_1, -40),
BPF_MOV64_IMM(BPF_REG_1, 0),
BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_1, -20),
BPF_MOV64_REG(BPF_REG_1, BPF_REG_10),
BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, -40),
BPF_MOV64_IMM(BPF_REG_2, sizeof("%d/%s send %d bytes\n")),
BPF_MOV64_REG(BPF_REG_3, BPF_REG_7),
BPF_MOV64_REG(BPF_REG_4, BPF_REG_8),
BPF_MOV64_REG(BPF_REG_5, BPF_REG_6),
BPF_EMIT_CALL(BPF_FUNC_trace_printk),
BPF_MOV64_IMM(BPF_REG_0, 0),
BPF_EXIT_INSN(),
};

int progfd = bpf_prog_load(BPF_PROG_TYPE_KPROBE, bpf_func_name, "GPL", insns, sizeof(insns) / sizeof(struct bpf_insn), &load_opts);
if (progfd < 0)
{
printf("failed to load bpf program\n");
return 0;
}

struct perf_event_attr attr = {0};
attr.size = sizeof(attr);
attr.type = 6;
attr.config1 = (__u64)(unsigned long)func_name;
attr.config2 = 0;

int pfd = syscall(__NR_perf_event_open, &attr, -1, 0, -1, PERF_FLAG_FD_CLOEXEC);
if (pfd < 0)
{
printf("failed to create kprobe event\n");
close(progfd);
return 0;
}

if (ioctl(pfd, PERF_EVENT_IOC_SET_BPF, progfd) < 0)
{
printf("failed to attach ebpf program\n");
close(pfd);
close(progfd);
return 0;
}

if (ioctl(pfd, PERF_EVENT_IOC_ENABLE, 0) < 0)
{
printf("failed to enable ebpf program\n");
close(pfd);
close(progfd);
return 0;
}

while (1)
sleep(3);

return 0;
}

0 comments on commit 088bbb0

Please sign in to comment.