2017-07-24 125 views
0

我有一个问题,使用arm64内联汇编从一个LKM中加载64位地址到寄存器。ARM64-汇编分支到函数地址

我想在内核内存中设置一个函数钩子。所以每次调用某个特定的函数时,都应该分支到我的函数中。

我的想法是一个地址加载到寄存器中,这是在使用该运行获得:

unsigned long address = &hooked_do_undefinstr; 

然后写的

BLR X3 

相应的操作码到存储器中。

我想因为我有运行时获得的地址与

__asm__ __volatile__ ("MOV x3, %[var]" : [var] "=r" (address)); 

加载地址到寄存器X3(因为它的64位操作系统),我不能使用LDR命令。当我打印的X3含量为零

[email protected]___ :~# insmod mod_init.ko 
[ 70.386938] mod_init: Unknown symbol x19 (err 0) 
[ 70.391508] mod_init: Unknown symbol x3 (err 0) 

使用此命令,输出:插入模块时,我收到以下错误

[ 558.948492]   MOV x3 Register value 0x0 

现在是我的问题,是有办法来加载一个64位地址注册到一个寄存器? 或者是否有一个更好的方法来实现我的功能挂钩,以跳转到我的地址?

问候,并感谢您的帮助

回答

1

这并不完全清楚自己在做什么。如果你想挂钩一个函数,你不能只把你的blr x3放在那里,并且期望能够保存你在其他地方使用内联asm设置的值(除非你知道它在任何地方都没有被触摸,但我觉得不太可能)。你需要把加载代码也到挂钩的函数,这样的事情可能工作:

ldr x3, .+8 
blr x3 

创建使用汇编的机器代码给出:43 00 00 58 60 00 3F D6

修补时,你的代码应该追加目标在结束地址:

void patch(unsigned char* target) 
{ 
    unsigned char code[] = { 0x43, 0x00, 0x00, 0x58, 0x60, 0x00, 0x3F, 0xD6 }; 
    memcpy(target, code, 8); 
    *(void (**)())(target + 8) = hooked_do_undefinstr; 
} 

另外请注意,无论你已覆盖应该由你的钩子函数进行补偿。像往常一样,您还需要确保您正在修补的部分是可写的。

+0

谢谢您的回答。我没有想到,寄存器可能会被覆盖。 我已经禁用了内存写保护并为我正在覆盖的代码创建了一个备份。此外,我必须将您的十六进制代码转换为小端。 你的代码,我将不得不保存(从原始条目)8Byte的两个命令加上8字节的地址权? 但我正在尝试这个。再次感谢 – MajorasKid

+0

编辑:我只是检查,看到你的OPCode已经在little endian – MajorasKid

0

我用@ Jester的想法解决了这个问题。

请注意,如果您使用的是他的代码,请检查您的系统是否运行小端或大端。

//Get the SCTLR_EL1 content 
__asm__ __volatile__ ("MRS %[result], SCTLR_EL1" : [result] "=r" (sctlr_el1)); 

//Check the 25th bit. if 1 -> big, else little 
if(sctlr_el1 & (1<<25)) 
{ 
    printk(KERN_INFO "   Big Endian Found\n"); 
    create_hook_big(addresse); 
}else 
{ 
    printk(KERN_INFO "   Little Endian found\n"); 
    create_hook_little(addresse); 
} 

否则:这可以这样做,这是我工作的代码:

//Backup original entries 
memcpy(original_blr, (void*)el1_sync,sizeof(original_blr)); 


//Set function hook, el1_sync is my used target 
memcpy((void*)el1_sync,replace_jump_offset,sizeof(replace_jump_offset)); 
*(void (**)(void))(el1_sync + 8) = &hooked_do_undefinstr;