【IOS逆向】frida-trace小计
当越狱完成之后,可以尝试品尝下frida
frida-trace 用于跟踪函数或者 Objective-C 方法的调用,frida-trace -h 能够查看它的帮助,最重要的有下面几个参数:
-i 跟踪某个函数,-x 排除某个函数。
-m 跟踪某个 Objective-C 方法,-M 排除某个 Objective-C 方法。
-a 跟踪某一个地址,需要指名模块的名称。
frida-trace
~ frida-trace -U -m "-[HomeController aboutButtonClicked]" 1375
Instrumenting...
-[HomeController aboutButtonClicked]: Loaded handler at "/Users/xxxx/__handlers__/HomeController/aboutButtonClicked.js"
Started tracing 1 function. Press Ctrl+C to stop.
/* TID 0x303 */
2896 ms -[HomeController aboutButtonClicked]
其中1375是cydia的pid
然后输出的文件中可以添加我们自定义的代码
打印堆栈
{
onEnter(log, args, state) {
log(`-[HomeController aboutButtonClicked]`);
log('\tBacktrace:\n\t' + Thread.backtrace(this.context,Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n\t'));
},
onLeave(log, retval, state) {
}
}
通配符
frida-trace -U -m "-[Home* *]" 1375
trace CCCrypt
很多应用在登录时都会加密数据,我们的目标是获取某个应用的 AES 加密的原文和密钥
frida-trace -U -i CCCrypt xxxx
会发现他自动识别了CCrypt这个库
并自动生成了js我们看看
/*
* Auto-generated by Frida. Please modify to match the signature of CCCrypt.
* This stub is currently auto-generated from manpages when available.
*
* For full API reference, see: https://frida.re/docs/javascript-api/
*/
{
/**
* Called synchronously when about to call CCCrypt.
*
* @this {object} - Object allowing you to store state for use in onLeave.
* @param {function} log - Call this function with a string to be presented to the user.
* @param {array} args - Function arguments represented as an array of NativePointer objects.
* For example use args[0].readUtf8String() if the first argument is a pointer to a C string encoded as UTF-8.
* It is also possible to modify arguments by assigning a NativePointer object to an element of this array.
* @param {object} state - Object allowing you to keep state across function calls.
* Only one JavaScript function will execute at a time, so do not worry about race-conditions.
* However, do not use this to store function arguments across onEnter/onLeave, but instead
* use "this" which is an object for keeping state local to an invocation.
*/
onEnter(log, args, state) {
log(`CCCrypt(op=${args[0]}, alg=${args[1]}, options=${args[2]}, key=${args[3]}, keyLength=${args[4]}, iv=${args[5]}, dataIn=${args[6]}, dataInLength=${args[7]}, dataOut=${args[8]}, dataOutAvailable=${args[9]}, dataOutMoved=${args[10]})`);
},
/**
* Called synchronously when about to return from CCCrypt.
*
* See onEnter for details.
*
* @this {object} - Object allowing you to access state stored in onEnter.
* @param {function} log - Call this function with a string to be presented to the user.
* @param {NativePointer} retval - Return value represented as a NativePointer object.
* @param {object} state - Object allowing you to keep state across function calls.
*/
onLeave(log, retval, state) {
}
}
魔改一下
{
onEnter(log, args, state) {
log(`CCCrypt(op=${args[0]}, alg=${args[1]}, options=${args[2]}, key=${args[3]}, keyLength=${args[4]}, iv=${args[5]}, dataIn=${args[6]}, dataInLength=${args[7]}, dataOut=${args[8]}, dataOutAvailable=${args[9]}, dataOutMoved=${args[10]})`);
//保存参数
this.operation = args[0]
this.CCAlgorithm = args[1]
this.CCOptions = args[2]
this.keyBytes = args[3]
this.keyLength = args[4]
this.ivBuffer = args[5]
this.inBuffer = args[6]
this.inLength = args[7]
this.outBuffer = args[8]
this.outLength = args[9]
this.outCountPtr = args[10]
//this.operation == 0 代表是加密
if (this.operation == 0) {
//打印加密前的原文
console.log("In buffer:")
console.log(hexdump(ptr(this.inBuffer), {
length: this.inLength.toInt32(),
header: true,
ansi: true
}))
//打印密钥
console.log("Key: ")
console.log(hexdump(ptr(this.keyBytes), {
length: this.keyLength.toInt32(),
header: true,
ansi: true
}))
//打印 IV
console.log("IV: ")
console.log(hexdump(ptr(this.ivBuffer), {
length: this.keyLength.toInt32(),
header: true,
ansi: true
}))
}
},
onLeave(log, retval, state) {
}
}
参考文章
https://www.exchen.net/frida-ios.html