欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 资讯 > Dart逆向之函数调用

Dart逆向之函数调用

2025/5/20 2:47:35 来源:https://blog.csdn.net/kelxLZ/article/details/147129711  浏览:    关键词: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

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词