2017-07-24 106 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;