https://bbs.kanxue.com/thread-280758.htm
https://bbs.kanxue.com/thread-280812.htm#msg_header_h2_1
本地雷电模拟器Android9 x64,夜神模拟器Android7 x86
连接模拟器 https://blog.csdn.net/kxltsuperr/article/details/133838337
https://blog.csdn.net/weixin_45541986/article/details/128319312
10061说明模拟器没开
先启动模拟器里的应用
雷电模拟器:adb connect 127.0.0.1:5555
夜神模拟器:adb connect 127.0.0.1:62001
1 adb devices`,若有多个设备`adb.exe kill-server
获得root权限adb root
(失败的时候多试几次)
连接到远程adb shell
,进入fs目录cd /data/local/tmp
,./fs
执行
一开始有两个设备,后面kill之后就只剩一个了
查看架构:adb shell getprop ro.product.cpu.abi
先push,再去对应路径
也可以用共享文件夹传frida-server
经验 打开的方式安装不了可以拖动或者adb install
可通过下面路径查找日志
处于开发者模式一直未被调试
可以关闭开发者模式
安装的Android是7
虽然可以通过模拟器安装Android9,但是无法adb shell,因为找不到Android路径
用frida-server hook https://www.cnblogs.com/lxh2cwl/p/14842544.html
/data/local/tmp目录下启动frida-server,必须要有上面的root权限:./fs
进行端口转发监听:adb forward tcp:27042 tcp:27042
搜索特定进程:frida-ps -U
| grep -i settings
查看进程真正包名:frida-ps -U -a
输入空格键会有提示与补全
静态 模拟器上启动软件后再去注入mobile包:objection -g mobilego explore
在内存中所有已加载的类中搜索包含game的类:android hooking search classes game
查看com.android.settings.DisplaySettings类有哪些方法:android hooking list class_methods com.android.settings.DisplaySettings
直接生成代码但可能没参数:**android hooking generate simple com.android.settings.DisplaySettings**
在堆上搜索是否存在DisplaySettings类的实例:android heap search instances com.android.settings.DisplaySettings
进入显示设置,软件如果没有做校验,可以直接使用这个命令跳过注册登录:android intent launch_activity com.android.settings.DisplaySettings
识别应用程序的各种数据目录:env
动态 hook类:android hooking watch class android.bluetooth.BluetoothDevice
hook方法,查看参数、返回值和调用栈:**android hooking watch class_method game.Game.checkflag --dump-args --dump-return --dump-backtrace**
在模拟器输入字符串ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijkl(符合题目要求)后,再Called game.Game.checkflag(java.lang.String)
,得到return值
还可以import js代码
hook脚本 frida -U -l 1.js -f com.example.myapplication
包名通过frida-ps -U -a查看
返回值 java层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 function main ( ) { Java .perform (function ( ) { let Myjni = Java .use ("com.example.whathappened.MyJNI.Myjni" ); Myjni ["getstr" ].implementation = function ( ) { let re0 = this ["getstr" ](); console .log (`${re0} ` ); return re0; }; }); } setImmediate (main); function hook2 ( ){ var MainActivity = Java .use ("com.ad2001.frida0x1.MainActivity" ); MainActivity .check .overload ('int' ,'int' ).implementation = function (a,b ){ console .log ("Origin i and i2 = " ,a,b); return this .check (a,b); } } function main ( ){ Java .perform (function ( ){ hook2 (); }) } setImmediate (main);
native层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 function hook ( ){ var check_flag = Module .enumerateExports ("liba0x9.so" )[0 ]["function" ]; console .log ("Func address = " ,check_flag); Interceptor .attach (check_flag,{ onEnter :function (args ){ },onLeave :function (retval ){ console .log ("Origin retval : " ,retval); } }) }function main ( ){ Java .perform (function ( ){ hook (); }) }setImmediate (hook);
函数地址 Module.enumerateImports(“libfrida0x8.so”)查看导入表
Module.findExportByName():通过提供导出项的名称作为参数,这个函数会返回与该名称对应的导出项的地址
1 2 3 4 5 6 7 var func_addr = Module .findExportByName ("libmidand.so" , "_Z10murmur3_32PKcjj" );console .log ("func addr is ---" + func_addr);Interceptor .attach (func_addr, { onLeave : function (args ){ console .log ("enter murmur3_32 retvalue->\n" + hexdump (args)); } });
java层可以直接拿函数名字来hook,so层就要先通过函数名来找到该函数的地址,然后以地址为基准进行hook
frida -U -f com.example.demo1 –no-pause -l agent/demo1/demo1.js:-f指定目标应用程序的包名
一开始一直不让输get返回值的命令,在模拟器端输入字符然后点login就好了
发现有返回值了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 function hook ( ){ var targetAddress = Module .findExportByName ("libc.so" ,"strcmp" ); console .log ("Strcmp Address: " ,targetAddress.toString (16 )); Interceptor .attach (targetAddress,{ onEnter :function (args ){ var input = Memory .readUtf8String (args[0 ]); if (input.includes ("111" )){ console .log (Memory .readUtf8String (args[1 ])); } },onLeave :function (retval ){ } }) console .log ("success!" ); } function main ( ){ Java .perform (function ( ){ hook (); }) }setImmediate (main);
重载方法/实例方法/静态方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 var fridaDemo1Class = Java .use ("com.example.demo1.FridaDemo1" ) fridaDemo1Class.func .overload ('int' , 'int' ).implementation = function (arg1, arg2 ) { var result = this .func (arg1, arg2); console .log ("arg1, arg2, result" , arg1, arg2, result) return 9527 ; } fridaDemo1Class.func .overload ('java.lang.String' ).implementation = function (arg1 ) { var helloStr = Java .use ('java.lang.String' ).$new('Hello' ) var result = this .func (helloStr); console .log ("arg1, result" , arg1, result) return Java .use ('java.lang.String' ).$new("World" ); }Java .choose ("com.example.demo1.MainActivity" , { onMatch : function (instance ) { console .log ("found instance :" , instance) console .log ("found instance :" , instance.abc ()) }, onComplete : function ( ) { } }) fridaDemo1Class.nice .implementation = function ( ) { var result = this .nice (); console .log ("nice result" , result) return result; }var result = Java .use ("com.example.demo1.MainActivity" ).sabc ();console .log (result);
调用主函数中未被调用的方法 java层未被调用,但native层有未被调用的flag函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 function hook ( ){ var a = Module .findBaseAddress ("libfrida0xa.so" ); var b = Module .enumerateExports ("libfrida0xa.so" ); var get_flagaddress = null ; var mvaddress = null ; for (var i = 0 ; b[i]!= null ; i ++ ){ if (b[i]["name" ] == "_Z8get_flagii" ){ console .log ("function get_flag : " ,b[i]["address" ]); console .log ((b[i]["address" ] - a).toString (16 )); get_flagaddress = b[i]["address" ]; } } console .log (ptr.toString (16 )); var get_flag_ptr = new NativePointer (get_flagaddress); const get_flag = new NativeFunction (get_flag_ptr,'char' ,['int' ,'int' ]); var flag = get_flag (1 ,2 ); console .log (flag) } function main ( ){ Java .perform (function ( ){ hook (); }) }setImmediate (main)