爱意满满的作品展示区。
neocanable

AI + garlic 自动化逆向 Android App

  •  
  •   neocanable ·
    neocanable · 1 day ago · 1206 views

    我给garlic decompiler mcp-server 可以跑起来了。

    效果

    拿 Tinder 一个旧版本举例:

    
     ▎ Meet Fable 5, our newest model for complex, long-running work. Switch anytime with /model.
    
    ❯ 帮我分析一下 tinder.apk
    
    ..... bla bla bla
    
    ---
    Tinder APK 分析报告 — v17.24.0 (build 17240054)
    
    ---
    📦 基本信息
    
    这里列出来 tinder 的基本信息
    
    ✻ Sautéed for 1m 55s
    
    ※ recap: You asked me to analyze tinder.apk. I've completed the full analysis — extracted the AndroidManifest, decompiled 98,603 Java files, built a call graph with 586K nodes and 1.49M edges, and produced a comprehensive report covering permissions, API endpoints, architecture, security, and monetization. The manifest and decompiled sources are in `/Users/neo/apks/tinder/inner_analyze/decompiled/`. Let me know what you'd like to dive deeper into. (disable recaps in /config)
    
    

    紧接着,我要求 ai 帮我分析 tinder 的登录认证的流程,结果如下:

    
    ❯ 查看 feature/auth 模块的源码看看认证流程
    
      Thought for 40s, searched for 2 patterns, read 1 file, listed 5 directories, searched memories
    
    分析完毕,以下是 Tinder 认证( auth )模块 的完整源码分析报告:
    
    ---
    Tinder 认证模块源码分析
    
    目录结构
    
    feature/auth/
    ├── captcha/          # Arkose Captcha / HCaptcha 验证
    ├── collect/email/    # 邮箱收集
    ├── consent/          # 用户同意
    ├── email/otp/        # 邮箱 OTP 验证
    ├── google/           # Google 登录
    ├── inboundsms/       # 运营商 SMS 验证
    ├── internal/         # 核心认证逻辑
    │   ├── activity/     #   AuthStartActivity, TermsOfServiceActivity
    │   ├── authflow/     #   ★ 认证流程状态机(核心)
    │   ├── di/           #   Hilt DI 模块
    │   ├── fragment/     #   LoginFragment (登录 UI )
    │   ├── levers/       #   功能开关( A/B 测试)
    │   ├── phoneverification/ # 手机验证子流程
    │   ├── presenter/    #   MVP Presenter
    │   ├── usecase/      #   用例层
    │   └── viewmodel/    #   LoginViewModel
    ├── passkeys/         # Google Passkey 无密码认证
    ├── phone/
    │   ├── number/       # 手机号输入
    │   └── otp/          # 手机 OTP 验证
    └── usecases/         # 暴露给外部的接口
    
    ---
    1. 认证方式 (AuthType)
    
    8 种认证方式,每种对应一个 key 字符串:
    
    ┌────────────────┬──────────────────┬───────────────────────────┐
    │      枚举      │       key        │           说明            │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ LINE           │ "line"           │ LINE 第三方登录           │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ GOOGLE         │ "google"         │ Google 登录               │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ TINDER_SMS     │ "sms"            │ 短信验证码(主流程)      │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ PUSH           │ "push"           │ Push 推送认证             │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ STACKS         │ "stacks"         │ Stacks 认证               │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ EMAIL          │ "email"          │ 邮箱验证                  │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ CREATE_ACCOUNT │ "create_account" │ 创建新账号                │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ LOGIN          │ "login"          │ 登录(通用)              │
    ├────────────────┼──────────────────┼───────────────────────────┤
    │ PASSKEY        │ "passkey"        │ Google Passkey 无密码认证 │
    └────────────────┴──────────────────┴───────────────────────────┘
    
    ---
    2. 认证流程状态机 (AuthFlowStep)
    
    认证是一个状态机,每一步代表一个状态:
    
                        ┌─────────────┐
                        │  Processing │ (处理中)
                        └──────┬──────┘
                               │
                  ┌────────────┼────────────┐
                  ▼            ▼            ▼
          ┌────────────┐ ┌──────────┐ ┌──────────┐
          │InitialStep │ │NextStep  │ │ConsentIs │
          │Ready       │ │Ready     │ │Required  │
          └─────┬──────┘ └─────┬────┘ └──────────┘
                │              │
                ▼              ▼
        ┌──────────────┐ ┌──────────┐
        │ Authenticated│ │  Error   │
        └──────────────┘ └────┬─────┘
                              │
                  ┌───────────┼──────────┐
                  ▼           ▼          ▼
            ┌────────┐ ┌─────────┐ ┌────────┐
            │  Ban   │ │ Warning │ │Cancelled│
            └────────┘ └─────────┘ └────────┘
    
    认证完成后进入 AuthOutage (认证服务不可用)或 Authenticated 。
    
    ---
    3. 认证 Step 栈 (AuthStepV2)
    
    认证过程由多个 Step 按顺序推进,支持回退。Step 类型:
    
    ┌────────────────────────────────────┬─────────────────────────────┐
    │                Step                │            说明             │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ CaptchaStep                        │ 人机验证( Arkose/HCaptcha ) │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ CollectEmail                       │ 收集邮箱地址                │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ EmailOtp                           │ 邮箱 OTP 验证码             │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ Onboarding                         │ 新用户引导流程              │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ Phone                              │ 收集手机号                  │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ PhoneOtp                           │ 手机 OTP 验证码             │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ InboundSms                         │ 运营商 SMSC 自动验证        │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ IneligibleTinderUEmail             │ 不符合 Tinder U 条件的邮箱  │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ AccountRecoveryAwaitEmailMagicLink │ 账户恢复等待邮件            │
    ├────────────────────────────────────┼─────────────────────────────┤
    │ Passkey                            │ Passkey 验证                │
    └────────────────────────────────────┴─────────────────────────────┘
    
    Step 栈是有序列表:每次新 step 被 push 到栈顶,出错时可以 pop 回到上一个 step 。
    
    ---
    4. 请求/响应模型 (AuthRequest / AuthResult)
    
    AuthRequest ( 27 种请求):
    Captcha, CollectEmail, ChallengeRecovery,
    EmailForAccountRecovery, EmailMagicLinkOtp,
    EmailOtp, EmailOtpResend, DismissEmailOtp,
    DismissTinderUIneligibleEmail,
    Facebook, Google, Line,
    Phone, PhoneOtp, PhoneOtpResend,
    InboundSms, Refresh, PreEmail,
    ExistingPhoneOtp, ExistingPhoneOtpResend,
    CreateNewAccount, DismissPasskey,
    InitiatePasskey, ValidatePasskey,
    InitiateAuthenticatePasskey, AuthenticatePasskey
    
    AuthResult 类型:
    - Authenticated — 认证成功
    - Response — 需要下一步(携带 AuthStepV2 )
    - Error — 各种错误( Ban, Warning, IOError, 限流等)
    
    ---
    5. AuthFlowViewModel 核心方法
    
    注入关键 (反混淆后推测):
    
    ┌───────────────────────────────┬────────────────────────────────────────────┐
    │             依赖              │                    用途                    │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ SubmitAuthRequestV2Impl       │ 提交认证请求到 AGS ( Auth Gateway Service ) │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ SaveInitialAuthTypeImpl       │ 保存初始认证方式                           │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ LoadInitialAuthTypeImpl       │ 恢复上次认证方式                           │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ ClearAuthTokensImpl           │ 清除 token                                 │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ SaveBanImpl                   │ 保存封禁记录                               │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ FireworksAuthTracker          │ 分析事件埋点                               │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ AuthInteractTracker           │ 交互跟踪                                   │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ PasskeyAuthFlowDiagnostics    │ Passkey 诊断                               │
    ├───────────────────────────────┼────────────────────────────────────────────┤
    │ UpdatedEmailAddressRepository │ 邮箱更新仓库                               │
    └───────────────────────────────┴────────────────────────────────────────────┘
    
    关键词方法:
    - d0() — continueSetInitialAuthStep:设置初始认证 step
    - e0() — prePasskeyData:Passkey 前置检查
    - f0() — applyInitialAuthStep:应用初始 step
    - g0() — checkIfAuthIsUp:健康检查
    - h0() — 根据错误消息解析回退 step
    - i0() — handleBan:处理封禁/错误
    - j0() — handleAuthenticated:认证成功处理
    - k0() — 计算下一个可用 step
    - m0() / s0() — 显示错误/回退 UI
    - t0() — 从 AuthType 生成 Phone Step
    - u0() — 从 AuthType 生成认证请求
    - v0() — 更新 step 或显示错误
    
    ---
    6. 完整认证流程
    
    AuthStartActivity
      ├── onCreate() → 检查 Intent 中的 ban/onboarding/challenge 状态
      ├── 启动 LoginFragment (登录 UI )
      │     └── 用户选择登录方式( Google/SMS/Email/Passkey/LINE )
      │           └── LoginFragment.Listener.e(AuthType) 回调
      │                 └── 调用 AuthFlowActivity
      │
      └── AuthFlowActivity ★ 认证流程 Activity
            ├── AuthFlowViewModel 持有 StateFlow<AuthFlowState>
            │
            ├── 1) 首次进入:d0() → continueSetInitialAuthStep
            │     ├── e0() 检查 Passkey 是否可用
            │     ├── checkIfAuthIsUp() 健康检查
            │     └── applyInitialAuthStep() 设置初始 Step
            │
            ├── 2) AuthStepLauncher 根据 AuthStepV2 类型启动目标 Activity:
            │     ├── CaptchaStep → Captcha Activity (Arkose/HCaptcha)
            │     ├── CollectEmail → 邮箱输入 Activity
            │     ├── EmailOtp → 邮箱 OTP Activity
            │     ├── Phone → 手机号输入 Activity ★
            │     ├── PhoneOtp → 手机 OTP Activity ★
            │     ├── InboundSms → 运营商自动验证
            │     ├── Passkey → Passkey 全屏 Activity
            │     ├── Google → Google Sign-In
            │     ├── LINE → LINE 授权
            │     ├── Onboarding → 新用户引导
            │     └── IneligibleTinderUEmail → Tinder U 不兼容提示
            │
            ├── 3) 每个子 Activity 返回后,ViewModel 提交 AuthRequest
            │     └── AGS (Auth Gateway Service) 返回 AuthResult
            │           ├── Authenticated → j0() → 登录成功
            │           ├── Response(NextStep) → 推入 step 栈继续
            │           └── Error → i0() → 处理具体错误
            │
            └── 4) 错误处理 (i0):
                  ├── Ban (40301, 40341) → 保存封禁 + 显示 Ban 页面
                  ├── Warning → 显示警告
                  ├── 各种限流 → 显示 toast + 回退
                  ├── InvalidPhone/OTP → 显示错误 + pop step
                  └── IOError/Unknown → 通用错误
    
    7. 手机验证子流程 (主要认证路径)
    
    PhoneVerificationAuthViewModel 管理手机验证的独立流程:
    
    PhoneNumberCollectionActivity
      └── 用户输入手机号
            └── SubmitNewPhoneNumberImpl → 提交到 AGS
                  ├── GoToPhoneOtpStep → PhoneOtpActivity
                  │     └── 用户输入验证码
                  │           └── VerifyUpdatedPhoneOtpImpl → 验证
                  │                 ├── PhoneOtpSuccess → 完成
                  │                 └── Error → 各种错误/重试
                  └── 错误 → 显示错误提示
    
    注入的分析事件跟踪器:AuthVerifySMSEvent — 标记 enterPhoneNumber / submit / enterOTP 各阶段的指标。
    
    ---
    8. AuthStartActivity 入口
    
    AuthStartActivity 是认证入口 Activity (从 LaunchActivity 跳转),它:
    
    - 实现了 LoginTarget 接口( 16+ 方法)
    - 处理 deep link 跳转:deep_link_uri, onboarding_token_extra
    - 处理封禁参数:extra_ban_error_type, extra_suspension_policy, extra_appeal_token
    - 处理多种启动场景:新用户引导、Challenge 、Selfie Challenge
    - 登录方式选择 UI 由 LoginFragment 渲染
    - 创建 LoginViewModel 管理登录状态
    
    关键方法 (LoginTarget 接口):
    
    ┌─────────────┬──────────────────────────────────────────┐
    │    方法     │                 触发场景                 │
    ├─────────────┼──────────────────────────────────────────┤
    │ O()         │ 登录成功 → 跳转 MainActivity             │
    ├─────────────┼──────────────────────────────────────────┤
    │ e(AuthType) │ 用户选择认证方式 → 启动 AuthFlowActivity │
    ├─────────────┼──────────────────────────────────────────┤
    │ B2() / F1() │ 开启 overlay + 启动 AuthFlow             │
    ├─────────────┼──────────────────────────────────────────┤
    │ P0() / Z0() │ 封禁 → 跳转 BanActivity                  │
    ├─────────────┼──────────────────────────────────────────┤
    │ T0()        │ 账户恢复                                 │
    ├─────────────┼──────────────────────────────────────────┤
    │ G2()        │ 版本过期提示                             │
    ├─────────────┼──────────────────────────────────────────┤
    │ J2()        │ Selfie 验证                              │
    ├─────────────┼──────────────────────────────────────────┤
    │ w0()        │ Passkey 不可用 BottomSheet               │
    ├─────────────┼──────────────────────────────────────────┤
    │ Z1()        │ Passkey 登录                             │
    ├─────────────┼──────────────────────────────────────────┤
    │ B1()        │ 年龄验证                                 │
    ├─────────────┼──────────────────────────────────────────┤
    │ G0()        │ 邀请处理                                 │
    └─────────────┴──────────────────────────────────────────┘
    
    ---
    9. 与 AGS (Auth Gateway Service) 通信
    
    认证请求通过 SubmitAuthRequestV2Impl 发送到 Auth Gateway Service ( api.gotinder.com 上的认证网关),这是 Tinder 后端 API 。发送的 AuthRequest 序列化后会包含:
    
    - App-Session-Id — App 会话
    - User-Session-Id — 用户会话(登录后有)
    - Install-Id — 设备安装 ID
    - Device/Carrier/SIM 信息 — 设备指纹
    - Auth token headers — TinderAuth 拦截器注入
    
    认证成功后,ViewModel 调用 j0() → 保存 token → 更新状态为 Authenticated → 关闭 AuthFlowActivity → 回到 AuthStartActivity → O() 启动 MainActivity 。
    
    

    2. 原理

    garlic mcp server 和 garlic decompiler 都在一个二进制内, garlic mcp-server 没有 http 形式的,完全是 stdio 的形式,我试验了几个 http 形式的 mcp-server ,太慢了,感觉难以接受

    在 AI 分析一个 apk 的时候是什么流程呢?

    • 反编译 apk

    • 反编译 AndroidManifest.xm

    • 生成 apk 的 call graph

    • 生成 apk 的 strings 和 strings 的 xref

    • 导入 call graph/strings 到 duckdb

    3. 优点/缺点

    速度快 - garlic 是 c 写的,速度上能得到保证

    占用资源少 - 在分析完一个 apk 后,内存就释放掉,定位文件/方法都可以直接查 db

    追踪程序执行快 - duckdb 支持递归形式的查询,不用追踪每一条路径都去 grep file

    没有 windows 的机器,windows 版本的没有仔细测试。

    4. mcp server 配置方法

    {  
      "command": "garlic", // 这里直接写 garlic 的路径就 ok 了  
      "args": ["-m"]
    }
    

    5. native 分析

    native 的分析是我正在做的另外一个东西,现在只支持 arm64 ,现在能支持到的功能:

    • 反汇编

    • 控制流分析

    • 控制流还原

    • 数据流分析

    • IR

    • jumptable 还原

    • vtable 还原

    • 部分 blr 分析

    • xref 分析

    native 部分的分析也是 c 语言实现的,完全可以衔接到 garlic 上,没有任何三方库,比如 capstone 这些。

    大部分功能还在调试,现在能实现的基础效果是将 java 的 code 和 native 的流程关联起来,我相信有 AI 的加持下,可以更容易的从 java 一直跟到 native 的代码,分析微信效果如下:

    Waiting for analysis to start...[13:55:33] Started analysis for weixin.apk[13:55:33] Running aapt2 dump badging...[13:55:59] Generating Java call graph...[13:56:08] Building Java call graph index...[13:56:23] Call graph built: 770928 methods, 8998 native, 381196 strings[13:56:23] Decompilation completed successfully [39.6s][13:56:26] Extracting native function index...[13:56:40] Queueing native SO analysis...[13:56:40] Decompilation phase complete[13:56:40] Found 182 native SO files to analyze[13:56:40] [1/182] Analyzing libAdvanceP2P.so...[13:56:40] [1/182] libAdvanceP2P.so: imported successfully [0.43s][13:56:40] [2/182] Analyzing libAudioFFmpegDecode.so...[13:56:40] [2/182] libAudioFFmpegDecode.so: imported successfully [0.05s]# ... 这里略过了,是一堆 so 的分析 profile[13:58:41] [174/182] Analyzing libwxperf-tkill.so...[13:58:41] [174/182] libwxperf-tkill.so: imported successfully [0.02s][13:58:41] [175/182] Analyzing libxeffect_xlog.so...[13:58:51] [180/182] libxweb_linker.so: imported successfully [0.03s][13:58:51] [181/182] Analyzing libz-ng.so...[13:58:51] [181/182] libz-ng.so: imported successfully [0.03s][13:58:51] [182/182] Analyzing libzidl2.so...[13:58:51] [182/182] libzidl2.so: imported successfully [0.09s][13:58:51] Importing native strings and cross-references...[13:59:34] Native call graph analysis complete [174.2s]
    

    项目地址: https://github.com/neocanable/garlic ,欢迎使用反馈。

    12 replies    2026-07-18 18:49:44 +08:00
    longxk
        1
    longxk  
       1 day ago via Android
    为啥我用 fable 干不了一点逆向的活
    zbinlin
        2
    zbinlin  
       1 day ago
    现在的 APK 都是加固的,怎么进行逆向好
    owen800q
        3
    owen800q  
       1 day ago via iPhone
    我用 fable 就标记切换到 opus, 你是怎么用的
    owen800q
        4
    owen800q  
       1 day ago via iPhone
    支持 flutter app n 吗
    neocanable
        5
    neocanable  
    OP
       1 day ago via iPhone
    @owen800q 支持,但是 flutter 的 dartvm 要自己写 plugin ,native 部分我正在实现
    neocanable
        6
    neocanable  
    OP
       1 day ago via iPhone
    @owen800q 我用的 deepseek ,mcp-server 就是 garlic 的
    ntdll
        7
    ntdll  
       1 day ago   ❤️ 2
    @zbinlin #2 本身并不困难,大部分壳可以在 art::DexFile::OpenMemory 无痛拿出来,一些指令抽取类型的壳会需要一些额外的操作。但并不困难了。

    我甚至尝试过某大厂的,采用 OLLVM+VMP ,对人来说,很难死磕出来了,但是 AI (加上一些人类基于经验的指导),也仅仅跑了 3 天,被扒的明明白白。就这个,原本让我搞半年,我够呛能整出来,太折磨人了。
    neocanable
        8
    neocanable  
    OP
       1 day ago
    @zbinlin token 够的话,整理完 native 的 control flow ,ai 可以把虚拟机猜出来 -- 我推测
    owen800q
        9
    owen800q  
       1 day ago via iPhone
    @neocanable 了解, 希望可以支持 dartvm, 現在太多 app 用 flutter 写了
    neocanable
        10
    neocanable  
    OP
       23h 27m ago
    @ntdll 老哥过来人
    wuyanzu121
        11
    wuyanzu121  
       22h 7m ago
    卡密的怎么搞?服务器验证的
    neocanable
        12
    neocanable  
    OP
       14h 59m ago
    @wuyanzu121 理论上都可以打掉,看具体情况了。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2608 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 01:49 · PVG 09:49 · LAX 18:49 · JFK 21:49
    ♥ Do have faith in what you're doing.