Frida实用代码片段

各种类型读取和转换

var String_java = Java.use('java.lang.String');
var args_4 = Java.cast(args[4], String_java);
send("get args[4] value: " + args_4);

一个封装过的:

function print_dump(addr,size){
    var buf = Memory.readByteArray(addr,size)
    console.log("[function] send[*] " + addr.toString() + "  "+ "length: " + size.toString() + "\n[data]")
    console.log(hexdump(buf, {
      offset: 0,
      length: size,
          header: false,
          ansi: false
    }));
    console.log("")
}

调用的时候类似print_dump(args[4], 100)即可,size传大些也行。

转int32

args[2].toInt32()

读取string

Memory.readUtf8String(args[0],23)

读取指针对应的字符串值(可以给地址加偏移)

Memory.readUtf8String(Memory.readPointer(securityCheck.sub(0x11a8).add(0x628c)))

创建调试进程并附加

device = frida.get_usb_device()
pid = device.spawn(["com.android.browser"])
print("PID: " + str(pid))
session = device.attach(pid)
device.resume(pid)

将调试信息写入文件日志

def on_message(message ,data):
    file_object=open("log.txt",'ab+')
    file_object.write(message['payload'].encode())
    file_object.write(data.split(b'\x00')[0])
    file_object.write('\n'.encode())
    file_object.close()

send函数的原型是send(message[, data]),第二个参数为data


可见第二个参数是需要ArrayBuffer类型的,而Memory.readByteArray(args[0],256)的返回值刚好是ArrayBuffer类型的,所以直接传值就可以。如果不是ArrayBuffer类型的怎么办,比如说文档中的hexdump(target[, options])函数,它的返回值不是ArrayBuffer类型的,那么我们就需要利用下面的函数来转换:

function str2ab(str) {
            var buf = new ArrayBuffer(str.length); // 1 bytes for each char
            var bufView = new Uint8Array(buf);
            for (var i=0, strLen=str.length; i < strLen; i++) {
                bufView[i] = str.charCodeAt(i);
                }
            return buf;
        }

注入so层

#coding=utf-8
import frida
import sys
session = frida.get_remote_device().attach("com.example.hooktest")
#print session.enumerate_modules()
 
jscode = """
Java.perform(function(){
    send("Running Script");
  
    var getString = undefined;
    var i = undefined;
    var exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i

或者,例如hook在libc中的open函数:

setImmediate(function() {
Interceptor.attach(Module.findExportByName("libc.so" , "open"), {
    onEnter: function(args) {
    log('open(pathname='+Memory.readUtf8String(args[0])+") flag: "+args[1]);
    },
    onLeave:function(retval){
    
    }
});
});

在这里,读取内存还可以用Memory.readByteArray(args[0],256),例如send("open called! args[0]:",Memory.readByteArray(args[0],256));

获取(遍历)so层的导入导出函数地址

  • 方法一:
var exports = Module.enumerateExportsSync("libnative-lib.so");
    for (i = 0; i < exports.length; i++) {
        if (exports[i].name == "Java_com_iscc_crackme_MainActivity_checkSecond") {
            checkSecond = exports[i].address;
            //console.log(checkSecond);
            send("checkSecond is at " + checkSecond);
            break;
        }
    }
  • 方法二:
var chat = Module.findExportByName("libGameLogic.so", "_ZN6Player4ChatEPKc");
         console.log("Player::Chat() at  address: " + chat);
 
         Interceptor.attach(chat, {
             onEnter: function (args) { // 0 => this; 1 => cont char* (our text)
                var chatMsg = Memory.readCString(args[1]);
                console.log("[Chat]: " + chatMsg);
             }
 
         });

修改so中变量或内存

//Get base address of library
var libfoo = Module.findBaseAddress("libfoo.so");
//Calculate address of variable
var initialized = libfoo.add(ptr("0x400C"));
//Write 1 to the variable
Memory.writeInt(initialized,1);

反反调试

此处hook掉exit的调用

Java.perform(function() {
        exitClass = Java.use("java.lang.System");
        exitClass.exit.implementation = function() {
            console.log("[*] System.exit called");
        }
        console.log("[*] Hooking calls to System.exit");
    });

获取程序所有模块并打印

def on_message(message, data):
    print("[on_message] message:", message, "data:", data)


# session = frida.attach("notepad.exe")

session = frida.get_remote_device().attach('com.iscc.crackme')
script = session.create_script("""'use strict';

rpc.exports.enumerateModules = function () {
return Process.enumerateModulesSync();
};
""")
script.on("message", on_message)
script.load()
print([m["name"] for m in script.exports.enumerate_modules()])

C++ demangle

# Extract exports & demangle it
 
import frida
import cxxfilt
 
 
session = frida.attach("PwnAdventure3-Linux-Shipping")
script = session.create_script("""
    var exports = Module.enumerateExportsSync("libGameLogic.so");
    for (i = 0; i < exports.length; i++) {
        send(exports[i].name);
    }
        """);
 
def on_message(message, data):
    print message["payload"] + " - " + cxxfilt.demangle(message["payload"])
 
script.on('message', on_message)
script.load()

Hook okhttp3.Interceptor

function hook_okhttp3() {
    Java.perform(function () {
        var ByteString = Java.use("com.android.okhttp.okio.ByteString");
        var Buffer = Java.use("com.android.okhttp.okio.Buffer");
        var Interceptor = Java.use("okhttp3.Interceptor");
        var MyInterceptor = Java.registerClass({
            name: "okhttp3.MyInterceptor",
            implements: [Interceptor],
            methods: {
                intercept: function (chain) {
                    var request = chain.request();
                    try {
                        console.log("MyInterceptor.intercept onEnter:", request, "\nrequest headers:\n", request.headers());
                        var requestBody = request.body();
                        var contentLength = requestBody ? requestBody.contentLength() : 0;
                        if (contentLength > 0) {
                            var BufferObj = Buffer.$new();
                            requestBody.writeTo(BufferObj);
                            try {
                                console.log("\nrequest body String:\n", BufferObj.readString(), "\n");
                            } catch (error) {
                                try {
                                    console.log("\nrequest body ByteString:\n", ByteString.of(BufferObj.readByteArray()).hex(), "\n");
                                } catch (error) {
                                    console.log("error 1:", error);
                                }
                            }
                        }
                    } catch (error) {
                        console.log("error 2:", error);
                    }
                    var response = chain.proceed(request);
                    try {
                        console.log("MyInterceptor.intercept onLeave:", response, "\nresponse headers:\n", response.headers());
                        var responseBody = response.body();
                        var contentLength = responseBody ? responseBody.contentLength() : 0;
                        if (contentLength > 0) {
                            console.log("\nresponsecontentLength:", contentLength, "responseBody:", responseBody, "\n");
 
                            var ContentType = response.headers().get("Content-Type");
                            console.log("ContentType:", ContentType);
                            if (ContentType.indexOf("video") == -1) {
                                if (ContentType.indexOf("application") == 0) {
                                    var source = responseBody.source();
                                    if (ContentType.indexOf("application/zip") != 0) {
                                        try {
                                            console.log("\nresponse.body StringClass\n", source.readUtf8(), "\n");
                                        } catch (error) {
                                            try {
                                                console.log("\nresponse.body ByteString\n", source.readByteString().hex(), "\n");
                                            } catch (error) {
                                                console.log("error 4:", error);
                                            }
                                        }
                                    }
                                }
 
                            }
 
                        }
 
                    } catch (error) {
                        console.log("error 3:", error);
                    }
                    return response;
                }
            }
        });
        var ArrayList = Java.use("java.util.ArrayList");
        var OkHttpClient = Java.use("okhttp3.OkHttpClient");
        console.log(OkHttpClient);
        OkHttpClient.$init.overload('okhttp3.OkHttpClient$Builder').implementation = function (Builder) {
            console.log("OkHttpClient.$init:", this, Java.cast(Builder.interceptors(), ArrayList));
            this.$init(Builder);
        };
 
        var MyInterceptorObj = MyInterceptor.$new();
        var Builder = Java.use("okhttp3.OkHttpClient$Builder");
        console.log(Builder);
        Builder.build.implementation = function () {
            this.interceptors().clear();
            //var MyInterceptorObj = MyInterceptor.$new();
            this.interceptors().add(MyInterceptorObj);
            var result = this.build();
            return result;
        };
 
        Builder.addInterceptor.implementation = function (interceptor) {
            this.interceptors().clear();
            //var MyInterceptorObj = MyInterceptor.$new();
            this.interceptors().add(MyInterceptorObj);
            return this;
            //return this.addInterceptor(interceptor);
        };
 
        console.log("hook_okhttp3...");
    });
}

参考文章

https://www.jianshu.com/p/b833fba1bffe
https://bbs.pediy.com/thread-217424.htm
https://bbs.pediy.com/thread-252129.htm

你可能感兴趣的:(Frida实用代码片段)