
🔬 व्हॉट्सऐप, सिग्नल और टेलीग्राम पर परीक्षित एवं निर्मित, Android 14 पर libaudioflinger.so को डाइनैमिक रूप से हुक करके रियल-टाइम VoIP ऑडियो कैप्चर (Uplink/Downlink) के लिए एक उन्नत Android अनुसंधान उपकरण।
लक्ष्य: जब सिस्टम संचार मोड में हो तो Android के audioserver (विशेष रूप से libaudioflinger.so) को हुक करके VoIP स्ट्रीम कैप्चर का प्रदर्शन करना और अपलिंक (माइक) और डाउनलिंक (स्पीकर) PCM बफ़र्स रिकॉर्ड करना।
कंट्रोलर ऐप (Android)
SELINUX पॉलिसी सेटअप, पेलोड इंजेक्शन, डेटा स्थानांतरण और प्लेबैक प्रबंधित करने के लिए 9 बटनों वाला UI।
पेलोड (libaudiohook.so)
C++ शेयर्ड लाइब्रेरी (ऐप प्रोजेक्ट के हिस्से के रूप में बनाई गई) जो Dobby का उपयोग करके आंतरिक AudioFlinger विधियों को हुक करती है और कच्चे PCM बफ़र्स को सत्र निर्देशिका में लिखती है।
पोस्ट-प्रोसेसिंग
अतिरिक्त टूल, tools/audioparser.py कच्ची .ac(Downlink)/.bc(Uplink) फ़ाइलों को WAV में परिवर्तित करता है। ऐप का फ़ाइल मैनेजर भी इन-ऐप कन्वर्ट और प्ले कर सकता है।
रिसर्च उपयोगिताएँ
प्रारंभिक फ़ंक्शन ट्रेसिंग और ऑफ़सेट खोज के लिए Frida स्क्रिप्ट्स; सिंबल/ऑफ़सेट और अन्य स्निपेट्स के लिए विश्लेषण फ़ाइलें।
यह Android एप्लिकेशन audioserver के माध्यम से VoIP रिकॉर्डिंग प्रबंधित करने के लिए एक ग्राफिकल इंटरफ़ेस प्रदान करता है। यह एक नेटिव पेलोड के साथ एकीकृत होता है जो VoIP एप्लिकेशन से माइक्रोफ़ोन और स्पीकर ऑडियो कैप्चर करने के लिए Android ऑडियो स्टैक को हुक करता है।
यह ऐप एक कंट्रोल सेंटर के रूप में कार्य करता है, जो आपको आवश्यक SELinux पॉलिसियाँ इंजेक्ट करने, मॉनिटरिंग शुरू/बंद करने, रिकॉर्ड किए गए डेटा को प्रबंधित करने और कैप्चर की गई VoIP ऑडियो फ़ाइलों को चलाने की सुविधा देता है।
मुख्य एक्टिविटी में 9 कंट्रोल बटन होते हैं:
पॉलिसी इंजेक्ट करें
audioserver और इस ऐप को एक साथ काम करने के लिए आवश्यक SELinux पॉलिसियाँ इंजेक्ट करता है।
मॉनिटरिंग शुरू करें
audioserver में शेयर्ड लाइब्रेरी पेलोड इंजेक्ट करता है, RecordTrack और PlaybackTrack को हुक करके VoIP ऑडियो कैप्चर सक्षम करता है। प्रोसेस इंजेक्शन के लिए AndKittyInjector का उपयोग करता है।
मॉनिटरिंग बंद करें
audioserver प्रोसेस को पुनः प्रारंभ करता है, मॉनिटरिंग रोकता है और इंजेक्ट किए गए हुक्स को हटाता है।
डेटा कॉपी करें
कैप्चर किए गए कच्चे PCM ऑडियो को अस्थायी निर्देशिका /data/local/tmp/voip से /sdcard/voip में कॉपी करता है।
लॉग देखें
इंजेक्शन, हुकिंग और रिकॉर्डिंग स्थिति से संबंधित लॉग प्रदर्शित करता है।
SELinux सक्षम करें
SELinux को enforcing मोड में पुनर्स्थापित करता है।
SELinux अक्षम करें
SELinux को permissive मोड में सेट करता है, इंजेक्ट की गई पॉलिसियाँ विफल होने पर उपयोग करें।
ऑडियो चलाएँ
कस्टम VoIP फ़ाइल मैनेजर (/sdcard/voip/) खोलता है:
+----------------------+
| |
| App MainActivity |
| |
| |
|(9 Control Buttons UI)|
| |
| |
+----------+-----------+
|
|
|
+----------v-----------+
| |
| JNI Layer |
| |
| Selinux, Process Inje|
| ction, |
| |
| |
+----------------------+
यह शेयर्ड लाइब्रेरी AUDIO_MODE_IN_COMMUNICATION का पता लगाने और पूर्वनिर्धारित पैकेज नामों के सेट के लिए Android के ऑडियो स्टैक से सीधे VoIP ऑडियो स्ट्रीम कैप्चर करने हेतु audioserver में इंजेक्ट की जाती है।
यह libaudioflinger.so के अंदर महत्वपूर्ण विधियों को इंटरसेप्ट करने के लिए Dobby इनलाइन हुकिंग फ्रेमवर्क का उपयोग करता है।
अपलिंक (माइक्रोफ़ोन) और डाउनलिंक (स्पीकर) दोनों ऑडियो स्ट्रीम कैप्चर की जाती हैं और बाद में प्रोसेसिंग के लिए सत्र फ़ाइलों में लिखी जाती हैं।
लाइब्रेरी AudioFlinger और संबंधित क्लासेस के अंदर निम्नलिखित फ़ंक्शनों पर हुक्स स्थापित करती है:
लाइब्रेरी UID → पैकेज मैपिंग के आधार पर स्ट्रीम फ़िल्टर करती है।
वर्तमान में मॉनिटर किए जाने वाले ऐप्स:
com.whatsappcom.whatsapp.w4b (WhatsApp Business)org.thoughtcrime.securesms (Signal)org.telegram.messengerorg.telegram.messenger.webआप audioserver_hook.cpp के अंदर अन्य एप्लिकेशन भी जोड़ सकते हैं:
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उदाहरण सत्र:
/data/local/tmp/voip/audioserver_session_1725389200/
├── com.whatsapp_48000_1725389201_123456.ac
├── com.whatsapp_48000_1725389201_123789.bc
चूँकि लक्षित लाइब्रेरी stripped है और libaudioflinger.so में विधियाँ निर्यात (exported) नहीं हैं, इसलिए सफल हुकिंग के लिए हमें विधियों और अन्य संबंधित घटकों के सटीक ऑफ़सेट की आवश्यकता होती है।
हम उन ऑफ़सेट्स को IDA-PRO का उपयोग करके स्टैटिक विश्लेषण से या frida का उपयोग करके डायनामिक विश्लेषण से निकाल सकते हैं।
ऑफ़सेट्स ज्ञात होने के बाद हम उन्हें offsets.h हेडर फ़ाइल के अंदर बदल सकते हैं।
android::AudioFlinger::setMode(audio_mode_t)_ZN7android12AudioFlinger7setModeE11audio_mode_tandroid::AudioFlinger::RecordThread::RecordTrack::getNextBuffer(android::AudioBufferProvider::Buffer *)_ZN7android12AudioFlinger12RecordThread11RecordTrack13getNextBufferEPNS_19AudioBufferProvider6BufferEandroid::AudioFlinger::PlaybackThread::Track::getNextBuffer(android::AudioBufferProvider::Buffer *)_ZN7android12AudioFlinger14PlaybackThread5Track13getNextBufferEPNS_19AudioBufferProvider6BufferEandroid::AudioFlinger::PlaybackThread::Track::stop(void)_ZN7android12AudioFlinger14PlaybackThread5Track4stopEvये स्टैटिक विश्लेषण से प्राप्त किए जा सकते हैं।
libaudioflinger.soandroid::AudioFlinger::ThreadBase::TrackBase::TrackBaseTrackBase::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)
┌─────────────────────────────┐
│ 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) │
└───────────────────────────┘
उपयोग की गई प्रक्रिया:
AudioFlinger PlaybackThread और RecordThread के माध्यम से प्लेबैक/कैप्चर प्रबंधित करता है।PlaybackThread::Track (डाउनलिंक) और RecordThread::RecordTrack (अपलिंक) द्वारा दर्शाया जाता है।app/src/main/cpp/include/offsets.h में रखे गए) के माध्यम से एड्रेस हल करता है।MODE_IN_COMMUNICATION का पता लगानाहम AudioFlinger::setMode(int mode) को हुक करते हैं और एक ग्लोबल स्टेट बनाए रखते हैं:
g_currentAudioMode को अपडेट करते हैं।g_currentAudioMode == AUDIO_MODE_IN_COMMUNICATION।.
├── 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)
audioparser.py के लिए Pythonapp/ खोलें।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/
audioserver इंटरैक्शन के लिए आवश्यक SELinux नियम तैयार करता है।audioserver में पेलोड इंजेक्ट करने के लिए AndKittyInjector का उपयोग करता है।audioserver को पुनः प्रारंभ करता है।/data/local/tmp/voip/… से /sdcard/voip/ में स्थानांतरित करता है (और अस्थायी निर्देशिका साफ़ करता है)। adb pull /sdcard/voip/
python3 tools/audioparser.py voip/
अतिरिक्त बटन:
- "लॉग देखें": इंजेक्टर/हुक स्थिति देखें।
- "SELinux सक्षम करें" / "SELinux अक्षम करें": यदि पॉलिसियाँ बहुत सख्त हों तो अपनी प्रयोगशाला में enforcing/permissive टॉगल करें।
- "डेटा हटाएँ":
/data/local/tmp/voip/और/sdcard/voip/दोनों साफ़ करें।
dlsym के माध्यम से सीधे स्थित नहीं किया जा सकता।dlsym विफल हो सकता है।offsets.h) का उपयोग करें, जिन्हें Frida सिंबल डंप्स और IDA-PRO से मान्य किया गया है।AudioFlinger::setMode(IN_COMMUNICATION) पर हुक्स कैप्चर करते हैं; संक्रमणों को लॉग करते हैं; एक ग्लोबल मोड फ्लैग संग्रहीत करते हैं।audioserver के साथ IPC अवरुद्ध हो सकते हैं।.tmp में लिखें; stop() पर (डाउनलिंक) या (अपलिंक) में नाम बदलें।frameworks/av/services/audioflinger (AudioFlinger, PlaybackThread, RecordThread)system/media/audio (ऑडियो प्रारूप, एट्रिब्यूट्स, चैनल मास्क)डेटा हटाएँ
/data/local/tmp/voip और /sdcard/voip दोनों से सभी ऑडियो डेटा हटाता है।
नोट: डेटा हटाने के बाद, डेटा सहेजने के लिए निर्देशिका निर्माण हेतु audioserver में पुनः इंजेक्ट करना आवश्यक है।
| Function | उद्देश्य |
|---|
AudioFlinger::setMode | IN_COMMUNICATION मोड (VoIP सक्रिय) में/से संक्रमणों को ट्रैक करता है। |
RecordTrack::getNextBuffer | माइक्रोफ़ोन (अपलिंक) ऑडियो फ्रेम्स कैप्चर करता है। |
PlaybackThread::Track::getNextBuffer | स्पीकर (डाउनलिंक) ऑडियो फ्रेम्स कैप्चर करता है। |
Track::stop | डाउनलिंक फ़ाइल बंद और अंतिम रूप देता है। |
RecordTrack::stop | अपलिंक फ़ाइल बंद और अंतिम रूप देता है। |
android::AudioFlinger::RecordThread::RecordTrack::stop(void)_ZN7android12AudioFlinger12RecordThread11RecordTrack4stopEv.ac.bclibaudioflinger.so में PLT हुक्स नहीं
RecordTrack::getNextBuffer, Track::getNextBuffer, आदि) exported नहीं हैं और libaudioflinger.so में उनके लिए PLT/GOT एंट्रीज़ नहीं हैं।
dlsym() या PLT-आधारित हुकिंग तंत्र का उपयोग नहीं कर सके।target_addr = base_addr(libaudioflinger) + offset
DobbyHook(target_addr, hook_fn, &orig_fn)