内容简介:FRIDA 实用手册本文目的是作为工具类文章,收集整理了一些 FRIDA 的使用技巧和用例,方便同学们在开发使用过程中开袋即食。frida 的基础教程可以直接参看官网说明。
FRIDA 实用手册
本文目的是作为 工具 类文章,收集整理了一些 FRIDA 的使用技巧和用例,方便同学们在开发使用过程中开袋即食。
frida 的基础教程可以直接参看官网说明。
Python 部分
JS 中文支持
使用 codecs.open(scriptpath, "r", "utf-8") 打开文件读取 js 即可。
获取指定 UID 设备
device = frida.get_device_manager().get_device("094fdb0a0b0df7f8")
获取远程设备
mgr = frida.get_device_manager()
device = mgr.add_remote_device("30.137.25.128:13355")
启动调试进程
pid = device.spawn([packename])
process = device.attach(pid)
script = process.create_script(jscode)
script.on('message', on_message)
script.load()
device.resume(pid)
python 与 js 交互的官方示例
from future import print_function
import frida
import sys
session = frida.attach("hello")
script = session.create_script("""
Interceptor.attach(ptr("%s"), {
onEnter: function(args) {
send(args[0].toString());
var op = recv('input', function(value) {
args[0] = ptr(value.payload);
});
op.wait();
}
});
""" % int(sys.argv[1], 16))
def on_message(message, data):
print(message)
val = int(message['payload'], 16)
script.post({'type': 'input', 'payload': str(val * 2)})
script.on('message', on_message)
script.load()
sys.stdin.read()
从 bytecode 加载脚本
- - coding: utf-8 - -
from future import print_function
import frida
system_session = frida.attach(0)
bytecode = system_session.compile_script(name="bytecode-example", source="""\
'use strict';
rpc.exports = {
listThreads: function () {
return Process.enumerateThreadsSync();
}
};
""")
session = frida.attach("Twitter")
script = session.create_script_from_bytes(bytecode)
script.load()
api = script.exports
这里的 list_threads 是 listThreads 驼峰命名法自动转换后的结果,由 rpc exports 功能导出给 python 调用
print("api.list_threads() =>", api.list_threads())
JS 部分
hook Android 短信发送 SendDataMessage
function hook_sms() {
var SmsManager = Java.use('android.telephony.SmsManager');
SmsManager.sendDataMessage.implementation = function (
destinationAddress, scAddress, destinationPort, data, sentIntent, deliveryIntent) {
console.log("sendDataMessage destinationAddress: " + destinationAddress + " port: " + destinationPort);
showStacks();
this.sendDataMessage(destinationAddress, scAddress, destinationPort, data, sentIntent, deliveryIntent);
}
}
定时执行函数
setTimeout 延迟执行一次
setTimeout(funcA, 15000);
setInterval 间隔循环执行
var id_ = setInterval(funcB, 15000);
clearInterval(id_); // 终止
bin array 转字符串
function bin2String(array) {
if (null == array) {
return "null";
}
var result = "";
try {
var String_java = Java.use('java.lang.String');
result = String_java.$new(array);
}
catch (e) {
dmLogout("== use bin2String_2 ==");
result = bin2String_2(array);
}
return result;
}
function bin2String_2(array) {
var result = "";
try {
var tmp = 0;
for (var i = 0; i < array.length; i++) {
tmp = parseInt(array[i]);
if ( tmp == 0xc0
|| (tmp < 32 && tmp != 10)
|| tmp > 126 ) {
return result;
} // 不是可见字符就返回了, 换行符除外
result += String.fromCharCode(parseInt(array[i].toString(2), 2));
}
}
catch (e) {
console.log(e);
}
return result;
}
自己封装输出函数加入线程ID 和时间
function getFormatDate() {
var date = new Date();
var month = date.getMonth() + 1;
var strDate = date.getDate();
if (month >= 1 && month <= 9) {
month = "0" + month;
}
if (strDate >= 0 && strDate <= 9) {
strDate = "0" + strDate;
}
var currentDate = date.getFullYear() + "-" + month + "-" + strDate
+ " " + date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
return currentDate;
}
function dmLogout(str) {
var threadid = Process.getCurrentThreadId();
console.log("["+threadid+"][" + getFormatDate() + "]" + str);
}
打印 Android Java 层堆栈
var showStacks = function () {
Java.perform(function () {
dmLogout(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new())); // 打印堆栈
});
}
TracerPid fgets 反调试
var anti_fgets = function () {
dmLogout("anti_fgets");
var fgetsPtr = Module.findExportByName("libc.so", "fgets");
var fgets = new NativeFunction(fgetsPtr, 'pointer', ['pointer', 'int', 'pointer']);
Interceptor.replace(fgetsPtr, new NativeCallback(function (buffer, size, fp) {
var retval = fgets(buffer, size, fp);
var bufstr = Memory.readUtf8String(buffer);
if (bufstr.indexOf("TracerPid:") > -1) {
Memory.writeUtf8String(buffer, "TracerPid:\t0");
// dmLogout("tracerpid replaced: " + Memory.readUtf8String(buffer));
}
return retval;
}, 'pointer', ['pointer', 'int', 'pointer']));
};
反调试时读取 LR 寄存器溯源
var anti_antiDebug = function() {
var funcPtr = null;
funcPtr = Module.findExportByName("xxxx.so", "p57F7418DCD0C22CD8909F9B22F0991D3");
dmLogout("anti_antiDebug " + funcPtr);
Interceptor.replace(funcPtr, new NativeCallback(function (pathPtr, flags) {
dmLogout("anti ddddddddddddddebug LR: " + this.context.lr);
return 0;
}, 'int', ['int', 'int']));
};
hook JNI API NewStringUTF
function hook_native_newString() {
var env = Java.vm.getEnv();
var handlePointer = Memory.readPointer(env.handle);
dmLogout("env handle: " + handlePointer);
var NewStringUTFPtr = Memory.readPointer(handlePointer.add(0x29C));
dmLogout("NewStringUTFPtr addr: " + NewStringUTFPtr);
Interceptor.attach(NewStringUTFPtr, {
onEnter: function (args) {
...
}
});
}
hook JNI API GetStringUTFChars
function hook_native_GetStringUTFChars() {
var env = Java.vm.getEnv();
var handlePointer = Memory.readPointer(env.handle);
dmLogout("env handle: " + handlePointer);
var GetStringUTFCharsPtr = Memory.readPointer(handlePointer.add(0x2A4));
dmLogout("GetStringUTFCharsPtr addr: " + GetStringUTFCharsPtr);
Interceptor.attach(GetStringUTFCharsPtr, {
onEnter: function (args) {
var str = "";
Java.perform(function () {
str = Java.cast(args[1], Java.use('java.lang.String'));
});
dmLogout("GetStringUTFChars: " + str);
if (str.indexOf("linkData:") > -1) { // 设置过滤条件
dmLogout("========== found linkData LR: " + this.context.lr + " ==========");
}
}
});
};
循环输出参数的值
Interceptor.attach(Module.findExportByName("libc.so", "strcat"), {
onEnter: function (args) {
for (var i = 0; i < args.length; i ++) {
dmLogout("strcat args[" + i + "](" + ptr(args[i]) + "): " + Memory.readUtf8String(args[i]));
}
}
});
hook Android URI 打印堆栈
var hook_uri = function() {
// coord: (7520,0,19) | addr: Ljava/net/URI;->parseURI(Ljava/lang/String;Z)V | loc: ?
var uri = Java.use('java.net.URI');
uri.parseURI.implementation = function (a1, a2) {
a1 = a1.replace("xxxx.com", "yyyy.com");
dmLogout("uri: " + a1);
showStacks();
return this.parseURI(a1, a2);
}
}
hook KXmlSerializer 拼装内容
function hook_xml() {
var xmlSerializer = Java.use('org.kxml2.io.KXmlSerializer'); // org.xmlpull.v1.XmlSerializer
xmlSerializer.text.overload('java.lang.String').implementation = function (text) {
dmLogout("xtext: " + text);
if ("GPRS" == text) {
dmLogout("======>>> found GPRS");
showStacks();
}
return this.text(text);
}
}
hook Android Log 输出
function hook_log() {
dmLogout(TAG, "do hook log");
var Log = Java.use('android.util.Log');
Log.v.overload('java.lang.String', 'java.lang.String').implementation = function (tag, content) {
dmLogout(tag + " v", content);
};
Log.d.overload('java.lang.String', 'java.lang.String').implementation = function (tag, content) {
dmLogout(tag + " d", content);
};
Log.w.overload('java.lang.String', 'java.lang.String').implementation = function (tag, content) {
dmLogout(tag + " w", content);
};
Log.i.overload('java.lang.String', 'java.lang.String').implementation = function (tag, content) {
dmLogout(tag + " i", content);
};
Log.e.overload('java.lang.String', 'java.lang.String').implementation = function (tag, content) {
dmLogout(tag + " e", content);
};
}
native 主动调用
var friendlyFunctionName = new NativeFunction(friendlyFunctionPtr, 'void', ['pointer', 'pointer']);
var returnValue = Memory.alloc(sizeOfLargeObject);
friendlyFunctionName(returnValue, param1);
就先整理这么多,日后再追加。欢迎大佬们追加分享和指正错误。
本文作者:星均
本文为云栖社区原创内容,未经允许不得转载。
以上所述就是小编给大家介绍的《FRIDA 实用手册》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- MySQL™ 参考手册(关于本手册)
- LLVM 程序员手册 —— LLVM 4.0 文档(非常非常完整的手册)
- [译]Python手册——模块
- Axure函数使用手册
- 线上故障处理手册
- OpenSSH 实践手册
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Mastering Regular Expressions, Second Edition
Jeffrey E F Friedl / O'Reilly Media / 2002-07-15 / USD 39.95
Regular expressions are an extremely powerful tool for manipulating text and data. They have spread like wildfire in recent years, now offered as standard features in Perl, Java, VB.NET and C# (and an......一起来看看 《Mastering Regular Expressions, Second Edition》 这本书的介绍吧!
图片转BASE64编码
在线图片转Base64编码工具
HTML 编码/解码
HTML 编码/解码