【跨端框架检测】使用adb logcat检测Android APP使用的跨端框架方法总结
目录
- Weex 跨端框架
- 使用了uni-app的情况
- 区分使用了uni-app还是Weex
- 判断使用了Xamarin
- 判断使用了KMM框架
- 判断使用了 Ionic 框架
- 判断使用了Cordova框架
- 判断使用了Capacitor 框架
- 使用了React Native框架
- 使用了QT框架
- 使用了Cocos框架
- 使用了Electron 框架
- 使用了flutter 框架
- 使用了Taro框架
- 使用了Tauri框架
- 使用了MAUI框架
Weex 跨端框架
Logcat 日志过滤
运行应用时,通过 adb logcat
过滤 Weex 相关日志:
adb logcat | grep -iE "weex|WXSDK"
# 示例输出:
# I/WXSDKEngine: WXSDKEngine initialized.
# D/WeexCore: Load JS Bundle from assets/weex/main.js
使用了uni-app的情况
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 uni-app 相关日志:
adb logcat | grep -iE "dcloud|uni-app"# 示例输出:
# I/dcloud: [uni-app] JSBundle loaded.
# D/uni-app: App lifecycle: onLaunch
区分使用了uni-app还是Weex
要区分一个应用是基于 uni-app 还是 Weex 开发,可以通过以下 关键特征对比 进行判断:
一、核心差异总结
特征 | uni-app | Weex |
---|---|---|
跨端范围 | 全端(小程序、H5、App、快应用) | 原生 App(Android/iOS)为主 |
技术栈 | 基于 Vue.js + 条件编译 | 类似 Vue.js,但语法更原生化 |
入口文件 | main.js + App.vue + pages.json | main.js + .we 文件(旧版) |
全局对象 | uni (API 调用) | weex 或 WXEnvironment |
UI 组件 | 支持小程序组件 + 扩展组件(如 <uni-list> ) | 原生组件标签(如 <div> 、<text> ) |
原生交互 | 通过 uni.requireNativePlugin 调用原生插件 | 通过 weex.requireModule 调用原生模块 |
打包后目录结构 | assets/apps/__UNI__[APPID]/www | assets/weex/ 或 js/bundle.js |
运行时容器 | 基于 WebView(或小程序引擎) | 原生渲染引擎(无 WebView) |
二、具体区分方法
1. 安装包结构分析
• uni-app:
• 解压 APK 后,存在以下目录:
```bash
assets/apps/__UNI__ABCD1234/www/ # 应用核心资源
assets/uni-jsframework.js # uni-app 运行时库
```
• 原生库文件可能包含 libapp.so
(uni-app 渲染引擎)。
• Weex:
• 解压 APK 后,存在以下目录:
```bash
assets/weex/main.js # Weex 的 JS Bundle
lib/armeabi-v7a/libweexcore.so # Weex 原生渲染引擎
```
2. 代码特征验证
• uni-app:
• 条件编译指令:
```javascript
// #ifdef APP-PLUS
console.log('运行在 App 平台');
// #endif
```
• 全局 API 调用:
```javascript
uni.request({ url: '...' }); // uni-app 的 API 风格
```
• Weex:
• 原生模块调用:
```javascript
const module = weex.requireModule('stream');
module.fetch({ url: '...' }, callback);
```
• UI 组件标签:
```html
<div><text class="title">Hello Weex!</text>
</div>
```
3. 运行时检测
• uni-app:
• WebView 调试:
在 Chrome 控制台中检查全局对象:
```javascript
console.log(window.uni); // 输出 uni 对象
console.log(__dcloud_es6_polyfill__); // Polyfill 标识
```
• Weex:
• 全局环境变量:
```javascript
console.log(WXEnvironment.platform); // 输出 'Android' 或 'iOS'
```
• 无 WebView:
Weex 的 UI 是原生渲染,DOM 元素不可见(无法通过 `document.getElementById` 访问)。
4. 原生代码分析
• uni-app:
• 主 Activity 继承自 io.dcloud.PandoraEntry
:
```java
public class MainActivity extends io.dcloud.PandoraEntry { ... }
```
• Weex:
• 主 Activity 继承自 WXActivity
:
```java
public class MainActivity extends com.taobao.weex.WXActivity { ... }
```
三、混淆场景处理
若应用经过代码混淆或优化,可通过以下方式进一步验证:
-
JS Bundle 特征:
• uni-app 的 JS 代码包含createApp
和createPage
方法(基于 Vue 实例化)。• Weex 的 JS 代码包含
define
或bootstrap
方法(旧版)。 -
资源文件哈希值:
• uni-app 的www
目录下可能有manifest.json
,而 Weex 无此文件。 -
网络请求特征:
• uni-app 动态加载的 JS Bundle 可能包含uni-app
标识。• Weex 可能请求
.we
或.js
文件(路径包含/weex/
)。
四、总结判断步骤
- 解压 APK:检查
assets/apps/__UNI__
(uni-app)或assets/weex/
(Weex)。 - 查看代码:搜索
uni.
(uni-app)或weex.
(Weex)。 - 反编译原生代码:确认主 Activity 的父类(
PandoraEntry
vsWXActivity
)。 - 运行时调试:检查全局对象和环境变量。
通过以上方法,可快速区分应用基于 uni-app 还是 Weex。若仍有疑问,可结合具体业务逻辑和插件调用进一步分析。
判断使用了Xamarin
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Mono 运行时初始化日志:
adb logcat | grep -iE "monodroid|MonoRuntime"
# 输出示例:
# I/monodroid: JNI_OnLoad: mono.android.Runtime.init
# I/MonoRuntime: Initializing Mono runtime...
进程内存分析
Xamarin 应用会加载 Mono 运行时进程,可通过以下命令查看:
adb shell ps | grep -i "mono"
# 输出示例:
# com.myapp 12345 678 0% S mono.android.app.Application
判断使用了KMM框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 KMM 相关日志(如共享模块的初始化或跨平台调用):
adb logcat | grep -iE "KMM|shared|common"
# 示例输出:
# D/KMM: Initializing shared module...
# I/SharedModule: Fetching data from common logic.
判断使用了 Ionic 框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Ionic 相关日志:
adb logcat | grep -iE "Ionic|Cordova|Capacitor"
# 示例输出:
# I/Ionic: Angular 初始化完成
# D/Capacitor: 插件 com.getcapacitor.camera 已加载
判断使用了Cordova框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Cordova 相关日志:
adb logcat | grep -iE "Cordova|CordovaWebView"
# 示例输出:
# D/CordovaWebView: CordovaWebView is running on device made by: samsung
# I/CordovaLog: deviceready has not fired after 5 seconds.
判断使用了Capacitor 框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Capacitor 相关日志:
adb logcat | grep -iE "Capacitor|Bridge"
# 示例输出:
# D/Capacitor: Initializing plugin: Camera
# I/Capacitor: App launched with URL: capacitor://localhost
使用了React Native框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 React Native 相关日志:
adb logcat | grep -iE "ReactNativeJS|ReactNative"
# 示例输出:
# I/ReactNativeJS: Running application "MyApp" with appParams
# D/ReactNative: ReactInstanceManager.createReactContext()
使用了QT框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Qt 相关日志:
adb logcat | grep -iE "QtCore|Qt GUI|QML"
# 示例输出:
# D/QtCore: Initializing Qt...
# I/QML: Loading QML file: qml/Main.qml
使用了Cocos框架
Logcat 日志过滤
运行应用时,通过 adb logcat 过滤 Cocos 相关日志:
adb logcat | grep -iE "Cocos2d|CocosPlay"
# 示例输出:
# I/Cocos2dxActivity: Cocos2dxActivity initialized
# D/cocos2d-x: Director::setOpenGLView()
使用了Electron 框架
- Logcat 日志过滤:
运行应用时,通过 adb logcat 过滤以下关键词:
adb logcat | grep -iE "Electron|Chromium|Node.js"
# 若有输出,可能为自定义集成(但极罕见)
- 进程与线程分析:
Electron 桌面应用会启动 主进程 + 渲染进程,而 Android 应用若模拟此行为,可能包含类似多进程模式:
adb shell ps | grep -i "node"
# 检查是否存在 Node.js 进程
使用了flutter 框架
1. Logcat 日志过滤
运行应用时,通过 adb logcat
过滤 Flutter 相关日志:
adb logcat | grep -iE "flutter|dart|skia"
# 示例输出:
# I/flutter: Observatory listening on http://127.0.0.1:12345/
# D/FlutterActivity: FlutterActivity initialized
# I/Skia: Skia graphics engine initialized
2. 进程与线程分析
Flutter 应用启动后,进程内会创建 UI 线程、GPU 线程 和 I/O 线程,通过以下命令查看:
adb shell ps -T | grep -i "flutter"
# 输出示例:
# 12345 12345 com.example.app ... io.flutter.embedding.android.FlutterActivity
# 12345 12346 Thread-2 ... Dart Worker
使用了Taro框架
Logcat 日志过滤
运行应用时,通过 adb logcat
过滤 Taro 或 React Native 日志:
adb logcat | grep -iE "Taro|ReactNative"
# 示例输出:
# I/ReactNativeJS: Taro initialized
# D/TaroRuntime: Loading Taro components...
使用了Tauri框架
Logcat 日志过滤
运行应用时,通过 adb logcat
过滤 Rust 或 Tauri 相关日志:
adb logcat | grep -iE "tauri|rust"
# 示例输出(假设存在):
# I/rust: Tauri initialized
# D/tauri_mobile: Invoking Rust method: show_message
使用了MAUI框架
• 运行应用时,通过adb logcat
过滤MAUI相关日志:
adb logcat | grep -i "Maui"# 示例输出:# I/Maui: Initializing Microsoft.Maui.Graphics...```