Frida学习笔记(iOS为主)(不定时更新)

1. 基础

1.1 字符串处理

const NSString = ObjC.classes.NSString

# 创建字符串
var mystr = NSString.stringWithString_("Example");

1.2 根据关键字搜索方法并Hook

var resolver = new ApiResolver('objc');

// enumerateMatches() 中参数为正则表达式,格式为 *[* *]
resolver.enumerateMatches('*[aa* bbb*]',{
    onMatch: function(match){
        console.log(match['name'] + ":" +match['address']);
        var method = match['name'];
        var implementation = match['address'];

        if (method.indexOf(".cxx_destruct") == -1 ){
            try{
                Interceptor.attach(ptr(implementation), {
                    onEnter: function(args){
                        console.log("======onenter=======");
                        console.log("[*] Method Name: " + method);
                      	// args[0]指向类本身
                        // args[1]指向selector
                      	// oc的参数从args[2]开始
                        console.log("[*] args[2]: " + args[2]);
                      
                      	// 实体化为oc类
                        var arg2 = new ObjC.Object(args[2]);
                        console.log(arg2.toString());
                    },
                    onLeave: function(retval){
                        console.log("======onleave=======");
                        console.log("[*] Method Name: " + method);
                        console.log("\t[-] retval: " + retval);
                    }
                });
            } catch(err){
                console.log("[!] Exception: " + err.message);
            }
        }
    },
    onComplete: function(){}
});

1.3 直接Hook类方法

var hook = ObjC.classes.DeviceManager['+ isDeviceJailed'];
Interceptor.attach(hook.implementation, {
    onEnter: function (args) {
      },
     onLeave:function(retval){
        retval.replace(0x0);
     }
});

1.4 OC类常用参数

var cwObj = new ObjC.Object(args[0]);
console.log(`==> classname ${cwObj.$className}`);				// 类名
console.log(`==> ownmethods ${cwObj.$ownMethods}`); 		// 类方法
console.log(`==> methods ${cwObj.$methods}`);						// 类方法,包含父类方法

var ivars = cwObj.$ivars;																// 类参数
console.log(`==> _movieURL ${ivars.param1}`); 

1.5 直接调用OC类方法

类似字符串处理的方式

const UIImage = ObjC.classes.UIImage;

var path = 'path/myphoto.jpg'

var img = UIImage.imageWithContentsOfFile_(path); //UIImage

1.6 查看应用运行目录

这里使用基于frida的一个工具objection

objection  -g [AppName] explore

env

2. 进阶

2.1 根据地址Hook方法

先获取当前运行的Module名称, 一般和ipa包的名字时一致的

var modules = Process.enumerateModules();
for(var i=0;i<modules.length;i++){
		console.log(`== Name: ${modules[i].name}  <${modules[i].base}>`);
}

利用目标函数的相对地址获取绝对地址并hook

/**
* 根据module名字和目标方法的偏移地址获得方法的绝对地址
*/
function get_func_addr(module, offset) {
    // 根据名字获取module地址
    var base_addr = Module.findBaseAddress(module);
    console.log("base_addr: " + base_addr);
  
    console.log(hexdump(ptr(base_addr), {
              length: 16,
              header: true,
              ansi: true
    }));
  
    var func_addr = base_addr.add(offset);
    if (Process.arch == 'arm')
       return func_addr.add(1);  //如果是32位地址+1
    else
       return func_addr;
 }

// 获取目标函数的绝对地址
var func_addr = get_func_addr('Myapp', 0x387C04);
console.log('func_addr: ' + func_addr);

Interceptor.attach(ptr(func_addr), {
    onEnter: function(args) {
        console.log("====onEnter=====");
        console.log("arg0: " + args[0]);
        console.log(hexdump(ptr(args[0]), {
            length: 64,
            header: false,
            ansi: false
        }))
        console.log("arg1: " + args[1]);
        console.log("arg2: " + args[2]);
    },
    onLeave: function(retval) {
        console.log("====onLeave=====");
        console.log("arg0: " + retval);
        console.log(hexdump(ptr(retval), {
            length: 64,
            header: true,
            ansi: true
        }))
    }
});

2.1 Hook Native方法

const resolver = new ApiResolver('module');
resolver.enumerateMatches('exports:*CGGeometry*!*Rect*',{
        onMatch: function(match){
            console.log(match['name'] + ":" +match['address']);
            var method = match['name'];
            var implementation = match['address'];
    
            if (method.indexOf(".cxx_destruct") == -1 ){
                try{
                    Interceptor.attach(ptr(implementation), {
                        onEnter: function(args){
                            console.log("======onenter=======");
                            console.log("[*] Method Name: " + method);
                            console.log(args[0]);
                            console.log(hexdump(ptr(args[0]), {
                                length: 64,
                                header: true,
                                ansi: true
                            }))    
                        },
                        onLeave: function(retval){
                            console.log("======onleave=======");
                            console.log("[*] Method Name: " + method);
                            console.log("\t[-] retval: " + retval);
                        }
                    });
                } catch(err){
                    console.log("[!] Exception: " + err.message);
                }
            }
        },
        onComplete: function(){}
    });

2.3 向内存中写入数据

var array = [0xaa, 0x12, 0x22];

// 直接写数据可能存在权限问题,先修改内存权限
Memory.protect(targetAddr, array.length, 'rw-');

// 写入数据
Memory.writeByteArray(targetAddr, array);

2.4 直接调用Native方法

/** 
 * 调用NativeFunction,利用CoreMedia中的方法,从CMSampleBuffer中提取ImageBuffer 
 */
const CMSampleBufferGetImageBufferPtr = Module.getExportByName('CoreMedia','CMSampleBufferGetImageBuffer');

const CMSampleBufferGetImageBuffer = new NativeFunction(CMSampleBufferGetImageBufferPtr, 'pointer', ['pointer']);

var cvPixelBufferPtr = CMSampleBufferGetImageBuffer(bufferPtr);

2.5 对Native指针的操作

例如打印模板地址的字符串

// args[1] 目标地址
// args[2]要打印的字符串的长度
new NativePointer(args[1]).readCString(parseInt(args[2]))
  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Morphy_Amo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值