找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 2036|回复: 0

[【推荐】] 获取Linux 2.6.x sys_call_table

[复制链接]
发表于 2009-8-6 14:34:18 | 显示全部楼层 |阅读模式
网上搜索了一下, 发现此代码主要原理是通过搜索 int 0x80的中断服务程序中的sys_call_table来实现.

在linux中所有的syscall都是调用int 0x80, int 0x80的中断服务程序为system_call(arch/x86/kernel /traps_32.c:set_system_gate(SYSCALL_VECTOR,&system_call). system_call (arch/x86/entry_32.S)最终call *sys_call_table(,%eax,4)来完成一个syscall调用.

即 int 0x80 -> system_call -> sys_call_table, 这样我们只要首先获取int 0x80的中断服务地址system_call地址, 然后在system_call代码中直接搜索call指令即可找到sys_call_table地址了!

另一种方法就是直接修改

通过cat /boot/System.map-`uname -r` |grep sys_call_table 查看当前sys_call_table地址,并与通过以上方法取得的地址做比较!

内核版本: ubuntu 2.6.24-19-server

/*
* Standard in kernel modules
*/
#include <linux/kernel.h>  /* We&#39;re doing kernel work */
#include <linux/module.h>  /* Specifically, a module, */
#include <linux/moduleparam.h> /* which will have params */
#include <linux/unistd.h>  /* The list of system calls */

/*
* For the current (process) structure, we need
* this to know who the current user is.
*/
#include <linux/sched.h>
#include <asm/uaccess.h>


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 segment_select;
  unsigned char  reserved,  flags;
  unsigned short offset_high;
} __attribute__ ( ( packed ) ) * idt;


unsigned long* find_sys_call_table(void)
{
  unsigned long system_call = 0;     // x80中断处理程序system_call 地址
  char *call_hex = \"\\xff\\x14\\x85\";  // call 指令
  char *code_ptr = NULL;
  char *p = NULL;
  unsigned long sct = 0x0;
  int i = 0;

  // 获取中断描述符表寄存器的地址
  __asm__ ( \"sidt %0\": \"=m\" ( idtr ) );
  // 获取0x80中断处理程序的地址
  idt = ( void * ) ( idtr.base + 8 * 0x80 );
  system_call = ( idt->offset_high << 16 ) | idt->offset_low;

  // 搜索system_call代码
  code_ptr = (char *)system_call;
  for(i = 0;i < ( 100 - 2 ); i++) {
    //// 查找call指令
    if(code_ptr == call_hex[0]
      && code_ptr[i+1] == call_hex[1]
      && code_ptr[i+2] == call_hex[2] ) {
      //
      p = &code_ptr + 3;
      break;
    }
  }
  if ( p ){
    sct = *(unsigned long*)p;
  }
  return (unsigned long*)sct;
}

int init_module ( void ) {

  if ( ( sys_call_table = find_sys_call_table() ) )  {
    printk( \"sys_call_table = %p\\n\", sys_call_table );
  }
  return 0;
}

void cleanup_module ( void ) {
}

Makefile文件:

obj-m = get_sct.o
KVERSION = $(shell uname -r)
all:
      make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
      make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-5-25 00:41 , Processed in 0.262226 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表