我试图在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中看到的值不一致,所以我错在哪里?
答案 0 :(得分:0)
这不是x7e9fed00,而是-0x7e9fed00 - 负排量。
这是2的补码负数0x81601300
的符号幅度形式由小端处理器存储为“00 13 60 81”
不知道你是否会在结果地址找到sys_call_table。作为另一种想法,似乎有些人通过在内存中搜索应该列在其中的函数的已知指针来找到它。