Open Source / iLEAPP #2575

Reading sysdiagnose files with five new modules

A sysdiagnose holds many small files that answer real questions, such as which apps pair with which websites and which processes were running. Five new modules now read them. This contribution adds ten artifacts and records what each file does not establish.

  • Daniel Addai, SectraTEK Lab
  • Merged
  • CC BY 4.0

View the pull request on GitHub (opens in a new tab)

Summary

  • Five new iLEAPP modules read text and property-list files inside a sysdiagnose: the associated-domains database, two managed-configuration event lists, the Network Extension configuration archive, two iCloud Drive state files and the process list.
  • The pull request adds ten artifacts in five modules. Each reports the printed or stored values and carries notes on what the file does and does not establish.
  • Row counts on three sysdiagnoses were re-counted with separate code and agree. The count of one file was corrected from 557 to 554 process blocks before merge.
  • At submission, iOS 27, iOS 17 and 18 archives and several Network Extension types were unverified on real data. The Lab later ran the readers on an iOS 27.0 archive (Figure 4).
  • 10artifacts added
  • 5new modules
  • 3sysdiagnoses counted at submission
  • 1,942associated-domain entries in the largest report

Cite as

Addai, D., SectraTEK Lab (2026). Associated domains, managed-configuration events, Network Extension, iCloud Drive state and process task info in the iOS sysdiagnose: an iLEAPP contribution. iLEAPP pull request #2575, merged 25 October 2026. https://github.com/abrignoni/iLEAPP/pull/2575

Methodology note

Drafted with AI assistance and reviewed by the author before publication.

The issue

A sysdiagnose is a bundle of many small files, and most examiners read the few that a tool shows them. Several of the files in it answer questions that come up in real cases, and this pull request adds readers for them. Which apps declare a relationship with which websites? Was a managed-configuration setting or profile changed, and by which process? Is a VPN or a per-app network rule configured? Which apps have iCloud Drive containers, and when did they last sync? Which processes were running at the moment of capture?

Without a reader, an examiner opens each file as raw text or a serialised plist. com.apple.networkextension.plist is the harder case: it is a keyed archive, and its rules are not visible in a plain text view. The brctl files print identifiers in a shortened form that cannot be joined to the container list by eye. Figure 1 lists the files and the artifacts that now read them.

Five sysdiagnose files and the ten artifacts that read themA table of five source files, what each holds, and the artifacts added: two for swcutil, two for managed-configuration events, two for Network Extension, three for brctl and one for task info.File in the sysdiagnoseWhat it holdsArtifacts addedswcutil_show.txtAssociated-domains database;per-app settingsAssociated DomainsAssociated Domains SettingsMCSettingsEvents.plistMCProfileEvents.plistManaged-configurationevent listsSettings EventsProfile Eventscom.apple.networkextension.plistNetwork Extension configurations(a keyed archive)ConfigurationsPath Rule Groupsbrctl-container-list.txtbrctl-dump.txtiCloud Drive containers,version history, sync stateContainersVersion HistorySync Statetaskinfo.txtProcesses that existedat the moment of captureProcess Task Info
Show this figure as a table
Files and artifacts
ModuleSource file(s)Artifacts
sdl_swcutilswcutil_show.txtAssociated Domains; Associated Domains Settings
sdl_mc_eventsMCSettingsEvents.plist; MCProfileEvents.plistSettings Events; Profile Events
sdl_network_extensioncom.apple.networkextension.plistConfigurations; Path Rule Groups
sdl_brctlbrctl-container-list.txt; brctl-dump.txtContainers; Version History; Sync State
sdl_taskinfotaskinfo.txtProcess Task Info
Figure 1Five files, each read by its own module, give ten artifacts in total. Source: pull request text (list of modules and artifacts; diagram).

The failure here is not a wrong answer but a missing one. A question that the archive could answer goes unasked because reading the file takes hand work, and a hand-written count of 1,942 domain entries is not something anyone will check.

The essence

The pull request adds five modules in the style of the existing sysdiagnose readers. Each finds its file by name inside a .tar.gz or a folder and returns rows whose values are as printed or stored. Times are parsed to UTC only where the file states them in UTC, and are left as printed where the zone is not stated. The notes of each artifact say what the file does not establish.

Modules, sources and rows on the two devices read at submission
Artifact groupSource fileA row isRows (device 1 / device 2)
Associated domainsswcutil_show.txtA pairing of an app identifier and a domain in the DATABASE section1,942 / 1,690
Associated-domain settingsswcutil_show.txtA key printed under an entry of the SETTINGS section35 / 11
Setting eventsMCSettingsEvents.plistA dictionary holding an event, a process and a time431 / 376
Profile eventsMCProfileEvents.plistAn entry of the ProfileEvents list2 / 10
Network Extension configurationscom.apple.networkextension.plistOne configuration2 / 2
Path rule groupscom.apple.networkextension.plistA group of rules with the same values3 / 2
iCloud Drive containersbrctl-container-list.txt, brctl-dump.txtA container line, joined to its library line71 / 34
Version historybrctl-dump.txtA printed entry of the boot history lists21 / 5
Sync statebrctl-dump.txtA header, system or scheduler line21 / 21
Process task infotaskinfo.txtA process block413 and 463 / 554

Two design choices matter for how the rows are read. Large rule lists in the Network Extension file are grouped, because 163 rules with the same values are one fact, not 163. And a process is reported as printed, with no start time, because the tool's clock is not in the file.

Our methodology

The readers were written from the printed and serialised layouts. The pull request states that they were written from the file formats and not copied from other tools. For each file we looked at its structure first: the sections of the swcutil dump, the keys of the event dictionaries, the archive objects of the Network Extension file, the library lines of the brctl dump, the process: lines of the task list. Figure 2 shows the three reading modes.

Several details came from that look. The brctl library lines print the container identifier in shortened form, so each dump line is matched to a container by pattern; the match is reported as Yes, Ambiguous or No (Figure 3). The event files hold one event per setting field, not a sequence of changes: 431 rows shared 23 distinct times in the file read. Times in the brctl dump carry no zone, so they are shown as printed.

Three ways of reading five file formatsA sysdiagnose archive or folder is searched by file name. Text files are read as printed blocks, the managed-configuration lists as property lists, and the Network Extension file as a keyed archive. All give report rows with a source file column.InputA sysdiagnose_*.tar.gzor an extracted folder;files found by namePrinted text blocksswcutil, brctl and taskinfo files:one row per block or printed lineProperty listMCSettingsEvents and MCProfileEvents:dictionaries holding event, process, timeKeyed archiveNetwork Extension: the archive is walkedand its rules are groupedReport rowsValues as printed or storedA Source File columnNotes: what the file doesnot establish
Figure 2Each format gets its own reading, but the report rows follow the same rules: values as stored, the source file named, limits in the notes. Source: pull request text and the five modules in the diff (diagram).

On the real data, the checks followed one rule: do not trust the reader's own count. Counts for the three sysdiagnoses were re-made with separate code that reads the raw members: service blocks, process: lines, event dictionaries, library lines, and an archive walk for the Network Extension rules (247 and 184 rules, in 3 and 2 groups). They agreed, with one exception. The first draft of the notes said 557 process blocks for the iOS 26.6.2 file; the file holds 554, and the notes were corrected. A pass of the repository's output checker over three reports found four uniform columns on the iOS 26.6.2 report, which are now named in the notes.

How a shortened identifier is matched to a containerThree synthetic dump lines: one fits one container and is marked Yes, one fits two containers and is marked Ambiguous, one fits none and is marked No.Container listLibrary lines in the dumpiCloud.com.example.notesiCloud.com.example.photosiCloud.org.example.photosiCloud.{12}notesDump Match: Yes (fits one container)iCloud.{12}photosDump Match: Ambiguous (fits two)iCloud.{9}filesDump Match: No (no fit)no container fitsA printed identifier is shortened: a run of characters is replaced by a {n} placeholder. It is read as a pattern.A dump line is matched only when it fits exactly one listed container and that container fits no other line.
Figure 3The match is by pattern and is reported as Yes, Ambiguous or No, so a doubtful pairing is visible instead of hidden. Source: sdl_brctl.py notes in the diff; invented identifiers, placeholder notation simplified (synthetic example).

All test data is synthetic. A generator script builds the files with invented bundle identifiers (com.example.*), example.com domains and derived UUIDs, and ten test cases carry recorded baselines. On a Windows host the project's database-backed cases fail for a reason that is unrelated to this change, so the baselines hold the forward-slash form of the source path that the Linux job produces. The pull request also lists what was not verified: the Network Extension VPN, content filter and app VPN keys on a device that held them, any iOS 17 or 18 archive other than partial ones, and iOS 27. The uuid2path file was not implemented because it is absent from every iOS 26 sysdiagnose seen.

The value

For an examiner, the gain is a set of questions that a sysdiagnose can now answer from a report. Associated domains show pairings of app identifiers and websites, including system apps and App Clips. The managed-configuration lists show which process set or removed a restriction, and the profile list shows profile operations. Network Extension configurations and rule groups show what network policy the device carried. The brctl files show which iCloud Drive containers are registered and the operating system builds the daemon recorded over time. The process list shows what was running when the archive was made.

The same readers ran, unchanged, on an iOS 27.0 archive from a third device (Figure 4). Eight of the ten gave rows. Two were empty: the per-app associated-domain settings, where the section is present but prints no entries, and the profile events, where the stored list is empty. Both depend on what was configured on the device, so we do not attribute them to the release.

Rows each reader produced on three devicesA grid of ten readers against three devices. Associated-domain settings and managed-configuration profile events gave 0 rows on the iOS 27.0 device; all others gave rows.ReaderiOS 26.6iOS 26.6.2iOS 27.0Associated domains1,9421,6901,776Associated-domain settings35110Managed configuration: setting events431376531Managed configuration: profile events2100Network Extension: configurations223Network Extension: path rule groups323iCloud Drive containers7134120iCloud Drive version history21513iCloud Drive sync state212121Process task info413554582Dotted cells: the section was present but empty on iOS 27.0; whether that follows the release or what was configured is not established.
Show this figure as a table
Rows per reader and device
ReaderiOS 26.6iOS 26.6.2iOS 27.0
Associated domains1,9421,6901,776
Associated-domain settings35110
Managed configuration: setting events431376531
Managed configuration: profile events2100
Network Extension: configurations223
Network Extension: path rule groups323
iCloud Drive containers7134120
iCloud Drive version history21513
iCloud Drive sync state212121
Process task info413554582
Figure 4The same readers ran on a third device on iOS 27.0 with no change; two outputs were empty. Source: LAB-TR-0011 Table 6 (one archive per device); real counts, not synthetic.

Every row is a lead. A domain pairing does not show that the app is installed or that anything was opened from the site. A listed process does not show that the user opened it, and an absent one may still be installed. A container is registered, not shown to hold files. A remove event is the record of a value being removed, not of a setting having been used. An empty result is not evidence that no VPN, filter or profile was ever present. Only three sysdiagnoses were counted at submission and one more later, so the counts describe those devices.

Where this sits in the Lab's research

These readers are part of the file-level evidence in LAB-TR-0011, Log Compression and Archive Structure in the iOS 27.0 Sysdiagnose: An Early Observation Tested Against Ten Archives (version 1.2, preprint, not peer reviewed; doi:10.5281/zenodo.23720069). Section 4.5 and Table 6 re-run them on one archive of each device, which is the source of Figure 4. The report is on the Lab site at LAB-TR-0011.

LAB-TR-0010, on reading these new sysdiagnose files, is in preparation and has no public page. The method above rests on the pull request.

Sources

Every number and claim above, with where it came from. PR means the pull request text, its diff or its review thread.

Sources for the numbers and claims
Number or claimWhere it came from
Ten artifacts in five modules; the five modules and their source filesPR text, section What this changes; diff of scripts/artifacts/sdl_*.py
Counts on iOS 26.6 (twice) and 26.6.2: containers 71/71/34; version history 21/21/5; state 21/21/21; domains 1,942/1,942/1,690; settings 35/35/11; process blocks 463/413/554; setting events 431/431/376; profile events 2/2/10; NE configurations 2/2/2; path rule groups 3/3/2PR text, checklist, first item
Separate recount agrees; 247 and 184 Network Extension rules in 3 and 2 groups; 557 corrected to 554PR text, checklist, first item
Four uniform columns named in the notesPR text, checklist, second item
Written from the file formats, not copied from other tools; unverified items; uuid2path not implementedPR text, section Anything reviewers should know
Synthetic data: invented com.example.* identifiers, example.com domains, derived UUIDsPR text; admin/test/scripts/synthetic_sysdiagnose_family2.py
Ten test cases; baselines in forward-slash form; Windows-host database failuresPR text, Test record table
26 of 26 CI jobs pass on the final head; merged 25 October 2026PR text, Test record table; GitHub metadata (mergedAt)
431 rows share 23 distinct timesArtifact notes (mc_settings_events)
163 rules with one combination of valuesArtifact notes (ne_path_rules)
Rows on the third device, iOS 27.0: 1,776; 0; 531; 0; 3; 3; 120; 13; 21; 582LAB-TR-0011 Table 6