Frida Hook
Frida API介绍 : https://frida.re/docs/javascript-api/

Python + Javascript
Python代码作用是控制,写法固定,负责跟frida-server通信,把JS代码传递给fridaserver

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

改变程序执行流程的一种技术 在函数被调用前,通过HOOK技术,先得到该函数的控制权,实现该函数的逻辑改写

Hook 加密函数

案例1

import frida
import sys

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

jscode = """
function printstack(){
    send(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
}

// array 转 string
function array2string(array){
    var buffer = Java.array('byte', array);
    var result = "";
    for(var i=0; i<buffer.length; ++i){
        result += (String.fromCharCode(buffer[i]));
    }
    return result;
}

Java.perform(
    function(){
        var MessageDigest = Java.use('java.security.MessageDigest');
        
        MessageDigest.update.overload('[B').implementation = function(bytesarray){
            send('I am here 0:');
            send("ori:"+array2string(bytesarray));
            printstack();
            this.update(bytesarray);
        },
        MessageDigest.update.overload('byte').implementation = function(bytesarray){
            send('I am here 0:');
            send("ori:"+array2string(bytesarray));
            printstack();
            this.update(bytesarray);
        },
        MessageDigest.update.overload('[B', 'int', 'int').implementation = function(bytesarray){
            send('I am here 0:');
            send("ori:"+array2string(bytesarray));
            printstack();
            this.update(bytesarray);
        },
        MessageDigest.getInstance.overloads[0].implementation = function(algorithm){
            send("call -> getInstance for" + algorithm);
            printstack();
            return this.getInstance.overloads[0].apply(this, arguments);
        }
    }
);
"""

device = frida.get_remote_device()
# 先通过frida.add_remote_device来找到device,然后spawn方式启动settings,然后attach到上面,并执行frida脚本
pid = device.spawn('com.iCitySuzhou.suzhou001')
process = device.attach(pid)

script = process.create_script(jscode)
script.on('message', on_message)
print('[*] Runing CTF')
script.load()
device.resume(pid)
sys.stdin.read()

然后有几率会打印出加密字符串,可以看到是怎么加密的

下面还可以看到调用的栈

然后用 ApkTool 逆向,找到加密代码


案例2

import frida, sys


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


test='''
Java.perform(
    function(){
        console.log('i am coming')
        var MainActivity = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity')  // 类名
        MainActivity.onClick.implementation = function(v){  // 类名.函数.implementation  v 参数
            this.onClick(v)  // hook 之后要继续执行被 hook 的函数,以免影响正常执行流程
            console.log('mmm:'+this.m.value)
            console.log('nnn:'+this.n.value)
            
        }

        var TT = Java.use('com.example.seccon2015.rock_paper_scissors.MainActivity$1')
        TT.run.implementation = function(){

            this.this$0.value.m.value = 1  // 匿名类的成员变量名
            this.this$0.value.n.value = 2
            this.run()
        }
    }
)
'''


#两种启动方式

#启动方式1
process = frida.get_usb_device(-1).attach('com.example.seccon2015.rock_paper_scissors')  # 进程
script = process.create_script(test)  # 载入 hook 代码
script.on('message', on_message)
script.load()  #  执行
sys.stdin.read()  # 让程序不要断掉


#启动方式2 spawn 重启APP 可以hook APP启动阶段
# device = frida.get_usb_device(-1)
# pid = device.spawn(['com.example.seccon2015.rock_paper_scissors'])
# process = device.attach(pid)

# script = process.create_script(test)
# script.on('message', on_message)
# print('[*] Running')
# script.load()

# device.resume(pid)

# sys.stdin.read()

  1. attach 进程名 :APP启动后再hook,不能hook app启动阶段

  2. spawn :重启APP,适合hook app 启动阶段

淘宝 Hook

import frida, sys

hook_code = """
Java.perform(
    function(){
        var SwitchConfig = Java.use('mtopsdk.mtop.global.SwitchConfig')
        SwitchConfig.isGlobalSpdySwitchOpen.implementation = function(){
            // send('SwitchConfig')
            return false
        }
    }
)
"""

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

process = frida.get_remote_device().attach('com.taobao.taobao')
script = process.create_script(hook_code)
script.on('message', on_message)
script.load()
sys.stdin.read()

 posted on 2020-09-10 22:08  Rannie`  阅读(682)  评论(0编辑  收藏  举报
去除动画
找回动画