簡體   English   中英

從 C++ 重定位動態執行的 ARM ASM 系統調用

[英]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_castdlsym的結果轉換為任何普通的函數指針。 (成員函數完全是另一個問題,但這與此處無關)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM