Код: Выделить всё
void find_sys_call_table(void)
{
unsigned long *ptr;
unsigned long arr[4];
int i;
ptr=(unsigned long *)((current->mm->end_code + 4) & 0xfffffffc);
while((unsigned long)ptr < (unsigned long)current->mm->end_data)
{
if (*ptr == (unsigned long *)sys_close)
{
for(i=0;i<4;i++)
{
arr[i]=*(ptr+i);
arr[i]=(arr[i] >> 16) & 0x0000ffff;
}
if(arr[0] != arr[2] || arr[1] != arr[3])
{
sys_call_table=(ptr - __NR_close);
break;
}
}
ptr++;
}
printk(KERN_INFO"sys_call_table base found at: %x\n",sys_call_table);
};
Пробую перехватить sys_close. Так как вызов sys_close экспортируется то его легко перехватить, то почему не работает мой код перехвата close на ядре linux-2.6.32
Код: Выделить всё
char old_commands[COMMANDS_COUNT];
int sys_close(int fd);
int my_close(int fd){
return 0;
};
int old_close(int fd);
static int mod2_init(void){
unsigned long *Addr=sys_close;
memcpy(old_commands, (void *)sys_close, COMMANDS_COUNT);
printk(KERN_INFO"sys_close address: %x
",(unsigned long*) Addr);
Addr=my_close;
sys_close=Addr;
return -1;
};
Пишет /root/mod2/mod2.c:65: error: lvalue required as left operand of assignment.
У меня есть ещё одна процедура нахождения адресса этой таблицы, но он тоже не работает основан на поиске опкода команды перехода к таблице
Код: Выделить всё
phys_addr_t search_sct_address( void )
{
u_char *p;
uint push1,push2;
void *start_addr;
struct idtr idtr; //таблица дескрипторов прерываний
struct gate *igd; //дескриптор прерывания
char sc_asm[128];
asm("sidt %0" : "=m" (idtr)); //получили таблицу дескрипторов прерываний
igd=(void*)idtr.base+(8*0x80); //берем дескриптор для system_call
//start_addr = gate_offset(igd); //адресс обработчика system_call
start_addr = (igd->off2 << 16) | igd->off1; //адресс обработчика system_call
//теперь тупо ищем опкод call
printk(KERN_INFO"idt80: flags=%X sel=%X off=%X\n",
(unsigned)igd->flags,(unsigned)igd->sel,sys_call_table);
p=(u_char* )memmem( sc_asm, 100,"\xff\x14\x85", 3 );
if (p) { //если нашли
p+=3;
return *(phys_addr_t *)p;
} else { //если не нашли
return 0;
}
};
И ещё один через MSR и тоже не работает
Код: Выделить всё
phys_addr_t search_sct_address2( void )
{
u_char *p=NULL;
void *start_addr=NULL;
#ifdef CONFIG_X86_64
start_addr=(void*)native_read_msr(MSR_IA32_SYSENTER_EIP);
#else
{
u32 rh,rl;
rh=rl=0;
rdmsr( MSR_IA32_SYSENTER_EIP , rl, rh );
start_addr=(void*)rl;
}
#endif
if(start_addr)//начиная с адреса обработчика sysenter
{
p =(u_char*)memmem(start_addr, 150, "\xff\x14\x85",3);
if (p) { //если нашли
p+=3;
return *(phys_addr_t *)p;
}
}
return 0;
}
Оба последних используют функцию поиска опкода в памяти memmem описана тут Опкоды.