Lab Technical Report LAB-TR-0004
Informative but Individually Unreliable: An Empirical Study of Android Reset Indicators and Their Clocks
SectraTEK Lab, Prudential Associates
research@sectratek.com
Lab Technical Report, preprint, not peer reviewed
Version 1.2 · First published 27 October 2026; this version 7 November 2026 · CC BY 4.0 · doi:10.5281/zenodo.23717926
Abstract
Evidence of whether and when an Android device was reset lies in recovery logs, boot-reason properties and setup flags, each dated by its own clock, and descriptions of one or a few devices do not say how often these sources exist or how far their dates can be trusted. We read every reset-related source on 14 full file system extractions (12 Samsung; Android 10 to 16) and seven bug reports from four vendor families, classified the clock of each date, and tested a candidate rule that dates an undated recovery entry from a wipe's requested time. The Samsung recovery history was absent on all three units of one flagship generation, and on three older devices its header clock printed a constant, impossible year that passes a plausibility test. The boot-reason history never held a factory-reset entry, and the setup flags cycled around updates. The rule held on one phone, within 57 s of independent file times; on the only other phone able to test it, its central assumption failed by 526 days, a failure exposed by comparing two anchors. On these devices, reset indicators were informative but individually unreliable: each needs its own clock checked before a date is reported.
CCS Concepts • Applied computing → System forensics.
Keywords Android forensics, factory reset, recovery history, boot reason, setup wizard, clock reliability, timestamp estimation, tool validation, bug report
ACM Reference FormatDaniel Addai. 2026. Informative but Individually Unreliable: An Empirical Study of Android Reset Indicators and Their Clocks. Lab Technical Report LAB-TR-0004, version 1.2. SectraTEK Lab, Prudential Associates. Preprint, not peer reviewed. https://lab.sectratek.com/research/reports/lab-tr-0004/ DOI: https://doi.org/10.5281/zenodo.23717926
1 Introduction
An examiner who receives an Android phone is often asked a plain question: was it reset, and when? Android has no single reset record. A reset leaves several traces in different places, written by different components with different clocks, and the traces age differently: some are replaced on the next boot and some survive upgrades.
A motivating example. Samsung phones log every start of the recovery environment, and a wipe requested from Settings can carry two times: the header time, printed by the recovery program from its own clock, and the requested time, written by the requesting program before the device restarted (Section 2.1). When the header clock reads 1970, a later entry has no usable date, but it can in principle be dated by adding its header offset from a wipe to that wipe's requested time. Only two phones in our sample hold two Settings wipes with requested times, the condition for testing such a rule (Figure 1). On phone A, an Android 16 flagship whose header clock reads 1970, the two wipes are 3 h 25 m 32 s apart by header time and 3 h 25 m 32.632 s apart by requested time, and the estimates for later entries lie within 57 s of independent file times. On phone B, an Android 13 foldable, the same comparison gives 118 days by header time and 644 days by requested time, a difference of 526 days. The rule did not run on phone B, because its header prints the year 2020 and the rule is limited to headers before 2012; had it been applied, every estimate on that phone would have been wrong by months. The printed year was not what revealed the failure: the comparison of the two anchors was.
The problem. The example shows the problem this report addresses: the dates on Android reset indicators come from different clocks, and a wrong clock does not show in the date it prints. Each source has so far been described on one or a few devices (Section 2). Three things are therefore open. First, how often each source exists, how often it holds a wipe, and how its format varies across models and Android versions. Second, how reliable the dates are, including those of recovery entries whose clock reads 1970 or another wrong value: an undated wipe entry still matters, and so do the entries after it. Third, how setup flags and boot reasons, offered as supporting evidence, behave around updates, which also run through recovery.
Approach. We read every reset-related source on 14 full file system extractions and seven bug reports, classified the clock behind each date, and tested a candidate rule for dating undated entries on every device that could test it. We ask three research questions.
- RQ1 (Sources). Which on-device and bug report sources record resets, how often are they present, and how do their formats vary?
- RQ2 (Dates). How reliable are the dates these sources carry, and can an undated recovery entry be dated from an anchor entry (one candidate rule), with what error?
- RQ3 (Discrimination). Do setup-flag changes and boot-reason entries tell a reset from an update?
Contributions. This report makes four contributions.
- A census of reset-related sources on 14 full file system extractions and seven bug reports, with counts per source and the format variants met (Sections 5.1 and 5.2).
- A classification of the recovery header clock into five behaviours, including a constant printed year that cannot be the true year although it passes a plausibility test, and evidence that header times are UTC while requested times are device local time (Section 5.3).
- An empirical test of a candidate clock-anchored estimate with an error model: it held on one device, its central assumption failed by 526 days on the only other device that could test it, and we state the conditions under which such an estimate is unsafe (Sections 3.2, 5.4 and 6.1).
- Measurements showing that the setup flags cycle around updates and that the boot-reason history never held a factory-reset entry, and a comparison of three readers written from the file layouts with three existing open-source artifacts that read the same files, which exposes two errors that were not visible in the output (Sections 5.5 to 5.7).
Scope. The study describes what the devices stored. All results describe the 14 extractions and seven bug reports examined, 12 of the extractions from Samsung, and dates are judged against other values stored on the same devices (Section 4.3). The estimate is a candidate rule tested on two devices, not a validated method. Section 7 states the limits. Section 2 describes the sources and positions the work, Section 3 the readers, the candidate estimate and the checks, Section 4 the evidence, Section 5 the results, and Section 6 what they mean for dating a reset.
2 Background and Related Work
This section describes the sources a reset can leave and the clocks behind their dates, then places the work among practitioner descriptions of reset artifacts, studies of what a reset removes, platform documentation and work on tool testing.
2.1 Reset traces and their clocks
Android writes reset-related records in several places, each with its own clock (Table 1). Samsung phones keep a recovery history: a text file with one entry per start of the recovery environment, holding a header line, the options recovery was started with, a status line and a reboot reason (Listing 1). A companion file, extra_history, holds step lines linked to an entry by a two-letter code. The init process keeps a persistent boot-reason history, the settings provider keeps a history of setting changes per user, and the bootstat folder holds a marker file named factory_reset.
| Source | Where kept; what it records | Clock of the date |
|---|---|---|
| Recovery history (Samsung) | efs/; copies in data/log, cache/recovery and bug report members. One entry per recovery start | Header time: recovery program. Requested time: requesting program |
| Step lines (Samsung) | efs/. Step start and end lines per entry code | None; linked by code |
| Boot-reason history | A property in persistent_properties. One line per boot: reason[,subreason],epoch | Running system (UTC epoch) |
| Settings history | Per-user history files; History (name) blocks in bug reports. Old and new value, package, time | Epoch ms; no year in bug reports |
| Bootstat marker | File factory_reset in the bootstat folder | File time |
Two terms are used throughout. The header time of a recovery entry is the date printed in the entry's first line by the recovery program, which reads its own clock. The requested time is the value of the --requested_time option, written by the program that asked for the reset before the device restarted. They are different clocks, and Section 5.3 shows that they can also be in different time zones. An entry with no requested time and a header clock that is not a calendar clock has no usable date.
Listing 1: Schematic of one recovery history entry (values elided). The first line carries the header time; the lines after it are the options recovery was started with, one of which holds the requested time.
+ [CODE | YYYY/MM/DD HH:MM:SS | FIRMWARE] [-] --wipe_data --reason=... --requested_time=... <- requested time <status line> <reboot reason>
2.2 Practitioner descriptions of reset artifacts
The article by the Binary Hick [4] is the broadest public list we found. For Android 10 to 12 on Pixel and Samsung phones it names, among others, the reboot,factory_reset entry with an epoch time in persistent_properties, the earliest setup-wizard times in appops.xml, the Samsung history file in /efs/recovery/ with its --wipe_data entries, a Samsung boot-history file, a bootstat folder, and MediaStore clusters. It reports that the Pixel kept the three previous boot times and a Samsung A30 four, so that the factory-reset entry is lost after more reboots, and it notes that one persistent-property timestamp on a Samsung device was wrong and could not be reproduced. The Forensafe article [7] gives the paths / and / and the fields a commercial tool extracts (request time, event time, reason, initializer, reboot reason, locale); it does not discuss the reliability of the times. A 2026 article [6] uses the history file as one of several signatures, argues that three independent signatures within about 99 seconds make a safe conclusion, and stresses that one artifact is not enough. A research note by Addai [2] describes the Samsung recovery trail on two extractions and a first form of the time estimate tested here.
2.3 Studies of what a reset removes
Academic work has asked a different question: what survives a reset, not when it happened. Schwamm and Rowe [10] tested iOS, Android and BlackBerry devices in 2014, found that much user-specific configuration and some user data survived a reset, and listed a recovery log on the Android device among the surviving files. Simon and Anderson [11] studied whether a reset removes data from older Android versions.
2.4 Platform documentation
The Android Open Source Project documents the canonical boot reasons that a bootloader communicates to init [3]. The page lists reserved and example reasons (for example reboot,userrequested and reboot,recovery); it has no factory_reset value and does not mention a history property. Those two names therefore belong to platform and vendor code that we describe from observation, not from that page. The provisioned flag is the documented Settings.Global constant DEVICE_PROVISIONED [8]; the setup-complete flag is a per-user secure setting that, as far as we found, the public reference does not list.
2.5 Tool testing
Tool testing literature argues that forensic tools need validation against known data and independent counts [9]. Reset artifacts are a demanding case, because a tool that reads a date correctly can still report a wrong time if the clock behind it is wrong.
Among open-source parsers, ALEAPP [5] has three artifacts that read the same files as this study: the recovery history, its wipe entries and the persistent properties. None of them dates an undated entry, and the persistent-properties artifact scans the protobuf file as text (Section 5.7).
Position of this work. In the sources above we found no count of how many devices carry each artifact, no treatment of recovery entries whose header date is missing or wrong, no measurement of how the setup flags behave around updates, and no estimate of when an undated entry occurred. The work was done on one to a few devices per article, which is reasonable for practitioner notes. This study adds counts and an explicit statement of what each count supports. The sources are known [4], [7]; the census, the clock classes, the error model, the placeholder and zone findings and the setup-flag measurements are new here, as far as we found. The time estimate is a candidate rule that was tested on two devices, not a validated method, and the readers are engineering.
3 Method
This section describes how the sources were read, states the candidate estimate with its error model, and defines the checks and the flag cycles used in Section 5.
3.1 Readers
We wrote three reader modules from the raw files and from AOSP-style naming, without reusing an existing parser, and a fourth part for bug report text. They are described here at the level needed to read the results.
Recovery history. The file history and, in bug reports, the members last_history and last_all_history hold one entry per recovery start: a header line + [CODE | YYYY/ with an optional trailing [-], then the options recovery was started with (--wipe_data, --update_package, --just_exit, --reason=, --requested_time=), a status line, and a reboot reason. The companion extra_history holds lines [CODE][S] text and [CODE][E] text; the two-letter code links them to an entry, and format_volume : / lines show which volumes were formatted. An entry says that recovery was started with these options, not that the work finished.
Boot-reason history. The file / is a protobuf file written by init: a repeated field 1 of records, each with the property name as field 1 and the value as field 2. The reader walks varints directly.
Setup flags. We read the settings-history entries of the names device_provisioned and user_setup_complete and a few related names. In bug report text the same entries appear as History (name) blocks with a time in the form month-day hour:minute:second.millisecond, without a year.
3.2 A candidate clock-anchored estimate
We state the rule as a candidate to be tested, not as a validated method (Listing 2). An entry E that has no requested time and a header time that looks unset (before 2012) is given an estimate from an anchor A: a wipe entry (--wipe_data or --prompt_and_wipe_data) in the same file that has a requested time and an unset-looking header time. If several anchors exist, the one nearest to E by header time is used. With h the header time and r the requested time:
Listing 2: The candidate clock-anchored estimate and its error model.
anchor A: wipe option, r_A present, h_A before 2012
entry E: r_E absent, h_E before 2012
estimate: e_E = round( h_E + ( r_A - h_A ), 1 s )
error: e_E - t_E = - d_A + x_AE
d_A delay between the request of A and the start
of recovery for A (d_A >= 0)
x_AE drift of the recovery clock between A and E,
plus the truncation of the printed header (+/- 1 s)The error model shows what a check can and cannot test. Two anchors with the same delay give the same offset, so a wipe pair tests the drift x (and the equality of the delays) but not the delay itself. A bias of dA, seconds to minutes, remains in every estimate. The rule assumes that the recovery clock ran on without a reset between A and E, and that the recovery clock and the requested time use the same zone; we test both.
3.3 Checks of the estimate
- Pair check. For two anchors, compare the header gap with the requested gap.
- Independent file times. For estimated entries, compare the estimate with the modification times that the extraction container records for files that the platform rewrites at the same event (a region-code file, carrier configuration files), and with a configuration-update log whose first line carries a time and a UTC offset. These clocks are independent of the recovery clock.
- Boot-history cross-check. Compare a header time with a boot epoch of the persistent history.
- Negative control. Apply the pair check to every device that has two wipes with requested times, whatever its header year.
3.4 Setup-flag cycles
A cycle is a change of device_provisioned from 1 to 0 followed by a change back to 1. Cycle counts are taken from the history files (extractions) and from the history blocks (bug reports). A cycle is related to a recovery entry when that entry's header time (UTC) lies within 20 minutes before or after the start of the cycle.
3.5 Counting and independence
Counts were produced by the reader modules and re-derived by independent counts: the number of header lines for recovery entries, a separate varint walk for the property records, a JSON and an Android Binary XML count for settings, and, for wipe entries, the output of the existing sWipehist artifact. Agreement shows that the readers do what their specification says; it does not show that the specification matches what the platform meant.
4 Evidence and Setup
This section describes the extractions and bug reports, the tools, and the reference data against which the dates were judged.
4.1 Evidence
Table 2 lists the evidence. The seven bug reports are the set analysed in [1]. The extractions are of research devices in the Lab's research collection, in the form of zip files produced by a commercial extraction tool; they were read in place, and only small members (the files named in Section 3.1) were copied to a private scratch area. The census covered the research-collection volumes that were reachable on 27 October 2026 (four storage volumes). Copies of the same extraction were counted once: two further zip files have the same size as two extractions already counted, and a harvest folder of another project is derived from one of them. Two Android containers were not opened (a physical acquisition and a collected archive without a data tree), and some disk images of unknown content were not examined. Phone A is described only as a research device whose recovery history holds two wipe requests.
| Class | n | Android | Used for |
|---|---|---|---|
| Samsung, A-series phones | 4 | 14 (1), 16 (3) | history, boot, flags |
| Samsung, 2026 flagship S-series | 2 | 16 | history, boot, flags |
| Samsung, 2025 flagship S-series (Ultra) | 3 | 16 | boot, flags |
| Samsung, older: S-series (2018), foldable, Note-series | 3 | 10, 13, 13 | history, boot |
| Motorola phone | 1 | 12 | boot |
| Google Pixel | 1 | 16 | boot |
| Full file system extractions, total | 14 | 10, 12, 13, 14, 16 | |
| Bug reports: Samsung (4), Huawei, Motorola, Transsion | 7 | 10 (2), 15 (1), 16 (4) | history members, boot, flags |
| Synthetic fixtures (protobuf, ABX and text writers) | 48 tests | n/a | reader tests |
4.2 Tools and versions
The readers are three Python modules (Artifact Availability). Our analysis scripts ran on Python 3.14, and the readers ran in their own virtual environment. The comparison in Section 5.7 ran the three existing artifacts that read the same files [5], byte-identical to those on which the readers were built (version in Artifact Availability), through their file-system input type on the staged small members. All reading was read-only.
4.3 Reference data and time zones
Every date in this study is judged against other values stored on the same device. The reference data available are of three kinds, and only the first two are used to judge the estimate: the requested times written by the operating system for the wipes themselves; independent file times recorded by the extraction container for files rewritten at the same events; and boot epochs of the persistent history. The container records modification times in device local time (the recorded offset of the configuration-update log is UTC−04:00 on the dates concerned), and the header time of a valid recovery clock is UTC; Section 5.3 gives the evidence.
5 Results
The sources are not universal, their formats vary more than the earlier public descriptions suggest, and their dates are not uniformly reliable. Table 3 answers each research question; the subsections give the evidence.
| Question | Answer | Evidence |
|---|---|---|
| RQ1 Sources | The Samsung recovery history is the richest source but is not universal: present on 9 of 12 Samsung extractions, absent on all three units of one flagship generation, with wipe entries on 4 of the 9. The boot-reason history is on all 14 extractions and all 7 bug reports; the settings history files only on the Android 16 Samsung extractions. Formats vary: three header shapes, free-text reboot reasons, placeholder requested times and a legacy step-line grammar. | Sec. 5.1 and 5.2, Figure 2, Tables 4 and 5 |
| RQ2 Dates | Not uniformly reliable. The header clock was plausible on 4 of the 9 extractions with a history, and a plausible-looking printed year was impossible on 3. The candidate estimate held on one device (within 57 s of independent file times) and its central assumption failed by 526 days on the only other device with two Settings wipes; its precondition occurred on 1 of 14 extractions. Requested times are device local time, not UTC. | Sec. 5.3 and 5.4, Figures 1, 3 and 4, Tables 6 and 7 |
| RQ3 Discrimination | No. The flags cycled 13 times on 8 devices, none of which held a wipe entry, and 5 cycles lay within about 15 minutes of an update entry, so a flag change alone does not indicate a reset. None of the 65 boot-reason entries is a factory-reset entry. | Sec. 5.5 and 5.6, Figure 5, Table 8 |
5.1 Which sources exist, and how often (RQ1)
Figure 2 and Table 4 give the census. The boot-reason history property was present on all 14 extractions and the bootstat marker file factory_reset on all 14. The Samsung recovery history was present on 9 of the 12 Samsung extractions and on neither of the other two vendors' extractions. The three absences are the three extractions of one flagship generation (the 2025 Ultra units): their /efs tree is present with a few hundred files, but there is no recovery folder and no copy under /data/log. We do not know whether the file was never created on that generation, was relocated, or was not collected, so for those units the absence says nothing about resets.
| Class | n | History present | Entries | Wipe entries (with requested time) | Header clock | Settings history |
|---|---|---|---|---|---|---|
| A-series, Android 14 to 16 | 4 | 4 | 34 | 0 | plausible, in order | 3 of 4 |
| 2026 flagship S-series, Android 16 | 2 | 2 | 6 | 2 (2) | 1970 | 2 of 2 |
| 2025 flagship S-series (Ultra), Android 16 | 3 | 0 | n/a | n/a | n/a | 3 of 3 |
| Older Samsung, Android 10 and 13 | 3 | 3 | 92 | 10 (5) | wrong year, legacy shapes | 0 of 3 |
| Motorola (12) and Pixel (16) | 2 | 0 | n/a | n/a | n/a | 0 of 2 |
| Total | 14 | 9 | 132 | 12 (7) | 8 of 14 |
The log copy / exists on 8 of the 9 devices with a history and is byte-identical to the efs file on all 8. The cache/recovery history files exist on one extraction (Android 13): last_history and last_all_history, each with the 34 entries of the efs file. The settings history files were present on all 8 Samsung extractions with Android 16 and on none of the other 6. In the seven bug reports, the history members last_history and last_all_history were present in 3 (all Samsung, Android 16), with 1, 4 and 19 entries, identical to each other in each report; none held a wipe entry. The Huawei, Motorola and Transsion reports and one Samsung report had no history member. The persistent boot-reason history appeared as a property line in all 7 reports.
5.2 Formats and wipe entries (RQ1)
Wipe entries are a small minority of recovery entries, and not every wipe with a requested time can anchor a date. Of the 132 entries, 101 start an update package, 12 request a wipe, 9 are SIM-based region changes, and 10 are other runs (for example data resizing after a firmware download). Four of the nine devices hold wipe entries: 12 in total, of which 7 are reset requests from Settings, 2 from a factory application, 1 from a device-policy call, and 2 from a platform call whose reason is simply the platform's name. Seven wipe entries carry a requested time. Two of the factory-application wipes carry a requested time of the first minute of 2021, which is a device default clock and not a wall-clock time. An anchor must therefore be a Settings wipe, not any wipe with a requested time.
Table 5 lists the format variants we met. Several were not in our first specification: the trailing [-] on the header is present on 2 of 9 devices; a legacy device writes headers with a code only (11 entries) or with an unpadded date (9 entries); five options beyond the common ones occur; and the reboot reason is, on 5 of 9 devices, free text taken from a Java thread name and call, not a short code. The Build column of the existing sRecoveryhist artifact kept the trailing [- text of such headers in the one extraction where we measured it (5 of 5 rows), and the same header shape occurs in 6 entries on 2 devices.
| Variant | Devices | Note |
|---|---|---|
Header [CODE | date | firmware] | 9 | all entries on 8; 19 of 39 on the legacy device |
Header ends in [-] | 2 | 6 entries; 2 of the 3 bug reports with history (20 entries) |
| Code-only header, no date | 1 | 11 entries (legacy, Android 10) |
Header [CODE : yyyy/, unpadded | 1 | 9 entries (legacy device) |
Options --carry_out, --update_org_package | 7 | shown as printed |
Options --data_resizing, --delete_apn_changes, --delete_efs_ota | 1 | firmware-download runs |
--requested_time present | 3 | 7 entries; 2 are placeholders |
| Reboot reason is free text | 5 | thread name, process number, class and method |
| Dates not ascending in file order | 3 | and 1 of the 3 bug reports |
History also under mnt/vendor/efs | 1 | duplicate content |
extra_history step lines [CODE][S] text | 3 | the three have wipe entries; one line on one of them is not in this form |
extra_history step lines [CODE] [S] text, format_volume_dir | 1 | legacy device, 14 lines; the shared reader does not read them |
extra_history holds only a creation line (36 bytes) | 5 | the devices without wipe entries |
5.3 The header clock (RQ2)
The header clock behaves in five ways, and only one of them dates an entry directly (Figure 3, Table 6).
- Plausible and in order on 4 extractions (34 entries) and in 1 bug report (4 entries). On three of these extractions the clock is also consistent with independent evidence. On one, an
otaboot epoch of the persistent history lies 303 s after the header time of the last entry. On three, a setup-flag cycle (Section 5.6) starts 606 to 914 s after an update entry. - 1970 on 2 extractions of the 2026 flagship (6 entries). On the one that holds five entries the clock advances with elapsed time, from 1970/01/01 to 1970/01/07.
- 2010 in 1 bug report (1 entry).
- A constant printed year that cannot be the true year on 3 older extractions: 2018 on all 28 dated entries of the Android 10 device (19 in the full header form and 9 in a legacy unpadded form), 2019 on all 34 entries and 2020 on all 19 entries of the two Android 13 devices. On the Android 10 device the last two entries carry the firmware string of the installed build, whose build date in
build.propis in 2022. On each Android 13 device the requested times of the wipes lie in 2021, 2022 or 2024. A year test (header before 2012) passes all three. - Unresolved in 1 bug report: 19 entries printed with the year 2023, not ascending. We cannot say whether the dates are real.
| Class | Extr. | Bug rep. | Entries | Evidence |
|---|---|---|---|---|
| Plausible, in order | 4 | 1 | 38 | boot epoch (1 device), flag-cycle lag (3 devices) |
| 1970 | 2 | 0 | 6 | printed value |
| 2010 | 0 | 1 | 1 | printed value |
| Constant wrong year | 3 | 0 | 81 dated | build date, requested times, order breaks |
| Unresolved | 0 | 1 | 19 | order breaks only |
The 156 entries of the 9 extractions and 3 bug reports are the 145 counted here plus 11 entries of the legacy device that carry no date.
Order breaks. In the four sources with a constant printed year, the dated entries are not in order in file order: the order breaks 3 times among 19 dated entries (foldable), 3 among 34 (Note-series), 4 among the 28 dated entries of the Android 10 device (3 among its 19 full-form entries) and 3 among 19 (bug report). In the Note-series file each break is a fall from a late-year date to an early-year one, and month and day rise between breaks, as if the printed year did not advance; we have not tested this reading. A file whose dates fall out of order is evidence in itself that the clock is not a calendar clock.
Time zones. The header time and the requested time are in different zones. On the five extractions that have dated entries and do not read 1970 (the four plausible ones and the Android 10 device), the last header is later than the modification time of the history file recorded by the extraction container by a whole number of hours: 4 h on the four plausible extractions (dates from March to August) and 5 h on the Android 10 device, to within 1 s. The header time is therefore UTC, and the container's times are local. Both come from the same clock of the recovery program, so this shows the zone, not the correctness of the date. In the bug reports the member time equals the header time exactly. The requested time is not UTC: on phone A the estimates agree with container times in local time (Section 5.4), and the configuration-update log shows the offset −04:00. The requested time is therefore device local time; an estimate inherits that zone, and it must not be reported as UTC.
5.4 The clock-anchored estimate: one success, one failure (RQ2)
The candidate estimate of Section 3.2 was accurate on the one device where it applied, and its central assumption failed on the only other device that could test it. Table 7 and Figure 4 give the checks.
Phone A. The rule is applicable on exactly one device of the 14, the Android 16 flagship whose five entries all print 1970: two Settings wipes with requested times, and three SIM region changes between and after them.
- Pair check. The two wipes are 3 h 25 m 32 s apart by header time and 3 h 25 m 32.632 s apart by requested time, a difference of 0.63 s, inside the 1 s truncation of the printed header. Read as a drift, the bound is 51 parts per million from one pair.
- The entry between the wipes is estimated 0.63 s apart from either anchor and falls between the two requested times.
- The entry that follows the second wipe by 3 d 21 h 55 m 05 s (about 4 d 1 h after the first request) is estimated at a time 29 s after the modification time of one carrier-configuration file and 57 s before another.
- The last entry, 6 d 14 h 31 m 38 s after the second wipe by header time, is estimated 6 s after the modification time of the region-code file and 36 s before the start of the configuration-update log.
| Check | Result | Verdict |
|---|---|---|
| Pair, phone A (Android 16, 1970 clock) | header gap 3 h 25 m 32 s; requested gap 3 h 25 m 32.632 s | agrees (0.63 s) |
| Pair, phone B (Android 13 foldable, year 2020) | header gap 118 d 8 h 8 m 46 s; requested gap 644 d 8 h 20 m 5 s | disagrees (526 d); rule gated off |
| Phone A, entry between the wipes | estimate from either anchor, 0.63 s apart; t0 + 3 h 02 m | consistent |
| Phone A, entry t0 + 4 d 01 h | +29 s and −57 s against two carrier-configuration file times | within 60 s |
| Phone A, entry t0 + 6 d 18 h | +6 s against the region-code file; −36 s against the update-log start | within 40 s |
t0 is the requested time of the first wipe on phone A. The independent times are modification times in the extraction container (device local time); they follow the recovery event by an unknown delay, so they bound the error but are not the recovery start time.
Phone B. On the second device with two Settings wipes, the Android 13 foldable, the gaps do not agree: 118 d 8 h 8 m 46 s by header time and 644 d 8 h 20 m 5 s by requested time, a difference of 526 days that is not a multiple of a year. The header there prints 2020, and the rule does not run because of the year gate. Had it been applied, every estimate on that device would have been wrong by months. Two order breaks lie between the two wipes in the file, so the header gap cannot measure elapsed time there, whatever the requested times say. The example shows why the gate is needed, and why it is not sufficient (Section 5.3, class 4): the pair check, not the year, is what detects the failure.
Reach. Of the 9 devices with a history, the rule applies to 1; on 7 no header is before 2012, and on 1 (a 1970 clock) there is no wipe to anchor to. On the 5 extractions without a history it cannot be applied. The rule has therefore held on one device and failed its central assumption on the only other device that could test it; we regard it as unvalidated.
5.5 Boot-reason history (RQ3)
The boot-reason history is too short to hold a reset in practice. It held 42 entries on the 14 extractions: three on twelve devices, two on one and four on one. The 7 bug reports gave 23 entries (two to four each). None of the 65 entries is a factory-reset entry (Table 8). The spans differ widely: on 12 extractions the oldest entry is at most 32 days before the newest; on the Motorola extraction it is 233 days; on the Android 10 device one stale entry makes it 3,091 days. On phone A the oldest boot entry is 104 days after the later wipe request, and on a Note-series device 598 days after its last Settings wipe request, so the factory-reset boot had long rolled off on both. On phone B the two clocks disagree: its oldest boot entry is 253 days before its last Settings wipe request, so one of the two is wrong and we cannot say which. The Android 10 device has only undated wipes. This matches the roll-off reported in [4]; the history held three entries on 12 of 14 devices and four on one, so a capacity of three is not general.
Two extractions hold an entry reboot,userrequested,recovery, and one an abfotaupdate entry, so the history does distinguish some recovery boots. A boot epoch relates to a recovery entry only if both are recent; we found one such pair (Section 5.3).
| Reason string | Extr. (42) | Bug rep. (23) |
|---|---|---|
reboot (no subreason) | 10 | 2 |
reboot,userrequested | 7 | 4 |
shutdown,userrequested | 5 | 1 |
shutdown,lpm | 5 | 2 |
reboot,lpm | 2 | 8 |
reboot,ota | 3 | 0 |
shutdown,no_power or shutdown,battery | 4 | 3 |
reboot,userrequested,recovery | 2 | 0 |
Others (cold,powerkey, reboot,charger, reboot,device_locked_3days, reboot,abfotaupdate, one with a one-letter subreason) | 4 | 3 |
factory_reset in any form | 0 | 0 |
5.6 Setup flags (RQ3)
The setup flags cycle next to updates, so a flag change does not by itself indicate a reset. We found 13 cycles of device_provisioned (and, at the same time, user_setup_complete) from 1 to 0 and back, on 8 devices: 9 on 6 extractions and 4 in 2 bug reports. They last from 75 s to 7 h 37 m (Figure 5). The 8 cycles on devices with a recovery history cannot be compared with a wipe, because none of those devices holds a wipe entry. Phone A is the only device with both a wipe and a settings history, and its flags show no 1-to-0 change in the retained history, only the first transition to 1, about four days after the second wipe, when the setup wizard finished (presumably the wipe cleared the earlier history).
Of the 8 cycles on devices with a recovery history, 5 start within 20 minutes of an update-package entry: 4 follow one by 606 to 914 s, and 1 precedes one by 293 s. Three have no recovery entry within 9 hours (one in a bug report whose nearest entry is 9 hours later, two in a bug report whose entries date from 2023), so an update need not leave a recovery entry, or the entry has rolled off. The other 5 cycles are on devices without a recovery history.
One further observation concerns phone A only: 483 of its 1,684 settings-history rows with an epoch time lie within five minutes of the firmware build time, against 0 of 12,125 rows on the six other devices with a history file and a known build time. The marker file factory_reset of the bootstat folder also bears a time of the build time plus 14 s, not the time of the wipes. Section 6.4 discusses a hypothesis for this.
5.7 Comparison with the existing artifacts
Table 9 compares the extended reading with the three existing artifacts [5] that read the same files. Row counts for the recovery history are equal (171 on the nine devices, 39 of them from a duplicate path on one device); the extension adds columns, the activity words, the estimate and the cache copies (68 more rows on one device). The wipe artifact reports 12 rows, equal to the 12 wipe entries of our reader. The persistent-properties artifact, which scans the protobuf file as text, found 3 of the 42 history entries; reading the records gives all 42.
| Measure | Existing | Extended | Note |
|---|---|---|---|
| Recovery history rows, 9 devices | 171 | 239 | 68 extra rows are the cache copies on one device |
| Wipe rows (wipe artifact against wipe entries) | 12 | 12 | equal |
| Boot-reason history entries, 14 devices | 3 | 42 | text scan of a protobuf file |
| Setup-flag rows (history, current values, properties) | n/a | 275 | current global values equal the global-settings artifact |
Rows with a damaged build text (headers ending in [-]) | 5 of 5 | 0 of 5 | measured on one image only |
6 Discussion
The results say less about where reset traces live than about when their dates can be believed. This section states when a clock-anchored estimate is unsafe, gives an order of work for examiners, and draws two lessons for tool users.
6.1 When a clock-anchored estimate is unsafe
The central result of this study is negative and specific. The same rule, applied to the same file format, gave estimates within a minute of independent times on phone A and would have been wrong by months on phone B (Figure 1). Its central assumption, that the header gap equals the requested gap, is a property of the device's recovery clock, and it can be checked only where two anchors exist. The year gate kept the rule off phone B only because phone B prints 2020. A year cannot show that a header clock measures elapsed time, and a constant wrong year passes a year test as if it were a valid date (Section 5.3); the pair check, not the year, is what detects the failure. Table 10 lists the conditions under which an estimate is unsafe, as observed in this sample or implied by the error model, with the check that exposes each.
| Condition | Seen in this study | Check that exposes it |
|---|---|---|
| Header gap does not measure elapsed time | Phone B: gaps differ by 526 days, with two order breaks between the wipes | Pair check of two anchors; dates in file order |
| Printed year plausible but impossible | 3 older devices print a constant 2018, 2019 or 2020 | Year against build date, firmware string and requested times; a year test does not detect it |
| Anchor's requested time is a placeholder | 2 factory-application wipes at the first minute of 2021 | Anchor only on a Settings wipe |
| Delay between request and recovery start | Not measured; a bias of seconds to minutes in every estimate | None in the data; a pair check cannot see it |
| Zone mismatch | Requested time in device local time (−04:00), header time in UTC | Report the estimate in the zone of the requested time, never as UTC |
Two consequences follow. First, the precondition is rare: a Settings wipe with a requested time, plus later entries on an unset clock, occurred on 1 of 14 extractions. Second, a passing pair check is necessary but does not remove the bias dA. The rule therefore needs a pair check on each device and a controlled series before it is used, and an estimate made without a passing pair check should not be reported.
6.2 A practical order of work
- Establish the recovery clock class before reading any date: header year before 2012; dates in file order; the last header against an independent clock (a boot epoch, a settings-history time, a file time in local time); the year against the build date and the firmware string of the entries.
- Prefer the requested time of a Settings wipe over every other time. If it is a placeholder (the first minute of 2021 in our data), do not use it.
- If an estimate is attempted at all, make it only on a class-1970 or class-2010 clock after a pair check passes, and label it as an unvalidated estimate in the zone of the requested time, with the anchor and the header gap.
- Treat a missing history file as unknown, not as no reset: three of three units of one generation lacked the file.
- Use setup-flag cycles and boot reasons only as supporting evidence next to a recovery entry. A flag change alone does not indicate a reset, and the absence of a cycle does not indicate that none occurred.
6.3 Errors that do not show in a tool's output
The persistent-properties artifact found 3 of 42 boot-history entries by scanning a binary file as text, and the build text of some history rows was damaged. Neither error was visible in the output. The comparison in Section 5.7 is a small instance of the validation that tool testing literature calls for [9], and it also shows that agreement between two tools that share a code base is weak evidence.
6.4 A candidate indicator: the build-time clock
On phone A, hundreds of settings-history rows are stamped within minutes of the firmware build time, and the bootstat marker carries the build time, not the wipe time (Section 5.6). A hypothesis is that after a wipe the system clock starts at the build time and stays there until a network time arrives (here four days). If that holds on other devices, it would be a separate wipe indicator that needs no recovery file at all. We have not tested it, and one device does not make an indicator.
7 Threats to Validity
Internal validity. Counts were produced by the readers and re-derived by independent counts (header lines, a separate varint walk, JSON and XML counts, the existing wipe artifact). Agreement shows that the readers do what their specification says, not that the specification matches what the platform meant. The rule was designed after the first device was inspected, so the estimator may be fitted to that device; the second device with two wipes is a negative control, which was examined after the rule was written, and the rule was not changed.
Construct validity. A row is a record the device stored or printed, not proof of a user action. An entry with --wipe_data shows that recovery was started with that option, not that the wipe completed. The independent times are container modification times: they follow the event by an unknown delay and depend on the container recording local time, which we inferred from one log offset and from five history files rather than from documentation. We did not observe the actions that produced these records, so each date is judged only against other stored values. The remark on the build-time clock is a hypothesis.
External validity. The sample is one research collection: 12 of 14 extractions are Samsung, most from one market, and the Pixel and the Motorola contribute only to the boot-history count. Android 11 and 12 are absent for Samsung, 15 is absent entirely for extractions, and only one extraction per older model was seen. The device class and the Android version are confounded: the older devices that show wrong years are all older Android versions. Results are stated per class and are not generalised.
Conclusion validity. No inference beyond the counts is made. The estimate agreed with independent times on one device with one wipe pair, and its central assumption failed on a second. Percentages would suggest a precision the sample does not have, so none is given for the estimate.
Limitations. The study does not measure the delay between the request and the recovery start; the drift of the recovery clock over long intervals other than through one pair; the behaviour of Pixel and other vendors' recovery logs; or other tools' parsers. The shared reader does not read the legacy step-line grammar of the Android 10 device (14 lines) and does not date 21 of its 39 entries, 11 of which carry no date and 10 of which (nine unpadded headers and one whose code contains a bracket) do. Two of the three bug-report histories could not be checked against an independent clock. The Android version of one 2026 flagship extraction without a build file was taken from its device class, not read from the image. Copies of the same extraction were identified by size, not by hash.
8 Conclusion and Future Work
Dating a reset on Android depends on several things lining up: a history file that exists, an entry that is a Settings wipe, and a clock that is either valid or of a known unset class. We measured how often these occur on 14 extractions and 7 bug reports, showed that the recovery header clock falls into five classes of which one cannot be detected from the printed year, and tested one candidate estimate for undated entries: it agreed with independent times to within a minute on the one device where it could be checked, and its central assumption failed by 526 days on the only other device that could test it. We also showed that setup flags cycle around updates and that the boot-reason history is too short to hold a reset in practice. On the devices examined, Android reset indicators were therefore informative but individually unreliable, and each needs a check of its own clock before any date is reported. The clock classes and the pair check can be built into any reader of these files, open-source parsers included.
Future work, in order of value: (1) a controlled series with wipes, updates and SIM changes at logged times, across Samsung generations and a Pixel, to measure the delay and the drift and to say which hardware starts its recovery clock at 1970; (2) the same census on Android 11 to 15 extractions and on bug reports that contain a wipe; (3) a test of the build-time clock hypothesis after a wipe.
Artifact Availability
The three reader modules (recovery history, boot reason history and setup flags) are merged in ALEAPP [5] under its MIT licence: the recovery history readers as ALEAPP #1834 and the boot reason history and setup flags as ALEAPP #1835. Their synthetic fixtures and tests are part of those pull requests. Versions 1.0 and 1.1 of this report described the readers as a branch that was not yet public (feat/, head c4a59548). The comparison of Section 5.7 used the ALEAPP checkout at commit 7bc49e3e. No fixtures are released with this report itself. The extractions and bug reports cannot be released.
Data Handling Statement
Data were of two kinds: (1) full file system extractions and Android bug reports 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 recovery histories, property stores and settings files written by the author with invented values. All 14 extractions and seven bug reports in this paper are of kind (1). Only aggregate counts, device classes, vendor families, operating system versions, relative time offsets and file and property names are reported. No names, numbers, accounts, serial numbers, absolute dates, network or carrier names, model numbers, package lists or file paths from the real data appear in this paper. Small members (history files, property stores, settings history files) were read into a private scratch area for analysis and are kept outside any repository. No offensive technique, exploit or credential-recovery method is described.
Declaration of AI Assistance
The reader 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
- Daniel Addai. 2026. Making Silent Failures Visible: A Single-Pass Section Reader for Android Bug Reports. Lab Technical Report LAB-TR-0001, version 1.0. SectraTEK Lab. https://lab.sectratek.com/research/reports/lab-tr-0001/
- Daniel Addai. 2026. Samsung recovery and reset trail. Lab research note LAB-0001, version 1.0. SectraTEK Lab. https://lab.sectratek.com/research/lab-0001/
- Android Open Source Project. [n. d.]. Canonical boot reason. Retrieved October 27, 2026 from https://source.android.com/docs/core/architecture/bootloader/boot-reason
- Binary Hick. 2021. Wipeout! Detecting Android factory resets. Blog post, August 19, 2021 (updated September 11, 2023). Retrieved October 27, 2026 from https://thebinaryhick.blog/2021/08/19/wipeout-detecting-android-factory-resets/
- Alexis Brignoni et al. [n. d.]. ALEAPP: Android Logs Events And Protobuf Parser. GitHub repository (MIT licence). Retrieved October 27, 2026 from https://github.com/abrignoni/ALEAPP
- Cellphone Forensics. 2026. When was this Samsung Galaxy last factory reset? Web article, May 19, 2026. Retrieved October 27, 2026 from https://www.cellphoneforensics.ca/blog/samsung-galaxy-factory-reset-forensics.html
- Forensafe. 2024. Samsung wipe history. Web article, December 20, 2024. Retrieved October 27, 2026 from https://www.forensafe.com/blogs/SamsungWipeHistory.html
- Google. [n. d.]. Settings.Global. Android Developers API reference. https://developer.android.com/reference/android/provider/Settings.Global (Not re-verified: the fetched page text did not reach the constants; DEVICE_PROVISIONED recalled from the public reference.)
- 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 (Bibliographic data confirmed from index records; full text not read.)
- R. Schwamm and N. C. Rowe. 2014. Effects of the factory reset on mobile devices. In Proceedings of the 6th International Conference on Digital Forensics and Cyber Crime (ICDF2C), New Haven, CT, USA, September 2014. Retrieved October 27, 2026 from https://faculty.nps.edu/ncrowe/resets_icdf2c14.htm
- L. Simon and R. Anderson. 2015. Security analysis of Android factory resets. In Mobile Security Technologies (MoST) Workshop. https://www.cl.cam.ac.uk/~rja14/Papers/fr_most15.pdf (Title, authors and venue confirmed from search results and the MoST 2015 programme; the PDF text could not be read by the fetch tool.)