You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改ARM64二进制文件替换所有函数调用至指定函数以实现调用日志

替换ARM64二进制中所有函数调用为自定义跟踪函数的方案

要实现给所有函数调用插入日志并转发的功能,需要分二进制指令修改和自定义跟踪函数实现两部分完成,以下是具体步骤:

一、核心思路

把原二进制中所有的直接/间接函数调用(bl/blr指令),修改为调用自定义的my_func,同时把原目标函数的地址传递给my_func;my_func负责打印调用日志,再转发调用到原目标函数,最后返回原函数的结果。

二、二进制指令修改

1. 直接调用(bl target)的替换

原ARM64汇编的直接函数调用是单条bl指令,需要替换为加载原目标地址到临时寄存器+**调用my_func**的两条指令:

; 原指令
bl      bar

; 修改后
adr     x16, bar  ; 用相对寻址把bar的地址加载到x16(x16是调用者可临时使用的寄存器)
bl      my_func

注:如果是PIE(位置无关可执行文件),adr可以正确加载相对地址;如果是非PIE,也可以用ldr x16, =bar加载绝对地址。

2. 间接调用(blr xN)的替换

对于通过函数指针的间接调用,需要先把函数指针的值保存到临时寄存器,再调用my_func:

; 原指令
blr     x0

; 修改后
mov     x16, x0   ; 把原函数指针地址存到x16
bl      my_func

3. 工具实现方式

可以用以下工具批量修改二进制:

  • IDA Pro/Ghidra:编写脚本遍历所有函数调用指令,自动替换为上述指令序列;注意需要处理指令长度变化(单条4字节指令变两条8字节),如果原位置没有空间,需要把指令移到空闲区域(比如段末尾的padding),再修改跳转。
  • radare2:用命令行脚本遍历所有bl/blr指令,通过asm命令替换为目标指令。

三、my_func的汇编实现(适配ARM64调用约定)

由于ARM64采用寄存器传参的调用约定,直接用C++模板无法完美适配(无法直接捕获所有寄存器参数),因此需要用汇编实现my_func,保证参数和寄存器状态的正确传递:

.global my_func
.type my_func, %function

my_func:
    ; 保存调用者保存的寄存器(ARM64约定x29/x30为callee-saved,需保存)
    stp     x29, x30, [sp, #-16]!
    mov     x29, sp

    ; 打印原函数地址日志
    adr     x0, fmt_str   ; 格式化字符串地址作为printf的第一个参数
    mov     x1, x16       ; 原函数地址作为printf的第二个参数
    bl      printf        ; 调用printf打印日志

    ; 转发调用到原函数:原参数已在x0-x7,直接用blr跳转
    blr     x16

    ; 恢复寄存器并返回
    ldp     x29, x30, [sp], #16
    ret

fmt_str:
    .asciz  "calling: %p\n"

实现说明

  • 用x16传递原函数地址:x16属于ARM64的临时寄存器,调用者可以自由使用,不需要被my_func保存/恢复。
  • 参数转发:原函数的输入参数已经在x0-x7寄存器中,blr x16会直接使用这些寄存器调用原函数,无需额外处理。
  • 返回值传递:原函数的返回值会存在x0-x3中,ret指令会直接把这些值返回给上层调用者,保证逻辑一致。

四、注意事项

  • 栈对齐:ARM64要求栈始终保持16字节对齐,修改指令时要确保栈操作(如stp/ldp)符合对齐要求。
  • PIE/非PIE适配:加载原函数地址时,根据二进制类型选择adr(相对寻址,适配PIE)或ldr(绝对寻址,非PIE)。
  • 异常处理:汇编实现的my_func会保留原函数的栈帧结构,因此原函数抛出的异常可以正常向上传递。
  • 性能开销:每个函数调用都会增加一次跳转和日志打印,仅适合调试场景,不建议在生产环境使用。

内容的提问来源于stack exchange,提问作者A. K.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 02:40:26