app逆向(8)| frida和frida-rpc

文章目录

  • 一、frida和frida-rpc
    • 1.简单介绍
    • 2.安装frida
  • 二、了解app的hook
    • 1.hook能干嘛
    • 2.frida中使用implementation进行hook
    • 3.hook分析加密值的注意事项
    • 4.使用implementation进行hook的案例
    • 5.这里简单使用一下frida-rpc

一、frida和frida-rpc

1.简单介绍

  • frida是一款轻量级逆向HOOK框架,可用于多平台上,例如android、windows、ios等。
  • frida分为两部分,服务端运行在目标机上,通过注入进程的方式来实现劫持应用函数,另一部分运行在系统机器上。
  • frida上层接口支持js、python、c等
  • frida官方github地址为:https://github.com/frida

Frida 常用模块API:

  • Java 模块:Hook Java 层的类 方法 相关
  • Process 模块:处理当前线程相关
  • Interceptor 模块:操作指针相关,多用来Hook Native 相关
  • Memory 模块:内存操作相关
  • Module 模块:处理so相关

2.安装frida

1. 安装python3.7以上版本,并安装frida和frida-tools。

pip install frida
pip install frida-tools

2. 在手机上下载frida-sever端,官方下载地址:https://github.com/frida/frida/releases,下载时要选择对应的版本下载,例如我的机器为arm64位架构,就选择frida-server-15.1.11-android-arm64.xz下载

# 查看手机架构
adb shell 
su
getprop ro.product.cpu.abi

app逆向(8)| frida和frida-rpc_第1张图片

3. 将第四步下载好的文件解压,名字修改为frida-server,然后通过命令adb push 电脑存放位置 /data/local/tmp将文件传输到手机中,然后通过adb shell进入手机端,给文件赋权777,并于root权限启动。

在这里插入图片描述

# 然后进入手机
adb shell
su 
cd /data/local/tmp
chmod 777 frida-server

4. 启动frida,执行未输出任何东西,表示执行成功

./fridaserver1280_32
./fridaserver1280_32&   (以后台模式运行)

5. 启动frida-server之后, 再打开一个cmd窗口,通过命令转发tcp端口 (端口转发, 将设备信息端口转发至PC端)

adb forward tcp:27043 tcp:27043
adb forward tcp:27042 tcp:27042

6.执行frida-ps -U
app逆向(8)| frida和frida-rpc_第2张图片
app逆向(8)| frida和frida-rpc_第3张图片

二、了解app的hook

1.hook能干嘛

功能:不改变代码功能的前提下,捕获要用的代码,获取要用的信息。hook一般hook两层:

  • Java层
  • Native层(so层),汇编代码,难度较大

2.frida中使用implementation进行hook

# -*- coding: utf-8 -*-
import sys
import frida


def on_message(message, data):
    if message["type"] == "send":  # 当通过send函数发送时,会打印至控制台
        print(u"[*] {0}".format(message["payload"]))
    else:
        print(message)

jsCode = """
Java.perform(
            function(){
                java.use("com.me.world").check.implentation = function (v1,v2){
                	return False;
                	}
                }
            )   
"""

process = frida.get_remote_device().attach("com.taobao.taobao")  # 标准端口 使用包名 该包名通过frida-ps -U 获取

script = process.create_script(jsCode)  # 识别JS字符串
script.on("message", on_message)  # 输出 打印
script.load()  # 加载  注入
sys.stdin.read()  # 程序等待, 防止程序结束
# -------------------------------------------------------------------------------
# 如果我们想要在app启动的时候就想hook到某个函数,将上述的代码改成如下
# 前提也需要将APP启动,只不过后面有函数会让app重启
device = frida.get_remote_device()
pid = device.spawn("com.yaotong.crackme") # 获取进程id
process = device.attach(pid)

script = process.create_script(jsCode)
script.on("message", on_message)
script.load()
device.resume(pid)   表示app重启
sys.stdin.read()

其中jsCode中的函数有一些是固定写法,分别代表

Java.perform(匿名函数)
var MainActivity=Java.use(app类名)
MainActivity.方法名.implementation = function(){}   hook这个类中的函数

由于在JAVA中有函数重载,即函数名相同,传入参数类型不同或者数量不同,执行的函数也不同,因此在面对这种情况,hook的时候需要找到自己究竟要hook哪个函数

例如Overloading.java 有两个test函数

public class Overloading {
    public int test(){
        System.out.println("test1");
        return 1;
    }
 
    public void test(int a){
        System.out.println("test2");
    }   
}

如果直接调用会报错
app逆向(8)| frida和frida-rpc_第4张图片

这种情况hook就需要指定是哪一个函数,在overload里传参数代表hook哪一个

jsCode = """
	Java.perfom(
	     function(){
	     	// 无参数的test
	        java.use("Overloading").test.overload().implentation = function (){};
	        
	        // 有参数的test
			java.use("Overloading").test.overload(a).implentation = function (a){};
	           }
	       )   
"""

3.hook分析加密值的注意事项

正常分析app加密值的逻辑

  • 反编译app(加固需要脱壳)
  • 通过 关键字/其他手段 定位到加密值的地方
  • 分析如何加密

反向分析app加密值的逻辑

  • 无论加密值怎么变化,通常是调用常见的加密算法(md5,rsa,base64等等)

  • 那么我们直接hook底层加密算法,并在hook的时候进行堆栈打印,这样就可以知道哪个方法调用了加密操作,然后找到该方法

    // 打印调用栈
    function print_stack(){
        	   send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Excepetion").$new()));
    }
    
    

进行hook操作需要注意

  • 尽量不要改写原来的方法流程逻辑,执行完自己的操作以后,别忘了调用本身

    this.function()
    

4.使用implementation进行hook的案例

安装该app到手机:http://www.downcc.com/soft/276877.html
安装app后进入app,会提示输入手机号,然后输入一个手机号,点击下一步,进行抓包

app逆向(8)| frida和frida-rpc_第5张图片
抓包后,我们看一下参数

{"phone":"15811223344","sign":"BE1B05B2ED7689457F9DCE74E4F8C743","currTime":"20220818161311","type":"1"}

看到里边生成了一个sign,然后我们用jadx反编译一下该app,该app是无壳的,然后我们搜一下getSmscode

app逆向(8)| frida和frida-rpc_第6张图片

进入代码后看到
app逆向(8)| frida和frida-rpc_第7张图片
sign值是

HttpUtils.getStringMD5toUpperCase(yyyyMMddHHmmss + i + str + str2);
而四个值分别是:  日期格式化 + type + str + 手机号
看样子是进行拼接后,然后好像进行md5

str是传入的值,因此我们需要知道str是什么,这里使用frida抓一下

打开cmd窗口开启frida-server
app逆向(8)| frida和frida-rpc_第8张图片
再卡开另一个cmd,进行转发
在这里插入图片描述
然后构造python代码

# -*- coding: utf-8 -*-
import sys
import frida


def on_message(message, data):
    if message["type"] == "send":  # 当通过send函数发送时,会打印至控制台
        print(u"[*] {0}".format(message["payload"]))
    else:
        print(message)


jsCode = """
Java.perform(
    function () {
        var MainActivity = Java.use('com.jx885.library.http.CommAction');
        MainActivity.getSmscode.implementation = function (arg1,arg2,arg3) {
            console.log(arg1,arg2,arg3);
            return this.getSmscode(arg1,arg2,arg3);
        }      
    });
"""

process = frida.get_remote_device().attach("驾培创业教练")  # 标准端口 使用包名 该包名通过frida-ps -U 获取
script = process.create_script(jsCode)  # 识别JS字符串
script.on("message", on_message)  # 输出 打印
script.load()  # 加载  注入
sys.stdin.read()  # 程序等待, 防止程序结束

重启app,运行代码,输入手机号,点击下一步,我们看到刚才的str串结果是wocaonima,然后我们将刚才的值拼接一下

日期格式化 + type + str + 手机号
202208181613111wocaonima15811223344

找个网站md5一下,发现和刚开始的值吻合
app逆向(8)| frida和frida-rpc_第9张图片
这里我们有两种方式得出结果

  1. 自己拼接,然后python进行md5加密
  2. 使用frida-rpc进行自动调取手机app中的md5

5.这里简单使用一下frida-rpc

我们不通过app触发得到结果,我们主动调用的方式一般就是frida-rpc解决。

进入该方法
app逆向(8)| frida和frida-rpc_第10张图片

然后修改代码,变为主动调用app里的md5方法

# -*- coding: utf-8 -*-
import sys
import frida


def on_message(message, data):
    if message["type"] == "send":  # 当通过send函数发送时,会打印至控制台
        print(u"[*] {0}".format(message["payload"]))
    else:
        print(message)


jsCode = """
var sign = function (s) {
    var result = '';
    Java.perform(function () {
        result = Java.use('com.jx885.library.http.network.HttpUtils').getStringMD5toUpperCase(s);
    });
    return result;
};

rpc.exports = {
    getsign: sign
};
"""

process = frida.get_remote_device().attach("驾培创业教练")  # 标准端口 使用包名 该包名通过frida-ps -U 获取
script = process.create_script(jsCode)  # 识别JS字符串
script.on("message", on_message)  # 输出 打印
script.load()  # 加载  注入

yyyyMMddHHmmss = '20220818161311'
i = '1'
str_1 = 'wocaonima'
str_2 = '15811223344'
s = yyyyMMddHHmmss + i + str_1 + str_2
sign = script.exports.getsign(s)
print(sign)

运行
app逆向(8)| frida和frida-rpc_第11张图片

你可能感兴趣的:(APP逆向,rpc,android,网络协议)