Lab Technical Report LAB-TR-0006

Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile Forensic Parsers on iOS 26 and Android 16

Daniel Addai

SectraTEK Lab, Prudential Associates

Lab Technical Report, preprint, not peer reviewed

Abstract

A mobile forensic parser written for one release’s storage layout can, after a release changes that layout, return an empty table instead of an error, which an examiner cannot tell from an unused feature. We ran the complete artifact sets of an iOS suite and an Android suite of open-source parsers, 2,607 artifact parsers, on two iOS 26 full file system images and one Android 16 image (completion of the Android pass is not established), classified every outcome, and traced zero-row outcomes to the raw stores. About 18 percent of the iOS artifacts matched a file and returned nothing. Among these we isolated at least four drift defects in existing artifacts, of three behaviours (loud abort, silent zero, benign sidecar read), each exposed by a different check. A second failure class produces rows and is invisible to outcome counts: an app-update module that took the first matching database returned only a second user’s copy on three Android 16 devices, and none of the primary users’ 1,793 rows. A doubling test, in which a second user’s copy must double the row count, exposes it. Parsers should therefore report how many files each pattern matched, and tests should include a second user.

CCS Concepts • Applied computing → System forensics.

Keywords silent failure, schema drift, mobile forensics, tool validation, iOS 26, Android 16, multi-user, metamorphic testing

ACM Reference FormatDaniel Addai. 2026. Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile Forensic Parsers on iOS 26 and Android 16. Lab Technical Report LAB-TR-0006, version 1.0. SectraTEK Lab, Prudential Associates. Preprint, not peer reviewed. https://lab.sectratek.com/research/reports/lab-tr-0006/ DOI: https://doi.org/10.5281/zenodo.23717928

1 Introduction

Open-source mobile forensic suites [11] ship hundreds of artifact modules, each written against the on-device layout seen when the module was contributed. Operating systems often change that layout with a release: a table is dropped, a key moves, a date field takes a value the language runtime cannot hold, a store is split by user. The symptom can be an empty table rather than an error message. An empty table is also the correct result for a feature the device’s user never used, so the two cases look alike to the examiner.

A motivating failure. On the Android 16 image of our sweep, the artifact that reads the Samsung media database reported none of the 213 image rows that the database held (Listing 1). The release removed a location table but kept a view over it, so the artifact’s address join fails; the database error is written to the log, and the report shows an empty table. On four Android 16 images the artifact returned 0, 0, 0 and 3 rows where the fixed artifact returns 5,523, 215, 4,582 and 1,450 (Section 5.3). Nothing in the report distinguishes this from a phone with no images.

Listing 1: The silent zero of the motivating failure, as an examiner and as the raw store see it (schematic; wording shortened, not the real log text).

Artifact    Samsung media database (Android 16)
Report      0 rows; no error shown
Log         database error: location view
            cannot be queried
Raw store   image table holds rows
            (213 on the sweep image)
After fix   image rows kept when the view
            cannot be queried

The problem: silent failure. We call a run a silent failure when it completes, the report shows a plausible table, often an empty one, and nothing in the report says that the store held more. The problem this report addresses is narrower than tool reliability in general: in which forms the artifact parsers of two open-source suites fail silently on current iOS 26 and Android 16 images, and which check exposes each form. We found little that measures how a parser suite behaves on a current release, artifact by artifact (Section 2).

Approach. We ran every artifact of both suites on current images, classified each outcome, and traced the zero-row outcomes to the raw stores. We ask four research questions.

  • RQ1 (Outcomes). On a current image, how many artifacts produce rows, and why do the others not?
  • RQ2 (Defects). What share of the zero-row and failed outcomes are drift defects rather than genuine absence, and what kinds of defect are they?
  • RQ3 (Detection). Which cheap checks reveal such defects, and which kinds does the outcome classification itself miss?
  • RQ4 (Store assumptions). When parsers are written for system stores that no open tool read, do the stores hold what their names and schemas suggest?

Two case studies carry RQ3 and RQ4 beyond the sweep. The first concerns a failure that produces rows and is therefore invisible to an outcome sweep: a module that resolves a path pattern to its first match can return one Android user’s database and silently skip another’s (Section 6). The second concerns parsers for five system stores of Samsung Android 16 (One UI 8) devices that no open tool read (Section 7).

Contributions. This report makes four contributions.

  • A measurement of the outcome of every artifact of an iOS suite and an Android suite on current images, with a four-class outcome taxonomy (Sections 3.2 and 5.1). The counts are measurements; the taxonomy is a simple device and not a method claim.
  • A typology of the defects isolated by attributing zero-row outcomes to the raw stores: four drift defects in existing artifacts with three behaviours and one defect in new code, each matched to the check that exposed it (Sections 3.1, 5.3 and 5.4) [7], [8].
  • A measured case of silent partial loss from first-match path resolution on four Android 16 images, a doubling test that detects it, and a crude static count of how many modules use a first-element pattern (Section 6) [9].
  • Case studies of five system stores (Smart Switch, Health Connect, Bluetooth file transfers, blocked numbers with Android Auto cars, and the telephony network and SIM logs) with row counts, schemas, and three assumptions that did not hold (Section 7) [1]–[5].

Scope. All results describe the images listed in Section 4.1. They are observations of current releases, not measurements of what an update changed, and the defect counts are a lower bound; Section 9 states the limits. Section 2 positions the work, Section 3 defines the failure classes and the method, Section 4 the setup, Section 5 the sweep results, Sections 6 and 7 the case studies, and Section 8 what the results mean for reading an empty or plausible table.

2 Background and Related Work

This section describes the suites under test and the mechanisms that shift a layout under a parser, then places the work among studies of forensic tool validation, testing without an oracle, and other tools and reports.

2.1 The suites under test

ALEAPP (Android) and iLEAPP (iOS) are open-source Python suites in which each artifact is a function that locates files in an extraction by path pattern, reads them, and returns rows for a report [11]. Both accept an extraction as a zip, tar or directory. A pattern that matches no file is a normal outcome: most artifacts target apps or features a given phone does not have. This is why an empty result carries little information on its own.

2.2 How layouts shift under a parser

Three mechanisms recur in this report. First, a release changes or removes a store, so a query that used to succeed finds a missing table or key. Second, a stored value falls outside what the parser’s language can represent; Python’s datetime accepts years 1 to 9999 and raises ValueError otherwise [19]. Third, the file a pattern matches is not the file intended. SQLite keeps a write-ahead log and a shared-memory index beside a database as separate files [20], so a wildcard that ends in the database name also matches these sidecars, and a different copy of the database may exist for another Android user. Android keeps app data per user and states that no user can access another’s app data [10], which is why a second user, such as a work or secure-folder profile, holds its own copy of the same database name.

2.3 Validation of forensic tools

Horsman argues that digital forensic tools need systematic testing and that their reliability cannot be assumed [16]. Garfinkel names growing evidence volume and the risk of tools becoming obsolete among the field’s challenges [14]. Both motivate the stance taken here: the output of a parser is a claim about a store, and it needs a check made by other means. Neither measures how a parser suite behaves on a current release, artifact by artifact.

2.4 Testing without an oracle

Metamorphic testing checks a property that must hold between the outputs of related inputs when no oracle for a single output exists [12]. Forensic parsing is such a setting: there is no list of the rows an artifact should return. Our doubling test for second users (Section 3.5) is a small instance of a metamorphic relation.

2.5 Other tools and reports of the same symptom

Other publicly available tools read related inputs, for example the Mobile Verification Toolkit [18], and a commercial suite announced an import of Samsung Smart Switch backups [13], which we did not test. An external report of the same symptom class is a public issue stating that a unified-log parser partially failed on iOS 27 log archives [17]; we cite its existence and did not study it.

Position of this work. To our knowledge there is no published per-artifact outcome sweep of these two suites on current releases; we searched informally and did not run a systematic literature search, so this is a statement about what we found, not a proof of novelty. The work differs from tool validation as usually practised in its unit of analysis: it records the outcome of every artifact of a suite, attributes the zeros to the stores, and studies a failure that produces rows.

3 Failure Model and Method

This section defines the failure behaviours we look for and the checks that expose them, then describes how outcomes were classified and attributed.

3.1 Failure behaviours

A parser can understate a store in several ways, and they differ in what the report shows. Table 1 lists the five behaviours this study met or could not examine, how each looks in the report, and the signal that exposed it. A loud failure raises and aborts the whole artifact. A silent zero returns nothing without raising in the report. A noisy but benign failure changes the log and not the rows. Silent partial loss returns rows, but only from one of several stores that should be read. A moved path no longer matches any file. The threat is not an attacker but ordinary change: new releases, unusual values, and per-user copies of stores.

Table 1: Failure behaviours of an artifact parser, how each looks in the report, and the signal that exposed it in this study.
BehaviourWhat happensHow it looks in the reportSignal that exposed itInstance
Loud failureThe artifact raises and abortsError outcome; no tableOutcome class; a raw count to tell it from an empty storeCalendar Events (Sec. 5.3)
Silent zeroThe artifact returns nothing; any error goes to the log onlyMatched, no rows; identical to an empty storeRaw table row count; key inspectionMedia database; location-services app list (Sec. 5.3)
Noisy but benignThe log changes, the rows do notNo change in any outcome classLog comparison of fixed and unfixed codeWaze sidecar (Sec. 5.3)
Silent partial lossRows come from one of several matching storesRows outcome; a plausible tableDoubling testSecond Android user (Sec. 6)
Moved pathA path changes and the pattern matches nothingNo file; identical to an absent appNot examined in this studyNone known (Sec. 9)

3.2 Outcome taxonomy

Each artifact was run once per image with the suite’s own command-line tool in file-system (zip) mode and put into one class: rows (at least one row returned), no file (no path pattern matched), matched, no rows (a file matched and zero rows came back), or error (the artifact raised). On the iOS images a fifth group of six artifacts reads device properties rather than files and does not fit the first four; we count it separately. For the Android image only the first and third classes were tallied; the remainder is reported as one group because the working notes did not split it.

3.3 Attribution of zeros

For the matched, no rows and error classes we compared the artifact with the raw store: the row count of the table or the presence of the key the artifact reads (Figure 1). An empty table or an unused feature is recorded as expected. A table that holds rows the artifact did not return, a key present under another name, or an exception on a stored value is recorded as a defect, reproduced with a synthetic file, fixed, and covered by a test. The no file class was not examined further.

How zero-row outcomes were attributedEvery artifact is run read-only once per image and put in one of four outcome classes; counts are for iOS 26.6.2, iOS 26.3.1 and Android 16. Rows (432, 297, 139) are recounted with separate code. Matched with no rows (227, 236, 143) and error (4 and 1 on iOS; not split on Android, shown as a dash) are compared with the raw store, the table row count or the presence of a key, which gives either an empty table or unused feature (expected) or a drift defect that is reproduced, fixed, tested and recounted. No file (603 and 732 on iOS; not split on Android, shown as a dash) is not examined, because a moved path looks the same as an absent app.1 Run every artifactread-only, once per image2 Classify the outcomefour classesRows432/297/139Matched,no rows227/236/143Error4/1/–No file603/732/–Recountwith separatecodeCompare with the raw storetable row count; key presentNot examineda moved pathlooks absentEmpty orunused:expectedDrift defectreproduce, fix,test, recount
Figure 1: Attribution workflow. The counts in each class are for iOS 26.6.2, iOS 26.3.1 and Android 16; a dash marks an Android class that was not split. The dashed box marks the class that was not examined.

3.4 Independent recount

Row counts on the real images were re-derived with separate code (plain SQL, plistlib, zipfile, JSON readers) and compared with the artifact output before each fix was proposed. We call these independent counts. A claim that failed this recount was withdrawn (Section 6.3).

3.5 Doubling test for second users

For each affected artifact we built a tree from real files in which the primary user’s databases also appear at a second user’s path and at a decoy package path. If the artifact reads one database per user, the row count must exactly double; if it takes the first match, it stays the same. The suite’s storage-view test mode applies the same idea to synthetic cases, with two legs: a duplicate view of one file must not change the count, and a second user’s copy must double it. This is a metamorphic relation [12], not a proof of correctness: it detects a dropped second user, not a wrong one.

3.6 Static pattern count

On the Android suite's checkout at the sweep base we counted artifact module files that call get_file_path or index files_found at a fixed position. This is a pattern count, not an audit: some single-file uses are correct. It gives an upper-bound scale for how many modules could share the first-match behaviour, and nothing more.

3.7 Cross-image agreement

For the two iOS sweeps we computed, per artifact, whether the outcome class agrees between the images. The images differ in device, user and OS version, so disagreement is confounded; the figure is a noise floor for any differential check, not a drift measurement.

4 Experimental Setup

This section lists the evidence, the tool versions and the reference measures against which the output was checked.

4.1 Evidence

All images are full file system extractions and were opened read-only; Table 2 lists them by use. Only counts, schemas and structure are reported, never content. Device models, identities, usage and ownership are not reported, and we did not establish that images used for different purposes come from different devices.

Table 2: Evidence classes and what each was used for.
UsePlatform and versionImagesNotes
iOS sweepiPhone, iOS 26.6.2 and 26.3.12Full iOS suite artifact set; per-artifact outcome files kept privately
iOS fix verificationiPhone, iOS 26.2.1, 26.3.1 (×3), 26.5.2, 26.6, 26.6.1, 26.6.28Fixed against unfixed code on every image; iOS 18.1.1 result carried from an earlier run
Android sweepSamsung phone, Android 16 (One UI 8)1Full Android suite artifact set, first pass
Android fixes and second-user checksSamsung phones, Android 16 (One UI 8): two S-series, two A-series4Three hold a second (secure-folder) user
Telephony storesSamsung, Android 10 to 167Five readable Android 16 (One UI 8.5) images hold the SIM log; two hold the network log
Synthetic fixturesBoth platformsn/aInvented values; one reproduction per defect

Source: working reports and test records [5], [7], [8], [9].

4.2 Tools and versions

The iOS sweep used the iOS suite's main branch at the time of the work (1,272 artifacts in 486 module files). The Android sweep and the static count used the Android suite's main branch at the sweep base (1,335 artifacts; the static count covered 529 artifact module files). Our test records cite a full run of 1,333 modules for the same suite on a slightly different base; we use 1,335 because it is the figure in the sweep notes. The sum of the two set sizes, 2,607, is the number of artifact parsers studied. It is not the number of artifact runs: the iOS set was run twice and the Android set once, which makes 3,879 runs. Each fix was checked by continuous integration where it ran and otherwise by the equivalent checks run locally (Artifact Availability).

4.3 Reference measures

The data stored on the device are the reference. We compare each artifact’s output with three measures taken from the store by other means: the raw store itself (table row counts and key presence), the independent counts, and for second users the exact-doubling relation. Where none of these applies, as for the no file class, outcomes are left unattributed.

5 Results

Most artifacts found no file, about 18 percent of the iOS set matched a file and returned nothing, and the drift defects among those outcomes each needed a different check to find. Table 3 answers each research question; the subsections and the two case studies give the evidence.

5.1 Outcome of the sweeps (RQ1)

On both iPhones most artifacts found no file, which is the normal case: a phone does not hold every app a suite supports (Table 4, Figure 2). The class that needs a person is the next one. About 18 percent of the iOS set matched a file and returned nothing, and this is where drift lives, because a defect and an unused feature produce the same outcome there. The two iPhones differ in device, user and release, so the difference between their counts is confounded (Section 5.2).

Table 3: Answers to the research questions on the images examined.
QuestionAnswerEvidence
RQ1 OutcomesMost artifacts find no file (47 to 58 percent on the iPhones), the normal case. A further 18 to 19 percent of the iOS set (227 and 236 artifacts) match a file and return nothing; on Android, 143 of 1,335 do.Sec. 5.1 and 5.2, Tables 4 and 5, Figure 2
RQ2 DefectsFour drift defects in existing artifacts (a removed table, a year printed as 0000, a renamed key, a sidecar read as a database) and one defect in new code. Of 322 iOS artifacts with a matched-no-rows or error outcome, two were drift defects; on Android, one of 143. These are lower bounds, not rates.Sec. 5.3, Table 6
RQ3 DetectionNo single check finds all of them. The outcome class flags two but cannot separate them from empty stores; a raw count, a key inspection, a log comparison and a doubling test each found a defect the others missed. Silent partial loss produces rows and lies outside the outcome classes.Sec. 5.4 and 6, Table 1
RQ4 Store assumptionsNot reliably. A table named trafficstats holds a lookup log, not per-SIM data usage. The Health Connect record tables, the Bluetooth transfer table and the rejected-cars table held no rows on any image examined.Sec. 7, Tables 8 and 9
Table 4: Outcome class of every artifact, per sweep (percent of the artifact set in parentheses).
SweepArtifactsRowsNo fileMatched, no rowsErrorOther
iOS 26.6.21,272432 (34.0)603 (47.4)22746
iOS 26.3.11,272297 (23.3)732 (57.5)23616
Android 161,335139 (10.4)1,053 (78.9)a143 (10.7)an/a

a For Android, 1,053 artifacts either matched no file or failed; the notes do not split the two. Other: artifacts that read device properties and are not file based. Source: iOS per-artifact outcome files (private), iOS and Android working reports.

Outcome of every artifact in the three sweepsThree horizontal stacked bars on one scale. iOS 26.6.2, 1,272 artifacts: 432 rows, 227 matched a file with no rows, 4 errors, 603 no file, 6 property readers. iOS 26.3.1, 1,272 artifacts: 297 rows, 236 matched with no rows, 1 error, 732 no file, 6 property readers. Android 16, 1,335 artifacts: 139 rows, 143 matched with no rows, 1,053 no file or error (not split).RowsMatched, no rowsErrorProperty readersNo file (Android: no file or error, not split)iOS 26.6.21,272 artifacts432227603iOS 26.3.11,272 artifacts297236732Android 161,335 artifacts1391431,05305001,0001,335Artifacts, one scale for all three sweeps
Figure 2: Outcome class of every artifact in each sweep, drawn to one scale. The hairline segments are the 4 and 1 errors on the iPhones and the 6 property readers. Source: iOS per-artifact outcome files (private notes) and the iOS and Android working reports.

The Android counts are less certain than the iOS counts. A full Android run in an earlier session filled the working disk (37 GB of output) and was aborted. The counts in Table 4 come from the sweep in a later session, during which the disk also became full and the output was deleted afterwards. The notes give the tallies but do not state that the run completed, so the Android counts may describe a partial pass.

5.2 Agreement between the two iPhone sweeps

The two iOS images agree on the outcome class of most artifacts, and their disagreements are not evidence of drift (Table 5). The same class occurred on both images for 1,007 of 1,272 artifacts (79.2 percent); 265 (20.8 percent) differ. Of the 322 artifacts that were in the matched-no-rows or error class on at least one image, we attribute two to drift (Section 5.3). Disagreement is dominated by device usage and by the one-release difference between the images, and a differential check would have to separate these.

Table 5: Outcome on the iOS 26.6.2 image (rows) against the iOS 26.3.1 image (columns).
26.6.2 \ 26.3.1RowsMatched, no rows or errorNo fileOther
Rows27579780
Matched, no rows or error11146740
No file11125800
Other0006

The per-artifact file of the iOS 26.6.2 image records its 4 errors together with matched-no-rows (231 artifacts), and the iOS 26.3.1 file lists its 1 error separately (236 and 1), so this table merges the two classes (231 and 237); Table 4 separates them. Diagonal total 1,007 of 1,272. Source: private per-artifact outcome files, aggregate counts only.

5.3 Drift defects (RQ2)

Checking matched-no-rows and error outcomes against the stores isolated the five defects in Table 6. Four are drift defects in existing artifacts and were found in the sweeps; a fifth was found while validating a new parser on real files. They span the first three behaviours of Table 1. Calendar Events failed loudly: one creation date outside Python’s year range aborted the whole artifact. The location-services app list and the media database failed silently. The Waze artifact was noisy but benign, because the database it misread had an empty places table.

Table 6: Defects found, with their behaviour, measured extent and fix.
DefectPlatformBehaviourMeasured extentStatus
Media database: location table removed, view kept (address join fails)Android 16 (One UI 8)Silent zero (error in log only)Unfixed 0, 0, 0 and 3 rows on four images; fixed 5,523, 215, 4,582 and 1,450. Independent counts 5,523; 213+2; 4,561+21; 1,447+3. On the sweep image 0 of 213 image rows were reportedFixed [7]
Calendar: creation date -63114076800 printed as year 0000iOS 26.3.1Loud failure; whole artifact aborts1 of 8 images; 866 rows lost (independent count 866, 5 items with the bad date); the other 7 images unchangedFixed [8]
Location-services app list: bundle key renamediOS 26.x (and 18.1.1 from an earlier run)Silent zero5 rows on 8 of 8 images against 0 unfixed; all eight files hold only the newer key formFixed [8]
Waze: pattern also matches the -wal and -shm sidecars; zip lists -shm firstiOS 26.6.2Noisy, benign here8 log errors unfixed, 0 after; no row change because the database’s places table is empty; three other images identicalFixed [8]
Health Connect first-grant file: shared-user element, no package element (new parser)Android 16, store version 26Silent zero in new code0 rows on 2 of 4 images before the fix; 1, 2, 2 and 1 rows afterFixed in the parser [3]

Rows in the first four entries are artifact rows, not file counts. The Waze fix is verified on one image and one failure mode (a search-order effect); other archive readers were not exercised with a sidecar listed first. Not fixed: a secure-folder history pattern that matches the databases directory (log noise only) and a JSON error on one clipboard item. Source: test records [3], [7], [8] and working reports.

Defects are a small fraction of the zero-row outcomes, and that fraction is a lower bound. Of the 322 iOS artifacts with a matched-no-rows or error outcome on at least one image, two were drift defects (Calendar Events and the app list) and one changed only log output. On the Android image, one of the 143 matched-no-rows artifacts was a defect that we fixed. The working reports state that the remaining iOS cases were checked against table row counts and found to be empty tables or unused features, with the knowledgeC battery, plug, do-not-disturb and location streams simply absent on iOS 26; they do not record the check per artifact, and for Android they say only that many of the 143 are legitimately empty. We therefore report the defect counts as a lower bound on what the sweep found and not as a rate.

One negative result belongs here. The Aggregate Dictionary store exists on 2 of 5 iOS 26 phones but holds only a stale seven-day window from 2022 and 2024, so no module was written for it.

5.4 Which check exposes which defect (RQ3)

Each defect was found by a different check, and no check found them all. A retrospective reading of Table 6 gives the following. The outcome class alone would have flagged Calendar Events (an error) and the media database (matched, no rows), but it would not have separated either from the empty cases; that needed the raw count. The app list was matched-no-rows on both iOS images and showed no difference between them, so a cross-image comparison would not have found it either; only the key inspection did. The Waze effect appeared in the log comparison of fixed and unfixed code, not in any outcome class. The second-user loss produced rows in every case and lies outside the taxonomy; the doubling test found it, and it was cheap because a storage-view test mode already existed (Sections 3.5 and 6). Of the five behaviours in Table 1, only the loud failure is visible to someone reading the report.

6 Case Study: Hidden Second Users

The outcome classes of Section 3.2 cannot see a parser that returns rows from the wrong database. This case study measures one such silent partial loss on Samsung Android 16 devices and the test that exposes it.

6.1 The failure

Four artifacts, the app-update database (frosting), the calendar, the settings search index and the file-manager recent-files list, took the first matching database. On a device with a secure-folder user, whose data lives under user 150, the second user’s smaller copy can sort first. We changed each artifact to read one database per Android user and to add an Android User column [9].

6.2 Measured loss

On the three devices with a second user, the unfixed artifact returned only the second user’s app-update rows, and none of the primary user’s (Table 7, Figure 3). After the change the app-update artifact returns 606, 870, 1,198 and 932 rows on the four devices. The unfixed artifact returned the secure-folder copy on the three two-user devices: 1,207 of the 3,000 rows on those devices, all of them the second user’s; none of the primary user’s 1,793 rows was returned. The unfixed artifacts returned no calendar events and no settings-search rows on three of the four devices. Independent counts on each user’s database agree with the new output.

Table 7: Rows per device after reading one database per Android user: app-update rows by user and what the unfixed artifact returned, and totals of three other artifacts.
DeviceUser 0User 150UnfixedCal.SearchFiles
D1606nonenot affected1115930
D249437637635214
D37404584582915280
D4559373373275142

D1 and D3 are S-series phones, D2 and D4 A-series. User 0 (primary user), User 150 (second, secure-folder user) and Unfixed are app-update (frosting) rows; Cal. (calendar events), Search (settings search) and Files (file-manager recent files) are totals over both users after the change (for D3 the recent-files total is 279 + 1). The unfixed artifact returned the second user’s copy on D2 to D4 and, per the test record, a smaller set or nothing for the calendar and settings search on three of four devices; the per-device unfixed counts for those artifacts were not recorded. Source: test record [9], independent counts.

App-update rows per device, split by Android user, and what the unfixed artifact returnedFour stacked columns of app-update database rows, one per Android 16 device, to one scale. D1: 606 rows of the primary user, no second user. D2: 494 primary-user and 376 second-user rows (870 in total). D3: 740 and 458 (1,198). D4: 559 and 373 (932). On D2 to D4 the unfixed artifact returned only the second-user segment: 1,207 of 3,000 rows, and none of the 1,793 primary-user rows.04008001,200App-update rows606no 2nd userD1494376870D27404581,198D3559373932D4Primary user (user 0): missing before the fix on D2 to D4Second user (150): all that was returned before the fix
Figure 3: App-update database rows by Android user on four Android 16 images, to one scale; the number above a column is its total. The unfixed artifact returned only the upper (grey) segment on D2 to D4; D1 has no second user and was not affected. Source: test record [9].

The Android Auto artifacts had the same first-match pattern. The doubling test on a tree built from a real database gives 16 rows from 8 for the allowed-cars artifact, and 1,122 from 561 for the new blocked-numbers artifact [1]. We found no real image on which a second user’s Android Auto database existed, so that case is demonstrated on constructed data only.

6.3 How far the pattern reaches

The recount caught one error of our own. An earlier version of our test record gave 677 primary-user rows for the file-manager recent-files artifact; the independent recount found that figure on none of the four images, and it was replaced by the counts in Table 7.

The doubling test is not a test of the whole suite. The first-element pattern appears in 67 of the 529 artifact module files at the sweep base (26 call get_file_path, 42 index files_found at a fixed position, with overlap). Some of these use a single system path and are correct, so 67 is a bound on scale and not on defects; the remaining modules with the pattern were not run against a two-user image. In a new WhatsApp Business parser [6], for which no real Business data were available, the doubling test returned the single count for the five artifacts that have data, and nine second-user legs are recorded as known failures. The defect lies in the suite’s existing WhatsApp code, which reads only the first message store, and was not fixed here.

7 Case Study: Five Under-Parsed Android System Stores

Writing parsers for stores that no open tool read (Table 8) exposed a second source of silent failure: assumptions about a store that were wrong, and stores that exist but hold nothing for the examiner. All counts in this section were re-derived with separate code.

Table 8: The five stores: what exists, what holds rows, and what is not verified.
StoreRows per image (4 images unless stated)Not verified on real dataCode
Smart SwitchSessions 2 / 0 / 1 / 1; categories 43 / 0 / 92 / 65; peer app entries 236 / 0 / 97 / 66; backup media 5,169 / 0 / 0 / 0One UI versions before 7; wearable databases were empty and not built[4]
Health ConnectApps 2 / 2 / 3 / 3; preferences 7 / 7 / 9 / 9; first grants 1 / 2 / 2 / 1; record tables 0All record artifacts; Android 14 and 15[3]
Bluetooth file transfers0 / 0 / 0 / 0 (schema present)Row content, timestamp unit[2]
Blocked numbers; Android Auto carsBlocked 126 / 0 / 561 / 958; allowed cars 0 / no database / 8 / 0; rejected cars 0 / no database / 0 / 0Rejected-cars values[1]
Telephony SIM and network logsSIM log 123, 223, 387, 423, 428 (5 of 7 Samsung images); network log 14,442 and 11,376 (2 images)Meaning of SIM states and codes; time zone; any non-Samsung build[5]

Source: test records [1]–[5] and the working reports; all counts were re-derived with separate code.

7.1 Stores that exist but hold little

Smart Switch. The transfer app keeps one folder of JSON files per transfer session and a backup-media index. On the four images the app held 2, 0, 1 and 1 sessions; one image held the app but no history folder. Several keys present in older session files are absent from newer ones, so columns such as the backup result and message counts are empty on one image.

Health Connect. The platform store shares health and fitness data between apps [15]. On all four images every record table was empty (store versions 23, 20, 26 and 26); only the application, preference and first-grant tables hold rows, so the ten record artifacts are validated on synthetic data only.

Bluetooth file transfers and Android Auto rejected cars. The schema is present and empty: a 16-column table on all four images, and the rejected-cars table with 24 columns and no rows anywhere.

Blocked numbers. The table holds rows on three of the four images. On the first device the identifiers run from 1 to 126 without gaps; on the third and fourth they reach 612 and 960 over 561 and 958 rows, so identifiers are missing (51 and 2), which we do not interpret.

7.2 A misleading name: the telephony network log

A table named trafficstats suggests per-SIM data usage. It is not that (Table 9). What the table holds is a lookup log (type, response time, response code) stamped with serving-cell data.

Table 9: The telephony network log on the two devices that have the file: what the table suggests and what it holds.
Suggested by the nameObserved
A consumed-data columnHolds the text 0 on every row (14,442 and 11,376 rows)
An address column of IP addressesHolds 32 hexadecimal digits in all 70,878 and 49,676 items, including failed lookups
Usage per SIMNothing ties a row to a SIM
What it does recordLookup type, response time and code, with serving-cell data: 92 and 48 cell groups, 75 and 25 distinct cell identifiers

Source: telephony working report and test record [5]; counts re-derived with separate code.

The SIM event log (123 to 428 rows on five Android 16 images) carries no ICCID or IMSI. Its subscription identifiers match the subscription table on 5 of 5 devices, and its time is device-local with no zone stored. Six damaged variants (truncated, zeroed first page, header only, empty, random bytes) of four real files returned no rows and no exception. The parsers for this store are described in [5].

8 Discussion

This section draws the practical consequences of the results and states what is new.

8.1 Implications for tool authors and examiners

Three practices follow from what we saw; each is a suggestion and not a proven remedy. First, an artifact could report how many files its pattern matched, so that 0 and 3 are distinguishable from 1; this would have exposed the first-match behaviour at no cost. Second, tests for a new artifact could include the second-tenant doubling leg, which an existing storage-view test mode already supports (Section 3.5). Third, an examiner who reads an empty result could ask whether the artifact matched a file at all. The case studies add a fourth caution: a store’s name can mislead, and a store can be present and empty, so the column meanings of a new parser are worth checking on real data before its output is read as evidence.

8.2 What is new

The sweep counts and the typology are new observations, as far as we found. The outcome taxonomy and the table-count comparison are ordinary engineering practice. The doubling test applies an established testing idea [12] to a known harness; in our view the measured silent partial loss from first-match path resolution, and how cheaply that test finds it, is the most transferable result. The case studies are a mixture: the telephony correction is a result; the empty-store entries are documentation of absence.

9 Threats to Validity

Internal validity. Counts were produced by the parsers under study and re-derived with separate code for the fixed artifacts and stores; the sweep outcome classes themselves were not independently recounted. One person attributed the zeros, and the per-artifact attribution was not recorded, so the defect counts are lower bounds. The no file class (603 and 732 on iOS) was not examined: a path that moved in a new release looks identical to an app that was never installed, so drift of that kind is invisible here, and the true number of defects is probably larger.

Construct validity. A zero is not a defect and a row is not a user action; we did not observe the actions that produced these records. The Android tallies split only two classes, and the disk filled during the Android work, so completion of a clean full pass is not demonstrated. The artifact counts differ slightly between sources (1,335 against 1,333 modules for the Android suite) because they come from different bases.

External validity. The study uses three sweep images, four store images and one vendor family per platform. Usage is unknown, and unused features look like failures. There is no Pixel image, no iOS 27 file system image and no iOS 16 or 17 image in this study, and the Samsung secure-folder behaviour may not match other vendors’ work profiles.

Conclusion validity. No statistical inference is made. The doubling test detects a dropped second user and cannot detect a wrong one. The static count of 67 modules is a pattern count and not an audit, and the iOS suite was not counted. Drift is inferred from single images: no pair of releases of the same device was compared, so the study does not measure the effect of an operating system update, only the state of current releases. We rate confidence as moderate for the counts of the fixed artifacts and stores, which were re-derived with separate code, and low for prevalence: three sweep images and four store images are not a sample.

Limitations. The study describes the two suites only; other tools, such as the Mobile Verification Toolkit [18], were not run on these images. The results do not show that a zero-row outcome is a defect, that other versions or vendors behave the same, or how many examiner conclusions an unreported silent zero would change; we did not measure the last.

10 Conclusion and Future Work

An empty table from the parsers of the two suites examined is not, on its own, evidence of absence. Running 2,607 artifact parsers across three current images showed that most outcomes are absence, that about 18 percent of iOS artifacts match a file and return nothing, and that a small number of those are drift defects of three behaviours. All five defects, four in existing artifacts and one in new code, were reproduced with a synthetic file, fixed and covered by a test. A first-match path pattern is a separate class that returns rows from the wrong user; on four Android 16 images it hid all 1,793 of the primary user’s app-update rows on three, and a doubling test finds it. The case studies show that a store’s name can mislead and that a store can be present and empty. A count of matched files per artifact and a second-user test are cheap enough for any parser suite to adopt, open-source suites included.

Future work, in order of value: (1) a clean second Android sweep with the unmatched class split, and a sweep of both suites on a pair of releases of one device to measure drift as a difference; (2) tracing a sample of the no file class to find moved paths; (3) a module-wide second-user audit with the doubling test on every module that uses a first-element pattern; (4) a recorded per-artifact attribution so that a defect rate can be stated; (5) a Pixel image and an iOS 27 file system image; (6) confirming the column meanings of the stores in Table 8 against data whose underlying actions (for example a file transfer or a health sample) are documented.

Artifact Availability

The fixes and new parsers are released as part of iLEAPP and ALEAPP [11] under the MIT licence, merged through iLEAPP pull request #2574 and ALEAPP pull requests #1779, #1780, #1781, #1782, #1783 and #1784; the telephony parsers #1787 and the WhatsApp Business parser #1785 are open drafts. The synthetic fixtures released with them reproduce each defect. For the iOS pull request 26 of 26 continuous-integration jobs passed; for the Android pull requests the five workflows awaited a maintainer’s approval for a first-time contributor, so the equivalent checks were run locally [8], [9]. The results can be repeated by running the merged artifacts named in Section 4 on comparable images. The real images cannot be released, and the per-artifact outcome files of the sweep are private working notes; their aggregate counts are in Section 5.

Data Handling Statement

Test data were of two kinds: (1) full file system extractions of research devices (test devices) provided to the Lab by their owners and held in its research collection, used read-only for research with the owners’ permission and never copied into any repository, fixture, paper or public file; (2) fully synthetic databases and property lists written by the author with invented values (reserved example domains, documentation phone numbers, placeholder identifiers). Every real image in this report is of kind (1). Only aggregate counts, device classes, operating system versions and table or key names are reported. No names, numbers, accounts, message text, serial numbers, network names, package lists or file paths from the real data appear in this report. A leak scan compared the committed fixtures with the real sources before release (49 files of the telephony contribution against 10,871 real values found none). The per-artifact outcome files of the sweeps are private working notes. No offensive technique, exploit or credential-recovery method is described.

Declaration of AI Assistance

The parser code, the data checks and the first draft of this report were produced with AI assistance (Anthropic Claude). The author directed the work, reviewed the results and the text, and is responsible for the content.

References

  1. Daniel Addai. 2026a. Add Blocked Numbers and Android Auto Rejected Cars artifacts; read every user’s Android Auto database. ALEAPP pull request #1780, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1780
  2. Daniel Addai. 2026b. Add Bluetooth File Transfers artifact (btopp.db). ALEAPP pull request #1781, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1781
  3. Daniel Addai. 2026c. Add Health Connect artifacts (Android 14+). ALEAPP pull request #1784, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1784
  4. Daniel Addai. 2026d. Add Samsung Smart Switch artifacts (com.sec.android.easyMover). ALEAPP pull request #1783, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1783
  5. Daniel Addai. 2026e. Add UICC log, SIM subscriptions and telephony network lookup artifacts. ALEAPP pull request #1787, open draft. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1787
  6. Daniel Addai. 2026f. Add WhatsApp Business (com.whatsapp.w4b) artifacts. ALEAPP pull request #1785, open draft. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1785
  7. Daniel Addai. 2026g. cmh: keep the image rows when location_view cannot be queried (Android 16). ALEAPP pull request #1779, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1779
  8. Daniel Addai. 2026h. Fix Calendar Events year 0000 failure, LSC clients.plist newer key, Waze -shm read. iLEAPP pull request #2574, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/iLEAPP/pull/2574
  9. Daniel Addai. 2026i. Read one database per Android user in frosting, Calendar, Settings Search and My Files recents. ALEAPP pull request #1782, merged October 25, 2026. Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP/pull/1782
  10. Android Open Source Project. [n. d.]. Support multiple users. Retrieved October 27, 2026 from https://source.android.com/docs/devices/admin/multi-user
  11. Alexis Brignoni et al. [n. d.]. ALEAPP and iLEAPP. GitHub repositories (MIT licence). Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP and https://github.com/abrignoni/iLEAPP
  12. Tsong Yueh Chen, Fei-Ching Kuo, Huai Liu, Pak-Lok Poon, Dave Towey, T. H. Tse, and Zhi Quan Zhou. 2018. Metamorphic testing: A review of challenges and opportunities. ACM Computing Surveys 51, 1, Article 4 (2018), 27 pages. https://doi.org/10.1145/3143561 (Bibliographic data confirmed on the publisher record; full text not read.)
  13. Forensic Focus. 2020. Oxygen Forensic Detective 13.2 introduces import of Samsung Smart Switch backups. News item, December 21, 2020. Retrieved October 27, 2026 from https://www.forensicfocus.com/news/oxygen-forensic-detective-13-2-introduces-import-of-samsung-smart-switch-backups/ (Vendor announcement; product not tested.)
  14. Simson L. Garfinkel. 2010. Digital forensics research: The next 10 years. Digital Investigation 7 (2010), S64–S73. https://doi.org/10.1016/j.diin.2010.05.009 (Bibliographic data confirmed from index records; full text not read.)
  15. Google. [n. d.]. Health Connect. Android Developers. Retrieved October 27, 2026 from https://developer.android.com/health-and-fitness/guides/health-connect
  16. Graeme Horsman. 2019. Tool testing and reliability issues in the field of digital forensics. Digital Investigation 28 (2019), 163–175. https://doi.org/10.1016/j.diin.2019.01.009
  17. Mandiant. 2026. Parsing of iOS 27 log archives partially fails. macos-UnifiedLogs, issue #145, opened August 4, 2026, closed August 27, 2026. Retrieved October 27, 2026 from https://github.com/mandiant/macos-UnifiedLogs (Issue title and state confirmed; content not studied beyond the summary.)
  18. MVT Project. [n. d.]. Mobile Verification Toolkit (MVT). GitHub repository. Retrieved October 27, 2026 from https://github.com/mvt-project/mvt (Existence confirmed; not run in this study.)
  19. Python Software Foundation. [n. d.]. datetime: Basic date and time types. Python 3 documentation (MINYEAR and MAXYEAR). Retrieved October 27, 2026 from https://docs.python.org/3/library/datetime.html
  20. SQLite. [n. d.]. Write-Ahead Logging. Retrieved October 27, 2026 from https://www.sqlite.org/wal.html

Cite and download

Cite as

Daniel Addai. 2026. Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile Forensic Parsers on iOS 26 and Android 16. Lab Technical Report LAB-TR-0006, version 1.0. SectraTEK Lab, Prudential Associates. Preprint, not peer reviewed. https://lab.sectratek.com/research/reports/lab-tr-0006/ DOI: https://doi.org/10.5281/zenodo.23717928

Citation guide

DOI (all versions): 10.5281/zenodo.23717928
DOI of version 1.0: 10.5281/zenodo.23717929
Archived at Zenodo: https://zenodo.org/records/23717929 (PDF and files)

lab-tr-0006.bib
@techreport{addai2026labtr0006,
  author      = {Addai, Daniel},
  title       = {Empty Is Not Absent: Silent Failure Modes in Open-Source Mobile
                 Forensic Parsers on {iOS} 26 and {Android} 16},
  institution = {SectraTEK Lab, Prudential Associates},
  type        = {Lab Technical Report},
  number      = {LAB-TR-0006},
  year        = {2026},
  month       = oct,
  doi         = {10.5281/zenodo.23717928},
  url         = {https://doi.org/10.5281/zenodo.23717928},
  howpublished = {https://lab.sectratek.com/research/reports/lab-tr-0006/},
  note        = {Version 1.0, preprint, not peer reviewed. CC BY 4.0}
}

Licence: CC BY 4.0. The print layout of this page is set for US Letter in two columns.

Versions and corrections

VersionDateChange
1.02026-10-27First release. Merges the planned reports LAB-TR-0005 (hidden second users) and LAB-TR-0007 (five under-parsed system stores) as Sections 6 and 7.
1.02026-10-27Posted on Zenodo (preprint), DOI 10.5281/zenodo.23717929.

Corrections: none so far. Errors can be reported through the corrections page.