一.環境
1.環境
1.手機運行服務端
2. 電腦端運行客戶端
3.進行端口轉發
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043
2. 測試
λ frida-ps -R
成功的標志:
PID Name
---- ------------------------
717 android.process.acore
9080 cat
1301 com.android.defcontainer
882 com.android.download
557 com.android.ime
647 com.android.launcher2
941 com.android.market
597 com.android.phone
523 com.android.systemui
823 com.android.tools
二.使用
得到android手機當前最前端Activity所在的進程
λ python37 C:\Users\1003441\Desktop\get_front_app.py.py Application(identifier="com.microvirt.launcher2", name="逍遙桌面", pid=647)
get_front_app.py.py
import frida rdev = frida.get_remote_device() front_app = rdev.get_frontmost_application() print (front_app)
枚舉android手機所有的進程
λ python37 C:\Users\1003441\Desktop\enum_process.py Process(pid=1, name="init") Process(pid=62, name="ueventd") Process(pid=72, name="flush-8:2") Process(pid=73, name="flush-8:3") Process(pid=74, name="logd") Process(pid=75, name="healthd") Process(pid=76, name="lmkd") Process(pid=77, name="servicemanager") Process(pid=78, name="vold") Process(pid=79, name="surfaceflinger") Process(pid=80, name="flush-8:0") Process(pid=81, name="flush-8:4") Process(pid=82, name="netd") Process(pid=83, name="debuggerd") Process(pid=84, name="rild") Process(pid=85, name="drmserver") Process(pid=86, name="mediaserver") Process(pid=87, name="installd") Process(pid=88, name="keystore")
enum_process.py內容如下:
import frida rdev = frida.get_remote_device() processes = rdev.enumerate_processes() for process in processes: print (process)
枚舉某個進程加載的所有模塊以及模塊中的導出函數
import frida rdev = frida.get_remote_device() session = rdev.attach("com.tencent.mm") #如果存在兩個一樣的進程名可以采用rdev.attach(pid)的方式 modules = session.enumerate_modules() for module in modules: print (module) export_funcs = module.enumerate_exports() print ("\tfunc_name\tRVA") for export_func in export_funcs: print ("\t%s\t%s"%(export_func.name,hex(export_func.relative_address)))
這邊的這個版本不知道為啥調用不了enumerate_modules,所以換了js的接口
from __future__ import print_function import frida, sys def on_message(message, data): print(message) jscode = """ Process.enumerateModules({ onMatch:function(exp){ send(exp.name); }, onComplete:function(){ send("stop"); } }) """ process = frida.get_usb_device().attach('com.yinghuan.aiyou') script = process.create_script(jscode) script.on('message', on_message) script.load() sys.stdin.read()
這邊更好的做法是把js代碼寫成一個js文件,js文件可以利用編輯器寫,然后讀取
from __future__ import print_function import frida, sys def on_message(message, data): print(message) jscode = """ Process.enumerateModules({ onMatch:function(exp){ send(exp.name); }, onComplete:function(){ send("stop"); } }) """ process = frida.get_usb_device().attach('com.yinghuan.aiyou')
file=open('test.js')
jscode=file.read() script = process.create_script(jscode) script.on('message', on_message) script.load() sys.stdin.read()
hook android的native函數
import frida import sys rdev = frida.get_remote_device() session = rdev.attach("com.tencent.mm") scr = """ Interceptor.attach(Module.findExportByName("libc.so" , "open"), { onEnter: function(args) { send("open("+Memory.readCString(args[0])+","+args[1]+")"); }, onLeave:function(retval){ } }); """ script = session.create_script(scr) def on_message(message ,data): print (message) script.on("message" , on_message) script.load() sys.stdin.read()
hook android的java層函數
如下代碼為hook微信(測試版本為6.3.13,不同版本由於混淆名字的隨機生成的原因或者代碼改動導致類名不一樣)
com.tencent.mm.sdk.platformtools.ay類的隨機數生成函數,讓微信猜拳隨機(type=2),而搖色子總是為6點(type=5)
import frida import sys rdev = frida.get_remote_device() session = rdev.attach("com.tencent.mm") scr = """ Java.perform(function () { var ay = Java.use("com.tencent.mm.sdk.platformtools.ay"); ay.pu.implementation = function(){ var type = arguments[0]; send("type="+type); if (type == 2) { return this.pu(type); } else { return 5; } }; }); """ script = session.create_script(scr) def on_message(message ,data): print message script.on("message" , on_message) script.load() sys.stdin.read()
通過frida向android進程注入dex
import frida, sys, optparse, re def on_message(message, data): if message['type'] == 'send': print("[*] {0}".format(message['payload'])) else: print(message) jscode = """ Java.perform(function () { var currentApplication = Java.use("android.app.ActivityThread").currentApplication(); var context = currentApplication.getApplicationContext(); var pkgName = context.getPackageName(); var dexPath = "%s"; var entryClass = "%s"; Java.openClassFile(dexPath).load(); console.log("inject " + dexPath +" to " + pkgName + " successfully!") Java.use(entryClass).%s("%s"); console.log("call entry successfully!") }); """ def checkRequiredArguments(opts, parser): missing_options = [] for option in parser.option_list: if re.match(r'^\[REQUIRED\]', option.help) and eval('opts.' + option.dest) == None: missing_options.extend(option._long_opts) if len(missing_options) > 0: parser.error('Missing REQUIRED parameters: ' + str(missing_options)) if __name__ == "__main__": usage = "usage: python %prog [options] arg\n\n" \ "example: python %prog -p com.android.launcher " \ "-f /data/local/tmp/test.apk " \ "-e com.parker.test.DexMain/main " \ "\"hello fridex!\"" parser = optparse.OptionParser(usage) parser.add_option("-p", "--package", dest="pkg", type="string", help="[REQUIRED]package name of the app to be injected.") parser.add_option("-f", "--file", dest="dexPath", type="string", help="[REQUIRED]path of the dex") parser.add_option("-e", "--entry", dest="entry", type="string", help="[REQUIRED]the entry function Name.") (options, args) = parser.parse_args() checkRequiredArguments(options, parser) if len(args) == 0: arg = "" else: arg = args[0] pkgName = options.pkg dexPath = options.dexPath entry = options.entry.split("/") if len(entry) > 1: entryClass = entry[0] entryFunction = entry[1] else: entryClass = entry[0] entryFunction = "main" process = frida.get_usb_device(1).attach(pkgName) jscode = jscode%(dexPath, entryClass, entryFunction, arg) script = process.create_script(jscode) script.on('message', on_message) print('[*] Running fridex') script.load() sys.stdin.read()
通過注入拋出異常代碼實現跟蹤程序調用棧
在<<Android 軟件安全與逆向分析>>這本書中第八章有介紹通過重打包寫入異常代碼進行棧跟蹤,但是這樣比較麻煩,使用frida注入更方便。
frida的相關資源