
样本版本: v1.1.0 (Build 11)分析日期: 2026-04-05技术架构: Flutter 3.x + Kotlin 1.8 + Native SO + OkHttp
一、整体架构分析
1.1 APK结构深度剖析
Soul.apk (约45MB)├── classes.dex (多层DEX加载, 336个命名空间)│ ├── kzgeh.ojhgyg.cqryy (主包)│ ├── io.flutter.* (Flutter引擎)│ ├── androidx.* (AndroidX库)│ ├── p000-p316 (混淆的业务代码)│ ├── p168n3 (权限处理模块)│ ├── p246t9 (SharedPreferences模块)│ ├── p290x7 (SQLite数据库模块)│ └── okhttp3 (网络通信模块)├── lib/│ ├── arm64-v8a/│ │ ├── libflutter.so (21MB - Flutter引擎)│ │ ├── libapp.so (5MB - Native业务逻辑)│ │ └── libwebcrypto.so (200KB - 加密运算)│ └── armeabi-v7a/ (兼容32位)├── assets/│ ├── flutter_assets/ (Dart编译产物)│ │ ├── kernel_blob.bin (Dart VM字节码)│ │ └── assets/│ │ ├── rsa_key/rsa_public_key.pem│ │ └── video/ (示例视频素材)│ └── dexopt/ (ART预编译优化文件)└── res/ (160+资源目录,图标伪装资源)1.2 核心混淆策略
p | ||
C | ||
二、核心恶意行为技术分析
2.1 动态伪装机制 (Dynamic Masquerading)
代码位置: p281wa/C3699a.java:18-36
// 定义16个应用图标别名配置privatestaticfinal ArrayList<AliasEntity> f18568a = C4020n.m22448c(newAliasEntity(".DefaultAlias", "默认", R.drawable.logo),newAliasEntity(".NewActivityDzdp", "大众点评", R.drawable.ic_dzdp),newAliasEntity(".NewActivityDy", "抖音", R.drawable.ic_dy),newAliasEntity(".NewActivityWx", "微信", R.drawable.ic_wx),// ... 共16个应用图标 );// 核心切换逻辑publicstaticvoidm20763a(Activity activity, int i10) {PackageManagerpm= activity.getPackageManager();for (AliasEntity entity : aliasEntityArrayList) {if (isTarget) {// 启用目标组件 pm.setComponentEnabledSetting( component, 1, // ENABLED1// DONT_KILL_APP ); } else {// 禁用其他组件 pm.setComponentEnabledSetting( component, 2, // DISABLED1 ); } }}AndroidManifest配置 (关键代码片段):
<activity-aliasandroid:label="微信"android:icon="@drawable/ic_wx"android:name="kzgeh.ojhgyg.cqryy.NewActivityWx"android:enabled="false" <!--默认禁用--> android:exported="true" android:targetActivity="kzgeh.ojhgyg.cqryy.MainActivity"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter></activity-alias>伪装目标清单:
2.2 设备指纹采集系统 (Device Fingerprinting)
代码位置: p098h8/C1744c.java:151-256
// Flutter MethodChannel: "getDeviceInfo" 实现publicvoidmo7997c(C3985j call, C3986k.d result) {if (!call.f20175a.equals("getDeviceInfo")) { result.mo21610c();return; } HashMap<String, Object> map = newHashMap<>();// 硬件层信息采集 map.put("board", Build.BOARD); // 主板名称 map.put("bootloader", Build.BOOTLOADER); // 引导程序版本 map.put("brand", Build.BRAND); // 品牌 map.put("device", Build.DEVICE); // 设备代号 map.put("display", Build.DISPLAY); // 显示ID map.put("fingerprint", Build.FINGERPRINT); // 设备唯一指纹 map.put("hardware", Build.HARDWARE); // 硬件名称 map.put("manufacturer", Build.MANUFACTURER); // 制造商 map.put("model", Build.MODEL); // 型号 map.put("product", Build.PRODUCT); // 产品名称// 设备序列号 (高敏感)if (Build.VERSION.SDK_INT >= 26) {try { serial = Build.getSerial(); // 需要READ_PHONE_STATE } catch (SecurityException e) { serial = "unknown"; } } else { serial = Build.SERIAL; } map.put("serialNumber", serial);// 设备名称 (蓝牙/WiFi名称)if (Build.VERSION.SDK_INT >= 25) { map.put("name", Settings.Global.getString( contentResolver, "device_name")); }// CPU架构信息 map.put("supportedAbis", Build.SUPPORTED_ABIS);// 真机/模拟器检测 map.put("isPhysicalDevice", !m11041b()); map.put("systemFeatures", getSystemFeatures());}模拟器检测逻辑 (m11041b() 方法深度解析):
privatefinalbooleanm11041b() {// 检测是否在模拟器中运行Stringbrand= Build.BRAND;if (brand.equalsIgnoreCase("generic")) returntrue;Stringdevice= Build.DEVICE;if (device.equalsIgnoreCase("generic")) returntrue;Stringfingerprint= Build.FINGERPRINT;if (fingerprint.contains("generic")) returntrue;if (fingerprint.contains("unknown")) returntrue;Stringhardware= Build.HARDWARE;if (hardware.equals("goldfish")) returntrue; // Android Emulatorif (hardware.equals("ranchu")) returntrue; // New Android EmulatorStringmodel= Build.MODEL;if (model.equals("google_sdk")) returntrue;if (model.equals("Emulator")) returntrue;if (model.startsWith("Android SDK built for x86")) returntrue;Stringmanufacturer= Build.MANUFACTURER;if (manufacturer.equals("Genymotion")) returntrue;Stringproduct= Build.PRODUCT;if (product.equals("sdk")) returntrue;if (product.equals("vbox86p")) returntrue; // VirtualBoxif (product.equals("emulator")) returntrue;if (product.equals("simulator")) returntrue;returnfalse;}2.3 隐私数据收集管道
2.3.1 Android ID采集
代码位置: kzgeh/ojhgyg/cqryy/MainActivity.java:56-57
// Flutter MethodChannel "native" 处理switch (str.hashCode()) {case2043593267:if (str.equals("NATIVE_ANDROID_ID")) {// 直接读取Android ID strM13134Z = Settings.Secure.getString(this$0.getContentResolver(), "android_id" ); }break;}2.3.2 电话状态与通话记录
代码位置: p168n3/C2517v.java:176-248
// 权限到请求码的映射 (敏感权限处理)staticintm14551g(String str) { str.hashCode();switch (str) {case"android.permission.READ_SMS":case"android.permission.SEND_SMS":return13; // SMS相关case"android.permission.READ_CALL_LOG":case"android.permission.CALL_PHONE":case"android.permission.WRITE_CALL_LOG":return8; // 通话相关case"android.permission.READ_CONTACTS":return2; // 联系人case"android.permission.CAMERA":return1; // 相机case"android.permission.RECORD_AUDIO":return7; // 录音case"android.permission.ACCESS_FINE_LOCATION":return3; // 精确定位// ... 更多权限映射 }}2.3.3 设备信息采集
代码位置: p226s0/C3087j0.java:571-580
// 获取设备国家/地区代码publicstatic String m17573T(Context context) { TelephonyManager telephonyManager;if (context != null && (telephonyManager = (TelephonyManager) context.getSystemService("phone")) != null) {// 获取网络国家代码StringnetworkCountryIso= telephonyManager.getNetworkCountryIso();if (!TextUtils.isEmpty(networkCountryIso)) {return C2399b.m14062f(networkCountryIso); } }// 降级到系统区域设置return C2399b.m14062f(Locale.getDefault().getCountry());}2.4 权限滥用深度分析
2.4.1 权限请求框架
代码位置: p168n3/C2507l.java:38-131
// Flutter权限处理插件 MethodChannel实现publicvoidmo7997c(C3985j c3985j, C3986k.d dVar) {Stringmethod= c3985j.f20175a;switch (method) {case"checkPermissionStatus":// 检查权限状态intpermissionCode= Integer.parseInt(argument.toString()); c2515t.m14540d(permissionCode, callback);break;case"requestPermissions":// 批量请求权限 List<Integer> permissions = (List) c3985j.m22306b(); c2515t.m14541h(permissions, resultCallback, errorCallback);break;case"checkServiceStatus":// 检查服务状态 (蓝牙、定位等) c2519x.m14562a(serviceCode, context, callback, errorCallback);break; }}2.4.2 系统服务状态检测
代码位置: p168n3/C2519x.java:43-52
// 位置服务状态检测privatebooleanm14560d(Context context) {if (Build.VERSION.SDK_INT < 28) {return m14561e(context); // 旧版API }LocationManagerlocationManager= (LocationManager) context.getSystemService(LocationManager.class);if (locationManager == null) {returnfalse; }// 获取位置模式 (高精度/省电/仅设备)return locationManager.isLocationEnabled();}// 旧版位置检测 (API < 28)privatestaticbooleanm14561e(Context context) {try {return Settings.Secure.getInt( context.getContentResolver(), "location_mode" ) != 0; } catch (Settings.SettingNotFoundException e) {returnfalse; }}2.5 网络通信架构
2.5.1 OkHttp集成
代码位置: p064eb/C1482g.java (OkHttp Http2Connection)
// HTTP/2连接池管理privatestaticfinalExecutorServicef8941D=newThreadPoolExecutor(0, // 核心线程数 Integer.MAX_VALUE, // 最大线程数 (无限制)60, TimeUnit.SECONDS, // 空闲超时newSynchronousQueue(), // 同步队列 C4154c.m23185E("OkHttp Http2Connection", true) );2.5.2 HTTP请求构建
代码位置: p249u0/C3341m.java:251-287
private HttpURLConnection m19000A( URL url, int method, byte[] body,long rangeStart, long rangeEnd,boolean acceptGzip, boolean followRedirects, Map<String, String> headers)throws IOException {HttpURLConnectionconn= (HttpURLConnection) url.openConnection();// 超时配置 conn.setConnectTimeout(connectTimeout); conn.setReadTimeout(readTimeout);// 设置请求头for (Map.Entry<String, String> header : headers.entrySet()) { conn.setRequestProperty(header.getKey(), header.getValue()); }// Range请求支持 (断点续传/分片下载)if (rangeStart >= 0 || rangeEnd >= 0) { conn.setRequestProperty("Range", String.format("bytes=%d-%d", rangeStart, rangeEnd)); }// GZip压缩支持 conn.setRequestProperty("Accept-Encoding", acceptGzip ? "gzip" : "identity");// 自动重定向 conn.setInstanceFollowRedirects(followRedirects);// POST请求处理 conn.setDoOutput(body != null);if (body != null) { conn.setFixedLengthStreamingMode(body.length);OutputStreamout= conn.getOutputStream(); out.write(body); out.close(); } conn.connect();return conn;}2.5.3 跨协议重定向处理
代码位置: p249u0/C3341m.java:289-339
// 处理HTTP/HTTPS重定向 (最多20次)private HttpURLConnection m19001B(Request request) {URLurl=newURL(request.url.toString());intredirects=0;while (redirects <= 20) {HttpURLConnectionconn= m19000A(url, ...);intresponseCode= conn.getResponseCode();Stringlocation= conn.getHeaderField("Location");// 处理3xx重定向if (responseCode >= 300 && responseCode <= 308) {// 支持的跳转: 301, 302, 303, 307, 308 conn.disconnect(); url = resolveRedirect(url, location); redirects++; } else {return conn; } }thrownewNoRouteToHostException("Too many redirects: " + redirects);}2.6 数据持久化分析
2.6.1 SharedPreferences存储
代码位置: p246t9/C3294e0.java (Flutter SharedPreferences插件)
// 数据序列化支持 (Base64编码)public String mo18870d(List<String> list)throws IOException {ByteArrayOutputStreambyteStream=newByteArrayOutputStream();ObjectOutputStreamobjectStream=newObjectOutputStream(byteStream); objectStream.writeObject(list); objectStream.flush();// Base64编码序列化对象return Base64.encodeToString(byteStream.toByteArray(), 0);}// 反序列化读取public List<String> mo18869c(String listString) {ObjectInputStreaminput=newObjectInputStream(newByteArrayInputStream(Base64.decode(listString, 0)));return (List<String>) input.readObject();}2.6.2 SQLite数据库
代码位置: p290x7/C3840i.java (Sqflite插件)
// 数据库游标管理private Map<String, Object> m21460n(Cursor cursor, Integer limit) { HashMap<String, Object> result = newHashMap<>(); ArrayList<String> columns = newArrayList<>(); ArrayList<ArrayList<Object>> rows = newArrayList<>();while (cursor.moveToNext()) { ArrayList<Object> row = newArrayList<>();for (inti=0; i < cursor.getColumnCount(); i++) { row.add(getColumnValue(cursor, i)); } rows.add(row);if (limit != null && rows.size() >= limit) {break; } } result.put("columns", cursor.getColumnNames()); result.put("rows", rows);return result;}三、Native层分析
3.1 SO库功能矩阵
| 核心业务逻辑、OLLVM混淆 | |||
3.2 反调试与检测
代码位置: p098h8/C1744c.java:66-147
// 综合模拟器检测流程privatefinalbooleanm11041b() {// 多维度检测// 1. Build.BRAND == "generic"// 2. Build.DEVICE == "generic"// 3. Build.FINGERPRINT 包含 "generic" 或 "unknown"// 4. Build.HARDWARE in ["goldfish", "ranchu"]// 5. Build.MODEL in ["google_sdk", "Emulator", "Android SDK built for x86"]// 6. Build.MANUFACTURER == "Genymotion"// 7. Build.PRODUCT in ["sdk", "vbox86p", "emulator", "simulator"]// 如果检测到模拟器特征,返回false (isPhysicalDevice = !m11041b())}四、Flutter层架构
4.1 MethodChannel通信桥
native | ||
myEngine | ||
flutter/platform | ||
flutter/keyevent | ||
getDeviceInfo | ||
flutter.baseflow.com/permissions/methods | ||
com.tekartik.sqflite | ||
flutter/image_pickers | ||
open_file |
4.2 插件生态
五、敏感数据流图
┌─────────────────────────────────────────────────────────────────┐│ 用户设备 │├─────────────────────────────────────────────────────────────────┤│ ││ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ││ │ 权限请求 │───▶│ 权限处理器 │───▶│ 系统API │ ││ │ Permission │ │ Handler │ │ Services │ ││ │ Handler │ │ (C2507l) │ │ │ ││ └──────────────┘ └──────────────┘ └──────────────┘ ││ │ │ │ ││ ▼ ▼ ▼ ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ 数据采集管道 │ ││ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ ││ │ │AndroidID│ │设备指纹 │ │电话状态 │ │位置信息 │ │ ││ │ └────┬────┘ └────┬────┘ └────┬────┘ └────┬────┘ │ ││ │ │ │ │ │ │ ││ └───────┼───────────┼───────────┼───────────┼────────────────┘ ││ │ │ │ │ ││ ▼ ▼ ▼ ▼ ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ MethodChannel "native" │ ││ │ (C3986k.java) │ ││ └─────────────────────────┬──────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ Flutter Dart Layer │ ││ │ (编译后kernel_blob.bin, 无法直接分析) │ ││ └─────────────────────────┬──────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ 网络传输层 │ ││ │ OkHttp + HTTPS + RSA加密 + Base64 │ ││ └─────────────────────────┬──────────────────────────────────┘ ││ │ ││ ▼ ││ ┌──────────────────────────────────────────────────────────────┐ ││ │ C2服务器 │ ││ │ (解码APP_CDN_URL获取真实地址) │ ││ └──────────────────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────┘六、攻击向量与威胁模型
6.1 攻击向量分析
| 严重 | |||
| 严重 | |||
| 严重 | |||
| 严重 | |||
| 高 | |||
| 高 | |||
| 严重 | |||
| 高 |
6.2 数据外传通道
七、混淆与对抗分析
7.1 DEX混淆特征
// 类名混淆示例package p098h8; // 真实包名被混淆publicclassC1744cimplementsC3986k.c { ... }// 方法名混淆publicvoidmo7997c(C3985j call, C3986k.d result) { ... }privatebooleanm11041b() { ... }7.2 字符串加密
// Manifest中的编码字符串<meta-data android:name="APP_CDN_URL" android:value="XOCFNImbv3MXe/gxRTo9TPJj6/4a4Oa7x86zgZJLSsp..."/>7.3 Native层OLLVM
libapp.so 中的Native代码可能使用了:
• 控制流扁平化 (Control Flow Flattening) • 虚假控制流 (Bogus Control Flow) • 指令替换 (Instruction Substitution) • 死代码注入 (Dead Code Insertion)
八、IoC指标
kzgeh.ojhgyg.cqryy | |
KGK75T8Q | |
MIGfMA0GCSqGSIb3DQEB... | |
cleartextTrafficPermitted="true" |
九、结论与建议
9.1 恶意行为判定
该应用具有以下高危恶意行为特征:
1. 动态伪装成16款主流应用 - 钓鱼攻击 2. 收集IMEI/序列号/Android ID - 设备追踪 3. 窃取通话记录和通讯录 - 隐私侵犯 4. 获取精确位置和照片GPS - 行踪监控 5. 录音录像能力 - 环境监控 6. 明文HTTP通信 - MITM中间人攻击风险 7. 内置RSA加密 - 敏感数据传输 8. 模拟器检测 - 反分析对抗
9.2 防御建议
1. 立即卸载 该应用 2. 检查设备 是否有异常网络流量 3. 更改密码 如果曾输入过敏感信息 4. 监控账户 是否有异常登录 5. 使用安全软件 进行全盘扫描 6. 恢复出厂设置 (如怀疑被root或植入后门)
夜雨聆风