-
http://bbs.chinaunix.net/thread-2143235-1-1.html
-
Linux System Call Table
http://bluemaster.iu.hio.no/edu/dark/lin-asm/syscalls.html
-
#include <linux/kernel.h>
-
#include <linux/init.h>
-
#include <linux/module.h>
-
#include <asm/uaccess.h>
-
#include <asm/fcntl.h>
-
#include <asm/unistd.h>
-
#include <asm/ia32_unistd.h>
-
#include <asm/msr.h>
-
-
-
-
#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."
-
MODULE_DESCRIPTION( THIS_DESCRIPTION );
-
MODULE_AUTHOR("albcamus <albcamus@gmail.com>");
-
MODULE_LICENSE("GPL");
-
-
-
/**
-
* TODO: if you want shut this up, comment the following line.
-
*/
-
#define BY_IDT_DEBUG
-
-
#ifdef BY_IDT_DEBUG
-
#define dbgprint(format,args...) \
-
printk("get_syscall: function:%s-L%d: "format, __FUNCTION__, __LINE__, ## args);
-
#else
-
#define dbgprint(format,args...) do {} while(0);
-
#endif
-
-
-
/**
-
* sys call table
-
*/
-
void ** my_ia32_syscall_table;
-
void ** my_syscall_table;
-
-
-
-
/**
-
* 10 bytes -- please refer to AMD64 Architecture Programmer's
-
* Manuals for more information.
-
*/
-
struct idtr {
-
unsigned short limit;
-
unsigned long base; //in 64bit mode, base address is 8 bytes
-
} __attribute__ ((packed));
-
-
-
/**
-
* in long mode -- 64bit mode and compatity mode,
-
* every IDT entry has a 16-byte size
-
*/
-
struct idt {
-
u16 offset_low;
-
u16 segment;
-
unsigned ist : 3, zero0 : 5, type : 5, dpl :2, p : 1;
-
u16 offset_middle;
-
u32 offset_high;
-
u32 zero1;
-
} __attribute__ ((packed));
-
-
-
-
-
/**
-
* Return the first appearence of NEEDLE in HAYSTACK. -- copied from PHRACK
-
* */
-
static void *memmem(const void *haystack, size_t haystack_len,
-
const void *needle, size_t needle_len)
-
{/*{{{*/
-
const char *begin;
-
const char *const last_possible
-
= (const char *) haystack + haystack_len - needle_len;
-
-
if (needle_len == 0)
-
/* The first occurrence of the empty string is deemed to occur at
-
the beginning of the string. */
-
return (void *) haystack;
-
-
/* Sanity check, otherwise the loop might search through the whole
-
memory. */
-
if (__builtin_expect(haystack_len < needle_len, 0))
-
return NULL;
-
-
for (begin = (const char *) haystack; begin <= last_possible;
-
++begin)
-
if (begin[0] == ((const char *) needle)[0]
-
&& !memcmp((const void *) &begin[1],
-
(const void *) ((const char *) needle + 1),
-
needle_len - 1))
-
return (void *) begin;
-
-
return NULL;
-
}/*}}}*/
-
-
-
/**
-
* Find the location of ia32_sys_call_table
-
*/
-
static unsigned long get_syscall_table_ia32(void)
-
{/*{{{*/
-
#define OFFSET_SYSCALL 100 /* from system_call/ia32_syscall, we'll read first 150 bytes */
-
-
struct idtr idtr;
-
struct idt idt;
-
-
unsigned long sys_call_off;
-
unsigned long retval;
-
-
char sc_asm[OFFSET_SYSCALL], *p;
-
-
-
-
-
/* well, let's read IDTR */
-
asm("sidt %0"
-
:"=m"(idtr)
-
: );
-
-
dbgprint("idtr base at %p\n", (void *)idtr.base);
-
-
/**
-
* Read in IDT for vector 0x80 (syscall)
-
*/
-
memcpy(&idt, (char *) idtr.base + 16 * 0x80, sizeof(idt));
-
sys_call_off = ( ( (unsigned long)idt.offset_high ) << 32 ) |
-
( ((idt.offset_middle << 16 ) | idt.offset_low) & 0x00000000ffffffff );
-
dbgprint("sys_call_off at %p\n", (void *)sys_call_off);
-
-
/* we have syscall routine address now, look for syscall table
-
dispatch (indirect call) */
-
memcpy(sc_asm, (void *)sys_call_off, OFFSET_SYSCALL);
-
/**
-
* ia32_call > ia32_tracesys > ia32_do_syscall > 'call *ia32_sys_call_table(,%rax,8)'
-
* Find callq *ia32_sys_call_table(,%rax,8)
-
*
-
* (gdb) disassemble ia32_syscall
-
* Dump of assembler code for function ia32_syscall:
-
* 0xffffffff81066b98 <ia32_syscall+0>: swapgs
-
* 0xffffffff81066b9b <ia32_syscall+3>: sti
-
* 0xffffffff81066b9c <ia32_syscall+4>: mov %eax,%eax
-
* 0xffffffff81066b9e <ia32_syscall+6>: push %rax
-
* 0xffffffff81066b9f <ia32_syscall+7>: cld
-
* 0xffffffff81066ba0 <ia32_syscall+8>: sub $0x48,%rsp
-
* 0xffffffff81066ba4 <ia32_syscall+12>: mov %rdi,0x40(%rsp)
|