【Frida】【Android】03_RPC

发布于:2024-03-30 ⋅ 阅读:(66) ⋅ 点赞:(0)

🛫 系列文章导航

🛫 导读

开发环境

版本号 描述
文章日期 2024-03-24
操作系统 Win11 - 22H2 22621.2715
node -v v20.10.0
npm -v 10.2.3
夜神模拟器 7.0.5.8
Android 9
python 3.9.9
frida 16.2.1
frida-tools 12.3.0
objection 1.11.0

1️⃣ Android App解释

过Frida存在两种操作模式,其中第一种命令行模式在之前的章节中一直使用,在这一节中,将介绍一些关于RPC模式以及使用RPC完成自动化的相关知识。
在Frida中,可以使用Python完成JavaScript脚本对进程的注入以及相应的Hook。

Java示例代码

参考《【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446》,我们需要通过python代码完成下面两个任务:

  • 每次调用secret()函数对字符串进行扩展。
  • 获取total这个实例变量的值。

2️⃣ 注入的js代码

注意事项:

  • 整体逻辑,不用通过Java.perform(rpc测试)执行,该函数是通过对rpc.exports赋值,实现rpc的功能导出。
  • 由于目标不是静态变量,我们需要对实例进行操作,所以,需要使用Java.choose动态获取。
  • 导出的对象中,必须使用全小写作为key,否则python访问不到。

function rpc测试() {
  function CallSecretFunc(){
    Java.perform(function(){
      // 动态函数主动调用
      Java.choose('com.yemao.demo.MainActivity',{
        onMatch: function(instance){
          instance.secret()
        },
        onComplete: function(){
        }
      })
    })
  }
  function getTotalValue(){
    Java.perform(function(){
      // var MainAcitivity = Java.use('com.yemao.demo.MainActivity')
      // 动态函数主动调用
      Java.choose('com.yemao.demo.MainActivity',{
        onMatch: function(instance){
          //  console.log('instance found',instance)
          // instance.secret()
          console.log('total value = ',instance.total.value)
          // console.log('secret func exec success')
        },
        onComplete: function(){
          console.log('search Complete')
        }
      })
    })
  }
  rpc.exports = {
    gettotalvalue: getTotalValue,
    callfunc: CallSecretFunc,
    CallSecretFunc: CallSecretFunc
  }
}

rpc测试()

3️⃣ python控制端

  • 由于我们使用的是模拟器,需要使用frida.get_remote_device()获取设备对象device。对于真机,使用frida.get_usb_device()
  • 附加目标进程,使用的是device.attach,传参需要注意,一开始使用的是com.yemao.demo,没有效果。
    通过执行device.enumerate_processes(),打印所有进程,看到名称为demo,传递给device.attach才正常运行。
    在这里插入图片描述
  • 读取js时,需要指定编码encoding='utf-8',否则会报错的。
import frida

def on_message(message, data):
    if message['type'] == 'send':
        print("[*] {0}".format(message['payload']))
    else:
        print(message)


def main():
  # device = frida.get_usb_device()
  # device = frida.get_device_manager().add_remote_device('127.0.0.1:62025')
  device = frida.get_remote_device()
  print(device, device.enumerate_processes())
  # return

  # process = device.attach('com.yemao.demo')
  process = device.attach('demo')
  # process = device.attach('com.android.settings.intelligence')

  with open('./build/02.js', encoding='utf-8') as f:
      jscode = f.read()
  script = process.create_script(jscode)

  script.on('message', on_message)
  script.load()

  while True:
    command = input ("\nEnter command:\nl: Exit\n2: Call secret function\n3: Get Total Value\nchoice:")
    if command == "1":
      print('script.exports_sync = ', dir(script.exports_sync))
      break
    elif command== "2":#在这里调用
      script.exports_sync.callfunc()
    elif command == "3":
      script.exports_sync.gettotalvalue()
    elif command == "4":
      script.exports_sync.CallSecretFunc()

main()


4️⃣ 效果

测试流程:

  • 执行一次3: Get Total Value,获取修改前的total
  • 执行一次Call secret function,修改total
  • 再执行一次3: Get Total Value,获取修改后的total
    在这里插入图片描述

从图中可以看到,满足我们的预期,测试通过!!!

🛬 文章小结

  • 通过dir(script.exports_sync)可以打印所有的exports_sync内容['CallSecretFunc', 'callfunc', 'gettotalvalue'],这里面就是我们导出的三个函数。
    我们可以看到,其中是有区分大小写的方法CallSecretFunc的,但是如果通过rpc进行调用,又会报如下错误:
    在这里插入图片描述
    所以,命名上,我们只可以写小写的rpc函数

📖 参考资料

ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到