Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
AudioServer-Voip-Recorder — 🔬 一款高级 Android 研究工具,通过动态 hook libaudioflinger.so 实现实时 VoIP 音频捕获(上行/下行)。已在 Android 14 上针对 WhatsApp、Signal 和 Telegram 完成测试与构建。 | Kitploit
工具/GitHubGitHub/nighthawkk/audioserver-voip-recorder
Android安全逆向工程移动安全
GitHubnighthawkk/audioserver-voip-recorder

AudioServer-Voip-Recorder

🔬 一款高级 Android 研究工具,通过动态 hook libaudioflinger.so 实现实时 VoIP 音频捕获(上行/下行)。已在 Android 14 上针对 WhatsApp、Signal 和 Telegram 完成测试与构建。

查看仓库

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
9小时29分前尚未审核

目标: 演示如何通过挂钩 Android 的 audioserver(特别是 libaudioflinger.so)来捕获 VoIP 音频流,并在系统处于通信模式时录制上行(麦克风)和下行(扬声器)的 PCM 缓冲区。

项目设计与方法论

架构:

  • 控制器应用(Android)
    包含 9 个按钮的 UI,用于管理 SELINUX 策略设置、载荷注入、数据传输和播放。

  • 载荷(libaudiohook.so)
    C++ 共享库(作为应用项目的一部分构建),使用 Dobby 挂钩 AudioFlinger 的内部方法,并将原始 PCM 缓冲区写入会话目录。

  • 后处理
    附加工具 tools/audioparser.py 可将原始 .ac(Downlink)/.bc(Uplink) 文件转换为 WAV。应用的文件管理器也可以在应用内进行转换和播放。

  • 研究工具
    用于初始函数跟踪和偏移量发现的 Frida 脚本;用于符号/偏移量分析的文件及其他代码片段。

控制器应用

该 Android 应用提供了通过 audioserver 管理 VoIP 录音的图形界面。它与一个原生载荷集成,该载荷挂钩 Android 音频栈,以从 VoIP 应用中捕获麦克风和扬声器音频。

该应用充当控制中心,允许你注入所需的 SELinux 策略、启动/停止监控、管理录制的数据,以及播放捕获的 VoIP 音频文件。

特性

主 Activity 包含 9 个控制按钮:

  1. 注入策略
    注入所需的 SELinux 策略,使 audioserver 与本应用能够协同工作。

  2. 开始监控
    将共享库载荷注入 audioserver,通过挂钩 RecordTrack 和 PlaybackTrack 实现 VoIP 音频捕获。使用 AndKittyInjector 进行进程注入。

  3. 停止监控
    重启 audioserver 进程,停止监控并移除注入的挂钩。

  4. 复制数据
    将捕获的原始 PCM 音频从临时目录 /data/local/tmp/voip 复制到 /sdcard/voip。

    • 之后清理临时目录。
  5. 查看日志
    显示与注入、挂钩和录制状态相关的日志。

  6. 启用 SELinux
    恢复 SELinux 强制模式。

  7. 禁用 SELinux
    将 SELinux 设置为宽容模式,在注入的策略失败时使用。

  8. 播放音频
    打开自定义的 VoIP 文件管理器(/sdcard/voip/):

    • 在内存中将原始 PCM 文件转换为 WAV 格式。
    • 直接在应用内播放转换后的音频。
  9. 删除数据
    删除 /data/local/tmp/voip 和 /sdcard/voip 中的所有音频数据。 :删除数据后,我们需要重新注入 ,以创建用于保存数据的目录。

root@kitploit:~
+----------------------+    
|                      |    
|   App MainActivity   |    
|                      |    
|                      |    
|(9 Control Buttons UI)|    
|                      |    
|                      |    
+----------+-----------+    
           |                
           |                
           |                
+----------v-----------+    
|                      |    
|       JNI Layer      |    
|                      |    
| Selinux, Process Inje|    
| ction,               |    
|                      |    
|                      |    
+----------------------+    

挂钩载荷

该共享库被注入到 audioserver 中,用于检测 AUDIO_MODE_IN_COMMUNICATION,并针对预定义的包名集合直接从 Android 音频栈捕获 VoIP 音频流。

它使用 Dobby 内联挂钩框架来拦截 libaudioflinger.so 内部的关键方法。
**上行(麦克风)和下行(扬声器)**音频流都会被捕获,并写入会话文件以供后续处理。

挂钩点

该库在 AudioFlinger 及相关类内部对以下函数安装挂钩:

目标应用

该库根据 UID → 包名映射 过滤音频流。

当前监控的应用:

  • com.whatsapp
  • com.whatsapp.w4b (WhatsApp Business)
  • org.thoughtcrime.securesms (Signal)
  • org.telegram.messenger
  • org.telegram.messenger.web

你也可以在 audioserver_hook.cpp 内部添加其他应用:

root@kitploit:~
static const char* kTargetPackages[] = {  
    "com.whatsapp",  
    "com.whatsapp.w4b",  
    "org.thoughtcrime.securesms",  
    "org.telegram.messenger",  
    "org.telegram.messenger.web"  
};

文件输出

  • 注入 audioserver 时会创建一个会话目录,位于: /data/local/tmp/voip/audioserver_session_<timestamp>/

  • 文件首先以 .tmp 扩展名创建,然后在轨道停止时重命名:

    • 上行(麦克风) → <packageName>_<sampleRate>_<timestamp>.bc
    • 下行(扬声器) → <packageName>_<sampleRate>_<timestamp>.ac
  • 示例会话:

root@kitploit:~
	/data/local/tmp/voip/audioserver_session_1725389200/
	├── com.whatsapp_48000_1725389201_123456.ac
	├── com.whatsapp_48000_1725389201_123789.bc
	

偏移量

由于目标库已剥离符号,且方法未在 libaudioflinger.so 中导出,因此我们需要方法和相关组件的精确偏移量才能成功挂钩。

我们可以通过 IDA-PRO 进行静态分析,或使用 Frida 进行动态分析来提取这些偏移量。 一旦获得偏移量,我们就可以在 offsets.h 头文件中替换它们。

所需偏移量:
方法:
  1. AUDIOFLINGER_SETMODE_OFFSET
    • 方法:android::AudioFlinger::setMode(audio_mode_t)
    • Mangled 名称:_ZN7android12AudioFlinger7setModeE11audio_mode_t
  2. RECORDTRACK_GETNEXTBUFFER_OFFSET
    • 方法:android::AudioFlinger::RecordThread::RecordTrack::getNextBuffer(android::AudioBufferProvider::Buffer *)
    • Mangled 名称:_ZN7android12AudioFlinger12RecordThread11RecordTrack13getNextBufferEPNS_19AudioBufferProvider6BufferE
  3. TRACK_GETNEXTBUFFER_OFFSET
    • 方法:android::AudioFlinger::PlaybackThread::Track::getNextBuffer(android::AudioBufferProvider::Buffer *)
    • Mangled 名称:_ZN7android12AudioFlinger14PlaybackThread5Track13getNextBufferEPNS_19AudioBufferProvider6BufferE
  4. TRACK_STOP_OFFSET
    • 方法:android::AudioFlinger::PlaybackThread::Track::stop(void)
    • Mangled 名称:_ZN7android12AudioFlinger14PlaybackThread5Track4stopEv
其他偏移量:
  1. SAMPLERATE_OFFSET
  2. UID_OFFSET
  3. ISOUT_OFFSET
  4. FORMAT_OFFSET
  5. CHANNELMASK_OFFSET
  6. ATTR_OFFSET

这些可以通过静态分析获得。

  • 库 - libaudioflinger.so
  • 方法 - android::AudioFlinger::ThreadBase::TrackBase::TrackBase
root@kitploit:~
TrackBase::TrackBase(
        IAfThreadBase *thread,
            const sp<Client>& client,
            const audio_attributes_t& attr,
            uint32_t sampleRate,
            audio_format_t format,
            audio_channel_mask_t channelMask,
            size_t frameCount,
            void *buffer,
            size_t bufferSize,
            audio_session_t sessionId,
            pid_t creatorPid,
            uid_t clientUid,
            bool isOut,
            const alloc_type alloc,
            track_type type,
            audio_port_handle_t portId,
            std::string metricsId)

注意事项

  • 仅捕获 IN_COMMUNICATION 模式。普通音频(音乐、铃声等)将被忽略。
  • 对 Telegram 和 Signal 的特殊处理会强制使用正确的采样率(Telegram:48000 Hz,Signal:8000 Hz),以忽略其他不必要的音频,如来电铃声和电话挂断音。
  • PCM 以原始格式存储;控制器应用稍后将 PCM 转换为 WAV 以进行播放。
root@kitploit:~
 ┌─────────────────────────────┐
 │        VoIP Apps            │
 │  (WhatsApp / Signal / TG)   │
 └───────────────┬─────────────┘
                 │ Audio in/out
                 ▼
 ┌─────────────────────────────┐
 │       audioserver           │
 │  (libaudioflinger.so)       │
 └───────┬─────────┬───────────┘
         │         │
   uplink│         │downlink
 (mic)   │         │(speaker)
         ▼         ▼
 ┌───────────-──┐   ┌────────────-─┐
 │ RecordTrack  │   │  Track       │
 │ getNextBuffer│   │ getNextBuffer│
 └───────┬────-─┘   └───────┬────-─┘
         │                 │
   ┌─────▼─────┐     ┌─────▼─────┐
   │ hook_...  │     │ hook_...  │
   │ (uplink)  │     │ (downlink)│
   └─────┬─────┘     └─────┬─────┘
         │                 │
         └──────┬───┬──────┘
                │   │
                ▼   ▼
     ┌───────────────────────────┐
     │  /data/local/tmp/voip/    │
     │  audioserver_session_*    │
     │   - *.bc  (uplink)        │
     │   - *.ac  (downlink)      │
     └───────────────────────────┘

目标函数识别

使用的方法:

  1. 动态跟踪 - Frida:
    • 使用 Frida 跟踪 VoIP 通话期间的所有函数调用
    • 筛选出所有负责音频缓冲区处理的函数。
    • 然后创建 Frida 脚本来捕获和处理音频缓冲区。
  2. AOSP 审查与类映射
    • AudioFlinger 通过 PlaybackThread 和 RecordThread 管理播放/捕获。
    • 每个客户端的音频由 PlaybackThread::Track(下行)和 RecordThread::RecordTrack(上行)表示。
  3. 筛选特定应用的音频流
    • 使用 UID→包名映射来限制到目标应用。
  4. 稳定性与偏移量
    • 最终的原生载荷通过基址 + 硬编码偏移量(保存在 app/src/main/cpp/include/offsets.h 中)解析地址,以应对符号剥离。

检测 MODE_IN_COMMUNICATION

我们挂钩 AudioFlinger::setMode(int mode) 并维护一个全局状态:

  • 每次调用时,我们记录模式变化并更新 g_currentAudioMode。
  • 挂钩(包括麦克风挂钩和扬声器挂钩)会检查 g_currentAudioMode == AUDIO_MODE_IN_COMMUNICATION。
  • 这确保我们仅在 VoIP 会话处于活动状态时转储缓冲区,从而避免音乐/铃声/设备播放/麦克风录音等。

构建与运行 PoC

项目结构

root@kitploit:~
.
├── Android_App/ 
|   ├── app/                           # Android Studio project (App + Payload)
|	│   ├── src/
|	│   │   ├── main/
|	│   │   │   ├── java/              # Controller App Java/Kotlin sources
|	│   │   │   ├── cpp/               # Payload source (built with the app)
|	│   │   │   │   └── include/
|	│   │   │   │       └── offsets.h  # Function offsets for tested builds
├── tools/
│   ├── audioparser.py             # Converts .ac/.bc raw files → WAV
│   ├── frida/                     # Frida scripts for initial hook discovery
│   │   ├── host_audioserver.py
│   │   ├── agent_audioserver.js
├── app-release.apk                 # Signed release apk
└── README.md                       # Root README (design, build, run instructions)

前提条件

  • Android Studio + NDK
  • 已 root 的模拟器(例如 rootAVD)或你自有的测试设备(例如 Magisk)
  • 已安装测试用 VoIP 应用(与你拥有/管理的应用相同)
  • 用于运行 audioparser.py 的 Python

构建应用(同时构建载荷)

  1. 在 Android Studio 中打开 app/。
  2. 确保已安装 NDK(SDK Manager → SDK Tools → NDK)。
  3. 构建 Debug 变体。Gradle/CMake 配置会将该原生载荷(libaudiohook.so)作为项目的一部分进行编译。

在测试目标上安装

adb install -r app/build/outputs/apk/debug/app-debug.apk 或安装提供的 app-release.apk: adb install -r app-release.apk

如果你要单独分发产物,也可以推送共享库进行测试: adb push app/src/main/jniLibs/arm64-v8a/libaudiohook.so /data/local/tmp/

运行 PoC(模拟器/自有设备)

  1. 启动控制器应用 -> 在提示时授予 root 权限。
  2. 点击 “注入策略”
    为你的测试环境中应用与 audioserver 的交互准备所需的 SELinux 规则。
  3. 点击 “开始监控”
    应用使用 AndKittyInjector 将载荷注入 audioserver。
  4. 拨打一个测试 VoIP 电话(例如,使用你自己的 WhatsApp/Signal/Telegram 账号)。
  5. 点击 “停止监控”
    重启 audioserver。
  6. 点击 “复制数据”
    将会话文件从 /data/local/tmp/voip/… 移动到 /sdcard/voip/(并清理临时目录)。
  7. 播放
    • 应用内:“播放音频” 将 PCM 转换为 WAV 并播放。
    • 或离线处理:
      root@kitploit:~
       adb pull /sdcard/voip/
      python3 tools/audioparser.py voip/
      

其他按钮:

  • “查看日志”:查看注入器/挂钩状态。
  • “启用 SELinux” / “禁用 SELinux”:如果策略过于严格,可在你的实验室环境中切换强制/宽容模式。
  • “删除数据”:清除 /data/local/tmp/voip/ 和 /sdcard/voip/。

已测试的版本与设备

  • 模拟器:AVD API 34 (x86_64) - Android 14 - 通过 rootAVD 获取 root 权限
  • 设备:Samsung Galaxy S22 (ARM64) - Android 14 - 构建版本 S901EXXSCEYB1 - 通过 Magisk 获取 root 权限

已测试的应用

  • Whatsapp
  • Whatsapp Business
  • Signal
  • Telegram

值得注意的挑战与解决方案

  1. 符号剥离
    • 问题: 无法通过 dlsym 直接定位符号。
    • 解决方案: 使用静态分析获得的偏移量。
  2. 不同构建版本间的符号/偏移差异
    • 问题: 剥离后的符号因构建版本而异;直接使用 dlsym 可能会失败。
    • 解决方案: 对已测试的构建版本使用基址 + 硬编码偏移量(offsets.h),并通过 Frida 符号转储和 IDA-PRO 验证。
  3. 模式检测准确性
    • 问题: 在 VoIP 会话之外进行录音会产生噪声数据。
    • 解决方案: 在 AudioFlinger::setMode(IN_COMMUNICATION) 上挂钩捕获;记录状态转换;存储全局模式标志。
  4. SELinux
    • 问题: 写入临时目录以及与 audioserver 的 IPC 可能会被阻止。
    • 解决方案: 提供注入策略步骤以添加必要的规则;在测试环境中暴露启用/禁用 SELinux 开关以便调试。
  5. 文件生命周期与重命名
    • 问题: 避免线程停止时产生不完整/损坏的输出。
    • 解决方案: 先写入 .tmp;在 stop() 时重命名为 .ac(下行)或 .bc(上行)。
  6. libaudioflinger.so 中没有 PLT 挂钩

参考资料(开源与文档)

  • Dobby(内联挂钩框架) - https://www.github.com/jmpews/Dobby
  • AndKittyInjector(Android 进程注入器) - https://github.com/MJx0/AndKittyInjector
  • AOSP
    • frameworks/av/services/audioflinger(AudioFlinger、PlaybackThread、RecordThread)
    • system/media/audio(音频格式、属性、声道掩码)
下载工具
注意
audioserver
FunctionPurpose
AudioFlinger::setMode跟踪进入/退出 IN_COMMUNICATION 模式(VoIP 活动)的状态转换。
RecordTrack::getNextBuffer捕获麦克风(上行)音频帧。
PlaybackThread::Track::getNextBuffer捕获扬声器(下行)音频帧。
Track::stop关闭并最终确定下行文件。
RecordTrack::stop关闭并最终确定上行文件。
  • RECORDTRACK_STOP_OFFSET
    • 方法:android::AudioFlinger::RecordThread::RecordTrack::stop(void)
    • Mangled 名称:_ZN7android12AudioFlinger12RecordThread11RecordTrack4stopEv
    • 问题: 目标函数(RecordTrack::getNextBuffer、Track::getNextBuffer 等)未导出,且 libaudioflinger.so 中没有对应的 PLT/GOT 条目。
      • 我们无法使用标准的 dlsym() 或基于 PLT 的挂钩机制。
    • 解决方案: 我们使用 Dobby 进行内联函数挂钩。
      • 挂钩在运行时按以下公式安装:
        root@kitploit:~
        target_addr = base_addr(libaudioflinger) + offset
        DobbyHook(target_addr, hook_fn, &orig_fn)