Administrator
发布于 2024-07-16 / 80 阅读
0

04-跟踪文件系统与Ftrace

Linux跟踪技术官方文档

https://docs.kernel.org/trace/index.html

TRACES

Ftrace手动Uprobe Hook

Ftrace手动Kprobe Hook

Ftrace内核Hook技术

#查看debugfs
mount |grep debugfs
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
#查看tracefs,低版本内核挂载在/sys/kernel/debug/tracing下面
mount |grep  tracefs
tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
tracefs on /sys/kernel/debug/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
sudo  ls /sys/kernel/debug/tracing
#available_filter_functions:linux 内核开启了kprobe,记录了内核中所有可以被探测的列表。

available_events	    options		    stack_trace
available_filter_functions  osnoise		    stack_trace_filter
available_tracers	    per_cpu		    synthetic_events
buffer_percent		    printk_formats	    timestamp_mode
buffer_size_kb		    README		    trace
buffer_total_size_kb	    saved_cmdlines	    trace_clock
current_tracer		    saved_cmdlines_size     trace_marker
dynamic_events		    saved_tgids		    trace_marker_raw
dyn_ftrace_total_info	    set_event		    trace_options
enabled_functions	    set_event_notrace_pid   trace_pipe
error_log		    set_event_pid	    trace_stat
events			    set_ftrace_filter	    tracing_cpumask
free_buffer		    set_ftrace_notrace	    tracing_max_latency
function_profile_enabled    set_ftrace_notrace_pid  tracing_on
hwlat_detector		    set_ftrace_pid	    tracing_thresh
instances		    set_graph_function	    uprobe_events
kprobe_events		    set_graph_notrace	    uprobe_profile
kprobe_profile		    snapshot
max_graph_depth		    stack_max_size
#查看kprobe函数个数
#linux 内核中所有可以被kprobe探测的函数列表。
sudo cat /sys/kernel/debug/tracing/available_filter_functions |wc -l
53763
sudo bpftrace -l "kprobe:*" |wc -l
53763
#稳定的函数接口 kproc
sudo cat /sys/kernel/tracing/available_events|wc -l 
sudo bpftrace -l "tracepoint:*" |wc -l

#以events结尾的表示tracefs当前正在hook的函数列表
#这个是总的,包括kprobe uprobe 等事件
/sys/kernel/debug/tracing/dynamic_events

1500
1518

99a098a5-6f31-4d21-92ea-2fd6e4b11cac.png

#event目录 存放可以监控的hook 点,通过目录去分类
sudo ls /sys/kernel/tracing/events
echo '--------------------'
#系统调用相关的, enter,exit 进入、退出的点
sudo ls /sys/kernel/tracing/events/syscalls
alarmtimer    gpio	    mptcp	    scsi
amd_cpu       header_event  msr		    signal
avc	      header_page   napi	    skb
block	      huge_memory   neigh	    smbus
bpf_test_run  hwmon	    net		    sock
bpf_trace     hyperv	    netlink	    spi
bridge	      i2c	    nmi		    swiotlb
cgroup	      initcall	    oom		    sync_trace
clk	      intel_iommu   osnoise	    syscalls
compaction    interconnect  page_isolation  task
cpuhp	      iocost	    pagemap	    tcp
cros_ec       iomap	    page_pool	    thermal
dev	      iommu	    percpu	    thermal_power_allocator
devfreq       io_uring	    power	    timer
devlink       irq	    printk	    tlb
dma_fence     irq_matrix    pwm		    udp
drm	      irq_vectors   qdisc	    vmscan
enable	      jbd2	    ras		    vsock
error_report  kmem	    raw_syscalls    vsyscall
exceptions    libata	    rcu		    wbt
ext4	      mce	    regmap	    workqueue
fib	      mdio	    regulator	    writeback
fib6	      migrate	    resctrl	    x86_fpu
filelock      mmap	    rpm		    xdp
filemap       mmap_lock     rseq	    xen
fs_dax	      mmc	    rtc		    xhci-hcd
ftrace	      module	    sched
--------------------\n\r
enable				   sys_enter_writev
filter				   sys_exit_accept
sys_enter_accept		   sys_exit_accept4
sys_enter_accept4		   sys_exit_access
sys_enter_access		   sys_exit_acct
sys_enter_acct			   sys_exit_add_key
sys_enter_add_key		   sys_exit_adjtimex
sys_enter_adjtimex		   sys_exit_alarm
sys_enter_alarm			   sys_exit_arch_prctl
sys_enter_arch_prctl		   sys_exit_bind
sys_enter_bind			   sys_exit_bpf
sys_enter_bpf			   sys_exit_brk
sys_enter_brk			   sys_exit_capget
sys_enter_capget		   sys_exit_capset
sys_enter_capset		   sys_exit_chdir
sys_enter_chdir			   sys_exit_chmod
sys_enter_chmod			   sys_exit_chown
sys_enter_chown			   sys_exit_chroot
sys_enter_chroot		   sys_exit_clock_adjtime
sys_enter_clock_adjtime		   sys_exit_clock_getres
sys_enter_clock_getres		   sys_exit_clock_gettime
sys_enter_clock_gettime		   sys_exit_clock_nanosleep
sys_enter_clock_nanosleep	   sys_exit_clock_settime
sys_enter_clock_settime		   sys_exit_clone
sys_enter_clone			   sys_exit_clone3
sys_enter_clone3		   sys_exit_close
sys_enter_close			   sys_exit_close_range
sys_enter_close_range		   sys_exit_connect
sys_enter_connect		   sys_exit_copy_file_range
sys_enter_copy_file_range	   sys_exit_creat
sys_enter_creat			   sys_exit_delete_module
sys_enter_delete_module		   sys_exit_dup
sys_enter_dup			   sys_exit_dup2
sys_enter_dup2			   sys_exit_dup3
sys_enter_dup3			   sys_exit_epoll_create
sys_enter_epoll_create		   sys_exit_epoll_create1
sys_enter_epoll_create1		   sys_exit_epoll_ctl
sys_enter_epoll_ctl		   sys_exit_epoll_pwait
sys_enter_epoll_pwait		   sys_exit_epoll_pwait2
sys_enter_epoll_pwait2		   sys_exit_epoll_wait
sys_enter_epoll_wait		   sys_exit_eventfd
sys_enter_eventfd		   sys_exit_eventfd2
sys_enter_eventfd2		   sys_exit_execve
sys_enter_execve		   sys_exit_execveat
sys_enter_execveat		   sys_exit_exit
sys_enter_exit			   sys_exit_exit_group
sys_enter_exit_group		   sys_exit_faccessat
sys_enter_faccessat		   sys_exit_faccessat2
sys_enter_faccessat2		   sys_exit_fadvise64
sys_enter_fadvise64		   sys_exit_fallocate
sys_enter_fallocate		   sys_exit_fanotify_init
sys_enter_fanotify_init		   sys_exit_fanotify_mark
sys_enter_fanotify_mark		   sys_exit_fchdir
sys_enter_fchdir		   sys_exit_fchmod
sys_enter_fchmod		   sys_exit_fchmodat
sys_enter_fchmodat		   sys_exit_fchown
sys_enter_fchown		   sys_exit_fchownat
sys_enter_fchownat		   sys_exit_fcntl
sys_enter_fcntl			   sys_exit_fdatasync
sys_enter_fdatasync		   sys_exit_fgetxattr
sys_enter_fgetxattr		   sys_exit_finit_module
sys_enter_finit_module		   sys_exit_flistxattr
sys_enter_flistxattr		   sys_exit_flock
sys_enter_flock			   sys_exit_fork
sys_enter_fork			   sys_exit_fremovexattr
sys_enter_fremovexattr		   sys_exit_fsconfig
sys_enter_fsconfig		   sys_exit_fsetxattr
sys_enter_fsetxattr		   sys_exit_fsmount
sys_enter_fsmount		   sys_exit_fsopen
sys_enter_fsopen		   sys_exit_fspick
sys_enter_fspick		   sys_exit_fstatfs
sys_enter_fstatfs		   sys_exit_fsync
sys_enter_fsync			   sys_exit_ftruncate
sys_enter_ftruncate		   sys_exit_futex
sys_enter_futex			   sys_exit_futimesat
sys_enter_futimesat		   sys_exit_getcpu
sys_enter_getcpu		   sys_exit_getcwd
sys_enter_getcwd		   sys_exit_getdents
sys_enter_getdents		   sys_exit_getdents64
sys_enter_getdents64		   sys_exit_getegid
sys_enter_getegid		   sys_exit_geteuid
sys_enter_geteuid		   sys_exit_getgid
sys_enter_getgid		   sys_exit_getgroups
sys_enter_getgroups		   sys_exit_getitimer
sys_enter_getitimer		   sys_exit_get_mempolicy
sys_enter_get_mempolicy		   sys_exit_getpeername
sys_enter_getpeername		   sys_exit_getpgid
sys_enter_getpgid		   sys_exit_getpgrp
sys_enter_getpgrp		   sys_exit_getpid
sys_enter_getpid		   sys_exit_getppid
sys_enter_getppid		   sys_exit_getpriority
sys_enter_getpriority		   sys_exit_getrandom
sys_enter_getrandom		   sys_exit_getresgid
sys_enter_getresgid		   sys_exit_getresuid
sys_enter_getresuid		   sys_exit_getrlimit
sys_enter_getrlimit		   sys_exit_get_robust_list
sys_enter_get_robust_list	   sys_exit_getrusage
sys_enter_getrusage		   sys_exit_getsid
sys_enter_getsid		   sys_exit_getsockname
sys_enter_getsockname		   sys_exit_getsockopt
sys_enter_getsockopt		   sys_exit_gettid
sys_enter_gettid		   sys_exit_gettimeofday
sys_enter_gettimeofday		   sys_exit_getuid
sys_enter_getuid		   sys_exit_getxattr
sys_enter_getxattr		   sys_exit_init_module
sys_enter_init_module		   sys_exit_inotify_add_watch
sys_enter_inotify_add_watch	   sys_exit_inotify_init
sys_enter_inotify_init		   sys_exit_inotify_init1
sys_enter_inotify_init1		   sys_exit_inotify_rm_watch
sys_enter_inotify_rm_watch	   sys_exit_io_cancel
sys_enter_io_cancel		   sys_exit_ioctl
sys_enter_ioctl			   sys_exit_io_destroy
sys_enter_io_destroy		   sys_exit_io_getevents
sys_enter_io_getevents		   sys_exit_ioperm
sys_enter_ioperm		   sys_exit_io_pgetevents
sys_enter_io_pgetevents		   sys_exit_iopl
sys_enter_iopl			   sys_exit_ioprio_get
sys_enter_ioprio_get		   sys_exit_ioprio_set
sys_enter_ioprio_set		   sys_exit_io_setup
sys_enter_io_setup		   sys_exit_io_submit
sys_enter_io_submit		   sys_exit_io_uring_enter
sys_enter_io_uring_enter	   sys_exit_io_uring_register
sys_enter_io_uring_register	   sys_exit_io_uring_setup
sys_enter_io_uring_setup	   sys_exit_kcmp
sys_enter_kcmp			   sys_exit_kexec_file_load
sys_enter_kexec_file_load	   sys_exit_kexec_load
sys_enter_kexec_load		   sys_exit_keyctl
sys_enter_keyctl		   sys_exit_kill
sys_enter_kill			   sys_exit_landlock_add_rule
sys_enter_landlock_add_rule	   sys_exit_landlock_create_ruleset
sys_enter_landlock_create_ruleset  sys_exit_landlock_restrict_self
sys_enter_landlock_restrict_self   sys_exit_lchown
sys_enter_lchown		   sys_exit_lgetxattr
sys_enter_lgetxattr		   sys_exit_link
sys_enter_link			   sys_exit_linkat
sys_enter_linkat		   sys_exit_listen
sys_enter_listen		   sys_exit_listxattr
sys_enter_listxattr		   sys_exit_llistxattr
sys_enter_llistxattr		   sys_exit_lremovexattr
sys_enter_lremovexattr		   sys_exit_lseek
sys_enter_lseek			   sys_exit_lsetxattr
sys_enter_lsetxattr		   sys_exit_madvise
sys_enter_madvise		   sys_exit_mbind
sys_enter_mbind			   sys_exit_membarrier
sys_enter_membarrier		   sys_exit_memfd_create
sys_enter_memfd_create		   sys_exit_memfd_secret
sys_enter_memfd_secret		   sys_exit_migrate_pages
sys_enter_migrate_pages		   sys_exit_mincore
sys_enter_mincore		   sys_exit_mkdir
sys_enter_mkdir			   sys_exit_mkdirat
sys_enter_mkdirat		   sys_exit_mknod
sys_enter_mknod			   sys_exit_mknodat
sys_enter_mknodat		   sys_exit_mlock
sys_enter_mlock			   sys_exit_mlock2
sys_enter_mlock2		   sys_exit_mlockall
sys_enter_mlockall		   sys_exit_mmap
sys_enter_mmap			   sys_exit_modify_ldt
sys_enter_modify_ldt		   sys_exit_mount
sys_enter_mount			   sys_exit_mount_setattr
sys_enter_mount_setattr		   sys_exit_move_mount
sys_enter_move_mount		   sys_exit_move_pages
sys_enter_move_pages		   sys_exit_mprotect
sys_enter_mprotect		   sys_exit_mq_getsetattr
sys_enter_mq_getsetattr		   sys_exit_mq_notify
sys_enter_mq_notify		   sys_exit_mq_open
sys_enter_mq_open		   sys_exit_mq_timedreceive
sys_enter_mq_timedreceive	   sys_exit_mq_timedsend
sys_enter_mq_timedsend		   sys_exit_mq_unlink
sys_enter_mq_unlink		   sys_exit_mremap
sys_enter_mremap		   sys_exit_msgctl
sys_enter_msgctl		   sys_exit_msgget
sys_enter_msgget		   sys_exit_msgrcv
sys_enter_msgrcv		   sys_exit_msgsnd
sys_enter_msgsnd		   sys_exit_msync
sys_enter_msync			   sys_exit_munlock
sys_enter_munlock		   sys_exit_munlockall
sys_enter_munlockall		   sys_exit_munmap
sys_enter_munmap		   sys_exit_name_to_handle_at
sys_enter_name_to_handle_at	   sys_exit_nanosleep
sys_enter_nanosleep		   sys_exit_newfstat
sys_enter_newfstat		   sys_exit_newfstatat
sys_enter_newfstatat		   sys_exit_newlstat
sys_enter_newlstat		   sys_exit_newstat
sys_enter_newstat		   sys_exit_newuname
sys_enter_newuname		   sys_exit_open
sys_enter_open			   sys_exit_openat
sys_enter_openat		   sys_exit_openat2
sys_enter_openat2		   sys_exit_open_by_handle_at
sys_enter_open_by_handle_at	   sys_exit_open_tree
sys_enter_open_tree		   sys_exit_pause
sys_enter_pause			   sys_exit_perf_event_open
sys_enter_perf_event_open	   sys_exit_personality
sys_enter_personality		   sys_exit_pidfd_getfd
sys_enter_pidfd_getfd		   sys_exit_pidfd_open
sys_enter_pidfd_open		   sys_exit_pidfd_send_signal
sys_enter_pidfd_send_signal	   sys_exit_pipe
sys_enter_pipe			   sys_exit_pipe2
sys_enter_pipe2			   sys_exit_pivot_root
sys_enter_pivot_root		   sys_exit_pkey_alloc
sys_enter_pkey_alloc		   sys_exit_pkey_free
sys_enter_pkey_free		   sys_exit_pkey_mprotect
sys_enter_pkey_mprotect		   sys_exit_poll
sys_enter_poll			   sys_exit_ppoll
sys_enter_ppoll			   sys_exit_prctl
sys_enter_prctl			   sys_exit_pread64
sys_enter_pread64		   sys_exit_preadv
sys_enter_preadv		   sys_exit_preadv2
sys_enter_preadv2		   sys_exit_prlimit64
sys_enter_prlimit64		   sys_exit_process_madvise
sys_enter_process_madvise	   sys_exit_process_mrelease
sys_enter_process_mrelease	   sys_exit_process_vm_readv
sys_enter_process_vm_readv	   sys_exit_process_vm_writev
sys_enter_process_vm_writev	   sys_exit_pselect6
sys_enter_pselect6		   sys_exit_ptrace
sys_enter_ptrace		   sys_exit_pwrite64
sys_enter_pwrite64		   sys_exit_pwritev
sys_enter_pwritev		   sys_exit_pwritev2
sys_enter_pwritev2		   sys_exit_quotactl
sys_enter_quotactl		   sys_exit_quotactl_fd
sys_enter_quotactl_fd		   sys_exit_read
sys_enter_read			   sys_exit_readahead
sys_enter_readahead		   sys_exit_readlink
sys_enter_readlink		   sys_exit_readlinkat
sys_enter_readlinkat		   sys_exit_readv
sys_enter_readv			   sys_exit_reboot
sys_enter_reboot		   sys_exit_recvfrom
sys_enter_recvfrom		   sys_exit_recvmmsg
sys_enter_recvmmsg		   sys_exit_recvmsg
sys_enter_recvmsg		   sys_exit_remap_file_pages
sys_enter_remap_file_pages	   sys_exit_removexattr
sys_enter_removexattr		   sys_exit_rename
sys_enter_rename		   sys_exit_renameat
sys_enter_renameat		   sys_exit_renameat2
sys_enter_renameat2		   sys_exit_request_key
sys_enter_request_key		   sys_exit_restart_syscall
sys_enter_restart_syscall	   sys_exit_rmdir
sys_enter_rmdir			   sys_exit_rseq
sys_enter_rseq			   sys_exit_rt_sigaction
sys_enter_rt_sigaction		   sys_exit_rt_sigpending
sys_enter_rt_sigpending		   sys_exit_rt_sigprocmask
sys_enter_rt_sigprocmask	   sys_exit_rt_sigqueueinfo
sys_enter_rt_sigqueueinfo	   sys_exit_rt_sigreturn
sys_enter_rt_sigreturn		   sys_exit_rt_sigsuspend
sys_enter_rt_sigsuspend		   sys_exit_rt_sigtimedwait
sys_enter_rt_sigtimedwait	   sys_exit_rt_tgsigqueueinfo
sys_enter_rt_tgsigqueueinfo	   sys_exit_sched_getaffinity
sys_enter_sched_getaffinity	   sys_exit_sched_getattr
sys_enter_sched_getattr		   sys_exit_sched_getparam
sys_enter_sched_getparam	   sys_exit_sched_get_priority_max
sys_enter_sched_get_priority_max   sys_exit_sched_get_priority_min
sys_enter_sched_get_priority_min   sys_exit_sched_getscheduler
sys_enter_sched_getscheduler	   sys_exit_sched_rr_get_interval
sys_enter_sched_rr_get_interval    sys_exit_sched_setaffinity
sys_enter_sched_setaffinity	   sys_exit_sched_setattr
sys_enter_sched_setattr		   sys_exit_sched_setparam
sys_enter_sched_setparam	   sys_exit_sched_setscheduler
sys_enter_sched_setscheduler	   sys_exit_sched_yield
sys_enter_sched_yield		   sys_exit_seccomp
sys_enter_seccomp		   sys_exit_select
sys_enter_select		   sys_exit_semctl
sys_enter_semctl		   sys_exit_semget
sys_enter_semget		   sys_exit_semop
sys_enter_semop			   sys_exit_semtimedop
sys_enter_semtimedop		   sys_exit_sendfile64
sys_enter_sendfile64		   sys_exit_sendmmsg
sys_enter_sendmmsg		   sys_exit_sendmsg
sys_enter_sendmsg		   sys_exit_sendto
sys_enter_sendto		   sys_exit_setdomainname
sys_enter_setdomainname		   sys_exit_setfsgid
sys_enter_setfsgid		   sys_exit_setfsuid
sys_enter_setfsuid		   sys_exit_setgid
sys_enter_setgid		   sys_exit_setgroups
sys_enter_setgroups		   sys_exit_sethostname
sys_enter_sethostname		   sys_exit_setitimer
sys_enter_setitimer		   sys_exit_set_mempolicy
sys_enter_set_mempolicy		   sys_exit_setns
sys_enter_setns			   sys_exit_setpgid
sys_enter_setpgid		   sys_exit_setpriority
sys_enter_setpriority		   sys_exit_setregid
sys_enter_setregid		   sys_exit_setresgid
sys_enter_setresgid		   sys_exit_setresuid
sys_enter_setresuid		   sys_exit_setreuid
sys_enter_setreuid		   sys_exit_setrlimit
sys_enter_setrlimit		   sys_exit_set_robust_list
sys_enter_set_robust_list	   sys_exit_setsid
sys_enter_setsid		   sys_exit_setsockopt
sys_enter_setsockopt		   sys_exit_set_tid_address
sys_enter_set_tid_address	   sys_exit_settimeofday
sys_enter_settimeofday		   sys_exit_setuid
sys_enter_setuid		   sys_exit_setxattr
sys_enter_setxattr		   sys_exit_shmat
sys_enter_shmat			   sys_exit_shmctl
sys_enter_shmctl		   sys_exit_shmdt
sys_enter_shmdt			   sys_exit_shmget
sys_enter_shmget		   sys_exit_shutdown
sys_enter_shutdown		   sys_exit_sigaltstack
sys_enter_sigaltstack		   sys_exit_signalfd
sys_enter_signalfd		   sys_exit_signalfd4
sys_enter_signalfd4		   sys_exit_socket
sys_enter_socket		   sys_exit_socketpair
sys_enter_socketpair		   sys_exit_splice
sys_enter_splice		   sys_exit_statfs
sys_enter_statfs		   sys_exit_statx
sys_enter_statx			   sys_exit_swapoff
sys_enter_swapoff		   sys_exit_swapon
sys_enter_swapon		   sys_exit_symlink
sys_enter_symlink		   sys_exit_symlinkat
sys_enter_symlinkat		   sys_exit_sync
sys_enter_sync			   sys_exit_sync_file_range
sys_enter_sync_file_range	   sys_exit_syncfs
sys_enter_syncfs		   sys_exit_sysfs
sys_enter_sysfs			   sys_exit_sysinfo
sys_enter_sysinfo		   sys_exit_syslog
sys_enter_syslog		   sys_exit_tee
sys_enter_tee			   sys_exit_tgkill
sys_enter_tgkill		   sys_exit_time
sys_enter_time			   sys_exit_timer_create
sys_enter_timer_create		   sys_exit_timer_delete
sys_enter_timer_delete		   sys_exit_timerfd_create
sys_enter_timerfd_create	   sys_exit_timerfd_gettime
sys_enter_timerfd_gettime	   sys_exit_timerfd_settime
sys_enter_timerfd_settime	   sys_exit_timer_getoverrun
sys_enter_timer_getoverrun	   sys_exit_timer_gettime
sys_enter_timer_gettime		   sys_exit_timer_settime
sys_enter_timer_settime		   sys_exit_times
sys_enter_times			   sys_exit_tkill
sys_enter_tkill			   sys_exit_truncate
sys_enter_truncate		   sys_exit_umask
sys_enter_umask			   sys_exit_umount
sys_enter_umount		   sys_exit_unlink
sys_enter_unlink		   sys_exit_unlinkat
sys_enter_unlinkat		   sys_exit_unshare
sys_enter_unshare		   sys_exit_userfaultfd
sys_enter_userfaultfd		   sys_exit_ustat
sys_enter_ustat			   sys_exit_utime
sys_enter_utime			   sys_exit_utimensat
sys_enter_utimensat		   sys_exit_utimes
sys_enter_utimes		   sys_exit_vfork
sys_enter_vfork			   sys_exit_vhangup
sys_enter_vhangup		   sys_exit_vmsplice
sys_enter_vmsplice		   sys_exit_wait4
sys_enter_wait4			   sys_exit_waitid
sys_enter_waitid		   sys_exit_write
sys_enter_write			   sys_exit_writev
#所有的event 监测点的总开关,启用,如果在子目录下只对子目录起作用。
echo 1> /sys/kernel/tracing/events/enable 

#只监控 sys_enter  sys_exit
echo 1> /sys/kernel/debug/tracing/events/raw_syscalls/enable

#只监控 sys_enter 
echo 1> /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/enable

echo "#filter 是过滤器,过滤进程id"
sudo ls /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter

bash: echo: write error: Invalid argument
bash: echo: write error: Invalid argument
bash: echo: write error: Invalid argument
#filter 是过滤器,过来进程id
enable	filter	format	hist  id  inject  trigger
echo format 描述了接口的字段信息
sudo  cat /sys/kernel/debug/tracing/events/raw_syscalls/sys_enter/format
format 描述了接口的字段信息n
name: sys_enter
ID: 348
format:
	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
	field:int common_pid;	offset:4;	size:4;	signed:1;

	field:long id;	offset:8;	size:8;	signed:1;
	field:unsigned long args[6];	offset:16;	size:48;	signed:0;

print fmt: "NR %ld (%lx, %lx, %lx, %lx, %lx, %lx)", REC->id, REC->args[0], REC->args[1], REC->args[2], REC->args[3], REC->args[4], REC->args[5]
#开启uprobes,手动激活添加时才存在
sudo ls /sys/kernel/debug/tracing/events/uprobes
# 查看程序的位置。
readelf -s /bin/bash | grep readline | grep  FUNC
cat: /sys/kernel/debug/tracing/events/uprobes: No such file or directory
   328: 00000000000b7c90   594 FUNC    GLOBAL DEFAULT   16 readline_internal_char
   813: 00000000000b7160   351 FUNC    GLOBAL DEFAULT   16 readline_internal_setup
   863: 00000000000870e0    76 FUNC    GLOBAL DEFAULT   16 posix_readline_initialize
   882: 00000000000b84f0   154 FUNC    GLOBAL DEFAULT   16 readline
  1239: 0000000000087370  1963 FUNC    GLOBAL DEFAULT   16 initialize_readline
  1824: 000000000008faa0    69 FUNC    GLOBAL DEFAULT   16 pcomp_set_readline_variab
  2041: 00000000000b72c0   288 FUNC    GLOBAL DEFAULT   16 readline_internal_teardow
#设置跟踪点
sudo bash -c 'echo p:readline /bin/bash:0x00000000000b7c90 %ip %ax > /sys/kernel/debug/tracing/uprobe_events'
echo @#查看跟踪点或者调试点的信息
sudo cat /sys/kernel/debug/tracing/uprobe_events
#开启uprobes 成功后, uprobes目录创建成功,readline创建成果
ls /sys/kernel/debug/tracing/events/uprobes/readline

@#查看跟踪点或者调试点的信息
p:uprobes/readline /bin/bash:0x00000000000b7c90 arg1=%ip arg2=%ax
enable  filter  format  hist  id  inject  trigger
echo @#开启追踪
sudo bash -c 'echo 1 > /sys/kernel/debug/tracing/events/uprobes/readline/enable'
sudo bash -c 'echo 1 >/sys/kernel/debug/tracing/tracing_on'

@#开启追踪
# 查看日志信息,trace_pipe是基于trace的管道,读取完就会消失
#sudo cat /sys/kernel/debug/tracing/trace_pipe
sudo cat /sys/kernel/debug/tracing/trace


# tracer: nop
#
# entries-in-buffer/entries-written: 8/8   #P:4
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
            bash-809624  [003] ..... 272913.606499: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272913.657051: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272913.657239: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272918.054206: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272918.054315: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272918.104849: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272918.104963: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
            bash-809624  [003] ..... 272918.155528: readline: (0x556e620d6c90) arg1=0x556e620d6c90 arg2=0x0
#关闭readline
sudo bash -c 'echo 0 > /sys/kernel/debug/tracing/events/uprobes/readline/enable'

#关闭 all
sudo bash -c 'echo 0 > /sys/kernel/debug/tracing/events/enable'

# 关闭单个的events 
sudo bash -c 'echo >/sys/kernel/debug/tracing/kprobe_events'
sudo bash -c 'echo >/sys/kernel/debug/tracing/uprobe_events'

sudo bash -c 'echo 0 >/proc/sys/kernel/ftrace_enabled'
sudo bash -c 'echo 0 >/sys/kernel/debug/tracing/tracing_on'




# ftrace缺点,正在跟踪激活的情况,是没有办法添加其他的激活的。
#设置跟踪点
sudo bash -c 'echo p:readline /bin/bash:0x00000000000b7c90 %ip %ax > /sys/kernel/debug/tracing/uprobe_events'
bash: /sys/kernel/debug/tracing/uprobe_events: Device or resource busy

perf-tools工具,老的方案

https://github.com/brendangregg/perf-tools/blob/master/opensnoop

https://elixir.bootlin.com/linux/v5.15.52/source/samples/ftrace/ftrace-direct.c
#cp /lib/modules/5.15.0-92-generic/build/vmlinux .
cd /home/abc/src/kernel/linux
make  M=samples/ftrace clean
make  M=samples/ftrace

#BTF [M] samples/ftrace/ftrace-direct-modify.ko
#BTF 已经加入
  CLEAN   samples/ftrace/Module.symvers
  CC [M]  samples/ftrace/ftrace-direct.o
  CC [M]  samples/ftrace/ftrace-direct-too.o
  CC [M]  samples/ftrace/ftrace-direct-modify.o
  CC [M]  samples/ftrace/sample-trace-array.o
  MODPOST samples/ftrace/Module.symvers
  CC [M]  samples/ftrace/ftrace-direct-modify.mod.o
  LD [M]  samples/ftrace/ftrace-direct-modify.ko
  BTF [M] samples/ftrace/ftrace-direct-modify.ko
  CC [M]  samples/ftrace/ftrace-direct-too.mod.o
  LD [M]  samples/ftrace/ftrace-direct-too.ko
  BTF [M] samples/ftrace/ftrace-direct-too.ko
  CC [M]  samples/ftrace/ftrace-direct.mod.o
  LD [M]  samples/ftrace/ftrace-direct.ko
  BTF [M] samples/ftrace/ftrace-direct.ko
  CC [M]  samples/ftrace/sample-trace-array.mod.o
  LD [M]  samples/ftrace/sample-trace-array.ko
  BTF [M] samples/ftrace/sample-trace-array.ko
sudo insmod samples/ftrace/ftrace-direct.ko
insmod: ERROR: could not insert module samples/ftrace/ftrace-direct.ko: Operation not permitted

#sudo bash -c 'echo 0 >/proc/sys/kernel/ftrace_enabled'
sudo bash -c 'echo 1 >/sys/kernel/debug/tracing/tracing_on'
#sudo cat /sys/kernel/debug/tracing/trace_pipe

https://github.com/ilammy/ftrace-hook/blob/master/ftrace_hook.c

/*
 * Hooking kernel functions using ftrace framework
 *
 * Copyright (c) 2018 ilammy
 */

#define pr_fmt(fmt) "ftrace_hook: " fmt

#include <linux/ftrace.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/linkage.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <linux/version.h>
#include <linux/kprobes.h>

MODULE_DESCRIPTION("Example module hooking clone() and execve() via ftrace");
MODULE_AUTHOR("ilammy <[email protected]>");
MODULE_LICENSE("GPL");

#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,7,0)
static unsigned long lookup_name(const char *name)
{
	struct kprobe kp = {
		.symbol_name = name
	};
	unsigned long retval;

	if (register_kprobe(&kp) < 0) return 0;
	retval = (unsigned long) kp.addr;
	unregister_kprobe(&kp);
	return retval;
}
#else
static unsigned long lookup_name(const char *name)
{
	return kallsyms_lookup_name(name);
}
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)
#define FTRACE_OPS_FL_RECURSION FTRACE_OPS_FL_RECURSION_SAFE
#endif

#if LINUX_VERSION_CODE < KERNEL_VERSION(5,11,0)
#define ftrace_regs pt_regs

static __always_inline struct pt_regs *ftrace_get_regs(struct ftrace_regs *fregs)
{
	return fregs;
}
#endif

/*
 * There are two ways of preventing vicious recursive loops when hooking:
 * - detect recusion using function return address (USE_FENTRY_OFFSET = 0)
 * - avoid recusion by jumping over the ftrace call (USE_FENTRY_OFFSET = 1)
 */
#define USE_FENTRY_OFFSET 0

/**
 * struct ftrace_hook - describes a single hook to install
 *
 * @name:     name of the function to hook
 *
 * @function: pointer to the function to execute instead
 *
 * @original: pointer to the location where to save a pointer
 *            to the original function
 *
 * @address:  kernel address of the function entry
 *
 * @ops:      ftrace_ops state for this function hook
 *
 * The user should fill in only &name, &hook, &orig fields.
 * Other fields are considered implementation details.
 */
struct ftrace_hook {
	const char *name;
	void *function;
	void *original;

	unsigned long address;
	struct ftrace_ops ops;
};

static int fh_resolve_hook_address(struct ftrace_hook *hook)
{
	hook->address = lookup_name(hook->name);

	if (!hook->address) {
		pr_debug("unresolved symbol: %s\n", hook->name);
		return -ENOENT;
	}

#if USE_FENTRY_OFFSET
	*((unsigned long*) hook->original) = hook->address + MCOUNT_INSN_SIZE;
#else
	*((unsigned long*) hook->original) = hook->address;
#endif

	return 0;
}

static void notrace fh_ftrace_thunk(unsigned long ip, unsigned long parent_ip,
		struct ftrace_ops *ops, struct ftrace_regs *fregs)
{
	struct pt_regs *regs = ftrace_get_regs(fregs);
	struct ftrace_hook *hook = container_of(ops, struct ftrace_hook, ops);

#if USE_FENTRY_OFFSET
	regs->ip = (unsigned long)hook->function;
#else
	if (!within_module(parent_ip, THIS_MODULE))
		regs->ip = (unsigned long)hook->function;
#endif
}

/**
 * fh_install_hooks() - register and enable a single hook
 * @hook: a hook to install
 *
 * Returns: zero on success, negative error code otherwise.
 */
int fh_install_hook(struct ftrace_hook *hook)
{
	int err;

	err = fh_resolve_hook_address(hook);
	if (err)
		return err;

	/*
	 * We're going to modify %rip register so we'll need IPMODIFY flag
	 * and SAVE_REGS as its prerequisite. ftrace's anti-recursion guard
	 * is useless if we change %rip so disable it with RECURSION.
	 * We'll perform our own checks for trace function reentry.
	 */
	hook->ops.func = fh_ftrace_thunk;
	hook->ops.flags = FTRACE_OPS_FL_SAVE_REGS
	                | FTRACE_OPS_FL_RECURSION
	                | FTRACE_OPS_FL_IPMODIFY;

	err = ftrace_set_filter_ip(&hook->ops, hook->address, 0, 0);
	if (err) {
		pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
		return err;
	}

	err = register_ftrace_function(&hook->ops);
	if (err) {
		pr_debug("register_ftrace_function() failed: %d\n", err);
		ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
		return err;
	}

	return 0;
}

/**
 * fh_remove_hooks() - disable and unregister a single hook
 * @hook: a hook to remove
 */
void fh_remove_hook(struct ftrace_hook *hook)
{
	int err;

	err = unregister_ftrace_function(&hook->ops);
	if (err) {
		pr_debug("unregister_ftrace_function() failed: %d\n", err);
	}

	err = ftrace_set_filter_ip(&hook->ops, hook->address, 1, 0);
	if (err) {
		pr_debug("ftrace_set_filter_ip() failed: %d\n", err);
	}
}

/**
 * fh_install_hooks() - register and enable multiple hooks
 * @hooks: array of hooks to install
 * @count: number of hooks to install
 *
 * If some hooks fail to install then all hooks will be removed.
 *
 * Returns: zero on success, negative error code otherwise.
 */
int fh_install_hooks(struct ftrace_hook *hooks, size_t count)
{
	int err;
	size_t i;

	for (i = 0; i < count; i++) {
		err = fh_install_hook(&hooks[i]);
		if (err)
			goto error;
	}

	return 0;

error:
	while (i != 0) {
		fh_remove_hook(&hooks[--i]);
	}

	return err;
}

/**
 * fh_remove_hooks() - disable and unregister multiple hooks
 * @hooks: array of hooks to remove
 * @count: number of hooks to remove
 */
void fh_remove_hooks(struct ftrace_hook *hooks, size_t count)
{
	size_t i;

	for (i = 0; i < count; i++)
		fh_remove_hook(&hooks[i]);
}

#ifndef CONFIG_X86_64
#error Currently only x86_64 architecture is supported
#endif

#if defined(CONFIG_X86_64) && (LINUX_VERSION_CODE >= KERNEL_VERSION(4,17,0))
#define PTREGS_SYSCALL_STUBS 1
#endif

/*
 * Tail call optimization can interfere with recursion detection based on
 * return address on the stack. Disable it to avoid machine hangups.
 */
#if !USE_FENTRY_OFFSET
#pragma GCC optimize("-fno-optimize-sibling-calls")
#endif

#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_clone)(struct pt_regs *regs);

static asmlinkage long fh_sys_clone(struct pt_regs *regs)
{
	long ret;

	pr_info("clone() before\n");

	ret = real_sys_clone(regs);

	pr_info("clone() after: %ld\n", ret);

	return ret;
}
#else
static asmlinkage long (*real_sys_clone)(unsigned long clone_flags,
		unsigned long newsp, int __user *parent_tidptr,
		int __user *child_tidptr, unsigned long tls);

static asmlinkage long fh_sys_clone(unsigned long clone_flags,
		unsigned long newsp, int __user *parent_tidptr,
		int __user *child_tidptr, unsigned long tls)
{
	long ret;

	pr_info("clone() before\n");

	ret = real_sys_clone(clone_flags, newsp, parent_tidptr,
		child_tidptr, tls);

	pr_info("clone() after: %ld\n", ret);

	return ret;
}
#endif

static char *duplicate_filename(const char __user *filename)
{
	char *kernel_filename;

	kernel_filename = kmalloc(4096, GFP_KERNEL);
	if (!kernel_filename)
		return NULL;

	if (strncpy_from_user(kernel_filename, filename, 4096) < 0) {
		kfree(kernel_filename);
		return NULL;
	}

	return kernel_filename;
}

#ifdef PTREGS_SYSCALL_STUBS
static asmlinkage long (*real_sys_execve)(struct pt_regs *regs);

static asmlinkage long fh_sys_execve(struct pt_regs *regs)
{
	long ret;
	char *kernel_filename;

	kernel_filename = duplicate_filename((void*) regs->di);

	pr_info("execve() before: %s\n", kernel_filename);

	kfree(kernel_filename);

	ret = real_sys_execve(regs);

	pr_info("execve() after: %ld\n", ret);

	return ret;
}
#else
static asmlinkage long (*real_sys_execve)(const char __user *filename,
		const char __user *const __user *argv,
		const char __user *const __user *envp);

static asmlinkage long fh_sys_execve(const char __user *filename,
		const char __user *const __user *argv,
		const char __user *const __user *envp)
{
	long ret;
	char *kernel_filename;

	kernel_filename = duplicate_filename(filename);

	pr_info("execve() before: %s\n", kernel_filename);

	kfree(kernel_filename);

	ret = real_sys_execve(filename, argv, envp);

	pr_info("execve() after: %ld\n", ret);

	return ret;
}
#endif

/*
 * x86_64 kernels have a special naming convention for syscall entry points in newer kernels.
 * That's what you end up with if an architecture has 3 (three) ABIs for system calls.
 */
#ifdef PTREGS_SYSCALL_STUBS
#define SYSCALL_NAME(name) ("__x64_" name)
#else
#define SYSCALL_NAME(name) (name)
#endif

#define HOOK(_name, _function, _original)	\
	{					\
		.name = SYSCALL_NAME(_name),	\
		.function = (_function),	\
		.original = (_original),	\
	}

static struct ftrace_hook demo_hooks[] = {
	HOOK("sys_clone",  fh_sys_clone,  &real_sys_clone),
	HOOK("sys_execve", fh_sys_execve, &real_sys_execve),
};

static int fh_init(void)
{
	int err;

	err = fh_install_hooks(demo_hooks, ARRAY_SIZE(demo_hooks));
	if (err)
		return err;

	pr_info("module loaded\n");

	return 0;
}
module_init(fh_init);

static void fh_exit(void)
{
	fh_remove_hooks(demo_hooks, ARRAY_SIZE(demo_hooks));

	pr_info("module unloaded\n");
}
module_exit(fh_exit);