当前位置: 首页 > news >正文

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

相关文章:

  • 做游戏赚钱的网站深圳网络推广服务是什么
  • 凡科做的网站怎么改壁纸百度权重3的网站值多少
  • java做网站开发成本高怎样查询百度收录和排名情况
  • 如今做哪些网站能致富今日关注
  • 网站开发功能表百度查询入口
  • 网站建设和软件开发哪个有前途全国疫情最新情况
  • AI | 字节跳动 AI 中文IDE编辑器 Trae 初体验
  • java线程安全-单例模式-线程通信
  • Python刷题笔记
  • Laravel 实现 队列 发送邮件功能
  • IP证书的作用与应用:保障数字身份与通信安全
  • Docker MySQL的主从同步 数据备份 数据同步 配置文件
  • C++学习之ORACLE①
  • 基于flask+vue框架的助贫公益募捐管理系统1i6pi(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
  • BUUCTF-web刷题篇(18)
  • Python设计模式-单例模式
  • 【华为战报】2025年3月 考试战报!
  • 消息队列(IPC技术)
  • 需求获取全攻略
  • PostGIS 常用处理空间函数
  • 文章记单词 | 第26篇(六级)
  • MySQL行列转换
  • 数据泄露与防范
  • C++进阶——C++11_右值引用和移动语义_可变参数模板_类的新功能
  • window部署虚拟机VirtualBox来部署flink
  • 网络机顶盒怎么连接WiFi-机顶盒连接wifi攻略,轻松畅享网络视听