H5app逆向——XX谷
这里显示为真,说明app没有禁用WebView调试。
所以调试考虑
- 反编译出错
- 利用字符串加密或者反射的方式去禁用调试
通过什么方式可以查找自己想frida hook的类?
在使用 Frida 进行逆向工程时,查找你想要 hook 的类和方法是一个关键步骤。以下是一些常见的方法和工具,可以帮助你找到目标类和方法:
1. 使用 Frida 自带的脚本
Frida 提供了一些内置的脚本,可以帮助你枚举和查找类和方法。
枚举所有加载的类
你可以使用以下脚本来枚举所有加载的类:
Java.perform(function() {Java.enumerateLoadedClasses({onMatch: function(className) {console.log(className);},onComplete: function() {console.log("Enumeration complete");}});
});
枚举类中的所有方法
找到目标类后,你可以使用以下脚本来枚举该类中的所有方法:
Java.perform(function() {var targetClass = Java.use('com.example.TargetClass');var methods = targetClass.class.getDeclaredMethods();methods.forEach(function(method) {console.log(method.toString());});
});
2. 使用 jadx 反编译 APK
你可以使用 jadx 反编译 APK 文件,以查看应用程序的源代码。这可以帮助你找到感兴趣的类和方法。
安装和使用 jadx
-
安装 jadx:你可以从 jadx GitHub 页面 下载并安装 jadx。
-
反编译 APK:使用以下命令反编译 APK 文件:
jadx -d output_dir your_app.apk
-
浏览源代码:在输出目录中浏览反编译后的源代码,查找你感兴趣的类和方法。
3. 使用 Android Studio 进行动态调试
你可以使用 Android Studio 的调试工具来动态调试应用程序,设置断点并检查运行时的类和方法。
4. 使用 Frida 的 findClass
方法
你可以使用 Frida 的 findClass
方法来查找特定的类:
Java.perform(function() {var className = 'com.example.TargetClass';if (Java.available) {try {var targetClass = Java.use(className);console.log('Class found: ' + className);} catch (e) {console.log('Class not found: ' + className);}}
});
5. 使用 Frida 的 enumerateClassLoaders
方法
有时候类可能还没有加载,你可以使用 enumerateClassLoaders
方法来查找类加载器并手动加载类:
Java.perform(function() {Java.enumerateClassLoaders({onMatch: function(loader) {try {if (loader.findClass('com.example.TargetClass')) {console.log('Class loader found: ' + loader);}} catch (e) {// Ignore}},onComplete: function() {console.log('Enumeration complete');}});
});
6. 使用 Frida 的 Interceptor
和 Stalker
你可以使用 Frida 的 Interceptor
和 Stalker
来动态跟踪和 hook 方法调用。
示例:拦截方法调用
Java.perform(function() {var targetClass = Java.use('com.example.TargetClass');targetClass.targetMethod.implementation = function(arg1, arg2) {console.log('targetMethod called with arguments: ' + arg1 + ', ' + arg2);var result = this.targetMethod(arg1, arg2);console.log('targetMethod returned: ' + result);return result;};
});
总结
通过上述方法,你可以有效地查找和 hook 你感兴趣的类和方法。根据具体情况选择合适的方法和工具,可以大大提高你的逆向工程效率。如果你有任何进一步的问题或需要更多的帮助,请随时告诉我!
解决方法:
直接hook类
andriod.webkit.WebView
hook实战
Java.perform(function (){var WebView = Java.use("android.webkit.WebView");//hook 类android.webkit.WebViewWebView.setWebContentsDebuggingEnabled.overload("boolean").implementation = function (s) {// send(s.toString());console.log("webview hook")//当出现webview hook时,说明有布尔值被hook了// this.loadUrl.overload("java.lang.String").call(this, s);// console.log(this.)this.setWebContentsDebuggingEnabled(true)//设置webview可调};} 作者:叫我龙哥就好re https://www.bilibili.com/read/cv7946527/ 出处:bilibili
hook WebView脚本
Java.perform(function () {var WebView = Java.use("android.webkit.WebView");WebView.$init.overload('android.content.Context').implementation = function (a) {console.log("WebView.$init is called");var retval = this.$init(a);this.setWebContentsDebuggingEnabled(true);return retval;}WebView.$init.overload('android.content.Context','android.util.AttributeSet').implementation = function (a,b) {console.log("WebView.$init is called");var retval = this.$init(a,b);this.setWebContentsDebuggingEnabled(true);return retval;}WebView.$init.overload('android.content.Context','android.util.AttributeSet','int').implementation = function (a,b,c) {console.log("WebView.$init is called");var retval = this.$init(a,b,c);this.setWebContentsDebuggingEnabled(true);return retval;}WebView.$init.overload('android.content.Context','android.util.AttributeSet','int','boolean').implementation = function (a,b,c,d) {console.log("WebView.$init is called");var retval = this.$init(a,b,c);this.setWebContentsDebuggingEnabled(true);return retval;}WebView.$init.overload('android.content.Context','android.util.AttributeSet','int','int').implementation = function (a,b,c,d) {console.log("WebView.$init is called");var retval = this.$init(a,b,c,d);this.setWebContentsDebuggingEnabled(true);return retval;}// WebView.$init.overload('android.content.Context','android.util.AttributeSet','int','int','java.util.Map','boolean').implementation = function (a,b,c,d) {// console.log("WebView.$init is called");// var retval = this.$init(a,b,c,d,e,f);// this.setWebContentsDebuggingEnables(true);// return retval;// }// WebView.setWebContentDebuggingEnabled.implementation = function () {// this.setWebContentsDebuggingEnabled(true);// console.log("setWebContentDebuggingEnabled is called")// }// 检查 WebView 类是否存在if (WebView) {// 重写 setWebContentsDebuggingEnabled 方法WebView.setWebContentsDebuggingEnabled.implementation = function (enabled) {this.setWebContentsDebuggingEnabled(true);console.log("setWebContentsDebuggingEnabled is called with argument: " + enabled);};//setWebContentsDebuggingEnabled} else {console.log("WebView class not found");
结果
现在可以调试了
这里的到的http是发送的端口。httpcanary可以抓包,charles要设置非标准端口抓包。
login: function() {var A = this, t = A.$refs.phone.value;/^1[3456789]\d{9}$/.test(t) ? A.$http.post(A.$store.state.marUrl + "/login/login", {phone: A.$refs.phone.value,password: A.$refs.password.value}, {emulateJSON: !0}).then((function(t) {if ("用户名或密码错误" == t.body.msg)this.presentAlert("手机号或密码错误");else {var e = t.body.user;A.$cookies.set("user", e, "15d"),A.$store.commit("changeToken", t.body.token),A.$store.commit("changeTokenState", t.body.token),this.$router.push({path: "/shop"})}}这里我获得了A.$store.state.marUrl"http://121.36.75.162:7878",算是逆向吗?可以通过这个url获取什么有价值的信息吗?
加密通常在JS文件中,
解决方法:远程调试、修改JS代码注入
H5app的发包方法:
- 纯JS发包,可以在远程调试工具抓包(chrom:inspect)
- 部分JS发包,部分java,这时调试工具抓不了,要分析
- JS和java如何互相调用,找java层接口
- 纯java发包
webView远程调试的要求:
- 手机端的webview比电脑端的Chrome版本低
- 手机端的webview需要开启可调式
- 需要科学上网(VPN)才能在chrome浏览器调试
批处理脚本(.bat)
这里是博主写的用来一键启动frida server的批处理文件。
确保你的批处理脚本在启动 Frida Server 之前检查并释放端口:
@echo off
adb kill-server
adb start-serverREM 检查并杀掉占用端口的进程
adb shell "su -c 'lsof -i :27042 | grep LISTEN | awk '{print $2}' | xargs kill -9'"adb shell "su -c 'cd /data/local/tmp && chmod 777 frida-server-14.2.2-android-arm64 && ./frida-server-14.2.2-android-arm64 &'"
adb forward tcp:27042 tcp:27042REM 检查 Frida Server 是否成功启动
adb shell "ps | grep frida-server"
if %errorlevel% neq 0 (echo Frida Server failed to start.pauseexit /b 1
) else (echo Frida Server started successfully!
)REM 检查端口转发是否成功
adb forward --list | findstr "tcp:27042"
if %errorlevel% neq 0 (echo Port forwarding failed.pauseexit /b 1
) else (echo Port forwarding set up successfully!
)REM 测试连接到 Frida Server
frida-ps -H 127.0.0.1:27042
if %errorlevel% neq 0 (echo Failed to connect to Frida Server.pauseexit /b 1
) else (echo Successfully connected to Frida Server!
)pause
netstat -tunlp
- 用于查看frida server的端口占用情况
kill -9 [PID]
- 可以杀死fridaserver进程,重启frida server
总结
引用webview类的方法
找webview类时遇到的问题
在 Android Studio 中没有看到 WebView.setWebContentsDebuggingEnabled
方法,可能是因为你引用的 WebView
类是一个模拟(mock)版本,而不是实际的 Android 系统中的 WebView
类。模拟版本通常用于测试和开发环境中,并不包含所有实际类的方法。
解决方法
-
确保引用正确的库:确保你的项目引用了正确的 Android SDK 库,而不是模拟库。
-
检查依赖项:在
build.gradle
文件中,确保你引用了正确的 Android 库。
示例 build.gradle
文件
确保你的 build.gradle
文件中包含以下依赖项:
dependencies {implementation 'com.android.support:appcompat-v7:28.0.0'implementation 'com.android.support:design:28.0.0'implementation 'com.android.support:support-v4:28.0.0'implementation 'com.android.support:recyclerview-v7:28.0.0'implementation 'com.android.support:cardview-v7:28.0.0'implementation 'com.android.support.constraint:constraint-layout:1.1.3'implementation 'com.android.support:support-annotations:28.0.0'implementation 'com.android.support:support-core-utils:28.0.0'implementation 'com.android.support:support-core-ui:28.0.0'implementation 'com.android.support:support-fragment:28.0.0'
}
检查类路径
确保你引用的是实际的 android.webkit.WebView
类,而不是模拟类。你可以通过以下方式检查:
-
在代码中直接引用
android.webkit.WebView
:import android.webkit.WebView;public class MyActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);WebView webView = findViewById(R.id.webview);webView.setWebContentsDebuggingEnabled(true);} }
-
确保没有引用模拟类:检查你的项目中是否有类似
com.android.layoutlib.bridge.MockView
的引用,如果有,移除或替换为实际的 Android 类。
使用正确的方法
确保你使用的是正确的方法名 setWebContentsDebuggingEnabled
,而不是其他类似的方法名。
示例代码
以下是一个完整的示例代码,确保正确引用 WebView
类并调用 setWebContentsDebuggingEnabled
方法:
import android.os.Bundle;
import android.webkit.WebView;
import androidx.appcompat.app.AppCompatActivity;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);WebView webView = findViewById(R.id.webview);WebView.setWebContentsDebuggingEnabled(true);}
}
进一步排查
-
检查 Android SDK 版本:确保你使用的 Android SDK 版本支持
setWebContentsDebuggingEnabled
方法。该方法在 API 级别 19(Android 4.4 KitKat)及以上版本中可用。 -
查看官方文档:查阅 Android 官方文档,确保方法名和用法正确。
如果你有任何进一步的问题或需要更多的帮助,请随时告诉我!
资料
安卓逆向第七篇-hook android WebView js注入 - 简书 (jianshu.com)
WebViewDebugHook: 深度调试Webview的利器-CSDN博客
我找到了几个关于使用 Frida hook WebView 重载方法的资源和示例。以下是一些有用的链接和信息:
-
Stack Overflow - Frida Intercept all webview traffic
- 讨论了如何使用 Frida 拦截所有 WebView 流量,包括异步 JavaScript 请求。
- 链接
-
Node Security - Android Hooking in Frida
- 详细解释了如何使用 Frida hook Android 的 WebView 类,包括获取
loadUrl
方法的重载版本。 - 链接
- 详细解释了如何使用 Frida hook Android 的 WebView 类,包括获取
-
OWASP - Testing for URL Loading in WebViews
- 介绍了如何使用 Frida 或 frida-trace 动态测试 WebView 中的深度链接,包括 hook
shouldOverrideUrlLoading
和shouldInterceptRequest
方法。 - 链接
- 介绍了如何使用 Frida 或 frida-trace 动态测试 WebView 中的深度链接,包括 hook
-
GitHub - iddoeldor/frida-snippets
- 提供了多个 Frida 示例,包括如何 hook 所有方法重载。
- 链接
-
GitHub - How to hook WebSettings.getSettings() method
- 讨论了如何 hook WebView 类中的
getSettings
方法,并获取与 WebView 关联的 WebSettings 对象。 - 链接
- 讨论了如何 hook WebView 类中的
这些资源应该能帮助你找到更多关于如何使用 Frida hook WebView 重载方法的示例和详细信息。如果你有任何进一步的问题或需要更多的帮助,请随时告诉我!