eunomia-bpf / bpftime

Userspace eBPF runtime for fast Uprobe & Syscall hook & Extensions with LLVM JIT
https://eunomia.dev/bpftime/
MIT License
699 stars 70 forks source link

[BUG] Need more details on frida uprobe attach failures #191

Open agentzh opened 6 months ago

agentzh commented 6 months ago

I'm getting the following error with uprobe + llvm jit:

[2024-01-28 01:12:03][info][707874] Created uprobe/uretprobe perf event handler, module name /500g-a/git/ebpf-plus/libbpf/uprobes/a.out, offset 1126
[2024-01-28 01:12:03.112] [info] [agent.cpp:66] Entering bpftime agent
[2024-01-28 01:12:03.112] [info] [bpftime_shm_internal.cpp:618] Global shm constructed. shm_open_type 1 for bpftime_maps_shm
[2024-01-28 01:12:03.112] [info] [agent.cpp:81] Initializing agent..
[2024-01-28 01:12:03][info][707879] Initializing llvm
[2024-01-28 01:12:03][info][707879] Executable path: /500g-a/git/ebpf-plus/libbpf/uprobes/a.out
[2024-01-28 01:12:03][info][707879] Attached 1 uprobe programs to function 401126
[2024-01-28 01:12:03][error][707879] Failed to execute frida gum_interceptor_attach for function 401126
terminate called after throwing an instance of 'std::runtime_error'
  what():  Failed to attach uprobe/uretprpbe

How can I get more details and reasons for the failure? The 0x401126 address is correct for the foo() function in the target program a.out:

$ nm a.out|grep foo
0000000000401126 T foo

It always fails on my side (but just succeeded for only once). How to troubleshoot this further?

agentzh commented 6 months ago

Seems like this is a known issue with short functions in Frida. Alas. See https://github.com/frida/frida-gum/issues/273#issuecomment-403037242. If I make the function foo bigger (by either adding more statements or use -O0 instead), then it succeeds:

[2024-01-28 01:26:44][info][708488] Created uprobe/uretprobe perf event handler, module name /500g-a/git/ebpf-plus/libbpf/uprobes/a.out, offset 1126
[2024-01-28 01:26:44.811] [info] [agent.cpp:66] Entering bpftime agent
[2024-01-28 01:26:44.811] [info] [bpftime_shm_internal.cpp:618] Global shm constructed. shm_open_type 1 for bpftime_maps_shm
[2024-01-28 01:26:44.811] [info] [agent.cpp:81] Initializing agent..
[2024-01-28 01:26:44][info][708493] Initializing llvm
[2024-01-28 01:26:44][info][708493] Executable path: /500g-a/git/ebpf-plus/libbpf/uprobes/a.out
[2024-01-28 01:26:44][info][708493] Attached 1 uprobe programs to function 401126
[2024-01-28 01:26:44][info][708493] Attach successfully

Here is the original foo function definition in C:

int __attribute__((noinline)) foo(int a) {
    return a + 1;
}

With gcc -O0, it has 7 instructions:

0000000000401126 <foo>:
foo():
  401126:   55                      push   rbp
  401127:   48 89 e5                mov    rbp,rsp
  40112a:   89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  40112d:   8b 45 fc                mov    eax,DWORD PTR [rbp-0x4]
  401130:   83 c0 01                add    eax,0x1
  401133:   5d                      pop    rbp
  401134:   c3                      ret

But with gcc -O1, it has only 2 instructions:

0000000000401126 <foo>:
foo():
  401126:   8d 47 01                lea    eax,[rdi+0x1]
  401129:   c3                      ret

And for this short foo() function, Frida always fails.

hp77-creator commented 5 days ago

I am observing similar behaviour in Debug and Release or RelWithDebugInfo config flags on cmake and running frida uprobe tests. Curiously this behaviour is observed on a aarch64 system.

hp77-creator commented 5 days ago

@Officeyutong fyr

Officeyutong commented 4 days ago

I am observing similar behaviour in Debug and Release or RelWithDebugInfo config flags on cmake and running frida uprobe tests. Curiously this behaviour is observed on a aarch64 system.

Trying inserting some nop instructions to make the function body larger and have a test