Firda基础命令和脚本入门 APP 逆向系列

1、常用命令

adb connect 127.0.0.1:62001 连接设备

adb shell 进入shell

adb kill-server 关闭服务

adb start-server 关闭服务

adb reboot 重启服务

adb forwardtcp:27042 tcp:27042 端口转发

adb shelldumpsys activity top 查看APK包名

frida-ls-devices 列出所有连接计算机的设备

frida-ps -U 查看正在运行进程

frida-ps -Uai 列出安装的程序

frida-ps -Ua 列出运行中的程序

frida-ps -D "设备ID" 连接frida到指定设备

frida-trace-U -f Name-i "函数名" 跟踪某个函数

frida-trace-U -f Name-m "方法名" 跟踪某个方法

frida-U -l name.js "进程ID" 加载js脚本

frida-discover-n Name 发现程序内部函数

frida-discover-p pid 发现程序内部函数

frida-kill -U "进程ID" 结束进程

2、Hook的基本语法

setTimeout(
    function(){
        Java.perform(function(){
            console.log("Hello world")
        })
    }
)

3、注入指定 js 文件 -U参数是指USB设备 -l参数用于指定注入脚本所在路径 最后是进程名

frida -U -l hello_world.js com.android.keychain

4、查看frida版本

frida --version

5、通过friad的cli模式以attach模式注入(不带改变参数)

function main(){
    console.log("脚本加载开始......")
    Java.perform(function(){
        console.log("内部java注入开始......")
        var MainActivity = Java.use('com.example.demo01.MainActivity')
        console.log("定位类成功......")
        MainActivity.fun.implementation = function(x,y){
            console.log("x => ", x, "y => ", y)
            var ret_value = this.fun(x,y);
            return ret_value
        }
    })
}
setImmediate(main)

6、通过friad的cli模式以attach模式注入(改变参数)

function main() {
    console.log("脚本加载开始......")
    Java.perform(function () {
        console.log("内部java注入开始......")
        var MainActivity = Java.use('com.example.demo01.MainActivity')
        console.log("定位类成功......")
        MainActivity.fun.implementation = function (x, y) {
            console.log("x => ", x, "y => ", y)
            var ret_value = this.fun(10, 1);
            return ret_value
        }
    })
}
setImmediate(main)

7、通过friad的cli模式以attach模式注入(方法重载就是有两个一样的方法如何hook)

function main() {
    console.log("脚本加载开始......")
    Java.perform(function () {
        console.log("内部java注入开始......")
        var MainActivity = Java.use('com.example.demo01.MainActivity')
        console.log("定位类成功......")
        //重载方法测试
        MainActivity.fun.overload('int', 'int').implementation = function (x, y) {
            console.log("x => ", x, "y => ", y)
            var ret_value = this.fun(133, 1);
            return ret_value
        }
    })
}
setImmediate(main)

8、java层主动调用(概念:主动调用就是强制一个函数去执行,被动调用就是按照app的正常逻辑去执行函数,函数的执行完全依靠与用户完成交互逻辑从而间接完成到关键函数,而主动调用则可以主动直接调用到关键行函数主动性更强),载java中函数可分为两种:类函数和实力方法,就是静态的方法和动态的方法,类函数使用关键字static修饰和对应的类是绑定的如果类函数还是被public关键词修饰的在外部就可以直接通过类去掉用,实例方法则是没有关键词static关键词修饰在外部只能通过创建对应类的实例在通过实例去访问,在frida中的主动调用的类型会根据方法类型区分开,如果是类函数的主动调用直接使用java.use()函数找到类去进行调用就可,如果是实例方法的主动调用则需要找到对应的实例后对方法进行调用,这里用到了非常重要的一个api函数java.choose()这个函数可以找到java堆中寻找制定类的实例。

function main() {
    console.log("脚本加载开始......")
    Java.perform(function () {
        console.log("内部java注入开始......")
        //静态函数主动调用
        var MainActivity = Java.use('com.example.demo01.MainActivity')
        MainActivity.staticSecret()

        //动态函数主动调用
        Java.choose('com.example.demo01.MainActivity', {
            onMatch: function(instance){
                console.log("instance found", instance)
                instance.secret()
            },
            onComplete: function(){
                console.log('search onComplete')
            }
        })
    })
}
setImmediate(main)

9、rpc及自动化

js Hook 文件 hook_demo01_rpc.js

function CallSecretFunc(){
    Java.perform(function(){

        //动态函数主动调用
        Java.choose('com.example.demo01.MainActivity', {
            onMatch: function(instance){
                instance.secret()
            },
            onComplete: function(){

            }
        })
    })
}

function getTotalValue(){
    Java.perform(function(){
        console.log("内部java注入开始......")
        var MainActivity = Java.use('com.example.demo01.MainActivity')

        //动态函数主动调用
        Java.choose('com.example.demo01.MainActivity',{
            onMatch: function(instance){
                console.log("total value = ", instance.total.value)
            },
            onComplete: function(){
                console.log('search Complete')
            }
        })
    })
}

//setImmediate(getTotalValue)

//rpc导出函数用于使用
rpc.exports = {
    callsecretfunc: CallSecretFunc,
    gettotalvalue: getTotalValue
}

python 文件加载js文件最终实现RPC

#!/usr/bin/python
# -*- coding:utf-8 -*-
import sys
import frida

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


devices = frida.get_usb_device()
process = devices.attach('demo01')

with open('hook_demo01_rpc.js') as f:
    jscode = f.read()


script = process.create_script(jscode)
script.on('message', on_message)
script.load()


command = ''
while 1 == 1:
    command = input("\nEnter command:\n1: Exit \n2:Call secret function \n3: Get Total Value \nchoice:")
    if command == "1":
        break
    elif command == "2": #在这里调用
        script.exports.callsecretfunc()
    elif command == "3":
        script.exports.gettotalvalue()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值