Frida学习笔记

Frida学习笔记准备工作使用 kali 时间改成中国时区 dpkg reconfiguret 加入中文字体 aptupgrde 如果报错 解决方法 下载最新 key 添加到 keylistwget q O https archive kali org archive key asc apt keyaddaptins intl chineseaptin wqy microhei 可以装一些好用的小工具 htopjnettop 安装 py 环境

准备工作

wget -q -O - https://archive.kali.org/archive-key.asc | apt-key add 

配置代理

ipconfig查看ip

nano /etc/proxychains.conf 注释poxy—_dns 最后改成sock5 ip最后改成1,端口1080 

将机器装入adb,且为了方便加入环境变量

wget https://dl.google.com/android/repository/platform-tools-latest-linux.zip 7z x platform-tools-latest-linux.zip root@kali:~/Downloads# cat ~/.bashrc |grep export export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" root@kali:~/Downloads# cd platform-tools/ root@kali:~/Downloads/platform-tools# cd .. export PATH="/root//Downloads/platform-tools:$PATH" 

Frida开发环境

目前最新正确的Frida环境搭建方法:

  1. git clone https://github.com/oleavr/frida-agent-example.git
  2. cd frida-agent-example/
  3. npm install
  4. 使用VSCode等IDE打开此工程,在agent下编写typescript,会有智能提示。
  5. npm run watch会监控代码修改自动编译生成js文件
  6. frida -U -f com.example.android –no-pause -l _agent.js

安装frida server

wget https://github.com/frida/frida/releases/download/12.8.0/frida-server-12.8.0-android-arm64.xz

特定版本

想要使用基于特定frida版本的objection,只需先安装好特定版本的frida和frida-tools(星球里搜“特定版本”有对应关系),再去objection的release里找那个日期之后一点点的版本。比如以frida 12.8.0版本举例: pip install frida==12.8.0 pip install frida-tools==5.3.0 pip install objection==1.8.4 按照这个顺序,在装objection的时候,就会直接Requirement already satisfied,不会再去下载新的frida来安装了。 

编写脚本注入

编写0530.js脚本

function main(){ Java.perform(function(){ console.log("Inside Frida Java Perform!") }) } setImmediate(main) 
root@kali:~/Downloads/frida-agent-example/agent# frida -U -n com.android.providers.calendar -l 0530.js ____ / _ | Frida 12.8.0 - A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at https://www.frida.re/docs/home/ Attaching... Inside Frida Java Perform! [Google Pixel XL::com.android.providers.calendar]-> 

wifi adb

手机端启动server ./fridaserver -l 0.0.0.0:8888//0.0.0.0.0为任意ip 案例如下: marlin:/data/local/tmp # ./fs1280arm64 -l 0.0.0.0:8888 手机端就可以查看与注入 frida-ps -H 手机ip:端口 案例如下: root@kali:~/Desktop# frida-ps H 192.168.15.98:8888 PID Name ---- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 905 (sd-pam) 596 ModemManager 562 NetworkManager 1109 Thunar 617 Xorg 559 accounts-daemon 2836 adb 1151 agent 616 agetty 1056 at-spi-bus-launcher 1075 at-spi2-registryd 1355 bash 3210 bash 3714 bash 3922 bash 4927 bash 3631 code 3673 code 注入就是: frida H 192.168.15.98:8888 -f 包名 -l 脚本 --no-pause -f为新开进程方式 

Objection环境、自动化分析和插件

root@kali:~# objection -N -h 192.168.15.98 -p 8888 -g com.android.settings explore Using networked device @`192.168.15.98:8888` Agent injected and responds ok! _ _ _ _ ___| |_|_|___ ___| |_|_|___ ___ | . | . | | -_| _| _| | . | | |___|___| |___|___|_| |_|___|_|_| |___|(object)inject(ion) v1.8.4 Runtime Mobile Exploration by: @leonjza from @sensepost [tab] for command suggestions com.android.settings on (google: 8.1.0) [net] # frida -------------------- ----------- Frida Version 12.8.0 Process Architecture arm64 Process Platform linux Debugger Attached False Script Runtime DUK Script Filename /script1.js Frida Heap Size 17.0 MiB -------------------- ----------- com.android.settings on (google: 8.1.0) [net] # env Name Path ---------------------- ----------------------------------------------------------- cacheDirectory /data/user_de/0/com.android.settings/cache codeCacheDirectory /data/user_de/0/com.android.settings/code_cache externalCacheDirectory /storage/emulated/0/Android/data/com.android.settings/cache filesDirectory /data/user_de/0/com.android.settings/files obbDir /storage/emulated/0/Android/obb/com.android.settings packageCodePath /system/priv-app/SettingsGoogle/SettingsGoogle.apk 

内存漫游、hook anywhere、抓包

获取基本信息

内存漫游

om.android.settings on (google: 8.1.0) [net] # memory list modules Save the output by adding `--json modules.json` to this command Name Base Size Path ----------------------------------------------- ------------ -------------------- -------------------------------------------------------------------- app_process64 0x5d907e9000 32768 (32.0 KiB) /system/bin/app_process64 libandroid_runtime.so 0x786e55a000  (1.9 MiB) /system/lib64/libandroid_runtime.so libbinder.so 0x786c  (544.0 KiB) /system/lib64/libbinder.so libcutils.so 0x786c 81920 (80.0 KiB) /system/lib64/libcutils.so libhwbinder.so 0x786f  (160.0 KiB) /system/lib64/libhwbinder.so liblog.so 0x786e4da000  (100.0 KiB) /system/lib64/liblog.so libnativeloader.so 0x786cfa2000 28672 (28.0 KiB) /system/lib64/libnativeloader.so libutils.so 0x786bf5d000  (128.0 KiB) /system/lib64/libutils.so libwilhelm.so 0x786f  (268.0 KiB) /system/lib64/libwilhelm.so libc++.so 0x786c58a000  (960.0 KiB) /system/lib64/libc++.so libc.so 0x786ed5f000  (872.0 KiB) /system/lib64/libc.so libm.so 0x786eb42000  (228.0 KiB) /system/lib64/libm.so libdl.so 0x786deaf000 20480 (20.0 KiB) /system/lib64/libdl.so libmemtrack.so 0x786c048000  (276.0 KiB) /system/lib64/libmemtrack.so libandroidfw.so 0x786dcc4000  (332.0 KiB) /system/lib64/libandroidfw.so libappfuse.so 0x786d12f000 57344 (56.0 KiB) /system/lib64/libappfuse.so libbase.so 0x786cf2b000 73728 (72.0 KiB) /system/lib64/libbase.so libcrypto.so 0x786d14f000  (1.1 MiB) /system/lib64/libcrypto.so libnativehelper.so 0x786ddd2000 36864 (36.0 KiB) /system/lib64/libnativehelper.so libdebuggerd_client.so 0x786c 28672 (28.0 KiB) /system/lib64/libdebuggerd_client.so libui.so 0x786eb87000  (144.0 KiB) /system/lib64/libui.so libgraphicsenv.so 0x786ed1a000 16384 (16.0 KiB) /system/lib64/libgraphicsenv.so libgui.so 0x786cc43000  (608.0 KiB) /system/lib64/libgui.so libsensor.so 0x786cb85000 94208 (92.0 KiB) /system/lib64/libsensor.so libinput.so 0x786d00b000  (180.0 KiB) /system/lib64/libinput.so libcamera_client.so 0x786dd52000  (320.0 KiB) /system/lib64/libcamera_client.so libcamera_metadata.so 0x786f45a000 45056 (44.0 KiB) /system/lib64/libcamera_metadata.so libskia.so 0x786d3cf000  (7.9 MiB) /system/lib64/libskia.so libsqlite.so 0x786ca02000  (1.1 MiB) /system/lib64/libsqlite.so libEGL.so 0x786e50e000  (188.0 KiB) /system/lib64/libEGL.so libGLESv1_CM.so 
function _ZNSt3__16__treeINS_12__value_typeIN7android8String16ElEENS_19__map_value_compareIS3_S4_NS_4lessIS3_EELb1EEENS_9allocatorIS4_EEE25__emplace_unique_key_argsIS3_JRKNS_21piecewise_construct_tENS_5tupleIJRKS3_EEENSG_IJEEEEEENS_4pairINS_15__tree_iteratorIS4_PNS_11__tree_nodeIS4_PvEElEEbEERKT_DpOT0_ 0x786c9d44e8 function _ZNK7android6VectorINS_12ProcessState12handle_entryEE12do_constructEPvm 0x786c9add70 function _ZNK7android6VectorIPNS_7BBinderEE8do_splatEPvPKvm 0x786c9b6cc8 function _ZN7android6binder5ValueC2ERKS1_ 0x786c9d868c variable _ZZ17internal_type_ptrIiEPKvvE6marker 0x786c9fc398 

当结果太多,终端无法全部显示的时候,可以将结果导出到文件中,然后使用其他软件查看内容

# memory list exports libart.so --json /root/libart.json Writing exports as json to /root/libart.json... Wrote exports to: /root/libart.json 
# android heap search instances com.android.settings.DisplaySettings Using exsiting matches for com.android.settings.DisplaySettings. Use --fresh flag for new instances. Handle Class toString() -------- ------------------------------------ ----------------------------------------- 0x252a com.android.settings.DisplaySettings DisplaySettings{69d91ee #0 id=0x7f0a0231} 
# android heap execute 0x2526 getPreferenceScreenResId Handle 0x2526 is to class com.android.settings.DisplaySettings Executing method: getPreferenceScreenResId()  
# android heap evaluate 0x2526 (The handle at `0x2526` will be available as the `clazz` variable.) console.log("evaluate result:"+clazz.getPreferenceScreenResId()) JavaScript capture complete. Evaluating... Handle 0x2526 is to class com.android.settings.DisplaySettings evaluate result: 
com.android.settings on (google: 8.1.0) [net] # android hooking list activities com.android.settings.ActivityPicker com.android.settings.AirplaneModeVoiceActivity com.android.settings.AllowBindAppWidgetActivity com.android.settings.AppWidgetPickActivity com.android.settings.BandMode com.android.settings.ConfirmDeviceCredentialActivity com.android.settings.CreateShortcut com.android.settings.CredentialStorage com.android.settings.CryptKeeper$FadeToBlack 
om.android.settings on (google: 8.1.0) [net] # android intent launch_activity com.android.settings.wifi.WifiSettings (agent) Starting activity com.android.settings.wifi.WifiSettings... (agent) Activity successfully asked to start. 

Frida学习笔记
直接启动service
也可以先使用android hooking list services查看可供开启的服务,然后使用android intent launch_service com.android.settings.bluetooth.BluetoothPairingService命令来开启服务。




Frida hook anywhere

学习Frida的时候,遇到的第一个问题就是,无法找到正确的类及子类,无法定位到实现功能的准确的方法,无法正确的构造参数、继而进入正确的重载,这时候可以使用Frida进行动态调试,来确定以上具体的名称和写法,最后写出正确的hook代码。

objection(内存漫游)

列出内存中所有的类

# android hooking list classes sun.util.logging.LoggingSupport sun.util.logging.LoggingSupport$1 sun.util.logging.LoggingSupport$2 sun.util.logging.PlatformLogger sun.util.logging.PlatformLogger$1 sun.util.logging.PlatformLogger$JavaLoggerProxy sun.util.logging.PlatformLogger$Level sun.util.logging.PlatformLogger$LoggerProxy void Found 11885 classes 
# android hooking search classes display [Landroid.hardware.display.WifiDisplay; [Landroid.icu.impl.ICUCurrencyDisplayInfoProvider$ICUCurrencyDisplayInfo$CurrencySink$EntrypointTable; [Landroid.icu.impl.LocaleDisplayNamesImpl$CapitalizationContextUsage; [Landroid.icu.impl.LocaleDisplayNamesImpl$DataTableType; [Landroid.icu.number.NumberFormatter$DecimalSeparatorDisplay; [Landroid.icu.number.NumberFormatter$SignDisplay; [Landroid.icu.text.DisplayContext$Type; [Landroid.icu.text.DisplayContext; [Landroid.icu.text.LocaleDisplayNames$DialectHandling; [Landroid.view.Display$Mode; [Landroid.view.Display; android.app.Vr2dDisplayProperties android.hardware.display.AmbientBrightnessDayStats android.hardware.display.AmbientBrightnessDayStats$1 android.hardware.display.BrightnessChangeEvent com.android.settings.wfd.WifiDisplaySettings$SummaryProvider com.android.settings.wfd.WifiDisplaySettings$SummaryProvider$1 com.android.settingslib.display.BrightnessUtils com.android.settingslib.display.DisplayDensityUtils com.google.android.gles_jni.EGLDisplayImpl javax.microedition.khronos.egl.EGLDisplay Found 144 classes 
# android hooking list class_methods com.android.settings.DisplaySettings private static java.util.List 
  
    com.android.settings.DisplaySettings.buildPreferenceControllers(android.content.Context,com.android.settingslib.core.lifecycle.Lifecycle) protected int com.android.settings.DisplaySettings.getPreferenceScreenResId() protected java.lang.String com.android.settings.DisplaySettings.getLogTag() protected java.util.List 
   
     com.android.settings.DisplaySettings.createPreferenceControllers(android.content.Context) public int com.android.settings.DisplaySettings.getHelpResource() public int com.android.settings.DisplaySettings.getMetricsCategory() static java.util.List com.android.settings.DisplaySettings.access$000(android.content.Context,com.android.settingslib.core.lifecycle.Lifecycle) Found 7 method(s) 
    
  

列出的方法与源码相比对之后,发现是一模一样的。

# android hooking generate simple com.android.settings.DisplaySettings Java.perform(function() { var clazz = Java.use('com.android.settings.DisplaySettings'); clazz.getHelpResource.implementation = function() { // return clazz.getHelpResource.apply(this, arguments); } }); Java.perform(function() { var clazz = Java.use('com.android.settings.DisplaySettings'); clazz.getLogTag.implementation = function() { // return clazz.getLogTag.apply(this, arguments); } }); Java.perform(function() { var clazz = Java.use('com.android.settings.DisplaySettings'); clazz.getPreferenceScreenResId.implementation = function() { // return clazz.getPreferenceScreenResId.apply(this, arguments); } }); 
objection(hook)
# android hooking watch class android.bluetooth.BluetoothDevice 
om.android.settings on (google: 8.1.0) [net] # android hooking search classes bluetooth android.bluetooth.BluetoothA2dp android.bluetooth.BluetoothA2dp$1 android.bluetooth.BluetoothA2dp$2 android.bluetooth.BluetoothAdapter android.bluetooth.BluetoothAdapter$1 android.bluetooth.BluetoothDevice$1 android.bluetooth.BluetoothDevice$2 android.bluetooth.BluetoothHeadset android.bluetooth.BluetoothHeadset$1 android.bluetooth.BluetoothHeadset$2 android.bluetooth.BluetoothHeadset$3 android.bluetooth.BluetoothManager android.bluetooth.BluetoothProfile android.bluetooth.BluetoothProfile$ServiceListener android.bluetooth.IBluetooth android.bluetooth.IBluetooth$Stub android.bluetooth.IBluetooth$Stub$Proxy android.bluetooth.IBluetoothA2dp android.bluetooth.IBluetoothA2dp$Stub android.bluetooth.IBluetoothA2dp$Stub$Proxy android.bluetooth.IBluetoothGatt android.bluetooth.IBluetoothGatt$Stub android.bluetooth.IBluetoothHeadset android.bluetooth.IBluetoothHeadset$Stub android.bluetooth.IBluetoothHeadset$Stub$Proxy android.bluetooth.IBluetoothManager android.bluetooth.IBluetoothManager$Stub android.bluetooth.IBluetoothManager$Stub$Proxy android.bluetooth.IBluetoothManagerCallback android.bluetooth.IBluetoothManagerCallback$Stub android.bluetooth.IBluetoothProfileServiceConnection android.bluetooth.IBluetoothProfileServiceConnection$Stub android.bluetooth.IBluetoothStateChangeCallback android.bluetooth.IBluetoothStateChangeCallback$Stub com.android.settings.Settings$BluetoothSettingsActivity 
com.android.settings on (google: 8.1.0) [net] # android hooking watch class android.bluetooth.BluetoothDevice (agent) Hooking android.bluetooth.BluetoothDevice.-get0() (agent) Hooking android.bluetooth.BluetoothDevice.-set0(android.bluetooth.IBluetooth) (agent) Hooking android.bluetooth.BluetoothDevice.convertPinToBytes(java.lang.String) (agent) Hooking android.bluetooth.BluetoothDevice.getService() (agent) Hooking android.bluetooth.BluetoothDevice.cancelBondProcess() (agent) Hooking android.bluetooth.BluetoothDevice.cancelPairingUserInput() (agent) Hooking android.bluetooth.BluetoothDevice.connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback) (agent) Hooking android.bluetooth.BluetoothDevice.connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int) (agent) Hooking android.bluetooth.BluetoothDevice.connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int) (agent) Hooking android.bluetooth.BluetoothDevice.connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler) (agent) Hooking android.bluetooth.BluetoothDevice.connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, boolean, int, android.os.Handler) (agent) Hooking android.bluetooth.BluetoothDevice.createBond() (agent) Hooking android.bluetooth.BluetoothDevice.createBond(int) (agent) Hooking android.bluetooth.BluetoothDevice.createBondOutOfBand(int, android.bluetooth.OobData) (agent) Hooking android.bluetooth.BluetoothDevice.createInsecureL2capSocket(int) (agent) Hooking android.bluetooth.BluetoothDevice.createInsecureRfcommSocket(int) (agent) Hooking android.bluetooth.BluetoothDevice.createInsecureRfcommSocketToServiceRecord(java.util.UUID) (agent) Hooking android.bluetooth.BluetoothDevice.createL2capSocket(int) (agent) Hooking android.bluetooth.BluetoothDevice.createRfcommSocket(int) (agent) Hooking android.bluetooth.BluetoothDevice.createRfcommSocketToServiceRecord(java.util.UUID) (agent) Hooking android.bluetooth.BluetoothDevice.createScoSocket() (agent) Hooking android.bluetooth.BluetoothDevice.describeContents() (agent) Hooking android.bluetooth.BluetoothDevice.equals(java.lang.Object) (agent) Hooking android.bluetooth.BluetoothDevice.fetchUuidsWithSdp() (agent) Hooking android.bluetooth.BluetoothDevice.getAddress() (agent) Hooking android.bluetooth.BluetoothDevice.getAlias() (agent) Hooking android.bluetooth.BluetoothDevice.getAliasName() (agent) Hooking android.bluetooth.BluetoothDevice.getBatteryLevel() (agent) Hooking android.bluetooth.BluetoothDevice.getBluetoothClass() (agent) Hooking android.bluetooth.BluetoothDevice.getBondState() (agent) Hooking android.bluetooth.BluetoothDevice.getMessageAccessPermission() (agent) Hooking android.bluetooth.BluetoothDevice.getName() (agent) Hooking android.bluetooth.BluetoothDevice.getPhonebookAccessPermission() (agent) Hooking android.bluetooth.BluetoothDevice.getSimAccessPermission() (agent) Hooking android.bluetooth.BluetoothDevice.getType() (agent) Hooking android.bluetooth.BluetoothDevice.getUuids() (agent) Hooking android.bluetooth.BluetoothDevice.hashCode() (agent) Hooking android.bluetooth.BluetoothDevice.isBluetoothDock() (agent) Hooking android.bluetooth.BluetoothDevice.isBluetoothEnabled() (agent) Hooking android.bluetooth.BluetoothDevice.isBondingInitiatedLocally() (agent) Hooking android.bluetooth.BluetoothDevice.isConnected() (agent) Hooking android.bluetooth.BluetoothDevice.isEncrypted() (agent) Hooking android.bluetooth.BluetoothDevice.removeBond() (agent) Hooking android.bluetooth.BluetoothDevice.sdpSearch(android.os.ParcelUuid) (agent) Hooking android.bluetooth.BluetoothDevice.setAlias(java.lang.String) (agent) Hooking android.bluetooth.BluetoothDevice.setDeviceOutOfBandData([B, [B) (agent) Hooking android.bluetooth.BluetoothDevice.setMessageAccessPermission(int) (agent) Hooking android.bluetooth.BluetoothDevice.setPairingConfirmation(boolean) (agent) Hooking android.bluetooth.BluetoothDevice.setPasskey(int) (agent) Hooking android.bluetooth.BluetoothDevice.setPhonebookAccessPermission(int) (agent) Hooking android.bluetooth.BluetoothDevice.setPin([B) (agent) Hooking android.bluetooth.BluetoothDevice.setRemoteOutOfBandData() (agent) Hooking android.bluetooth.BluetoothDevice.setSimAccessPermission(int) (agent) Hooking android.bluetooth.BluetoothDevice.toString() (agent) Hooking android.bluetooth.BluetoothDevice.writeToParcel(android.os.Parcel, int) (agent) Registering job pld7w7pk25n. Type: watch-class for: android.bluetooth.BluetoothDevice com.android.settings on (google: 8.1.0) [net] # jobs list Job ID Hooks Type ----------- ------- -------------------------------------------------- pld7w7pk25n 55 watch-class for: android.bluetooth.BluetoothDevice com.android.settings on (google: 8.1.0) [net] # 
com.android.settings on (google: 9) [usb] # (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getService() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.isConnected() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getService() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getAliasName() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getAlias() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getName() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.equals(java.lang.Object) (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getService() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.isConnected() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getService() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getAliasName() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getAlias() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.getName() (agent) [h0u5g7uclo] Called android.bluetooth.BluetoothDevice.equals(java.lang.Object) 

可以看到我们的切换操作,调用到了android.bluetooth.BluetoothDevice类中的多个方法。

android hooking watch class_method android.bluetooth.BluetoothDevice.getName --dump-args --dump-return --dump-backtrace 

注意最后加上的三个选项–dump-args –dump-return –dump-backtrace,为我们成功打印出来了我们想要看的信息,其实返回值Return Value就是getName()方法的返回值,我的蓝牙耳机的型号名字OnePlus Bullets Wireless 2;从调用栈可以反查如何一步一步调用到getName()这个方法的;虽然这个方法没有参数,大家可以再找个有参数的试一下。

# help android hooking watch class_method Command: android hooking watch class_method Usage: android hooking watch class_method 
   
   
     (optional: --dump-args) (optional: --dump-backtrace) (optional: --dump-return) Hooks a specified class method and reports on invocations, together with the number of arguments that method was called with. This command will also hook all of the methods available overloads unless a specific overload is specified. If the --include-backtrace flag is provided, a full stack trace that lead to the methods invocation will also be dumped. This would aid in discovering who called the original method. Examples: android hooking watch class_method com.example.test.login android hooking watch class_method com.example.test.helper.executeQuery android hooking watch class_method com.example.test.helper.executeQuery "java.lang.String,java.lang.String" android hooking watch class_method com.example.test.helper.executeQuery --dump-backtrace android hooking watch class_method com.example.test.login --dump-args --dump-return 
    
  

那我们可以用File类的构造器来试一下效果。

# android hooking watch class_method java.io.File.$init --dump-args 
com.android.settings on (google: 8.1.0) [net] # plugin load /root/Desktop/Wallbre aker 

就可以使用插件,查看查看各种变量及信息。

com.android.settings on (google: 8.1.0) [net] # plugin wallbreaker classdump --f ullname android.bluetooth.BluetoothDevice package android.bluetooth class BluetoothDevice { /* static fields */ static int ACCESS_ALLOWED; => 1 static int ACCESS_REJECTED; => 2 static int ACCESS_UNKNOWN; => 0 static java.lang.String ACTION_ACL_CONNECTED; => android.bluetooth.device.action.ACL_CONNECTED static java.lang.String ACTION_ACL_DISCONNECTED; => android.bluetooth.device.action.ACL_DISCONNECTED static java.lang.String ACTION_ACL_DISCONNECT_REQUESTED; => android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED static java.lang.String ACTION_ALIAS_CHANGED; => android.bluetooth.device.action.ALIAS_CHANGED static java.lang.String ACTION_BATTERY_LEVEL_CHANGED; => android.bluetooth.device.action.BATTERY_LEVEL_CHANGED static java.lang.String ACTION_BOND_STATE_CHANGED; => android.bluetooth.device.action.BOND_STATE_CHANGED static java.lang.String ACTION_CLASS_CHANGED; => android.bluetooth.device.action.CLASS_CHANGED static java.lang.String ACTION_CONNECTION_ACCESS_CANCEL; => android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL static java.lang.String ACTION_CONNECTION_ACCESS_REPLY; => android.bluetooth.device.action.CONNECTION_ACCESS_REPLY static java.lang.String ACTION_CONNECTION_ACCESS_REQUEST; => android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST static java.lang.String ACTION_DISAPPEARED; => android.bluetooth.device.action.DISAPPEARED static java.lang.String ACTION_FOUND; => android.bluetooth.device.action.FOUND static java.lang.String ACTION_MAS_INSTANCE; => android.bluetooth.device.action.MAS_INSTANCE static java.lang.String ACTION_NAME_CHANGED; => android.bluetooth.device.action.NAME_CHANGED static java.lang.String ACTION_NAME_FAILED; => android.bluetooth.device.action.NAME_FAILED static java.lang.String ACTION_PAIRING_CANCEL; => android.bluetooth.device.action.PAIRING_CANCEL static java.lang.String ACTION_PAIRING_REQUEST; => android.bluetooth.device.action.PAIRING_REQUEST static java.lang.String ACTION_SDP_RECORD; => android.bluetooth.device.action.SDP_RECORD static java.lang.String ACTION_UUID; => android.bluetooth.device.action.UUID static int BATTERY_LEVEL_UNKNOWN; => -1 static int BOND_BONDED; => 12 static int BOND_BONDING; => 11 static int BOND_NONE; => 10 static int BOND_SUCCESS; => 0 static int CONNECTION_ACCESS_NO; => 2 static int CONNECTION_ACCESS_YES; => 1 static int CONNECTION_STATE_CONNECTED; => 1 static int CONNECTION_STATE_DISCONNECTED; => 0 static int CONNECTION_STATE_ENCRYPTED_BREDR; => 2 static int CONNECTION_STATE_ENCRYPTED_LE; => 4 static android.os.Parcelable$Creator CREATOR; => [0x2272]: android.bluetooth.BluetoothDevice$2@7a81e5 static boolean DBG; => false static int DEVICE_TYPE_CLASSIC; => 1 static int DEVICE_TYPE_DUAL; => 3 static int DEVICE_TYPE_LE; => 2 static int DEVICE_TYPE_UNKNOWN; => 0 static int ERROR; => - static java.lang.String EXTRA_ACCESS_REQUEST_TYPE; => android.bluetooth.device.extra.ACCESS_REQUEST_TYPE static java.lang.String EXTRA_ALWAYS_ALLOWED; => android.bluetooth.device.extra.ALWAYS_ALLOWED static java.lang.String EXTRA_BATTERY_LEVEL; => android.bluetooth.device.extra.BATTERY_LEVEL static java.lang.String EXTRA_BOND_STATE; => android.bluetooth.device.extra.BOND_STATE static java.lang.String EXTRA_CLASS; => android.bluetooth.device.extra.CLASS static java.lang.String EXTRA_CLASS_NAME; => android.bluetooth.device.extra.CLASS_NAME static java.lang.String EXTRA_CONNECTION_ACCESS_RESULT; => android.bluetooth.device.extra.CONNECTION_ACCESS_RESULT static java.lang.String EXTRA_DEVICE; => android.bluetooth.device.extra.DEVICE static java.lang.String EXTRA_MAS_INSTANCE; => android.bluetooth.device.extra.MAS_INSTANCE static java.lang.String EXTRA_NAME; => android.bluetooth.device.extra.NAME static java.lang.String EXTRA_PACKAGE_NAME; => android.bluetooth.device.extra.PACKAGE_NAME static java.lang.String EXTRA_PAIRING_KEY; => android.bluetooth.device.extra.PAIRING_KEY static java.lang.String EXTRA_PAIRING_VARIANT; => android.bluetooth.device.extra.PAIRING_VARIANT static java.lang.String EXTRA_PREVIOUS_BOND_STATE; => android.bluetooth.device.extra.PREVIOUS_BOND_STATE static java.lang.String EXTRA_REASON; => android.bluetooth.device.extra.REASON static java.lang.String EXTRA_RSSI; => android.bluetooth.device.extra.RSSI static java.lang.String EXTRA_SDP_RECORD; => android.bluetooth.device.extra.SDP_RECORD static java.lang.String EXTRA_SDP_SEARCH_STATUS; => android.bluetooth.device.extra.SDP_SEARCH_STATUS static java.lang.String EXTRA_UUID; => android.bluetooth.device.extra.UUID static int PAIRING_VARIANT_CONSENT; => 3 static int PAIRING_VARIANT_DISPLAY_PASSKEY; => 4 static int PAIRING_VARIANT_DISPLAY_PIN; => 5 static int PAIRING_VARIANT_OOB_CONSENT; => 6 static int PAIRING_VARIANT_PASSKEY; => 1 static int PAIRING_VARIANT_PASSKEY_CONFIRMATION; => 2 static int PAIRING_VARIANT_PIN; => 0 static int PAIRING_VARIANT_PIN_16_DIGITS; => 7 static int PHY_LE_1M; => 1 static int PHY_LE_1M_MASK; => 1 static int PHY_LE_2M; => 2 static int PHY_LE_2M_MASK; => 2 static int PHY_LE_CODED; => 3 static int PHY_LE_CODED_MASK; => 4 static int PHY_OPTION_NO_PREFERRED; => 0 static int PHY_OPTION_S2; => 1 static int PHY_OPTION_S8; => 2 static int REQUEST_TYPE_MESSAGE_ACCESS; => 3 static int REQUEST_TYPE_PHONEBOOK_ACCESS; => 2 static int REQUEST_TYPE_PROFILE_CONNECTION; => 1 static int REQUEST_TYPE_SIM_ACCESS; => 4 static java.lang.String TAG; => BluetoothDevice static int TRANSPORT_AUTO; => 0 static int TRANSPORT_BREDR; => 1 static int TRANSPORT_LE; => 2 static int UNBOND_REASON_AUTH_CANCELED; => 3 static int UNBOND_REASON_AUTH_FAILED; => 1 static int UNBOND_REASON_AUTH_REJECTED; => 2 static int UNBOND_REASON_AUTH_TIMEOUT; => 6 static int UNBOND_REASON_DISCOVERY_IN_PROGRESS; => 5 static int UNBOND_REASON_REMOTE_AUTH_CANCELED; => 8 static int UNBOND_REASON_REMOTE_DEVICE_DOWN; => 4 static int UNBOND_REASON_REMOVED; => 9 static int UNBOND_REASON_REPEATED_ATTEMPTS; => 7 static android.bluetooth.IBluetoothManagerCallback mStateChangeCallback; => [0x2c1a]: android.bluetooth.BluetoothDevice$1@3db44ba static android.bluetooth.IBluetooth sService; => null /* instance fields */ java.lang.String mAddress; /* constructor methods */ android.bluetooth.BluetoothDevice(java.lang.String); /* static methods */ static android.bluetooth.IBluetooth -get0(); static android.bluetooth.IBluetooth -set0(android.bluetooth.IBluetooth); static [B convertPinToBytes(java.lang.String); static android.bluetooth.IBluetooth getService(); /* instance methods */ boolean cancelBondProcess(); boolean cancelPairingUserInput(); android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback); android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int); android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int); android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, int, android.os.Handler); android.bluetooth.BluetoothGatt connectGatt(android.content.Context, boolean, android.bluetooth.BluetoothGattCallback, int, boolean, int, android.os.Handler); boolean createBond(); boolean createBond(int); boolean createBondOutOfBand(int, android.bluetooth.OobData); android.bluetooth.BluetoothSocket createInsecureL2capSocket(int); android.bluetooth.BluetoothSocket createInsecureRfcommSocket(int); android.bluetooth.BluetoothSocket createInsecureRfcommSocketToServiceRecord(java.util.UUID); android.bluetooth.BluetoothSocket createL2capSocket(int); android.bluetooth.BluetoothSocket createRfcommSocket(int); android.bluetooth.BluetoothSocket createRfcommSocketToServiceRecord(java.util.UUID); android.bluetooth.BluetoothSocket createScoSocket(); int describeContents(); boolean equals(java.lang.Object); boolean fetchUuidsWithSdp(); java.lang.String getAddress(); java.lang.String getAlias(); java.lang.String getAliasName(); int getBatteryLevel(); android.bluetooth.BluetoothClass getBluetoothClass(); int getBondState(); int getMessageAccessPermission(); java.lang.String getName(); int getPhonebookAccessPermission(); int getSimAccessPermission(); int getType(); [Landroid.os.ParcelUuid; getUuids(); int hashCode(); boolean isBluetoothDock(); boolean isBluetoothEnabled(); boolean isBondingInitiatedLocally(); boolean isConnected(); boolean isEncrypted(); boolean removeBond(); boolean sdpSearch(android.os.ParcelUuid); boolean setAlias(java.lang.String); boolean setDeviceOutOfBandData(B[], B[]); boolean setMessageAccessPermission(int); boolean setPairingConfirmation(boolean); boolean setPasskey(int); boolean setPhonebookAccessPermission(int); boolean setPin(B[]); boolean setRemoteOutOfBandData(); boolean setSimAccessPermission(int); java.lang.String toString(); void writeToParcel(android.os.Parcel, int); } 

使用FRIDA-DEXDump脱壳

安装测试软件,加载FRIDA-DEXDump插件,查看有该包有什么类

root@kali:~/Desktop# objection -N -h 192.168.1.10 -p 8888 -g com.cz.babySister explore Using networked device @`192.168.1.10:8888` Agent injected and responds ok! _ _ _ _ ___| |_|_|___ ___| |_|_|___ ___ | . | . | | -_| _| _| | . | | |___|___| |___|___|_| |_|___|_|_| |___|(object)inject(ion) v1.8.4 Runtime Mobile Exploration by: @leonjza from @sensepost [tab] for command suggestions com.cz.babySister on (google: 8.1.0) [net] # plugin Unknown or ambiguous command: `plugin`. Try `help plugin`. com.cz.babySister on (google: 8.1.0) [net] # plugin load /root/Desktop/FRIDA-DEX Dump/frida_dexdump Loaded plugin: dexdump com.cz.babySister on (google: 8.1.0) [net] # android hooking search classes com. cz.babySister com.cz.babySister.activity.BaseActivity com.cz.babySister.activity.LoginActivity com.cz.babySister.activity.MainActivity com.cz.babySister.activity.N com.cz.babySister.activity.O com.cz.babySister.activity.P com.cz.babySister.activity.Q com.cz.babySister.activity.RegisterActivity com.cz.babySister.activity.S com.cz.babySister.activity.T com.cz.babySister.activity.WelcomeActivity com.cz.babySister.activity.a com.cz.babySister.activity.k com.cz.babySister.activity.l com.cz.babySister.activity.m com.cz.babySister.activity.n com.cz.babySister.activity.o com.cz.babySister.activity.oa com.cz.babySister.application.MyApplication com.cz.babySister.application.a com.cz.babySister.interfaces.CitySelectLiener com.cz.babySister.interfaces.JiFenInterFaces Found 22 classes 

查看积分所在类的函数

com.cz.babySister on (google: 8.1.0) [net] # android hooking list class_methods com.cz.babySister.interfaces.JiFenInterFaces public abstract void com.cz.babySister.interfaces.JiFenInterFaces.getJiFen(float) Found 1 method(s) 
om.cz.babySister on (google: 8.1.0) [net] # plugin dexdump search [DEXDump] Found: DexAddr=0x777f4ee01c, DexSize=0x636b10 [DEXDump] Found: DexAddr=0x777fbb8000, DexSize=0xba28 [DEXDump] Found: DexAddr=0x, DexSize=0xba28 [DEXDump] Found: DexAddr=0x7781dc4f85, DexSize=0x11c [DEXDump] Found: DexAddr=0x7781f2abde, DexSize=0x11c [DEXDump] Found: DexAddr=0xc, DexSize=0x3339c [DEXDump] Found: DexAddr=0x7782cb101c, DexSize=0xba28 [DEXDump] Found: DexAddr=0x778fddf080, DexSize=0x [DEXDump] Found: DexAddr=0x781f5bd000, DexSize=0x580 [DEXDump] Found: DexAddr=0x781f, DexSize=0x1ec com.cz.babySister on (google: 8.1.0) [net] # plugin dexdump dump [DEXDump]: DexSize=0x636b10, DexMd5=df1e99cee87d4efbc2913a2, SavePath=/root/Desktop/com.cz.babySister/0x777f4ee01c.dex [DEXDump]: DexSize=0xba28, DexMd5=a2fa46881e6a15401a35e782d91a5c30, SavePath=/root/Desktop/com.cz.babySister/0x777fbb8000.dex [DEXDump]: Skip duplicate dex 0x 
  
    [DEXDump]: DexSize=0x11c, DexMd5=f1771b68f5f9b168b79ff59ae2daabe4, SavePath=/root/Desktop/com.cz.babySister/0x7781dc4f85.dex [DEXDump]: Skip duplicate dex 0x7781f2abde 
   
     [DEXDump]: DexSize=0x3339c, DexMd5=b4b87d2c326c2cbd92b15ca9d453a565, SavePath=/root/Desktop/com.cz.babySister/0xc.dex [DEXDump]: DexSize=0xba28, DexMd5=e5a76d0e8fc1e7b36ffa744bfa47a183, SavePath=/root/Desktop/com.cz.babySister/0x7782cb101c.dex [Except] - Error: access violation accessing 0x778fe00000 at frida/runtime/core.js:144 at frida/runtime/message-dispatcher.js:15 at c (frida/runtime/message-dispatcher.js:25): {'addr': '0x778fddf080', 'size': } [DEXDump]: DexSize=0x580, DexMd5=1dd45877a3cd479a9e54953d0b0b029c, SavePath=/root/Desktop/com.cz.babySister/0x781f5bd000.dex [DEXDump]: DexSize=0x1ec, DexMd5=a5b3b0cf5f, SavePath=/root/Desktop/com.cz.babySister/0x781f.dex 
    
  

就报存下来dump文件了。

Frida上手和逆向三段

  • 基本操作:参数,调用栈,返回值
  • 方法重载,参数构造,动静态处理
  • 主动调用,忽略内部细节,直接返回结果
  • 逆向三段:hook,invoke,rpc

demo

源程序

package com.example.lesson4one; import androidx.appcompat.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); while(true){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } fun(50,80); } } int fun(int x,int y){ Log.d("kanxue",String.valueOf((x+y))); return x+y; } } 

注入脚本

function main(){ Java.perform(function(){ Java.use("com.example.lesson4one.MainActivity").fun.implementation =function(arg1,arg2){ var result=this.fun(arg1,arg2) console.log("arg1,arg2,result",arg1,arg2,result) return result; } }) } setImmediate(main) 
root@kali:~/Downloads/frida-agent-example/agent# frida -U com.example.lesson4one -l lesson4-2.js ____ / _ | Frida 12.8.0 - A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at https://www.frida.re/docs/home/ [Google Pixel XL::com.example.lesson4one]-> arg1,arg2,result 50 80 130 arg1,arg2,result 50 80 130 arg1,arg2,result 50 80 130 arg1,arg2,result 50 80 130 arg1,arg2,result 50 80 130 [Google Pixel XL::com.example.lesson4one]-> arg1,arg2,result 50 80 130 

修改脚本

var result=this.fun(100,200) 

返回结果

rg1,arg2,result 50 80 300 arg1,arg2,result 50 80 300 arg1,arg2,result 50 80 300 arg1,arg2,result 50 80 300 

以下一句话打印调用栈

console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new())); 

关于重载

如果在代码中加入

 String fun(String x ){ total +=x ; return x.toLowerCase(); } int fun(int x ,int y){ Log.d("kanxue", String.valueOf((x+y))); return x+y; } 

hook时如下会报错,提示重载

root@kali:~/Downloads/frida-agent-example/agent# frida -U com.example.lesson4one -l lesson4-2.js Error: fun(): has more than one overload, use .overload( 
  
    ) to choose from: .overload('java.lang.String') .overload('int', 'int') at throwOverloadError (frida/node_modules/frida-java-bridge/lib/class-factory.js:1020) at frida/node_modules/frida-java-bridge/lib/class-factory.js:707 at /lesson4-2.js:7 at frida/node_modules/frida-java-bridge/lib/vm.js:11 at E (frida/node_modules/frida-java-bridge/index.js:346) at frida/node_modules/frida-java-bridge/index.js:298 at frida/node_modules/frida-java-bridge/lib/vm.js:11 at frida/node_modules/frida-java-bridge/index.js:278 at main (/lesson4-2.js:8) 
  

需要按照提示加入

overload(‘int’, ‘int’)

function main(){ Java.perform(function(){ Java.use("com.example.lesson4one.MainActivity").fun.overload('int', 'int').implementation =function(arg1,arg2){ var result=this.fun(100,200) console.log("arg1,arg2,result",arg1,arg2,result) return result; } }) } setImmediate(main) 

此时就可以hook成功。

root@kali:~/Downloads/frida-agent-example/agent# frida -U com.example.lesson4one -l lesson4-2.js ____ java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 java.lang.Throwable at com.example.lesson4one.MainActivity.fun(Native Method) at com.example.lesson4one.MainActivity.onCreate(MainActivity.java:22) at android.app.Activity.performCreate(Activity.java:6999) at android.app.Activity.performCreate(Activity.java:6990) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1214) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2731) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2856) at android.app.ActivityThread.-wrap11(Unknown Source:0) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1589) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6494) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807) arg1,arg2,result 50 80 300 

关于未调用的动态函数

如在android程序中

 String secret(){ return total; } 
假如secret2是静态函数 Java.use("com.example.lesson4one.MainActivity").secret2() 

动态函数要找到实例,然后再通过实例调用

function invoke(){ Java.perform(function(){ Java.choose("com.example.lesson4one.MainActivity",{ onMatch:function(instance){ console.log("found insttance ",instance); console.log("invoke instance.secret ",instance.secret()); },onComplete:function(){console.log("search completed !")} }) }) } setTimeout(invoke,2000) 

Frida构造数组、对象、Map和类参数

数组

源码

 Log.d("SimpleArray", "onCreate: SImpleArray"); char arr[][] = new char[4][]; // 创建一个4行的二维数组 arr[0] = new char[] { '春', '眠', '不', '觉', '晓' }; // 为每一行赋值 arr[1] = new char[] { '处', '处', '闻', '啼', '鸟' }; arr[2] = new char[] { '夜', '来', '风', '雨', '声' }; arr[3] = new char[] { '花', '落', '知', '多', '少' }; Log.d("SimpleArray", "-----横版-----"); for (int i = 0; i < 4; i++) { // 循环4行 //Log.d("SimpleArraysToString", Arrays.toString(arr[i])); //Log.d("SimpleStringBytes", Arrays.toString (Arrays.toString (arr[i]).getBytes())); for (int j = 0; j < 5; j++) { // 循环5列 Log.d("SimpleArray", Character.toString(arr[i][j])); // 输出数组中的元素 } if (i % 2 == 0) { Log.d("SimpleArray", ",");// 如果是一、三句,输出逗号 } else { Log.d("SimpleArray", "。");// 如果是二、四句,输出句号 } } 

要对Character.toString用fridahook,观察值

function main(){ Java.perform(function(){ Java.use("java.lang.Character").toString.overload('char').implementation =function(x) { var result=this.toString(x) console.log("x,result",x,result) return result } }) } setImmediate(main) 

结果如下

root@kali:~/Downloads/frida-agent-example/agent# frida -U -f com.kanxue.lesson5 -l lesson5.js --no-pause Spawned `com.kanxue.lesson5`. Resuming main thread! [Google Pixel XL::com.kanxue.lesson5]-> x,result 春 春 x,result 眠 眠 x,result 不 不 x,result 觉 觉 x,result 晓 晓 x,result 处 处 x,result 处 处 x,result 闻 闻 

再如要打印一整行,然后hook改变结果,改变如下代码生成的结果

Log.d("SimpleArraysToString", Arrays.toString(arr[i])); 

脚本如下

function main(){ Java.perform(function(){ Java.use("java.util.Arrays").toString.overload('[C').implementation=function(x) { var result=this.toString(x); console.log("x,result",x,result); return result; } }) } 

结果如下:

[Google Pixel XL::com.kanxue.lesson5]-> x,result [object Object] [春, 眠, 不, 觉, 晓] x,result [object Object] [春, 眠, 不, 觉, 晓] x,result [object Object] [处, 处, 闻, 啼, 鸟] x,result [object Object] [处, 处, 闻, 啼, 鸟] x,result [object Object] [夜, 来, 风, 雨, 声] x,result [object Object] [夜, 来, 风, 雨, 声] x,result [object Object] [花, 落, 知, 多, 少] x,result [object Object] [花, 落, 知, 多, 少] 
function main(){ Java.perform(function(){ Java.openClassFile("/data/local/tmp/r0gson.dex").load(); const gson = Java.use('com.r0ysue.gson.Gson'); //console.log(gson.$new().toJson(xxx)); Java.use("java.util.Arrays").toString.overload('[C').implementation=function(x) { var result=this.toString(x); console.log("x,result",gson.$new().toJson(x),result); return result; } }) } setImmediate(main) 
[Google Pixel XL::com.kanxue.lesson5]-> x,result ["春","眠","不","觉","晓"] [春, 眠, 不, 觉, 晓] x,result ["处","处","闻","啼","鸟"] [处, 处, 闻, 啼, 鸟] x,result ["夜","来","风","雨","声"] [夜, 来, 风, 雨, 声] x,result ["花","落","知","多","少"] [花, 落, 知, 多, 少] x,result ["春","眠","不","觉","晓"] [春, 眠, 不, 觉, 晓] x,result ["处","处","闻","啼","鸟"] [处, 处, 闻, 啼, 鸟] x,result ["夜","来","风","雨","声"] [夜, 来, 风, 雨, 声] x,result ["花","落","知","多","少"] [花, 落, 知, 多, 少] 

构造数组

可以使用frida API Java.array构造

function main(){ Java.perform(function(){ Java.openClassFile("/data/local/tmp/r0gson.dex").load(); const gson = Java.use('com.r0ysue.gson.Gson'); //console.log(gson.$new().toJson(xxx)); Java.use("java.util.Arrays").toString.overload('[C').implementation=function(x) { var charArray=Java.array('char',['一', '行', '白', '鹭', '上', '青', '天']); var result=this.toString(charArray); console.log("x,result",gson.$new().toJson(charArray),result); return Java.use("java.lang.String").$new("我连安全在搞啥都不知道"); } }) } setImmediate(main) 

结果如下:

root@kali:~/Downloads/frida-agent-example/agent# frida -U -f com.kanxue.lesson5 -l lesson5.js --no-pause ____ / _ | Frida 12.8.0 - A world-class dynamic instrumentation toolkit | (_| | > _ | Commands: /_/ |_| help -> Displays the help system . . . . object? -> Display information about 'object' . . . . exit/quit -> Exit . . . . . . . . More info at https://www.frida.re/docs/home/ Spawned `com.kanxue.lesson5`. Resuming main thread! [Google Pixel XL::com.kanxue.lesson5]-> x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] x,result ["一","行","白","鹭","上","青","天"] [一, 行, 白, 鹭, 上, 青, 天] 

另外如果想hook以下代码,就是一个数组转为字符串,然后在getBytes打印。

Log.d("SimpleStringBytes", Arrays.toString (Arrays.toString (arr[i]).getBytes())); 

frida脚本为:

 Java.use("java.util.Arrays").toString.overload('[B').implementation=function(x) { var result=this.toString(x); console.log("x,result",gson.$new().toJson(x),result); return result; } 

强制类型转换

package com.kanxue.lesson5; import android.util.Log; public class Water { // 水 类 public static String flow(Water W) { // 水 的方法 // SomeSentence Log.d("2Object", "water flow: I`m flowing"); return "water flow: I`m flowing"; } public String still(Water W) { // 水 的方法 // SomeSentence Log.d("2Object", "water still: still water runs deep!"); return "water still: still water runs deep!"; } } package com.kanxue.lesson5; import android.util.Log; public class Juice extends Water { // 果汁 类 继承了水类 public String fillEnergy(){ Log.d("2Object", "Juice: i`m fillingEnergy!"); return "Juice: i`m fillingEnergy!"; } public static void main() { Water w1 = new Water(); flow(w1) ; // Juice J = new Juice(); // 实例化果汁类对象 flow(J) ; // 调用水的方法 向上转型 J → W Water w2 = new Juice(); ((Juice) w2).fillEnergy(); } } 

脚本

function main(){ Java.perform(function(){ var Waterhandle=null; Java.choose("com.kanxue.lesson5.Water",{ onMatch:function(instance){ console.log("found instance:",instance); console.log("instance call still:",instance.still(instance)); Waterhandle=instance; },onComplete:function(){console.log("search is completed!")} }) }) } setImmediate(main) 

结果

root@kali:~/Downloads/frida-agent-example/agent# frida -U com.kanxue.lesson5 -l found instance: com.kanxue.lesson5.Water@53ef60e instance call still: water still: still water runs deep! found instance: com.kanxue.lesson5.Water@79b382f instance call still: water still: still water runs deep! search is completed! [Google Pixel XL::com.kanxue.lesson5]-> 
 var JuiceHandle = null ; Java.choose("com.kanxue.lesson5.Juice",{ onMatch:function(instance){ console.log("found instance :",instance); console.log("filling energy,",instance.fillEnergy()); JuiceHandle= instance; },onComplete:function(){"Search Completed!"} }) var WaterHandle = Java.cast(JuiceHandle ,Java.use("com.kanxue.lesson5.Water")); console.log("Water invoke still ", WaterHandle.still(WaterHandle)); 

结果

found instance : com.kanxue.lesson5.Juice@b8f6e3c filling energy, Juice: i`m fillingEnergy! found instance : com.kanxue.lesson5.Juice@e1067c5 filling energy, Juice: i`m fillingEnergy! found instance : com.kanxue.lesson5.Juice@3f8651a filling energy, Juice: i`m fillingEnergy! found instance : com.kanxue.lesson5.Juice@bad284b filling energy, Juice: i`m fillingEnergy! Water invoke still water still: still water runs deep! 

父类转子类是不行的

接口interface

如下,代码,milk类实现了liquid接口

package com.kanxue.lesson5; public interface liquid { public String flow(); } package com.kanxue.lesson5; import android.util.Log; public class milk implements liquid { public String flow(){ Log.d("3interface", "flowing : interface "); return "nihao"; }; public static void main() { milk m = new milk(); m.flow(); } } 

我们可以用到Java.registerClass(spec),其可以根据接口创建一个类。

Java.registerClass(spec): create a new Java class and return a wrapper for it, where spec is an object containing: name: String specifying the name of the class. superClass: (optional) Super-class. Omit to inherit from java.lang.Object. implements: (optional) Array of interfaces implemented by this class. fields: (optional) Object specifying the name and type of each field to expose. methods: (optional) Object specifying methods to implement. 

实现了一个beer,beer类实现了接口liquid

function main(){ Java.perform(function(){ var beer = Java.registerClass({ name: 'com.kanxue.lesson5.beer', implements: [Java.use('com.kanxue.lesson5.liquid')], methods: { flow: function(){ console.log("flow beer"); return "test good"; } } }); console.log("beer.flow",beer.$new().flow()); }) } 

枚举

package com.kanxue.lesson5; import android.util.Log; enum Signal { GREEN, YELLOW, RED } public class TrafficLight { public static Signal color = Signal.RED; public static void main() { //Log.d("4enum", "enum "+ color.getClass().getName().toString()); Log.d("4enum", "enum "+ color); switch (color) { case RED: color = Signal.GREEN; break; case YELLOW: color = Signal.RED; break; case GREEN: color = Signal.YELLOW; break; } } } 

frida脚本查找匹配枚举

Java.choose("com.kanxue.lesson5.Signal",{ onMatch:function(instance){ console.log("found instance",instance); console.log("invoke getDeclaringClass",instance.getDeclaringClass()); },onComplete:function(){ {"Search Completed!"}; } }) }) 

结果

found instance GREEN invoke getDeclaringClass class com.kanxue.lesson5.Signal found instance YELLOW invoke getDeclaringClass class com.kanxue.lesson5.Signal found instance RED invoke getDeclaringClass class com.kanxue.lesson5.Signal 

关于stl打印。hook变量

在源程序如下:

 Map 
  
    mapr0ysue = new HashMap<>(); // 创建Map集合对象 mapr0ysue.put("ISBN 978-7-5677-8742-1", "Android项目开发实战入门"); // 向Map集合中添加元素 mapr0ysue.put("ISBN 978-7-5677-8741-4", "C语言项目开发实战入门"); mapr0ysue.put("ISBN 978-7-5677-9097-1", "PHP项目开发实战入门"); mapr0ysue.put("ISBN 978-7-5677-8740-7", "Java项目开发实战入门"); //Log.d("5map", "key值toString"+mapr0ysue.toString()); Set 
   
     set = mapr0ysue.keySet(); // 构建Map集合中所有key的Set集合 Iterator 
    
      it = set.iterator(); // 创建Iterator迭代器 Log.d("5map", "key值:"); while (it.hasNext()) { // 遍历并输出Map集合中的key值 try { Thread.sleep(2000); Log.d("5map", it.next()+" "); } catch (InterruptedException e) { e.printStackTrace(); } } 
     
    
  

frida代码如下:

function hashmap888(){ Java.perform(function(){ Java.choose("java.util.HashMap",{ onMatch:function(instance){ if(instance.toString().indexOf("ISBN")!=-1) { console.log("found HashMap:",instance); console.log("HashMap toString:",instance.toString()); } },onComplete:function(){ console.log("Search Completed!"); } }) }) } setImmediate(hashmap888,2000) 

结果:

found HashMap: {ISBN 978-7-5677-9097-1=PHP项目开发实战入门, ISBN 978-7-5677-8742-1=Android项目开发实战入门, ISBN 978-7-5677-8741-4=C语言项目开发实战入门, ISBN 978-7-5677-8740-7=Java项目开发实战入门} HashMap toString: {ISBN 978-7-5677-9097-1=PHP项目开发实战入门, ISBN 978-7-5677-8742-1=Android项目开发实战入门, ISBN 978-7-5677-8741-4=C语言项目开发实战入门, ISBN 978-7-5677-8740-7=Java项目开发实战入门} Search Completed! 

Frida综合情景案例

demo1

如图找到判断LoginActivity.a(obj, obj).equals(obj2)调用错误代码处

 public void onClick(View view) { String obj = editText.getText().toString(); String obj2 = editText2.getText().toString(); if (TextUtils.isEmpty(obj) || TextUtils.isEmpty(obj2)) { Toast.makeText(LoginActivity.this.mContext, "username or password is empty.", 1).show(); } else if (LoginActivity.a(obj, obj).equals(obj2)) { LoginActivity.this.startActivity(new Intent(LoginActivity.this.mContext, FridaActivity1.class)); LoginActivity.this.finishActivity(0); } else { Toast.makeText(LoginActivity.this.mContext, "Login failed.", 1).show(); } } }); 

进行fridahook

function main(){ Java.perform(function(){ Java.use("com.example.androiddemo.Activity.LoginActivity").a.overload('java.lang.String', 'java.lang.String').implementation=function(x,y){ var result=this.a(x,y); console.log("x,y,result:",x,y,result); return result; } }) } setImmediate(main) 

随便输出aaaaa,结果如下:

[Google Pixel XL::com.example.androiddemo]-> x,y,result: aaaaaa aaaaaa 4dca528a2131b62a29686c0cf67a15926faef3cfc24becfc49f635a5bfec7519 
adb shell input text 4dca528a2131b62a29686c0cf67a15926faef3cfc24becfc49f635a5bfec7519 
 public void CheckSuccess() { } 

根据代码找到第一关

ublic class FridaActivity1 extends BaseFridaActivity { private static final char[] table = {'L', 'K', 'N', 'M', 'O', 'Q', 'P', 'R', 'S', 'A', 'T', 'B', 'C', 'E', 'D', 'F', 'G', 'H', 'I', 'J', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'o', 'd', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'e', 'f', 'g', 'h', 'j', 'i', 'k', 'l', 'm', 'n', 'y', 'z', '0', '1', '2', '3', '4', '6', '5', '7', '8', '9', '+', '/'}; @Override // com.example.androiddemo.Activity.BaseFridaActivity public String getNextCheckTitle() { return "当前第1关"; } @Override // com.example.androiddemo.Activity.BaseFridaActivity public void onCheck() { try { if (a(b("请输入密码:")).equals("R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL=")) { CheckSuccess(); startActivity(new Intent(this, FridaActivity2.class)); finishActivity(0); return; } super.CheckFailed(); } catch (Exception e) { e.printStackTrace(); } } 
function main(){ Java.perform(function(){ Java.use("com.example.androiddemo.Activity.FridaActivity1").a.implementation=function(x){ var result="R4jSLLLLLLLLLLOrLE7/5B+Z6fsl65yj6BgC6YWz66gO6g2t65Pk6a+P65NK44NNROl0wNOLLLL="; console.log("result:",result); return result; } }) } setImmediate(main) 
 private static void setStatic_bool_var() { static_bool_var = true; } private void setBool_var() { this.bool_var = true; } @Override // com.example.androiddemo.Activity.BaseFridaActivity public void onCheck() { if (!static_bool_var || !this.bool_var) { super.CheckFailed(); return; } CheckSuccess(); 

代码如下:

function second(){ Java.perform(function(){ //static Java.use("com.example.androiddemo.Activity.FridaActivity2").setStatic_bool_var(); //dynamic Java.choose("com.example.androiddemo.Activity.FridaActivity2", {onMatch:function(instance){ console.log("found instance"); instance.setBool_var(); },onComplete:function(){console.log("search completed !")} }) }) } setImmediate(second) 
 public void onCheck() { if (!static_bool_var || !this.bool_var || !this.same_name_bool_var) { super.CheckFailed(); return; } 
function thrid(){ Java.perform( function(){ Java.use("com.example.androiddemo.Activity.FridaActivity3").static_bool_var.value=true; Java.choose("com.example.androiddemo.Activity.FridaActivity3", {onMatch:function(instance){ console.log("found instance"); instance.bool_var.value=true; instance._same_name_bool_var.value=true; },onComplete:function(){console.log("search completed !")} }) }) } setImmediate(thrid) 

第四关为内部类函数,全部要设置为true,才能进入下一关

public class FridaActivity4 extends BaseFridaActivity { @Override // com.example.androiddemo.Activity.BaseFridaActivity public String getNextCheckTitle() { return "当前第4关"; } private static class InnerClasses { public static boolean check1() { return false; } public static boolean check2() { return false; } public static boolean check3() { return false; } public static boolean check4() { return false; } public static boolean check5() { return false; } public static boolean check6() { return false; } private InnerClasses() { } } @Override // com.example.androiddemo.Activity.BaseFridaActivity public void onCheck() { if (!InnerClasses.check1() || !InnerClasses.check2() || !InnerClasses.check3() || !InnerClasses.check4() || !InnerClasses.check5() || !InnerClasses.check6()) { super.CheckFailed(); return; } CheckSuccess(); startActivity(new Intent(this, FridaActivity5.class)); finishActivity(0); } } 

frida代码如下:

function fourth(){ Java.perform(function(){ Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check1.implementation=function(){ return true; } Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check2.implementation=function(){ return true; } Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check3.implementation=function(){ return true; } Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check4.implementation=function(){ return true; } Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check5.implementation=function(){ return true; } Java.use("com.example.androiddemo.Activity.FridaActivity4$InnerClasses").check6.implementation=function(){return true;} } )} setImmediate(fourth) 

如果函数太多可以使用枚举:

function forth2(){ Java.perform(function(){ var class_name = "com.example.androiddemo.Activity.FridaActivity4$InnerClasses" ; var InnerClass = Java.use(class_name); var all_methods = InnerClass.class.getDeclaredMethods(); //console.log(all_methods); for(var i = 0;i 
  
public void onCheck() { if (getDynamicDexCheck() == null) { Toast.makeText(this, "onClick loaddex Failed!", 1).show(); } else if (getDynamicDexCheck().check()) { CheckSuccess(); startActivity(new Intent(this, FridaActivity6.class)); finishActivity(0); } else { super.CheckFailed(); } } 

脚本如下:

 function fifth() { Java.perform(function(){ Java.choose("com.example.androiddemo.Activity.FridaActivity5",{ onMatch:function(instance){ console.log("found instance getDynamicDexCheck:",instance.getDynamicDexCheck().$className); },onComplete:function(){console.log("search completed !")} }) }) } setImmediate(fifth) 

结果如下:

found instance getDynamicDexCheck: com.example.androiddemo.Dynamic.DynamicCheck 

然后添加脚本去改变check的值

 function fifth(){ Java.perform(function(){ Java.choose("com.example.androiddemo.Activity.FridaActivity5",{ onMatch:function(instance){ console.log("found instance getDynamicDexCheck :",instance.getDynamicDexCheck().$className); },onComplete:function(){console.log("search complete!")} }) Java.enumerateClassLoaders({ onMatch:function(loader){ try { if(loader.findClass("com.example.androiddemo.Dynamic.DynamicCheck")){ console.log("Succefully found loader!",loader); Java.classFactory.loader = loader; } } catch (error) { console.log("found error "+error) } },onComplete:function(){"enum completed!"} }) Java.use("com.example.androiddemo.Dynamic.DynamicCheck").check.implementation = function(){return true}; }) } setImmediate(fifth) 
function sixth (){ Java.perform(function(){ Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class0").check.implementation = function (){return true }; Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class1").check.implementation = function (){return true }; Java.use("com.example.androiddemo.Activity.Frida6.Frida6Class2").check.implementation = function (){return true }; }) } 

也可以使用枚举:

function sixth2(){ Java.perform(function(){ Java.enumerateLoadedClasses({ onMatch:function(name,handle){ if(name.toString().indexOf("com.example.androiddemo.Activity.Frida6.Frida6")>=0){ console.log("name",name) Java.use(name).check.implementation = function(){return true} } },onComplete(){} }) }) } 

综合案例、hook时机、制作dex、算法还原思路

关于单独打包.java文件,可以使用

root@kali:~/AndroidStudioProjects/lesson9/app/build/intermediates/javac/debug/cl asses/com/kanxue/lesson9# /root/Android/Sdk/build-tools/30.0.3/d8 reverseA.class Picked up _JAVA_OPTIONS: -Dawt.useSystemAAFontSettings=on -Dswing.aatext=true root@kali:~/AndroidStudioProjects/lesson9/app/build/intermediates/javac/debug/classes/com/kanxue/lesson9# ls BuildConfig.class classes.dex MainActivity.class reverseA.class 

参考资料

看雪视频

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/224406.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午12:00
下一篇 2026年3月17日 下午12:01


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号