frida
目前非常火爆,该框架从Java
层hook到Native
层hook无所不能,虽然持久化还是要依靠Xposed
和hookzz
等开发框架,但是frida
的动态和灵活对逆向以及自动化逆向的帮助非常巨大。frida
是啥呢,github目录Awesome Frida这样介绍frida
的:Frida is Greasemonkey for native apps, or, put in more technical terms, it’s a dynamic code instrumentation toolkit. It lets you inject snippets of JavaScript into native apps that run on Windows, Mac, Linux, iOS and Android. Frida is an open source software.
frida
是平台原生app
的Greasemonkey
,说的专业一点,就是一种动态插桩工具,可以插入一些代码到原生app
的内存空间去,(动态地监视和修改其行为),这些原生平台可以是Win
、Mac
、Linux
、Android
或者iOS
。而且frida
还是开源的。Greasemonkey
可能大家不明白,它其实就是firefox
的一套插件体系,使用它编写的脚本可以直接改变firefox
对网页的编排方式,实现想要的任何功能。而且这套插件还是外挂的,非常灵活机动。frida
也是一样的道理。那它为什么这么火爆呢?frida
做的跟它是一件事情。原则上是可以用frida
把金山游侠,包括CheatEngine
等“外挂”做出来的。frida
可以“看到”平时看不到的东西。出于编译型语言的特性,机器码在CPU和内存上执行的过程中,其内部数据的交互和跳转,对用户来讲是看不见的。当然如果手上有源码,甚至哪怕有带调试符号的可执行文件包,也可以使用gbd
、lldb
等调试器连上去看。app
进行逆向和动态调试、甚至自动化分析以及规模化收集信息的话,我们需要的是细粒度的流程控制和代码级的可定制体系,以及不断对调试进行动态纠正和可编程调试的框架,这就是frida
。frida
使用的是python
、JavaScript
等“胶水语言”也是它火爆的一个原因,可以迅速将逆向过程自动化,以及整合到现有的架构和体系中去,为你们发布“威胁情报”、“数据平台”甚至“AI风控”等产品打好基础。敏捷开发
和迅速适配到现有架构
的能力作为其核心卖点。FRIDA脚本
就是利用FRIDA
动态插桩框架,使用FRIDA
导出的API
和方法,对内存空间里的对象方法进行监视、修改或者替换的一段代码。FRIDA
的API
是使用JavaScript
实现的,所以我们可以充分利用JS
的匿名函数的优势、以及大量的hook
和回调函数的API。hello-world.js
setTimeout(function(){
Java.perform(function(){ console.log("hello world!");
});
});
FRIDA
版本的”Hello World!”,我们把一个匿名函数作为参数传给了setTimeout()
函数,然而函数体中的Java.perform()
这个函数本身又接受了一个匿名函数作为参数,该匿名函数中最终会调用console.log()
函数来打印一个“Hello world!”字符串。我们需要调用setTimeout()
方法因为该方法将我们的函数注册到JavaScript
运行时中去,然后需要调用Java.perform()
方法将函数注册到Frida
的Java
运行时中去,用来执行函数中的操作,当然这里只是打了一条log
。frida-server
运行起来,在电脑上进行操作:$ frida -U -l hello-world.js android.process.media
console.log()
执行成功,字符串打印了出来。HelloWorld.js
稍微加一点功能,比如说枚举所有已经加载的类,这就用到了Java
对象的enumerateLoadedClasses
方法。代码如下:setTimeout(function (){
Java.perform(function (){ console.log("n[*] enumerating classes...");
Java.enumerateLoadedClasses({ onMatch: function(_className){ console.log("[*] found instance of '"+_className+"'");
}, onComplete: function(){ console.log("[*] class enuemration complete");
}
});
});
});
frida-server
正在运行中,然后在电脑上操作:$ frida -U -l enumerate_classes.js android.process.media
Java.enumerateLoadedClasses({ onMatch: function(instance){ if (instance.split(".")[1] == "bluetooth"){ console.log("[->]t"+instance);
}
}, onComplete: function() { console.log("[*] class enuemration complete");
}
});
JavaScript
字符串的indexOf()
、search()
或者match()
方法,这个留给读者自己完成。FRIDA的API手册
可以得知,此时应该使用Java.choose()
函数,来选定某一个实例。android.bluetooth.BluetoothDevice
类的实例的代码。Java.choose("android.bluetooth.BluetoothDevice",{ onMatch: function (instance){ console.log("[*] "+" android.bluetooth.BluetoothDevice instance found"+" :=> '"+instance+"'");
bluetoothDeviceInfo(instance);
}, onComplete: function() { console.log("[*] -----");}
});
$ frida -U -l enumerate_classes_bluetooth_choose.js com.android.bluetooth
Java.use()
函数。Java.use()
与Java.choose()
最大的区别,就是在于前者会新建一个对象,后者会选择内存中已有的实例。function enumMethods(targetClass){ var hook = Java.use(targetClass); var ownMethods = hook.class.getDeclaredMethods();
hook.$dispose; return ownMethods;
}
...
...
var a = enumMethods("android.bluetooth.BluetoothDevice")
a.forEach(function(s) { console.log(s);
});
$ frida -U -l enumerate_classes_bluetooth_choose_allmethod.js com.android.bluetooth
dump
蓝牙信息的“加强版”——‘BlueCrawl’。VERSION="1.0.0"setTimeout(function(){
Java.perform(function(){
Java.enumerateLoadedClasses({ onMatch: function(instance){ if (instance.split(".")[1] == "bluetooth"){ console.log("[->]t"+lightBlueCursor()+instance+closeCursor());
}
}, onComplete: function() {}
});
Java.choose("android.bluetooth.BluetoothGattServer",{ onMatch: function (instance){
...
onComplete: function() { console.log("[*] -----");}
});
Java.choose("android.bluetooth.BluetoothGattService",{ onMatch: function (instance){
...
onComplete: function() { console.log("[*] -----");}
});
Java.choose("android.bluetooth.BluetoothSocket",{ onMatch: function (instance){
...
onComplete: function() { console.log("[*] -----");}
});
Java.choose("android.bluetooth.BluetoothServerSocket",{ onMatch: function (instance){
...
onComplete: function() { console.log("[*] -----");}
});
Java.choose("android.bluetooth.BluetoothDevice",{ onMatch: function (instance){
...
onComplete: function() { console.log("[*] -----");}
});
});
},0);
choose
了很多类,包括蓝牙接口信息以及蓝牙服务接口对象等,还加载了内存中已经分配好的蓝牙设备对象,也就是上文我们已经演示的信息。我们可以用这个脚本来“查看”App
加载了哪些蓝牙的接口,App
是否正在查找蓝牙设备、或者是否窃取蓝牙设备信息等。$ frida -U -l bluecrawl-1.0.0.js com.android.bluetooth
- 结尾 - 精彩推荐 【技术分享】工控安全入门(四)—— DNP3协议 【技术分享】Emotet木马运行原理完全分析 【技术分享】Fastjson <1.2.48 入门调试 戳“阅读原文”查看更多内容 原文始发于微信公众号(安全客):【技术分享】FRIDA脚本系列(一)入门篇:在安卓8.1上dump蓝牙接口和实例
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论