[英]Dynamically executed ARM ASM syscall with relocations from C++
我想從 C++ 調用 ARM/ARM64 ASM 代碼。 ASM 代碼包含系統調用和到外部函數的重定位。 ARM架構在這里不是那么重要,我只是想從概念上了解如何解決我的問題。
我有以下 ASM 系統調用(來自objdump -d
輸出),它在共享庫中被調用:
198: d28009e8 mov x8, #0x4f // #79
19c: d4000001 svc #0x0
1a0: b140041f cmn x0, #0x1, lsl #12
1a4: da809400 cneg x0, x0, hi
1a8: 54000008 b.hi 0 <__set_errno_internal>
1ac: d65f03c0 ret
這段代碼調用fstatat64
syscall並通過外部__set_errno_internal
函數設置errno
。 readelf -r
顯示__set_errno_internal
函數的以下重定位:
00000000000001a8 R_AARCH64_CONDBR19 __set_errno_internal
我想從C++中調用這段代碼,所以我將它轉換為緩沖區:
unsigned char machine_code[] __attribute__((section(".text"))) =
"\xe8\x09\x80\xd2"
"\x01\x00\x00\xd4"
"\x1f\x04\x40\xb1"
"\x00\x94\x80\xda"
"\x08\x00\x00\x54" // Here we have mentioned relocation
"\xc0\x03\x5f\xd6";
編輯:重要細節 - 我選擇使用緩沖區(不是內聯程序集等),因為我想在這個緩沖區上運行額外的處理(例如,字符串文字上的解密函數作為軟件保護機制,但這並不重要)在它被評估為之前機器碼。
之后,可以將緩沖區轉換為函數並直接調用以執行機器代碼。 很明顯relocation有問題,不是自動修復的,我必須手動修復。 但是在運行時我不能這樣做,因為.text
部分是只讀和可執行的。
盡管我幾乎可以完全控制源代碼,但我不能關閉堆棧保護和其他功能以使該部分可寫(不要問為什么)。 因此,似乎應該在鏈接階段以某種方式執行重定位修復。 據我所知,在鏈接器修復重定位后,共享庫包含相對偏移量(對於類似的外部函數調用),二進制 *.so 文件應包含正確的偏移量(無需運行時重定位工作),因此在此期間修復machine_code
緩沖區鏈接應該是可能的。
我正在使用手動構建的 Clang 7 編譯器,並且我可以完全控制 LLVM 傳遞,所以我想也許可以編寫某種在鏈接時執行的 LLVM 傳遞。 雖然看起來ld
最終被調用,所以也許 LLVM 通過在這里沒有幫助(這里不是專家)。
不同的想法也將不勝感激。 如您所見,問題非常復雜。 也許你有一些方向/想法如何解決這個問題? 謝謝!
已經有一個有效的打包機制來處理重定位。 它被稱為dlsym()
。 雖然它不直接給你一個函數指針,但所有主要的 C++ 編譯器都支持reinterpret_cast
將dlsym
的結果轉換為任何普通的函數指針。 (成員函數完全是另一個問題,但這與此處無關)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.