Search code examples
linux-kerneluprobe

uprobe on fixed address with ASLR disabled


I would like to use the tracefs mounted at /sys/kernel/tracing to setup a uprobe on a specific address within the memory map of a particular PIE binary that is normally run with ASLR. As I understand, the usual way for a PIE binary would be to use a relative adresse (like echo 'p:test /test.elf:0xabcd %ip' > /sys/kernel/tracing/uprobe_events) to setup the probe. However in my case, I would like the probe to be placed on a memory page that is returned through mmap at a known location (e.g., 0x155555551000) when the binary is run with linux64 -R /test.elf to temporarily disable the ASLR.

I tried to use the relative offset between the binary page and the mmaped page, but echo 1 > /sys/kernel/tracing/events/uprobes/test/enable fails with "Could not enable event".

Is this achievable? Thanks!


Solution

  • You most probably cannot do this with uprobes (see last paragraph for more details).

    Uprobes are effectively "bound" to the inode of the program you want to trace (whose path is the specified when writing to /sys/kernel/tracing/uprobe_events), and will only allow you to trace code that lives in VMAs mapping that inode.

    When the uprobe is enable, each currently alive mapping for the given inode is scanned and the probe is installed for the VMAs that matche both the requested inode and offset (code here). For future mappings, a check is done during mmap to determine whether any uprobe should be installed (code here).

    In your case, when you add the uprobe, you won't see any issue as the kernel only does some passive validation. However, enabling it will later fail because the address you are trying to trace does not belong to a VMA that maps the inode of the file you initially specified.

    If the code you are trying to trace is the result of a file-backed (not anonymous) mmap call, you may be able to add the uprobe specifying the path (and offset) of the file that is being mapped instead of the path of the executable that is mapping it. However, if (as I suspect) what you are trying to trace is an anonymous mapping containing some code (e.g., something that a JIT compiler would do) you cannot use uprobes. You will have to look for different userspace solutions. Just to mention some: a debugger like GDB, a binary instrumentation tool like Intel PIN (assuming you are on x86), an emulator like QEMU user or Unicorn.


    References: Defeating eBPF Uprobe Monitoring by Célian Glénaz on Quarkslab's blog.