Cleaner Guru 逻辑深挖

基于本地 APK/XAPK 静态证据生成。重点回答:Flutter 是否能看核心逻辑、Cleaner Guru 这类 cleaner 产品的实现链路、接口/订阅/权限/界面方案能学到什么。

结论先行

Flutter 能看到多少?

能稳定识别框架、插件、Manifest、权限、原生桥、assets、部分接口/文案/路由字符串;但 Dart AOT 的核心 widget tree、状态机和算法默认不是可读源码,需要 Flutter AOT 专用工具或动态运行补证。

Cleaner Guru 这个 APK 不是 Flutter

它是 React Native / Expo / Hermes:index.android.bundle 是 Hermes bytecode v96,app.config 暴露 Expo SDK 53、expo-router、expo-media-library。产品逻辑比 Flutter 更容易通过字符串和 Expo 配置推断。

可学的核心打法

先用“存储焦虑”拿权限和首次扫描结果,再用重复/相似照片分组制造可见价值,删除前确认,关键动作/恢复/高级清理接订阅,购买后走服务端校验和归因分析。

Flutter 逆向边界

层级静态能看到难点 / 补法
Native 壳Activity、Service、Receiver、Provider、权限、deep link、SDK、Billing、广告、推送、文件 provider。高置信。Manifest + apktool/jadx 足够。
Flutter assetsflutter_assets、图片、lottie、locale JSON、AssetManifest、插件痕迹,能反推产品模块和页面素材。中高置信。界面视觉能推断,但无法还原完整 widget tree。
Dart AOT / libapp.so部分字符串、接口域名、错误文案、埋点名、模型/功能名。核心逻辑默认编成 AOT,不能直接得到 Dart 源码;需要 blutter / Doldrums / reFlutter、符号恢复、或动态 hook。
接口和远端配置base URL、path 片段、SDK endpoint、证书/加密库痕迹。真实请求体、签名、remote config、paywall SKU 要靠抓包、Frida、logcat、真机流程。

本批 Flutter 样本里,AI Art Magic / AI Photo Lab 都能从 assets 和插件层看出 AI 图片、广告、分享、邮件/素材模块;但真正的生成 API、模板状态机和 paywall 触发逻辑需要动态补证。

APK 身份和技术栈

Identity
Manifest packagecom.cleanerguru.app
App config version1.0.0
Android versionCode8
Schemecleaner
Engine
CorrectedReact Native / Expo / Hermes
Hermes bundleassets/index.android.bundle · 2807432 bytes
Hermes version96
Expo SDK53.0.0
Identity Caveat

已有 iOS 机会报告锁到 Apple bundle gen.universe.app.cleaner;这次 Android APK 为 com.cleanerguru.app,bundle 内还出现 Play 链接 package 字符串。后续多版本采集必须用 package/bundle 锁定,避免同名 App 混淆。

Expo plugins

PluginConfig
expo-router
expo-build-properties{"android": {"kotlinVersion": "2.0.21"}}
expo-splash-screen{"image": "./assets/images/splash-icon.png", "imageWidth": 200, "resizeMode": "contain", "backgroundColor": "#ffffff"}
expo-media-library{"photosPermission": "Allow $(PRODUCT_NAME) to access your photos to find and remove duplicates.", "savePhotosPermission": "Allow $(PRODUCT_NAME) to save photos to your library.", "isAccessMediaLocationEnabled": false}
expo-av{"microphonePermission": ""}

Manifest 证据

权限重点
  • android.permission.ACCESS_MEDIA_LOCATION
  • android.permission.INTERNET
  • android.permission.MODIFY_AUDIO_SETTINGS
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.READ_MEDIA_IMAGES
  • android.permission.RECORD_AUDIO
  • android.permission.VIBRATE
  • android.permission.WRITE_EXTERNAL_STORAGE
  • com.android.vending.BILLING
  • com.google.android.gms.permission.AD_ID
  • android.permission.READ_MEDIA_VIDEO
  • android.permission.READ_MEDIA_AUDIO
  • android.permission.READ_MEDIA_VISUAL_USER_SELECTED
  • com.android.vending.CHECK_LICENSE
app.config Android 权限
  • com.android.vending.BILLING
  • android.permission.READ_EXTERNAL_STORAGE
  • android.permission.READ_MEDIA_IMAGES
  • android.permission.WRITE_EXTERNAL_STORAGE
  • android.permission.RECORD_AUDIO
  • android.permission.MODIFY_AUDIO_SETTINGS
blockedPermissions
  • android.permission.READ_MEDIA_AUDIO
  • android.permission.READ_MEDIA_VIDEO
  • android.permission.RECORD_AUDIO

Manifest 合并后仍有部分 blocked 权限痕迹,需安装后看实际运行时弹窗。

Activities

NameExportedAuthoritiesIntent filters
com.cleanerguru.app.MainActivitytrue{"actions": ["android.intent.action.MAIN"], "categories": ["android.intent.category.LAUNCHER"], "data": []}; {"actions": ["android.intent.action.VIEW"], "categories": ["android.intent.category.DEFAULT", "android.intent.category.BROWSABLE"], "data": [{"scheme": "cleaner"}, {"scheme": "exp+cleaner"}]}
com.android.billingclient.api.ProxyBillingActivityfalse
com.android.billingclient.api.ProxyBillingActivityV2false
com.google.android.gms.common.api.GoogleApiActivityfalse
com.google.android.play.core.common.PlayCoreDialogWrapperActivityfalse
com.pairip.licensecheck.LicenseActivityfalse

Providers

NameExportedAuthoritiesIntent filters
com.reactnativecommunity.webview.RNCWebViewFileProviderfalsecom.cleanerguru.app.fileprovider
expo.modules.filesystem.FileSystemFileProviderfalsecom.cleanerguru.app.FileSystemFileProvider
androidx.startup.InitializationProviderfalsecom.cleanerguru.app.androidx-startup
com.pairip.licensecheck.LicenseContentProviderfalsecom.cleanerguru.app.com.pairip.licensecheck.LicenseContentProvider

产品流程推断

启动 / onboarding

单 Activity 进入 RN/Expo,bundle 中有 onboarding status、trackOnboarding、hasCompletedOnboarding 等痕迹。

照片权限

expo-media-library 权限文案直指“访问照片以查找并删除重复项”。

扫描分析

可见 getAssetsAsyncloadAndAnalyzeInRealTimescanForDuplicates、扫描完成/智能更新状态。

结果呈现

可见 total photos、similar/duplicate、best result、clean up 等 UI/文案资产线索。

删除确认

可见单张/多选删除确认,底层有 deleteAssetsAsync 一类能力,删除不可逆是核心风险点。

订阅

Free trial、weekly auto-renewable、purchase/restore/acknowledge/check status 等 token 完整。

服务端校验

可见 xscan API、uuid 登录、Play 订阅校验、restore subscription 路径。

归因分析

AppsFlyer / Amplitude / Facebook / Firebase / RevenueCat 信号,用于广告归因、购买和漏斗事件。

Hermes Bundle 证据

这里保留 byte token 存在性做短证据;offset 用于本地复核,不代表源码行号。后续一节补充 Hermes 反编译后的 pseudo-code 结论。

media_scan_delete

TokenStatusByte offset
getAssetsAsyncfound507747
deleteAssetsAsyncfound539334
Failed to find duplicatesfound427078
scanForDuplicatesfound502733
loadAndAnalyzeInRealTimefound420395
Photo access deniedfound418788
scan completedfound381013
smart updatingfound381029
total photosfound415692
Are you sure you want to delete this photofound392184
Are you sure you want to delete selected photosfound476281

subscription_paywall

TokenStatusByte offset
premium_subscriptionfound377950
subscription_product_idfound596500
purchaseProductfound827354
purchaseSubscriptionfound827389
validateReceiptAndroidfound830316
validateSubscriptionfound830352
acknowledgePurchaseAndroidfound416587
checkSubscriptionStatusfound424323
restorePurchasesfound545707
Free for 3 daysfound418514
1 Week, auto-renewablefound422480
Welcome to Cleaner Guru Premiumfound542564

auth_backend

TokenStatusByte offset
https://api.xscan.app/found594372
https://api-dev.xscan.app/found594308
/app/signin/uuidv4found471308
/app/playstore/validateAndCheckExpiryfound471259
/api/subscriptions/restorefound471195
Checking token validityfound418185
Creating new accountfound418271
Validate tokens on serverfound417270
New tokens receivedfound418475

analytics_attribution

TokenStatusByte offset
AppsFlyerfound426995
Amplitudefound420313
logPurchaseEventfound824053
trackSubscriptionfound503455
trackOnboardingScreenViewfound539408
trackAppLaunchfound527888
https://api2.amplitude.com/2/httpapifound591454
https://api.eu.amplitude.com/found596549
https://sr-client-cfg.eu.amplitude.com/configfound391103

legal_store_links

TokenStatusByte offset
https://universeapps.limited/cleaner/privacy.htmlfound518431
https://universeapps.limited/cleaner/tos.htmlfound768750
https://universeapps.limited/cleaner/billing.htmlfound510730
https://play.google.com/store/apps/details?id=com.cleanerguru.cleanerfound768631

Hermes 反编译后的扫描逻辑

这轮已把 hermes-dec 安装到项目 .venv 并成功跑完 hbc-file-parserhbc-disassemblerhbc-decompiler。完整反编译输出保留在 ignored 的 data/extracted/package_forensics/runs/20260610-002429/cleaner-guru-cleaning-app/deep-tools,不提交原始 JS/hasm。

问题静态还原结论产品含义
照片怎么加载先用 getAssetsAsync({mediaType: photo, first: 1, sortBy: creationTime})totalCount,再按 after/endCursor 分页读取;其中一个实时路径批量值为 25,另一个全量缓存路径批量值为 500。这是典型“先快速拿总量,再分批显示进度”的 onboarding/扫描体验。
每张照片取哪些字段映射出 iduritimestampfileNamewidthheight;遇到 ph:// URI 会尝试 getAssetInfoAsynclocalUri这解释了它能做总量、进度、预览和删除,但不必一开始读取完整图片像素。
重复/相似怎么判断反编译出的 findDuplicates 先按 timestamp 排序,用 Set 避免重复处理;内层只比较时间接近的候选,出现 5000ms 时间窗。arePhotosSimilar 当前只检查时间差是否小于等于 60000ms。这个版本更像“按拍摄时间近似聚类 burst/连拍照片”,不是 pHash/AI 视觉相似。实现成本低,但误分组和漏识别风险都更高。
分组 key 怎么生成generateGroupKey 按年-月-日-小时:分钟生成 key。UI 上容易包装成“相似照片组”,但技术上更偏分钟桶。
扫描状态可见 REQUESTING_PERMISSIONLOADING_PHOTOSANALYZING_DUPLICATESCOMPLETEDERROR 等状态,并通过 callback 回传 totalPhotos/processedPhotos产品上能做实时进度、扫描完成、智能更新这些感知价值。

置信度:中高。证据来自 Hermes pseudo-code,还需要用受控测试相册动态验证实际分组结果,以及确认远端配置或其他版本是否替换了更强的视觉算法。

Activity / Flutter AOT / Ghidra 分流结论

问题当前结论下一步
Activity 好不好深挖Cleaner Guru 只有 6 个 Activity,first-party 只有 1 个 launcher/home 容器;其余主要是 billing、Facebook/custom tab 和未知 SDK 壳。Activity 对它不是核心逻辑入口。Activity triage 已生成:research/app-package-forensics/cleaner-guru-cleaning-app/apk-pure-latest/activity-triage.html。本包继续以 Hermes bundle 为主线。
Ghidra 对 Cleaner Guru 有没有价值价值中等偏低。它是 RN/Expo 包,核心业务在 Hermes bytecode;native `.so` 多数是 RN/Hermes/Expo/图片管线库,Ghidra 更适合确认 native image/transcoder 是否有自研算法,而不是还原扫描状态机。native-ghidra lane 已跑通;本机安装在 tools/vendor/ghidra,JDK 21 由 runner 自动注入。优先跑可疑 first-party/native media `.so`,不要全量跑 SDK 库。
Flutter AOT 怎么办本批 Flutter 样本只有 armeabi-v7a/libapp.solibflutter.so;blutter 官方路径主要面向 Android arm64,所以当前样本无法直接用 blutter。后续抓带 arm64-v8a split 的 XAPK/APK,再跑 flutter-aot lane;若只有 32-bit,先退回 asset/string/endpoint/动态证据。
哪些 App 更适合 Activity + GhidraRefoto 和 PDF Reader 更适合。Refoto 有 104 个 Activity,其中 35 个 first-party,`HighDefinition`、`PeopleRemove`、`TemplateGenerate`、`TextBrush` 链路很清晰;还包含 libXYAI_CL.solibXYAIBridge.solibrxffmpeg-core.so 等 native 学习候选。Refoto/PDF Reader 优先走 Activity triage + jadx,再对 AI/FFmpeg/PDF native `.so` 用 Ghidra 补函数和伪 C。

界面 / 素材线索

APK 内部素材名显示它至少准备了扫描/销售页/删除/结果类视觉:assets_salescreenanimation.mp4assets_card1.mp4assets_images_bestresult.pngassets_images_deletebuttonicon.pngsrc_assets_images_ph.pngsrc_assets_images_cl.pngsrc_assets_images_offericon.png

AssetBytes
unknown/res/drawable-mdpi-v4/assets_images_bestresult.png264
unknown/res/drawable-mdpi-v4/assets_images_deletebuttonicon.png216
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_arrow_down.png202
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_error.png469
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_file.png138
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_forward.png188
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_pkg.png364
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_sitemap.png428
unknown/res/drawable-mdpi-v4/node_modules_exporouter_assets_unmatched.png4715
unknown/res/drawable-mdpi-v4/node_modules_reactnavigation_elements_lib_module_assets_backiconmask.png653
unknown/res/drawable-mdpi-v4/src_assets_images_chevronright.png118
unknown/res/drawable-mdpi-v4/src_assets_images_cl.png8408
unknown/res/drawable-mdpi-v4/src_assets_images_offericon.png180
unknown/res/drawable-mdpi-v4/src_assets_images_ph.png12641
unknown/res/drawable-nodpi-v4/cleaner_ic_foreground.png25373
unknown/res/raw/assets_card1.mp4144650
unknown/res/raw/assets_fonts_spacemonoregular.ttf93252
unknown/res/raw/assets_salescreenanimation.mp4731273
unknown/res/raw/assets_splashdark.mp4173730

商店截图 OCR 模块

下面是已有公开商店截图采集的 OCR 摘要,帮助理解 Cleaner Guru 品类的产品包装;它反映 iOS 商店素材,不等同于这个 Android APK 全部功能。

STORAGESTORAGEUS

STORAGE

CLEAN UPCLEAN UPUS

CLEAN UP DUPLICATE PHOTOS

DUPLICATE CONTACTSDUPLICATE CONTACTSUS

DUPLICATE CONTACTS Merged Version

PHOTO SWIPEPHOTO SWIPEUS

PHOTO SWIPE TO SORT OUT

VIDEOSVIDEOSUS

VIDEOS

CHARGING ANIMATIONCHARGING ANIMATIONUS

CHARGING ANIMATION

PRIVATE PHOTOSPRIVATE PHOTOSUS

PRIVATE PHOTOS Secret Storage

实现拆解:我们能学什么

模块Cleaner Guru 证据可复用实现思路风险边界
首次价值扫描完成、total photos、similar/duplicate、best result。先做只读 inventory + 本地分组预览,让用户先看到可清理空间和重复组。不要先收费后看结果;否则评论风险会很高。
照片/视频清理expo-media-library、getAssetsAsync、deleteAssetsAsync、scanForDuplicates。iOS 用 PhotoKit,Android 用 MediaStore/ContentResolver;相似图用 pHash/dHash/embedding,重活放原生模块或后端 worker。删除必须二次确认、可预览、尽量提供撤销或最近删除说明。
Paywallfree trial、weekly subscription、purchase/restore/check status/acknowledge。免费扫描 + 高级操作/批量删除/自动清理/压缩接订阅;后端做 receipt 校验和 entitlement。trial、自动续订、取消路径必须透明,不复制误导免费素材。
后端xscan API、uuid 登录、Play 校验、subscription restore。匿名 UUID 账户 + entitlement API + receipt validation + remote config;本地不保存敏感媒体内容。接口签名、证书 pinning、风控要动态确认;隐私政策要和实际上传行为一致。
增长归因AppsFlyer、Amplitude、Facebook/Firebase、RevenueCat 信号。埋点覆盖 install、permission、scan_start、scan_result、delete_attempt、paywall_show、purchase、refund/support。广告 ID、跨站追踪、ATT/Google Data Safety 要同步披露。

下一步动态分析计划

优先级动作要验证的问题产物
P0安装到测试 Android,跑 first launch + permission + scan,不登录真实个人账号。真实请求哪些权限;scan 前/后 paywall 位置;是否上传照片/缩略图/统计。logcat 摘要、屏幕路径、权限弹窗截图 manifest。
P0Reqable/mitmproxy 抓包,必要时 Frida 绕过 pinning。api.xscan.app 的登录、订阅、配置接口和请求体 shape。脱敏 HAR manifest、endpoint 表、request schema。
P1补 Hermes 反汇编工具链。路由文件名、函数名、feature flag、paywall 状态机能否恢复更多。bundle symbol map / route map / 事件字典。
P1找更早 Android 版本。1.0.0 是否初始功能;早期是否只做照片重复清理,后面才扩 contacts/videos/private/charging。版本 diff HTML + 初始功能树。