Dart逆向之函数调用

我们从Blutter恢复的部分IL中可以看到Dart调用函数的逻辑

// 0x180490: r16 = <int>
//     0x180490: ldr             x16, [PP, #0x8a0]  ; [pp+0x8a0] TypeArguments: <int>
// 0x180494: r30 = Instance_MethodChannel
//     0x180494: ldr             lr, [PP, #0x78c0]  ; [pp+0x78c0] Obj!MethodChannel@3719a1
// 0x180498: stp             lr, x16, [SP, #8]
// 0x18049c: r16 = "getBatteryLevel"
//     0x18049c: ldr             x16, [PP, #0x78c8]  ; [pp+0x78c8] "getBatteryLevel"
// 0x1804a0: str             x16, [SP]
// 0x1804a4: r4 = const [0x1, 0x2, 0x2, 0x2, null]
//     0x1804a4: ldr             x4, [PP, #0x58]  ; [pp+0x58] List(5) [0x1, 0x2, 0x2, 0x2, Null]
// 0x1804a8: r0 = invokeMethod()
//     0x1804a8: bl              #0x1805ac  ; [package:flutter/src/services/platform_channel.dart] MethodChannel::invokeMethod

这段汇编代码展示了在ARM64架构上,Dart如何准备并执行methodChannel.invokeMethod(‘getBatteryLevel’)方法调用的完整流程。
首先是加载类型参数,从对象池(PP)加载泛型类型参数到x16寄存器,这指定了invokeMethod返回值的类型

// 0x180490: r16 = <int>
//     0x180490: ldr             x16, [PP, #0x8a0]  ; [pp+0x8a0] TypeArguments: <int>

然后是加载第二个参数,从对象池加载MethodChannel实例到lr(x30)寄存器,这是调用方法的this指针

// 0x180494: r30 = Instance_MethodChannel
//     0x180494: ldr             lr, [PP, #0x78c0]  ; [pp+0x78c0] Obj!MethodChannel@3719a1

然后就是将参数放入栈中,这里同时压入两个栈,存储this和类型参数到SP+8位置

// 0x180498: stp             lr, x16, [SP, #8]

然后加载"getBatteryLevel"字符串,存储方法名到栈顶

// 0x18049c: r16 = "getBatteryLevel"
//     0x18049c: ldr             x16, [PP, #0x78c8]  ; [pp+0x78c8] "getBatteryLevel"
// 0x1804a0: str             x16, [SP]

这里遵循了Dart的ARM64调用约定:

  • 第一个参数(方法名)放在栈顶 [SP]
  • 第二个参数(this)放在 [SP+8]
  • 第三个参数(类型参数)放在 [SP+16] (由stp指令自动处理)
    然后在Dart的函数调用阶段需要加载并传入参数描述符 可以参考SDK的源码:runtime/vm/dart_entry.h
// 0x1804a4: r4 = const [0x1, 0x2, 0x2, 0x2, null]
//     0x1804a4: ldr             x4, [PP, #0x58]  ; [pp+0x58] List(5) [0x1, 0x2, 0x2, 0x2, Null]

这个关键数据结构描述了调用的元数据:

  • 0x1 - 有1个类型参数()
  • 0x2 - 总共有2个参数(方法名和this)
  • 0x2 - 参数大小(总共占用空间)
  • 0x2 - 位置参数数量
  • null - 没有命名参数
    最后调用函数
// 0x1804a8: r0 = invokeMethod()
//     0x1804a8: bl              #0x1805ac  ; [package:flutter/src/services/platform_channel.dart] MethodChannel::invokeMethod
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值