Screenless Samsung Bring-Up & Rooting Forensics on the Exynos 7870 (SM-G610F)

When recovering discarded phone motherboards for my Phone Revival Lab, two of my clean octacore boards were Samsung Galaxy J7 Prime (SM-G610F / on7xelte) mainboards equipped with the Exynos 7870 (8× Cortex-A53 @ 1.6 GHz, aarch64) and 3 GB RAM.

Neither board had a display, touchscreen, or battery—just bare PCBs powered by a regulated 4.2 V bench supply soldered to the battery terminals.

Bringing up a screenless Samsung board presents an immediate catch-22:

  1. Stock Android builds ship with USB Debugging disabled (persist.sys.usb.config=mtp) and ro.adb.secure=1. Even if ADB were enabled, authorizing a new host PC requires tapping "Allow USB Debugging" on a screen that does not exist.
  2. Installing a custom recovery (TWRP) or custom kernel to bypass the screen requires OEM Unlock to be toggled in Settings → Developer Options—again, behind the missing screen.

Here is how I solved the screenless ADB problem using Samsung Factory Combination Firmware via Heimdall, followed by a systematic 4-vector forensic investigation into how Samsung's S-Boot bootloader and March 2018 Linux 3.18.14 kernel enforce privilege boundaries while keeping Knox warranty_bit = 0.


1. Bypassing the Missing Screen with Samsung Combination Firmware

Samsung produces internal factory engineering builds known as Combination Firmware (FA60_G610FDDU1ARC1 for the SM-G610F, Revision 1 / B:1). These images are designed for automated factory test rigs and have three properties that make them ideal for screenless board recovery:

  1. Cryptographically Signed by Samsung: Because the image carries an official Samsung production RSA signature matching bootloader anti-rollback revision B:1, a locked S-Boot bootloader (SECURE DOWNLOAD : ENABLE) accepts it without requiring OEM Unlock and without tripping the Knox e-fuse (warranty_bit stays 0).

  2. Pre-Authorized ADB on First Boot: The boot ramdisk default.prop sets:

    ro.secure=1
    ro.allow.mock.location=0
    ro.debuggable=1
    ro.adb.secure=0
    persist.sys.usb.config=mtp,adb
    

    Because ro.adb.secure=0, adbd never prompts for an on-screen RSA key confirmation—adb shell drops straight into a shell (uid=2000) seconds after cold boot.

  3. Permissive SELinux: The engineering kernel (Linux 3.18.14-10809540) boots with SELinux in Permissive mode (getenforce returns Permissive).

The Heimdall Single-Session Flashing Rule

When flashing the Combination Firmware from Linux using heimdall v1.4.2, flashing only BOOT, SYSTEM, and CACHE caused the board to hang during init because the existing MODEM and CM (CryptoManager) partitions were from a newer Android 8.1 Oreo build (U1CRL3).

Furthermore, flashing partitions across separate heimdall flash invocations did not cleanly transition the bootloader state. Passing all critical partitions in a single atomic heimdall flash session succeeded immediately on both boards:

heimdall flash \
  --CM cm.bin \
  --BOOT boot.img \
  --RECOVERY recovery.img \
  --SYSTEM system.img \
  --MODEM modem.bin \
  --CACHE cache.img

Thirty seconds after the automatic reset, adb devices listed the board online and ready for native aarch64 compute workloads in /data/local/tmp.


2. Forensic Evaluation of 4 Root & Boot-Chain Vectors (Knox 0x0)

With an interactive uid=2000(shell) session, SELinux Permissive, and a relatively old Linux 3.18.14 kernel (#1 SMP PREEMPT Tue Mar 13 18:10:02 KST 2018), I tested four distinct privilege escalation and boot-chain modification vectors to document the exact hardware and kernel security boundaries.

Vector 1: Chainloading Mainline U-Boot (Tauchgang)

  • Hypothesis: Package a mainline U-Boot binary (u-boot.bin) inside an Android boot.img envelope and flash it to the BOOT partition via Heimdall so S-Boot jumps into U-Boot instead of Linux.
  • Result: Rejected during Download Mode transfer (SECURE CHECK FAIL : BOOT).
  • Root Cause: With FRP / OEM Lock: ON, S-Boot refuses any BOOT or RECOVERY image lacking a valid Samsung RSA-2048 signature block.

Vector 2: Dirty COW (CVE-2016-5195) — tmpfs vs. ext4 Backport Analysis

  • Hypothesis: Linux 3.18.14 predates the upstream October 2016 Dirty COW fix (19be0eaffa3ac7d8eb6784ad9bdbc7d67ed8e619). Since SELinux is already Permissive, overwriting /system/bin/run-as or /system/bin/play via the madvise(MADV_DONTNEED) + /proc/self/mem race should yield uid=0.
  • Experiment 1 (tmpfs control test): Created a root-owned test file 0444 on /data/local/tmp (or tmpfs). Running the madvise + /proc/self/mem race succeeded in modifying the in-memory page cache within ~2 seconds.
  • Experiment 2 (ext4 /system/bin/run-as target): Ran the exact same race against /system/bin/run-as and /system/bin/play on the read-only ext4 /system mount (mmcblk0p20). Even after 60+ seconds of high-contention racing, the target bytes on /system/bin/run-as remained completely unchanged.
  • Forensic Finding: Samsung's March 2018 kernel build (3.18.14-10809540) contains a backported mitigation in the ext4 / VFS page-fault writeback path that prevents FOLL_FORCE / /proc/self/mem writes from dirtying file-backed pages on read-only block mounts, even though anonymous/tmpfs page racing still functions. And because /data/local/tmp is mounted with nosuid (MS_NOSUID), modifying a binary outside /system cannot grant elevated privileges via setuid.

Vector 3: CF-Auto-Root (Odin Recovery Injection)

  • Hypothesis: Flash Chainfire's CF-Auto-Root recovery.img for SM-G610F via Heimdall.
  • Result: Rejected (SECURE CHECK FAIL : RECOVERY).
  • Root Cause: Like Vector 1, CF-Auto-Root relies on an unsigned custom recovery image, which requires OEM Unlock to be enabled in FRP partition flags.

Vector 4: Byte-Padded In-Place boot.img Modification (Testing S-Boot Signature Verification)

Some older vendor bootloaders only check for the presence of the SEANDROIDENFORCE magic trailer or verify the header length without hashing the entire ramdisk payload. To test whether Exynos 7870 S-Boot performs a full cryptographic hash verification over the payload, I constructed a byte-identical-length in-place patch of the official signed boot.img:

  1. Located the gzip-compressed ramdisk inside the signed FA60_G610FDDU1ARC1 boot.img (offset 0x00A83000, size 1,401,561 bytes).
  2. Unpacked default.prop and changed a single ASCII byte: ro.secure=1 → ro.secure=0.
  3. Recompressed the cpio archive with gzip -n -9 and appended a carefully crafted gzip comment/padding block so the compressed ramdisk was the exact same byte length (1,401,561 bytes) as the original.
  4. Spliced the modified ramdisk into boot.img at 0x00A83000, leaving the Android boot header, kernel image, device tree, SEANDROIDENFORCE trailer, and 512-byte Samsung RSA signature block at the end of the file 100% untouched.
  5. Flashed the patched boot.img via heimdall flash --BOOT boot_patched.img.

Result: The transfer completed to 100%, and at commit time S-Boot rejected the image with SECURE CHECK FAIL : BOOT.

Definitive Conclusion: Exynos 7870 S-Boot (B:1) does not merely check header metadata or trailer magic; it computes a full SHA-256 digest over the kernel + ramdisk + DT payload and verifies it against the RSA-2048 signature block before committing to eMMC.


Summary

Even with a locked bootloader and without a display, Samsung Factory Combination Firmware (FA60_G610FDDU1ARC1) turns bare SM-G610F motherboards into reliable, pre-authorized 8-core aarch64 compute nodes over USB while keeping Knox 0x0 intact.

See the Samsung Galaxy J7 Prime (SM-G610F) device page for full hardware specs and partition maps.

Related Posts