1

我正在尝试在 Linux x86_64 上获取 sys_call_table 的偏移量。

首先,我通过从 MSR_LSTAR 读取指向 system_call 条目的指针,这是正确的

static unsigned long read_msr(unsigned int msr)
{

    unsigned low, high;
    asm volatile("rdmsr" : "=a" (low), "=d" (high) : "c" (msr));
    return ((low) | ((u64)(high) << 32));
}

然后我解析它以找到调用指令的操作码,它也是正确的

#define CALL_OP 0xFF
#define CALL_MODRM 0x14
static unsigned long find_syscall_table(unsigned char *ptr)
{

  //correct
  for (; (*ptr != CALL_OP) || (*(ptr+1) != CALL_MODRM); ptr++);

  //not correct
  ptr += *(unsigned int*)(ptr + 3);
  pr_info("%lx", (unsigned long)ptr);


  return ptr;
}

但是我在调​​用操作码后未能获得地址。ptr 的第一个字节是操作码,然后是 ModRM 字节,然后是 SIB,然后是 32 位位移,所以我将 3 添加到 ptr 并将其取消引用为整数值,然后将其添加到 ptr,因为它是 %RIP,并且地址是相对于 RIP 的。但是结果值是错误的,它与我在 gdb 中看到的值不一致,所以我错在哪里?

4

1 回答 1

0

它不是 x7e9fed00 而是 -0x7e9fed00 - 负位移。

那是 2 的补码负数 0x81601300 的符号大小形式

它由小端处理器存储为“00 13 60 81”


但是,不知道您是否会在结果地址中找到 sys_call_table。作为另一种想法,似乎有些人通过在内存中搜索指向应该在其中列出的函数的已知指针来找到它。

于 2012-05-07T15:10:43.200 回答