歡迎您光臨本站 註冊首頁

導出Linux系統調用表(sys_call_table)

←手機掃碼閱讀     火星人 @ 2014-03-26 , reply:0

轉貼:

Linux內核從2.4.18開始就不再導出系統調用表(sys_call_table),這對於我們想對系統調用做些手腳的朋友們來說,確實不是什麼好消息。少了很多便利條件,如果說改內核源碼,加上EXPORT_SYMBOL(sys_call_table),還是能夠導出的,不過這個需要重新編譯內核,最煩人就是重啟(我們有些時候最怕的就是重啟,至於為什麼,大家心裡明白,哈哈)。如果我們足夠幸運,能找到/boot/System.map,通過簡單的grep sys_call_table /boot/System.map也能如願以償,可是這個文件並不是所有的系統都有的。還好LKM給了我們訪問內核空間的能力,可是系統這麼大,從何下手呢?
反彙編系統調用相關代碼:
(gdb) disas syscall_call
Dump of assembler code for function syscall_call:
0xc0102e0a : call *0xc030948c(,%eax,4)
0xc0102e11 : mov %eax,0x18(%esp)
End of assembler dump.
(gdb) x/8x 0xc0102e0a
0xc0102e0a : 0x8c8514ff 0x89c03094 0xfa182444 0x66084d8b
0xc0102e1a : 0xfeffc1f7 0x00cc850f 0x448b0000 0x648a3024

可以看到藍色的部分就是需要找的標誌字元串,與之緊挨的高地址部分就是我們要找的sys_call_table的地址。為了縮小查找範圍,我們只要從int $0x80的入口函數向下順序查找就行,其地址用命令sidt就能直接得到了。具體代碼如下:
/*
* Copyright (c) 2006 xiaosuo <xiaosuo@gmail.com>
*
* Copyright (c) 2003 Dallachiesa Michele <xenionREMOVETHIS@antifork.org>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification are permitted.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*
* DESCRIPTION
*
* redhat kernels don't export the sys_call_table symbol anymore.. this
* is a workaround that let you use your old LKMs without fix them.
*
* In fact, the kernel (>= 2.4.18) don't export the sys_call_table symbol
* anymore...
*
* USAGE
*
* Build this as a kernel module and loaded
*
* + greetz: (#phrack.it|antifork.org) guys
* + sys_call_table[] address lookup code from phrack 58 #0x07 by sd
*/
#ifndef MODULE
#define MODULE
#endif
#ifndef __KERNEL__
#define __KERNEL__
#endif
#include
#ifdef USE_SYMBOL_NAME
#include
#endif
#include
#define CALLOFF 100
unsigned long sys_call_table = 0;
EXPORT_SYMBOL(sys_call_table);
struct {
unsigned short limit;
unsigned int base;
} __attribute__ ((packed)) idtr;
struct {
unsigned short offset_low;
unsigned short sel;
unsigned char none, flags;
unsigned short offset_high;
} __attribute__ ((packed)) * idt;
/*
* The /proc/kallsyms is not updated.
*/
int set_symbol_value(unsigned long old_value, unsigned long value)
{
struct kernel_symbol *ksyms;
int i;
ksyms = (struct kernel_symbol*)(THIS_MODULE->syms);
for(i = 0; i < THIS_MODULE->num_syms; i ++){
#ifdef USE_SYMBOL_NAME
if(strcmp(ksyms.name, "sys_call_table") == 0){
#else
if(ksyms.value == old_value){
#endif
ksyms.value = value;
return 0;
}
}
return -1;
}
char* findoffset(char *start)
{
char *p;
for (p = start; p < start + CALLOFF; p++)
if (*(p + 0) == '\xff' && *(p + 1) == '\x14'
&& *(p + 2) == '\x85')
return p;
return NULL;
}
int init_module(void)
{
unsigned sys_call_off;
char *p;
__asm__("sidt %0":"=m"(idtr));
idt = (void *) (idtr.base + 8 * 0x80);
sys_call_off = (idt->offset_high << 16) | idt->offset_low;
if ((p = findoffset((char *) sys_call_off))) {
return set_symbol_value((unsigned long)&sys_call_table,
*((unsigned long*)(p+3)));
}
return -1;
}
void cleanup_module(void)
{
}

另外,因為有這樣一個事實:sys_call_table總是在loops_per_jiffy和boot_cpu_data之間,所以可以用這兩個符號地址作為邊界進行查詢!
/* This method first be found in the dazuko 2.0.6
*/
static void** dazuko_get_sct(void)
{
unsigned long ptr;
extern int loops_per_jiffy;
unsigned long *p;
for(ptr=(unsigned long)&loops_per_jiffy; ptr<(unsigned long)&boot_cpu_data;
ptr+=sizeof(void *)){
p = (unsigned long *)ptr;
if (p[6] == (unsigned long)sys_close){
return (void **)p;
}
}
return NULL;
}

[火星人 ] 導出Linux系統調用表(sys_call_table)已經有583次圍觀

http://coctec.com/docs/linux/show-post-189901.html