1、使用frida-trace启动app并追踪方法:
frida-trace -U -f cn.testapp.main -m "*[Global *]"
cn.testapp.main 是APP的bundleID ,frida-trace以此判断要启动哪个app
2、frida-trace追踪app的方法时,修改方法的参数和返回值
iOS测试项目代码:
#import "ViewController.h"
@interface ViewController ()<UIWebViewDelegate>
@property(nonatomic,strong)UIButton * testBtn;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self addButton];
}
-(void)addButton{
UIButton * btn = [UIButton buttonWithType:UIButtonTypeSystem];
btn.frame = CGRectMake(100, 100, 100, 100);
btn.backgroundColor = [UIColor orangeColor];
[btn setTitle:@"点击" forState:UIControlStateNormal];
[btn addTarget:self action:@selector(btnClick) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:btn];
self.testBtn = btn;
}
-(void)btnClick{
NSLog(@"点击成功");
int age = [self testSendInt:18];
NSString * name = [self testSendString:@"jack"];
NSLog(@"\n%@\n%d",name,age);
}
-(int)testSendInt:(int)age{
int result = age+10;
return result;
}
-(NSString *)testSendString:(NSString *)name{
NSString * result = [name stringByAppendingString:@"--2"];
return result;
}
@end
使用frida-trace测试 testSendInt 和 testSendString 这两个方法
-[ViewController testSendInt:]方法对应的js脚本:
{
/**
* Called synchronously when about to call -[ViewController testSendInt:].
*
* @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: function (log, args, state) {
log('-[ViewController testSendInt:' + args[2] + ']');
// 修改参数为 20
args[2] = ptr("20");
},
/**
* Called synchronously when about to return from -[ViewController testSendInt:].
*
* 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: function (log, retval, state) {
//修改返回值为 99
retval2 = ptr("99");
retval.replace(retval2);
}
}
-[ViewController testSendString:]方法对应的js脚本:
{
/**
* Called synchronously when about to call -[ViewController testSendString:].
*
* @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: function (log, args, state) {
log('-[ViewController testSendString:' + args[2] + ']');
//修改参数为 “逆向APP”
args[2] = ObjC.classes.NSString.stringWithString_("逆向APP")
},
/**
* Called synchronously when about to return from -[ViewController testSendString:].
*
* 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: function (log, retval, state) {
//修改返回值为 "逆向APP---666"
newretval = ObjC.classes.NSString.stringWithString_("逆向APP---666")
retval.replace(newretval)
}
}
打开终端,输入frida-trace命令:
frida-trace -U 23745 -m "*[ViewController *]"
“23745”是我当前iOS APP 的pid,改成你自己的。
当点击 APP 中的按钮触发这两个方法的调用:
APP打印信息被修改了,以下是打印对比:
2020-05-26 10:56:12.583483+0800 testUIWebView[23745:2779627] 点击成功
2020-05-26 10:56:12.592081+0800 testUIWebView[23745:2779627]
jack--2
28
2020-05-26 10:58:29.192116+0800 testUIWebView[23745:2779627] 点击成功
2020-05-26 10:58:29.251267+0800 testUIWebView[23745:2779627]
逆向APP
99
2020-05-26 10:59:43.744645+0800 testUIWebView[23745:2779627] 点击成功
2020-05-26 10:59:43.791268+0800 testUIWebView[23745:2779627]
逆向APP--2
99
====================================================
修改返回值为bool的函数返回值:
onLeave(log, retval, state) {
retval.replace(0x0);//修改返回值为false
}