我正在尝试在 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 中看到的值不一致,所以我错在哪里?