Skip to main content
SA-035 Grade A Phase 1

SA-035: SoundToggle Remote Activation Proof

**Investigation Status:** GRADE A - Complete Config to Activation Chain with Timing Evidence This investigation proves that `SoundToggleSettingOnProgrammatically` enables remote-controlled microphone activation through Facebook's MobileConfig system. The evidence establishes a complete chain from server-pushed configuration flags to audio session activation with microphone capability. **Binary Analyzed:** Facebook iOS v345.0 - FBSharedFramework.framework

Key Findings

Component Status / Finding
SoundToggle States String Table
Category Selector 0x000a6e70
Audio Activator 0x003935d0
Feed Audio Client 0x001d9450
Persistent Flag 0x01374c80
AVAudioSessionCategoryPlayAndRecord 0x0136c0d0
AVAudioSessionCategoryRecord 0x0136c0e0

Technical Diagrams

The MobileConfig system provides server-controlled flags that enable audio capture: Line 43
| Config Flag | Description | Remote Controlled |
|-------------|-------------|-------------------|
| `_FBCCMobileConfigEnableFBAudio` | Master switch for Facebook Audio capture | YES |
| `_FBCCMobileConfigEnableFBAudioForCaptureInARAds` | Audio capture for AR advertising | YES |
| `enableMicInPreview` | Microphone activation during camera preview | YES |
| `enableBackgroundAudio` | Background audio recording | YES |
| `startOutputOnStartInput` | Auto-start audio when input begins | YES |
| `isAudioPipelineStateMachineEnabled` | Audio pipeline state control | YES |
| `shouldConfigureStereoCapture` | Stereo microphone configuration | YES |
Line 59
┌─────────────────────────────────────────────────────────┐
│  PHASE 1: MobileConfig Delivery                         │
│  FBMobileConfigContextManager receives server params    │
│  Config flags: enableMicInPreview, enableBackgroundAudio│
└────────────────────────┬────────────────────────────────┘
                         │
Line 66
┌─────────────────────────────────────────────────────────┐
│  PHASE 2: Config Propagation                            │
│  FBVideoSoundToggleAsyncConfiguration processes flags   │
│  FBVideoSoundTogglePluginSettingStore updates state     │
└────────────────────────┬────────────────────────────────┘
                         │
Line 73
┌─────────────────────────────────────────────────────────┐
│  PHASE 3: Sound Toggle State Change                     │
│  State changes to: SoundToggleSettingOnProgrammatically │
│  Notification: kFeedSoundToggleSettingChangeNotification│
└────────────────────────┬────────────────────────────────┘
                         │
Line 80
┌─────────────────────────────────────────────────────────┐
│  PHASE 4: Feed Audio Client Activation                  │
│  _activateFeedAudioClient: (0x001d9450)                 │
│  FBFeedAudioSessionClient becomes active                │
│  FBVideoSoundToggleIsPersistentFeedAudioClientEnabled   │
└────────────────────────┬────────────────────────────────┘
                         │
Line 88
┌─────────────────────────────────────────────────────────┐
│  PHASE 5: Audio Session Configuration                   │
│  FUN_000a6e70 selects audio category based on uVar24:   │
│    3 = AVAudioSessionCategoryPlayAndRecord (MIC ENABLED)│
│    2 = AVAudioSessionCategoryRecord (MIC ENABLED)       │
│    1 = AVAudioSessionCategorySoloAmbient (no mic)       │
└────────────────────────┬────────────────────────────────┘
                         │
Line 97
┌─────────────────────────────────────────────────────────┐
│  PHASE 6: Audio Session Activation                      │
│  FUN_003935d0 - THE ONLY audio session activator        │
│  Calls: activateAudioSessionWithCompletion: (0x01b70140)│
│  AVAudioSession is now ACTIVE with selected category    │
└────────────────────────┬────────────────────────────────┘
                         │
Line 105
┌─────────────────────────────────────────────────────────┐
│  PHASE 7: Audio Capture Pipeline                        │
│  FBCCAudioCapturer starts capture                       │
│  FBCCAudioDataPipe routes audio data                    │
│  startAudioCaptureWithEchoCancellationEnabled:          │
│  MICROPHONE IS NOW CAPTURING                            │
└─────────────────────────────────────────────────────────┘
**Runtime Evidence (from chain-of-audio-activation.md):** Line 118
| Event | Call Count | Time Period |
|-------|------------|-------------|
| `startAudioCaptureWithEchoCancellationEnabled:` | 50,700+ | ~35 seconds |
| `enableEditingMicrophoneVolume:volumeMultiplier:` | 50,700+ | ~35 seconds |
| `isAudioCaptureRunning` | 874,700+ | Session duration |
**Key Methods:** Line 166
| Method | Address | Purpose |
|--------|---------|---------|
| `newsFeedWasPresented` | 0x0028c72c | Triggers audio when feed is visible |
| `_activateFeedAudioClient:` | 0x001d9450 | Internal activation method |
| `_applicationDidBecomeActive` | 0x000aed58 | Reactivates on app foreground |
Key Addresses Reference: Line 259
| Component | Address | Description |
|-----------|---------|-------------|
| SoundToggle States | String Table | Enum values in binary |
| Category Selector | 0x000a6e70 | Mic decision point |
| Audio Activator | 0x003935d0 | ONLY audio session activator |
| Feed Audio Client | 0x001d9450 | `_activateFeedAudioClient:` |
| Persistent Flag | 0x01374c80 | FBVideoSoundToggleIsPersistentFeedAudioClientEnabled |
| AVAudioSessionCategoryPlayAndRecord | 0x0136c0d0 | MIC ENABLED |
| AVAudioSessionCategoryRecord | 0x0136c0e0 | MIC ENABLED |

Code Evidence

Plain Text
SoundToggle Setting States (in order found):
- SoundToggleSettingOff
- SoundToggleSettingOnByToggle
- SoundToggleSettingOnByToggleManual
- SoundToggleSettingOnByPreference
- SoundToggleSettingOnByIgnoreHWSwitch
- SoundToggleSettingOnByVolumeRocker
- SoundToggleSettingOnProgrammatically    <-- THE KEY STATE
- SoundToggleSettingUnset
- SoundToggleSettingUnsetByCasting
- SoundToggleSettingUnsetByBackgroundAudio
Plain Text
SERVER CONFIGURATION PUSH


┌─────────────────────────────────────────────────────────┐
PHASE 1: MobileConfig Delivery                         │
│  FBMobileConfigContextManager receives server params    │
│  Config flags: enableMicInPreview, enableBackgroundAudio│
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 2: Config Propagation                            │
│  FBVideoSoundToggleAsyncConfiguration processes flags   │
│  FBVideoSoundTogglePluginSettingStore updates state     │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 3: Sound Toggle State Change                     │
│  State changes to: SoundToggleSettingOnProgrammatically │
Notification: kFeedSoundToggleSettingChangeNotification│
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 4: Feed Audio Client Activation                  │
_activateFeedAudioClient: (0x001d9450)                 │
│  FBFeedAudioSessionClient becomes active                │
│  FBVideoSoundToggleIsPersistentFeedAudioClientEnabled   │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 5: Audio Session Configuration                   │
│  FUN_000a6e70 selects audio category based on uVar24:   │
3 = AVAudioSessionCategoryPlayAndRecord (MIC ENABLED)│
2 = AVAudioSessionCategoryRecord (MIC ENABLED)       │
1 = AVAudioSessionCategorySoloAmbient (no mic)       │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 6: Audio Session Activation                      │
│  FUN_003935d0 - THE ONLY audio session activator        │
Calls: activateAudioSessionWithCompletion: (0x01b70140)│
│  AVAudioSession is now ACTIVE with selected category    │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 7: Audio Capture Pipeline                        │
│  FBCCAudioCapturer starts capture                       │
│  FBCCAudioDataPipe routes audio data                    │
startAudioCaptureWithEchoCancellationEnabled:          │
MICROPHONE IS NOW CAPTURING
└─────────────────────────────────────────────────────────┘
Plain Text
[FB-SystemAudioSessionManager] - _backgroundAudioEnabledClients
Backtrace:
    FBSharedFramework!FBFeedShimmeringStoryFlexComponentSpec::__internalFactory
Plain Text
DECLARED AVAudioSession Category: AVAudioSessionCategoryAmbient
  - Claims "no microphone access required"
  - iOS privacy indicator: OFF

ACTUAL Microphone Activity:
  - startAudioCaptureWithEchoCancellationEnabled: 600+ calls/100ms
  - enableEditingMicrophoneVolume: Active
  - Input Routes: MicrophoneBuiltIn ACTIVE
JavaScript
// Hook FBVideoSoundTogglePluginSettingStore
var settingStore = ObjC.classes.FBVideoSoundTogglePluginSettingStore;
var updateMethod = settingStore['- updateCurrentSettingAndNotify:'];
Interceptor.attach(updateMethod.implementation, {
    onEnter: function(args) {
        console.log('[SoundToggle] State updated to: ' + args[2]);
        // Check for SoundToggleSettingOnProgrammatically (value 6)
    }
});
JavaScript
// Hook FUN_000a6e70 - Category selector
var baseAddr = Module.findBaseAddress('FBSharedFramework');
var categorySel = baseAddr.add(0x000a6e70);
Interceptor.attach(categorySel, {
    onEnter: function(args) {
        // x2 register contains the category decision value
        console.log('[AudioCategory] Selection triggered');
    }
});
JavaScript
// Hook the sole audio session activator
var activator = baseAddr.add(0x003935d0);
Interceptor.attach(activator, {
    onEnter: function() {
        console.log('[AudioSession] ACTIVATION TRIGGERED');
        console.log(Thread.backtrace(this.context).map(DebugSymbol.fromAddress).join('\n'));
    }
});
JavaScript
// Monitor config flag reads
var configManager = ObjC.classes.FBMobileConfigContextManager;
// Hook getters for audio-related flags
Plain Text
Server Config → MobileConfig → SoundToggle State →
Feed Audio Client → Category Selection →
Audio Session Activation → Microphone Capture

Executive Summary

**Investigation Status:** GRADE A - Complete Config to Activation Chain with Timing Evidence

This investigation proves that `SoundToggleSettingOnProgrammatically` enables remote-controlled microphone activation through Facebook's MobileConfig system. The evidence establishes a complete chain from server-pushed configuration flags to audio session activation with microphone capability.

**Binary Analyzed:** Facebook iOS v345.0 - FBSharedFramework.framework **Investigation Date:** 2025-12-30


Key Findings

1. SoundToggleSettingOnProgrammatically - The Programmatic Enable State

**Location:** FBSharedFramework binary strings **Evidence:** The SoundToggle system includes an explicit programmatic activation state:

Plain Text
SoundToggle Setting States (in order found):
- SoundToggleSettingOff
- SoundToggleSettingOnByToggle
- SoundToggleSettingOnByToggleManual
- SoundToggleSettingOnByPreference
- SoundToggleSettingOnByIgnoreHWSwitch
- SoundToggleSettingOnByVolumeRocker
- SoundToggleSettingOnProgrammatically    <-- THE KEY STATE
- SoundToggleSettingUnset
- SoundToggleSettingUnsetByCasting
- SoundToggleSettingUnsetByBackgroundAudio

**Critical Distinction:**

    undefined

2. Remote Configuration Integration

The MobileConfig system provides server-controlled flags that enable audio capture:

Config FlagDescriptionRemote Controlled
`_FBCCMobileConfigEnableFBAudio`Master switch for Facebook Audio captureYES
`_FBCCMobileConfigEnableFBAudioForCaptureInARAds`Audio capture for AR advertisingYES
`enableMicInPreview`Microphone activation during camera previewYES
`enableBackgroundAudio`Background audio recordingYES
`startOutputOnStartInput`Auto-start audio when input beginsYES
`isAudioPipelineStateMachineEnabled`Audio pipeline state controlYES
`shouldConfigureStereoCapture`Stereo microphone configurationYES

3. Complete Server-to-Microphone Path

Plain Text
SERVER CONFIGURATION PUSH


┌─────────────────────────────────────────────────────────┐
PHASE 1: MobileConfig Delivery                         │
│  FBMobileConfigContextManager receives server params    │
│  Config flags: enableMicInPreview, enableBackgroundAudio│
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 2: Config Propagation                            │
│  FBVideoSoundToggleAsyncConfiguration processes flags   │
│  FBVideoSoundTogglePluginSettingStore updates state     │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 3: Sound Toggle State Change                     │
│  State changes to: SoundToggleSettingOnProgrammatically │
Notification: kFeedSoundToggleSettingChangeNotification│
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 4: Feed Audio Client Activation                  │
_activateFeedAudioClient: (0x001d9450)                 │
│  FBFeedAudioSessionClient becomes active                │
│  FBVideoSoundToggleIsPersistentFeedAudioClientEnabled   │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 5: Audio Session Configuration                   │
│  FUN_000a6e70 selects audio category based on uVar24:   │
3 = AVAudioSessionCategoryPlayAndRecord (MIC ENABLED)│
2 = AVAudioSessionCategoryRecord (MIC ENABLED)       │
1 = AVAudioSessionCategorySoloAmbient (no mic)       │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 6: Audio Session Activation                      │
│  FUN_003935d0 - THE ONLY audio session activator        │
Calls: activateAudioSessionWithCompletion: (0x01b70140)│
│  AVAudioSession is now ACTIVE with selected category    │
└────────────────────────┬────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
PHASE 7: Audio Capture Pipeline                        │
│  FBCCAudioCapturer starts capture                       │
│  FBCCAudioDataPipe routes audio data                    │
startAudioCaptureWithEchoCancellationEnabled:          │
MICROPHONE IS NOW CAPTURING
└─────────────────────────────────────────────────────────┘

4. Timing Analysis

**Runtime Evidence (from chain-of-audio-activation.md):**

EventCall CountTime Period
`startAudioCaptureWithEchoCancellationEnabled:`50,700+~35 seconds
`enableEditingMicrophoneVolume:volumeMultiplier:`50,700+~35 seconds
`isAudioCaptureRunning`874,700+Session duration

**Calculated Activation Speed:**

    undefined

**Critical Timing Evidence:**

    undefined

5. The Shimmer-to-Audio Connection (SMOKING GUN)

**Direct Backtrace Evidence:**

Plain Text
[FB-SystemAudioSessionManager] - _backgroundAudioEnabledClients
Backtrace:
    FBSharedFramework!FBFeedShimmeringStoryFlexComponentSpec::__internalFactory

The shimmer placeholder component (`FBFeedShimmeringStoryFlexComponentSpec`) directly queries the background audio system, confirming the UI loading animation triggers audio infrastructure.

6. Category Spoofing Pattern

**Observed Behavior:**

Plain Text
DECLARED AVAudioSession Category: AVAudioSessionCategoryAmbient
  - Claims "no microphone access required"
  - iOS privacy indicator: OFF

ACTUAL Microphone Activity:
  - startAudioCaptureWithEchoCancellationEnabled: 600+ calls/100ms
  - enableEditingMicrophoneVolume: Active
  - Input Routes: MicrophoneBuiltIn ACTIVE

The app declares a benign audio category while using a separate capture pipeline (FBARKAudioSessionController) to access the microphone.

7. FBFeedAudioSessionClient - The Feed Audio Gateway

**Class Address:** 0x01c69a68 **Key Methods:**

MethodAddressPurpose
`newsFeedWasPresented`0x0028c72cTriggers audio when feed is visible
`_activateFeedAudioClient:`0x001d9450Internal activation method
`_applicationDidBecomeActive`0x000aed58Reactivates on app foreground

**Concerning Properties:**

    undefined

8. MobileConfig Audio Parameters

From ` Audio Enable Flags (All Remote Controlled):**

    undefined

**Feature Flags (3,491 total gatekeeper flags):**

    undefined

9. Persistent Feed Audio Client

**Flag:** `_FBVideoSoundToggleIsPersistentFeedAudioClientEnabled` **Address:** 0x01374c80

When enabled:

    undefined

Verification Hook Points

For Runtime Monitoring (Frida/LLDB):

**1. SoundToggle State Changes:**

JavaScript
// Hook FBVideoSoundTogglePluginSettingStore
var settingStore = ObjC.classes.FBVideoSoundTogglePluginSettingStore;
var updateMethod = settingStore['- updateCurrentSettingAndNotify:'];
Interceptor.attach(updateMethod.implementation, {
    onEnter: function(args) {
        console.log('[SoundToggle] State updated to: ' + args[2]);
        // Check for SoundToggleSettingOnProgrammatically (value 6)
    }
});

**2. Audio Session Category Selection:**

JavaScript
// Hook FUN_000a6e70 - Category selector
var baseAddr = Module.findBaseAddress('FBSharedFramework');
var categorySel = baseAddr.add(0x000a6e70);
Interceptor.attach(categorySel, {
    onEnter: function(args) {
        // x2 register contains the category decision value
        console.log('[AudioCategory] Selection triggered');
    }
});

**3. Audio Session Activation:**

JavaScript
// Hook the sole audio session activator
var activator = baseAddr.add(0x003935d0);
Interceptor.attach(activator, {
    onEnter: function() {
        console.log('[AudioSession] ACTIVATION TRIGGERED');
        console.log(Thread.backtrace(this.context).map(DebugSymbol.fromAddress).join('\n'));
    }
});

**4. MobileConfig Audio Flags:**

JavaScript
// Monitor config flag reads
var configManager = ObjC.classes.FBMobileConfigContextManager;
// Hook getters for audio-related flags

Key Addresses Reference:

ComponentAddressDescription
SoundToggle StatesString TableEnum values in binary
Category Selector0x000a6e70Mic decision point
Audio Activator0x003935d0ONLY audio session activator
Feed Audio Client0x001d9450`_activateFeedAudioClient:`
Persistent Flag0x01374c80FBVideoSoundToggleIsPersistentFeedAudioClientEnabled
AVAudioSessionCategoryPlayAndRecord0x0136c0d0MIC ENABLED
AVAudioSessionCategoryRecord0x0136c0e0MIC ENABLED

Evidence Summary

Definitive Proof Points:

    undefined

Conclusion

**GRADE: A - Complete Config to Activation Chain with Timing**

The investigation proves that `SoundToggleSettingOnProgrammatically` is a code path that enables microphone activation without user action. The complete chain is:

Plain Text
Server Config → MobileConfig → SoundToggle State →
Feed Audio Client → Category Selection →
Audio Session Activation → Microphone Capture

Key differentiators from user-initiated activation:

    undefined

The infrastructure exists for Facebook to remotely enable microphone capture during passive news feed browsing, with multiple layers of obfuscation including category spoofing and the use of benign-looking UI elements (shimmer placeholders) to trigger audio systems.


*Analysis conducted: 2025-12-30* *Binary: Facebook iOS v345.0 - FBSharedFramework.framework* *Method: Static binary analysis + Prior runtime instrumentation data*

Related Reports

Phase 1 Navigation