{
onEnter(log, args, state) {
var self = new ObjC.Object(args[0]); // 當前對象
var method = args[1].readUtf8String(); // 當前方法名
log(`[${self.$className} ${method}]`);
var isData = false;
// 如果參數(shù)是一個時間戳或者基本數(shù)據(jù)類型, 無法使用new ObjC.Object來轉(zhuǎn)換, 則可以使用toInt32來顯示原來的值
// var timestamp = args[4].toInt32();
// 字符串
// var str = ObjC.classes.NSString.stringWithString_("hi wit!") // 對應(yīng)的oc語法:NSString *str = [NSString stringWithString:@"hi with!"];
// args[2] = str // 修改入?yún)?
// array
// 數(shù)組
// var array = ObjC.classes.NSMutableArray.array(); // 對應(yīng)的oc語法:NSMutableArray array = [NSMutablearray array];
// array.addObject_("item1"); // 對應(yīng)的oc語法:[array addObject:@"item1"];
// array.addObject_("item2"); // 對應(yīng)的oc語法:[array addObject:@"item2"];
// args[2] = array; // 修改入?yún)?
// 字典
// var dictionary = ObjC.classes.NSMutableDictionary.dictionary(); // 對應(yīng)的oc語法:NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
// dictionary.setObject_forKey_("value1", "key1"); // 對應(yīng)的oc語法:[dictionary setObject:@"value1" forKey:@"key1"]
// dictionary.setObject_forKey_("value2", "key2"); // 對應(yīng)的oc語法:[dictionary setObject:@"value2" forKey:@"key2"]
// args[2] = dictionary; // 修改入?yún)?
// 字節(jié)
var data = ObjC.classes.NSMutableData.data(); // 對應(yīng)的oc語法:NSMutableData *data = [NSMutableData data];
var str = ObjC.classes.NSString.stringWithString_("hi wit!") // 獲取一個字符串。 對應(yīng)的oc語法:NSString *str = [NSString stringWithString:@"hi with!"];
var subData = str.dataUsingEncoding_(4); // 將str轉(zhuǎn)換為data,編碼為utf-8涯塔。對應(yīng)的oc語法:NSData *subData = [str dataUsingEncoding:NSUTF8StringEncoding];
data.appendData_(subData); // 將subData添加到data。對應(yīng)的oc語法:[data appendData:subData];
args[2] = data; // 修改入?yún)? isData = true;
// 更多數(shù)據(jù)類型:https://developer.apple.com/documentation/foundation
var before = args[2];
// 注意悴晰,日志輸出請直接使用log函數(shù)。不要使用console.log()
if (isData) {
// 打印byte對象
var after = new ObjC.Object(args[2]); // 打印NSData
var outValue = after.bytes().readUtf8String(after.length()) // 將data轉(zhuǎn)換為string
log(`before:=${before}=`);
log(`after:=${outValue}=`);
} else {
// 打印字符串乐横、數(shù)組垦页、字段
var after = new ObjC.Object(args[2]); // 打印出來是個指針時,請用該方式轉(zhuǎn)換后再打印
log(`before:=${before}=`);
log(`after:=${after}=`);
}
// 如果是自定義對象時比肄,使用以上方法無法打印時,請使用以下方法:
// var customObj = new ObjC.Object(args[0]); // 自定義對象
// // 打印該對象所有屬性
// var ivarList = customObj.$ivars;
// for (key in ivarList) {
// log(`key${key}=${ivarList[key]}=`);
// }
// // 打印該對象所有方法
// var methodList = customObj.$methods;
// for (var i=0; i<methodList.length; i++) {
// log(`method=${methodList[i]}=`);
// }
},
onLeave(log, retval, state) {
}
}
注意: args的第0個參數(shù)是self對象, 第1個參數(shù)是方法名, 上方代碼有.
frida-trace [options] target
1.命令格式
frida-trace [options] target
iOS常用的可選參數(shù):
// 設(shè)備相關(guān)
-D 連接到指定的設(shè)備囊陡,多個設(shè)備時使用芳绩。示例:frida-trace -D 555315d66cac2d5849408f53da9eea514a90547e -F
-U 連接到USB設(shè)備,只有一個設(shè)備時使用撞反。示例fria-trace -U -F// 應(yīng)用程序相關(guān)
-f 目標應(yīng)用包名妥色。spawn模式。示例:frida-trace -U -f com.apple.www
-F 當前正在運行的程序遏片。attach模式示例嘹害。示例:frida-trace -U -F或frida-trae -UF
-n 正在運行的程序的名字撮竿。attach模式。示例:frida-trace -U -n QQ
-N 正在運行的程序的包名笔呀。attach模式幢踏。示例:frida-trace -U -N com.apple.www
-p 正在運行的程序的pid。attach模式许师。示例:frida-trace -U -p 2302// 方法相關(guān)房蝉,以下參數(shù)在一條跟蹤命令中可重復(fù)使用
-I 包含模塊。示例:frida-trace -UF -I "libcommonCrypto*"
-X 不包含模塊微渠。示例:frida-trace -UF -X "libcommonCrypto*"
-i 包含c函數(shù)惨驶。示例:frida-trace -UF -i "CC_MD5"
-x 不包名c函數(shù)。示例:frida-trace -UF -i "*MD5" -x "CC_MD5"
-a 包含模塊+偏移跟蹤敛助。示例:frida-trace -UF -a 模塊名\!0x7B7D48
-m 包含某個oc方法。示例:frida-trace -UF -m "+[NSURL URLWithString:]"
-M 不包含某個oc方法屋确。示例:frida-trace -UF -M "+[NSURL URLWithString:]"http:// 日志相關(guān)
-o 日志輸出到文件纳击。示例:frida-trace -UF -m "*[* URL*]" -o run.log
2.常用命令
frida-trace中的方法匹配命令支持模糊匹配,星號匹配0個或多個字符攻臀,問號匹配1個字符:
-m "-[NSURL *]" // 匹配NSURL類的所有實例方法
-m "+[NSURL *]" // 匹配NSURL類的所有類方法
-m "*[NSURL *]" // 匹配NSURL類的所有方法
-m "*[*URL *]" // 匹配以URL結(jié)尾類的所有方法
-m "*[URL* *]" // 匹配以URL開頭類的所有方法
-m "*[*URL* *]" // 匹配包含URL的類的所有方法
-m "*[*URL* *login*]" // 匹配包含URL的類的帶login的所有方法
-m "*[????? *]" // 匹配類名只有五個字符的類的所有方法
簡而言之:
當你只知道部分類名時,不確定的地方用星號代替
當你只知道部分方法名時刨啸,不確定的地方用星號代替
當你不知道方法名時堡赔,直接用星號代替
當你不知道某個字母是大小寫時,用問號代替
Frida關(guān)于JavaScript API的文檔: JavaScript API