Kprobe/Jprobe in the middle of a function

689 views Asked by At

I want to intercept the load_elf_binary function in fs/binfmt_elf.c file, read a few custom section headers from the file passed to it via an argument and set a few registers(eax, ebx, ecx, edx) before returning from the function.

Now I read that Jprobes is a good way to access the arguments of the target function but the problem is that once the control returns from Jprobes function the register and stack values are restored as per it's specifications, so I am looking into a way around it and probably inserting a probe in the middle of the function (preferably towards the end) would be a good idea. Please correct me if I am wrong and help with this.

1

There are 1 answers

4
bdonlan On

So, let me see if I understand what you're doing properly.

You've modified the CPU (running in an emulator?) so that instruction 0xF1 does some sort of cryptographic thing. You want to arrange for load_elf_binary to invoke this instruction on return, with registers set properly for this instruction to do its magic. Somehow custom sections are involved.

This is going to be very difficult to do in the way you state. There are a few major problems:

  1. I'm not sure what your threat model is, but if your magic CPU instruction just decrypts the mapped data directly you'll modify the pages in the linux page cache, and the decrypted code or data will be visible to other processes that mmap these pages.
  2. Moreover, if the kernel frees the pages later, the encrypted data will be reloaded into memory, resulting in crashes at unpredictable times.
  3. If some process makes those pages dirty, the decrypted data will be flushed back to disk, leaving a mix of decrypted and encrypted data on disk.
  4. If you use a JProbe, your callback is invoked on entry to the function, which is way too early anyway.

All in all, this isn't going to work too well the way you state it.

A better approach might be to define your own binfmt (or replace the load_binary callback in elf_format). Your binfmt could then load the binary in whatever way it needs to. If you want to leverage the existing ELF loader, you could delegate to load_elf_binary, and on return do whatever you need to manipulate the loaded process, without any of this JProbe stuff.

In either case, do be sure to remap all of the pages you're encrypting/decrypting as MAP_PRIVATE and mark them dirty before changing their contents.