Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>There are at least two approaches. </p> <h1>Approach 1: Jprobes</h1> <p>Probably the most easy one: if <em>Jprobes</em> are suitable for your task, you could give them a try. They are the close relatives of kprobes (see their detailed description and links to the examples in the <a href="http://www.mjmwired.net/kernel/Documentation/kprobes.txt">kernel docs</a>). </p> <p>Jprobes allow to call your function with the same signature as the probed one on entry to the latter. You get all of the arguments automatically this way.</p> <h1>Approach 2: Registers and Stack</h1> <p>Another approach could be to extend a bit what you already do and retrieve the arguments from the registers and the stack. From the output log in your question, I assume you are working on a 32 bit x86 system. </p> <h2>x86, 32 bit</h2> <p>As far as I have seen, there are two most common conventions on argument passing in the Linux kernel on x86 (the details are available in the <a href="http://www.agner.org/optimize/calling_conventions.pdf">manual by Agner Fog</a>). Note that system calls follow other conventions (see the <a href="http://www.agner.org/optimize/calling_conventions.pdf">manual</a> for details) but I assume you are interested in analysing an "ordinary" function rather than a system call.</p> <h3>Convention 1</h3> <p>For the functions marked with <code>asmlinkage</code> as well as for the functions with variable argument lists, all parameters are passed on stack. The return address of the function should be at the top of the stack on entry to the function, the first parameter being located right below it. The second parameter is below the first one, and so on. </p> <p>As you have the saved value of <code>esp</code>, you can find what it points to. <code>*(esp+4)</code> should be the first argument, <code>*(esp+8)</code> - the second one, etc., if this convention is used.</p> <h3>Convention 2</h3> <p>It seems to be used for the most of the kernel functions including the one you mentioned in the question. </p> <p>The kernel is compiled with <code>-mregparm=3</code> and therefore the first 3 arguments are passed in <code>eax</code>, <code>edx</code> and <code>ecx</code>, in that order, the rest go on stack. <code>*(esp+4)</code> should be the 4th argument, <code>*(esp+8)</code> - the 5th one, and so on.</p> <h2>x86, 64bit</h2> <p>It seems that things are a bit simpler on x86-64. Most of the kernel functions (including those with variable argument list) get the first 6 arguments in <code>rdi</code>, <code>rsi</code>, <code>rdx</code>, <code>rcx</code>, <code>r8</code>, <code>r9</code>, in that order, the remaining ones go on stack. <code>*(esp+8)</code> should be the 7th argument, <code>*(esp+16)</code> - the 8th and so on.</p> <p><strong>EDIT:</strong> </p> <p>Note that on x86-32, the value of <code>esp</code> is not saved in <code>pt_regs</code> for kernel-mode traps (including the software breakpoints that KProbes rely upon). <a href="http://lxr.free-electrons.com/source/arch/x86/include/asm/ptrace.h">&lt;asm/ptrace.h&gt;</a> provides <code>kernel_stack_pointer()</code> function to retrieve the correct value of <code>esp</code>, it works both on x86-32 and on x86-64. See the description of <code>kernel_stack_pointer()</code> in that header file for details.</p> <p>In addition, <code>regs_get_kernel_stack_nth()</code> (also defined in that header) provides a convenient way to get the contents of the stack in the handler.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COThank you for nice answer. I'm a little bit confused with esp register, it should point to memory location where function return address is stored (start of the stack), right? But `regs->esp` contains the return address itself, the same value returns macro `__builtin_return_address(0)` in `foobar` function. So `*(esp+4)` doesn't point to the right location, how can I access the stack then?
      singulars
    2. COGood point! I have looked through the implementation of KProbes on x86-32. It seems that for optimized KProbes `esp` is not saved in `pt_regs`. The good news is, `regs` argument of the handler actually points to an area on stack and from what I could see in the implementation of KProbes, the stack area you need starts 60 bytes after `regs`. That is, `(unsigned long)regs + 60` is the address of the stack location for the return address, `(unsigned long)regs + 64` - for the argument #4 (yes, `dead4` is there), and so on. Checked this on Linux kernel 3.1 and 3.3.
      singulars
    3. CO(continued) As for where the offset `60` came from. In the optimized KProbes, a jump to a special function is places at the probe site. The template the special function is generated from is in [kprobes_optinsn_template_holder() function](http://lxr.free-electrons.com/ident?i=kprobes_optinsn_template_holder). On entry to the special function, `esp` is the same as on entry to the probed function. `pushf` and `SAVE_REGS_STRING` subtract 60 from it and then it is passed as the 2nd argument to the handler. On x86-64 things are different, though.
      singulars
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload