现在的位置: 首页 > 综合 > 正文

get system call table in x86-64 Linux

2012年09月23日 ⁄ 综合 ⁄ 共 3616字 ⁄ 字号 评论关闭

  1. http://bbs.chinaunix.net/thread-2143235-1-1.html
  2. Linux System Call Table

    http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html

  3. #include <linux/kernel.h>
  4. #include <linux/init.h>
  5. #include <linux/module.h>
  6. #include <asm/uaccess.h>
  7. #include <asm/fcntl.h>
  8. #include <asm/unistd.h>
  9. #include <asm/ia32_unistd.h>
  10. #include <asm/msr.h>



  11. #define THIS_DESCRIPTION "Dynamically get sys_call_table/ia32_sys_call_table in kernel module.\n\t\tI don't think there would be anyone who won't enable CONFIG_IA32_EMULATION these days.\n\t\tso you can add the unessary check if you really want to."
  12. MODULE_DESCRIPTION( THIS_DESCRIPTION );
  13. MODULE_AUTHOR("albcamus <albcamus@gmail.com>");
  14. MODULE_LICENSE("GPL");


  15. /**
  16. * TODO: if you want shut this up, comment the following line.
  17. */
  18. #define BY_IDT_DEBUG

  19. #ifdef BY_IDT_DEBUG
  20. #define dbgprint(format,args...) \
  21.                  printk("get_syscall: function:%s-L%d: "format, __FUNCTION__, __LINE__, ## args);
  22. #else
  23. #define dbgprint(format,args...)  do {} while(0);
  24. #endif


  25. /**
  26. * sys call table
  27. */
  28. void ** my_ia32_syscall_table;
  29. void ** my_syscall_table;



  30. /**
  31. * 10 bytes  -- please refer to AMD64 Architecture Programmer's 
  32. *         Manuals for more information.
  33. */
  34. struct idtr {
  35.     unsigned short limit;
  36.     unsigned long base; //in 64bit mode, base address is 8 bytes
  37. } __attribute__ ((packed));


  38. /**
  39. * in long mode -- 64bit mode and compatity mode, 
  40. * every IDT entry has a 16-byte size
  41. */
  42. struct idt {
  43.     u16 offset_low;
  44.     u16 segment;
  45.     unsigned ist : 3, zero0 : 5, type : 5, dpl :2, p : 1;
  46.     u16 offset_middle;
  47.     u32 offset_high;
  48.     u32 zero1;
  49. } __attribute__ ((packed));




  50. /**
  51. * Return the first appearence of NEEDLE in HAYSTACK.  -- copied from PHRACK
  52. * */
  53. static void *memmem(const void *haystack, size_t haystack_len,
  54.             const void *needle, size_t needle_len)
  55. {/*{{{*/
  56.     const char *begin;
  57.     const char *const last_possible
  58.         = (const char *) haystack + haystack_len - needle_len;

  59.     if (needle_len == 0)
  60.         /* The first occurrence of the empty string is deemed to occur at
  61.            the beginning of the string.  */
  62.         return (void *) haystack;

  63.     /* Sanity check, otherwise the loop might search through the whole
  64.        memory.  */
  65.     if (__builtin_expect(haystack_len < needle_len, 0))
  66.         return NULL;

  67.     for (begin = (const char *) haystack; begin <= last_possible;
  68.          ++begin)
  69.         if (begin[0] == ((const char *) needle)[0]
  70.             && !memcmp((const void *) &begin[1],
  71.                    (const void *) ((const char *) needle + 1),
  72.                    needle_len - 1))
  73.             return (void *) begin;

  74.     return NULL;
  75. }/*}}}*/


  76. /**
  77. * Find the location of ia32_sys_call_table
  78. */
  79. static unsigned long get_syscall_table_ia32(void)
  80. {/*{{{*/
  81. #define OFFSET_SYSCALL 100    /* from system_call/ia32_syscall, we'll read first 150 bytes */

  82.     struct idtr idtr;
  83.     struct idt idt;

  84.     unsigned long sys_call_off;
  85.     unsigned long retval;

  86.     char sc_asm[OFFSET_SYSCALL], *p;




  87.     /* well, let's read IDTR */
  88.     asm("sidt %0"
  89.         :"=m"(idtr)
  90.         : );

  91.     dbgprint("idtr base at %p\n", (void *)idtr.base);

  92.     /**
  93.      * Read in IDT for vector 0x80 (syscall) 
  94.      */
  95.     memcpy(&idt, (char *) idtr.base + 16 * 0x80, sizeof(idt)); 
  96.     sys_call_off =  ( ( (unsigned long)idt.offset_high ) << 32 ) | 
  97.         ( ((idt.offset_middle << 16 ) | idt.offset_low) & 0x00000000ffffffff ); 
  98.     dbgprint("sys_call_off at %p\n", (void *)sys_call_off);

  99.     /* we have syscall routine address now, look for syscall table
  100.        dispatch (indirect call) */
  101.     memcpy(sc_asm, (void *)sys_call_off, OFFSET_SYSCALL);
  102.     /**
  103.      * ia32_call > ia32_tracesys > ia32_do_syscall > 'call *ia32_sys_call_table(,%rax,8)'
  104.      * Find callq *ia32_sys_call_table(,%rax,8)
  105.      *
  106.      * (gdb) disassemble ia32_syscall
  107.      * Dump of assembler code for function ia32_syscall:
  108.      * 0xffffffff81066b98 <ia32_syscall+0>:    swapgs
  109.      * 0xffffffff81066b9b <ia32_syscall+3>:    sti
  110.      * 0xffffffff81066b9c <ia32_syscall+4>:    mov    %eax,%eax
  111.      * 0xffffffff81066b9e <ia32_syscall+6>:    push   %rax
  112.      * 0xffffffff81066b9f <ia32_syscall+7>:    cld
  113.      * 0xffffffff81066ba0 <ia32_syscall+8>:    sub    $0x48,%rsp
  114.      * 0xffffffff81066ba4 <ia32_syscall+12>:   mov    %rdi,0x40(%rsp)

抱歉!评论已关闭.