Note that there are some explanatory texts on larger screens.

plurals
  1. POPlaying with syscall table from LKM
    text
    copied!<p>I'm overriding <code>SYS_READ</code> from the syscall table in Linux (3.x) but I'm having some troubles when unloading the module itself. I first load my module which finds the syscall table, then enables <code>RW</code>, overrides <code>SYS_READ</code> with my own <code>SYS_READ</code> function (which in fact doesn't do anything else than calling the original <code>SYS_READ</code>), then I wait a few moments, and then unload the module. On the unload method of my module I restore the original <code>SYS_READ</code> function back in the syscall table and set back the syscall table to <code>RO</code>.</p> <p>The original <code>SYS_READ</code> function is restored properly, but I get this when I unload the module: <a href="http://pastebin.com/JyYpqYgL" rel="nofollow">http://pastebin.com/JyYpqYgL</a></p> <p>What am I missing? Should I be doing something more after restoring the real <code>SYS_READ</code> ?</p> <p>EDIT: GitHub link to the project: <a href="https://github.com/alexandernst/procmon" rel="nofollow">https://github.com/alexandernst/procmon</a></p> <p>EDIT: </p> <p>This is how I get the syscall table address:</p> <pre><code>void **sys_call_table; struct idt_descriptor{ unsigned short offset_low; unsigned short selector; unsigned char zero; unsigned char type_flags; unsigned short offset_high; } __attribute__ ((packed)); struct idtr{ unsigned short limit; void *base; } __attribute__ ((packed)); void *get_sys_call_table(void){ struct idtr idtr; struct idt_descriptor idtd; void *system_call; unsigned char *ptr; int i; asm volatile("sidt %0" : "=m" (idtr)); memcpy(&amp;idtd, idtr.base + 0x80 * sizeof(idtd), sizeof(idtd)); system_call = (void*)((idtd.offset_high&lt;&lt;16) | idtd.offset_low); for(ptr=system_call, i=0; i&lt;500; i++){ if(ptr[0] == 0xff &amp;&amp; ptr[1] == 0x14 &amp;&amp; ptr[2] == 0x85) return *((void**)(ptr+3)); ptr++; } return NULL; } sys_call_table = get_sys_call_table(); </code></pre> <p>And this is how I set RW/RO:</p> <pre><code>unsigned long set_rw_cr0(void){ unsigned long cr0 = 0; unsigned long ret; asm volatile("movq %%cr0, %%rax" : "=a"(cr0)); ret = cr0; cr0 &amp;= 0xfffffffffffeffff; asm volatile("movq %%rax, %%cr0" : : "a"(cr0)); return ret; } void set_ro_cr0(unsigned long val){ asm volatile("movq %%rax, %%cr0" : : "a"(val)); } </code></pre> <p>Finally, this is how I define my syscalls and change the syscall table:</p> <pre><code>asmlinkage ssize_t (*real_sys_read)(unsigned int fd, char __user *buf, size_t count); asmlinkage ssize_t hooked_sys_read(unsigned int fd, char __user *buf, size_t count); //set my syscall real_sys_read = (void *)sys_call_table[__NR_read]; sys_call_table[__NR_read] = (void *)hooked_sys_read; //restore real syscall sys_call_table[__NR_read] = (void *)real_sys_read; </code></pre>
 

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