The matter
As we know reading the first white-paper concerning MODEST project, our LKM was not able to capture the system calls requested by a dynamic linked binary. This awful issue was because of the fact that, in modern GNU/Linux Kernels, any System Call will be served through a call to the __kernel_vsyscall(); function, and, in the concrete case of dynamic binaries, this call will be translated in a sysenter/sysexit Ring0 mechanism. So, we could not catch any system call using our modest_syshandler() routine, which was useful only in the classic old-days Ring0 mechanism well-known as int 0×80.
The solution
Instead of writting some code to alter the MSR_* registers so as to point at a new kernel entry point for the sysenter call, I decided to use Kprobes, as well-described in my last white-paper. This way, I skipped the awful and difficult way of writting assembly code, and all I needed was to read the Kprobes documentation carefully and write a few C-high code lines to accomplish this goal. This piece of work is extensively explained and described in the last white-paper written expressly for this new MODEST behavior.
In short …
First of all, I decided I was in need of writting a pre-handler. This pre-handler would be executed as soon as the sysenter call was requested by a process. Therefore, my pre-handler routine would get all the interesting parameters, stored in the pt_regs data structure and accessible directly using C code. Finally, it would call my own my_sys_write() or my_sys_writev() functions so as to write the data to the fd’ descriptor, as usual.
The main problem to do that was related to where I had to put this handler. I mean, the exact memory address instruction. Logically, the first option could be at the sysenter entry point itself. But that was not possible ’cause my pre-handler routine had to use the current macro, and this macro had to get the task_struct * data structure for the current process from the stack. So, the pre-handler had to be placed right after the assembly call to movl TSS_sysenter_esp0(%esp),%esp. Looking at the file where GNU/Linux sysenter/sysexit are implemented, I discovered where this address would come to be:
267 # sysenter call handler stub 268 ENTRY(sysenter_entry) 269 CFI_STARTPROC simple 270 CFI_DEF_CFA esp, 0 271 CFI_REGISTER esp, ebp 272 movl TSS_sysenter_esp0(%esp),%esp 273 sysenter_past_esp: 274 /* 275 * No need to follow this irqs on/off section: the syscall 276 * disabled irqs and here we enable it straight after entry: 277 */ 278 sti
Thus, I added the pre-handler at sysenter_past_esp address, using Kprobes API – it was really a piece of cake, that’s for sure
-, and calling the Kernel aid kallsyms_lookup_name(), as described in the paper.
Below, the pre-handler in charge of catching any call to sys_write() or sys_writev() system calls requested by a binary linked in a dynamic way:
95 int kprobe_prehandler (struct kprobe *p , struct pt_regs *regs){ 96 if(pid_affected!=-1 && (regs->eax==__NR_write||regs->eax==__NR_writev )){ 97 /* Get the parameters through the registers : */ 98 bytes_to_read = regs->edx; // size_t count 99 userfd = regs->ebx; // int fd 100 memory = (const char __user *)regs->ecx; 101 102 if(pid_affected==current->pid && userfd==oldfd){ 103 if(atomic_read(&syscall_first_catched)==0){ 104 printk(KERN_INFO "MODEST %s by %s: PID %d on cpu %d ==> [sysenter/sysexit]\n", 105 _VERSION_, _AUTHOR_, current->pid , current->thread_info->cpu); 106 atomic_inc(&syscall_first_catched); 107 } 108 switch(regs->eax){ 109 case __NR_write: 110 schedule(); 111 my_sys_write(krn_fd, memory, bytes_to_read ); 112 break; 113 case __NR_writev: 114 schedule(); 115 my_sys_writev(krn_fd,(const struct iovec __user*)memory, 116 bytes_to_read); 117 break; 118 } 119 } 120 } return 0; /* Return to sys_write or sys_writev or whichever ! ;- */ 121 }
There’s a demonstrative video showing how MODEST can be used, finally, to peep data written by a given process, no matter if it is static or dynamic HERE.
Pausing and resuming the “peeping” process
The first improvement added to the MODEST project concerns a new “option” available at any time using the user-space utility umodest. Now, as long as a certain static or dynamic binary is being intercepted with the “-d” flag, the user can press the “p” key to resume this catching process, and whenever he or she desires, press the “r” key so that the peeping process can continue in a normal way. There’s a demonstrative video HERE where this option is fully auto-explained.
Below, the “new” umodest tool’s appearance:
Running shared tests (-d) over /tmp/modest-tests…
Running with PID: 2746
Redirecting fd: 3 to: /tmp/modest-tests.
When you want to restore original fd, just type q ENTER
Push p ENTER to pause the Ring 0 catching system.
Push r ENTER to resume the Ring 0 catching system.
>?
More verbosity
Continuing with our last additions to the MODEST source code, there’s now a more detailed level of verbosity, as far as the GNULinux Kernel is concerned. Any ioctl() call sent by the umodest utility to the driver, such as pausing, resuming or restoring the process FDT, a printk() message will show up, readable using dmesg, syslog or whatever.
In addition, another printk() message will be printed out as soon as the first system call will be executed, showing this way what sort of Ring 0 mechanism is being used by the current process. All this messages are shown below:
Load successful. Compiled at Aug 26 2009 17:59:21 @ new syscall (int $0x80) at: 0xd09f9970 @ sysenter_past_esp at: 0xc0102bbb , catched by 0xd09f97fa Restore FDT requested ... PID 2548 on cpu 0 ==> [sysenter/sysexit] Pause peeping has been requested ... Resuming peeping process ... Pause peeping has been requested ... Resuming peeping process ... Restore FDT requested ...
More information
Take a look at the white-paper concerning Kprobes and dynamic binaries HERE – written in LaTeX.
Here you have a lot of interesting demonstrative videos showing different aspects of using MODEST via Kprobes and dynamic linked binaries.
Of course, get the latest MODEST sources using the CVS at SourceForget net throught the kmodest web page : http://kmodest.sf.net


[...] calls, instead of two of them. This routine was hugely explained on a previous POST, read it right HERE.All we needed to do was to add a new kprobes structure to our code, ensuring this will be pointing [...]