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<exports.length; i++){
        if(exports[i].name == "Java_com_example_hooktest_MainActivity_getString"){
            var getString = exports[i].address;
            send("getInt is at " + getString);
            break;
        }
    }
 
    var getInt = undefined;
    var exports = Module.enumerateExportsSync("libtest.so");
    for(i=0; i<exports.length; i++){
        if(exports[i].name == "getInt"){
            var getInt = exports[i].address;
            send("getInt is at " + getInt);
            break;
        }
    }
    var fungetInt = new NativeFunction(getInt, 'int', ['int']);
     
    Interceptor.attach(getString,{
        onEnter: function (args) {
                send("onEnter");
                var res = fungetInt(99999);
                send(res);
            },
            onLeave: function (retval) {
                       send("onLeave");
            }
 
         
    });
});
"""
 
def on_message(message, data):
        print message
script = session.create_script(jscode)
script.on('message', on_message)
script.load()
sys.stdin.read()

或者,例如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...");
    });
}

参考文章

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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 230,791评论 6 545
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 99,795评论 3 429
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 178,943评论 0 384
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 64,057评论 1 318
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 72,773评论 6 414
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 56,106评论 1 330
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 44,082评论 3 450
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 43,282评论 0 291
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 49,793评论 1 338
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 41,507评论 3 361
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 43,741评论 1 375
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 39,220评论 5 365
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 44,929评论 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 35,325评论 0 28
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 36,661评论 1 296
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 52,482评论 3 400
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 48,702评论 2 380

推荐阅读更多精彩内容