andronedev/carminat-tomtom-live-re
GitHub: andronedev/carminat-tomtom-live-re
一份针对雷诺 Carminat TomTom LIVE 车载导航系统(NavCore 9.884 beaumont)的完整逆向工程文档,涵盖固件提取、文件系统与启动链分析、ttn 二进制逆向、SD 卡及 UART 攻击面识别和 QEMU 动态分析方法。
Stars: 0 | Forks: 0
# Carminat TomTom LIVE:逆向工程
```
flowchart TD
A[Carminat TomTom LIVE] --> B[Samsung S5P6440
Linux 2.6.28 verrouillé] B --> C[NAND interne] B --> D[Carte SD externe] C --> E[Verrouillé] D --> F[Modifiable] E -.->|UART| G[shell root théorique ?] F -.->|fichiers SD| H[Personnalisations
splash · menus · POI] style A fill:#5B4FBE,color:#fff style E fill:#A32D2D,color:#fff style F fill:#3B6D11,color:#fff style G fill:#EF9F27,color:#000 style H fill:#1D9E75,color:#fff ``` ## 目录 1. [背景与目标](#1-contexte-et-objectif) 2. [系统识别](#2-identification-du-système) 3. [硬件](#3-hardware) 4. [固件提取](#4-extraction-du-firmware) 5. [文件系统架构](#5-architecture-du-filesystem) 6. [启动链](#6-boot-chain) 7. [进程与服务](#7-processus-et-services) 8. [ttn 二进制文件分析](#8-analyse-du-binaire-ttn) 9. [GPRS 调制解调器与连接](#9-modem-gprs-et-connectivité) 10. [来自 SD 卡的攻击面](#10-surface-dattaque-depuis-la-carte-sd) 11. [UART root 访问](#11-accès-uart-root) 12. [无 UART 的个性化定制](#12-personnalisations-sans-uart) 13. [工具与资源](#13-outils-et-ressources) 14. [本项目中的 AI 使用](#14-utilisation-de-lia-dans-ce-projet) 15. [法律免责声明](#15-disclaimer-légal) ## 1. 背景与目标 **Carminat TomTom LIVE** 是雷诺(Renault)为 2009-2014 年款车型(Laguna 3、Mégane 3、Scénic 3、Espace 4、Fluence、Latitude、Koleos 等)配备的车载导航系统。它与非 Live 版的 Carminat TomTom 的区别在于: - 固件存储在**内部 NAND** 中(而不是 SD 卡上) - 内置 **GPRS 调制解调器**,用于提供实时服务(交通、天气、雷达测速) - **RSA 签名**且锁定的 bootloader - 根据社区反馈,一个名为 **`signedloop`** 的 kernel 模块会通过默克尔树(Merkle tree)验证 rootfs 的完整性(本次分析未证实,见第 3 节) 本仓库记录了对 NavCore 9.884 beaumont 固件的分析,包括文件系统映射、NavCore 二进制文件的静态分析,以及通过 QEMU/strace 进行的运行时分析。 **使用的方法:** - 通过**从车辆中提取的 SD 卡**识别系统(读取 `ttgo.bif`、`loopdir/ext3_loopback` 文件) - 通过 **TomTom 官方 CDN** 获取固件(参见 [固件提取](#4-extraction-du-firmware) 章节) - 对从 CAB 中提取的 rootfs 进行静态分析 - **搭建 QEMU 模拟器**,重现设备盒子的 ARM/Linux 环境以便对 `ttn` 二进制文件进行动态分析(strace 系统调用、观察打开的文件、运行时行为) 未对车辆的物理设备盒子进行任何修改。所有分析均是在 SD 卡文件副本和下载的固件上进行的。 **此处记录的所有工作均基于个人 SD 卡(从车辆中取出用于分析)以及从 TomTom CDN 下载的官方固件完成。** ## 2. 系统识别 | 字段 | 值 | |---|---| | **DeviceName** | TomTom Carminat LIVE | | **硬件代号** | `beaumont` (rev 11) | | **NavCore 版本** | `9.884`,build `9.884.1609031` | | **官方发布** | `NFA2.8-RC06`,于 2014 年 6 月 27 日在 Dieppe 编译 | | **Linux 内核** | `2.6.28.10-tt1574740` | | **工具链** | `gcc 4.3.3 TomTom CipherWizardry 2009q1_203-474426` | | **Libc** | uClibc | | **Init 系统** | Upstart (通过 shell 脚本 `/sbin/init` → `exec /sbin/upstart`) | 这些信息来源于从 SD 卡的 `loopdir/ext3_loopback` 镜像中提取的 `ttgo.bif` 以及 `TomTom-Cfg/release.nfo` 文件。 ``` # 提取 ttgo.bif [TomTomGo] DeviceName=TomTom Carminat LIVE DeviceVersionHW=beaumont ApplicationVersionVersionNumber=9884 ApplicationVersion=1609031.550 RamDiskVersion=20140626 BootLoaderVersion=839378 LinuxVersion=1574740 ``` ## 3. 硬件 | 组件 | 识别 | |---|---| | **SoC** | Samsung S5P6440 (通过 `/etc/udev/rules.d/20_local-s5p6440.rules` 确认) | | **CPU** | ARM1176JZF-S · ARMv6 · little-endian · EABI | | **RAM** | 无法通过静态分析确定 | | **内部存储** | NAND flash · eMMC (`/dev/mmcblk0`) | | **用户 SD 卡** | `/dev/mmcblk1` (可访问插槽) | | **屏幕** | Samsung LCD `LTA058B3L0F` (根据 DTB) · 480×272 | | **Framebuffer** | `/dev/fb0` · RGB16/24 | | **GPS** | SiRF3 PRIMA · `/dev/ttySAC2` | | **GSM/GPRS 调制解调器** | Wavecom WISMO218 · `/dev/ttyS0` | | **RDS-TMC 调谐器** | BCM4750 · `bcm4750_spi` | | **Bluetooth** | 内置 · `hci_uart` · 仅限 HFP + PBAP (不支持 A2DP) | | **触摸屏** | `libts` · `/dev/input/event0` | ### 已加载的内核模块(摘自 `/etc/modules`) ``` unionfs · ppp_async · ppp_generic · slhc · hidp · hid · rfcomm sco · hci_uart · l2cap · bluetooth · bcm4750_spi · vfat · msdos fat · evdev ``` ## 4. 固件提取 ### 4.1 下载官方 CAB 固件可**无需身份验证**从 TomTom 的 Akamai CDN 下载: ``` curl -A "TomTom HOME/2.24.11.8" -O \ "http://download.tomtom.com/sweet/navcore/9.884.1609031_RC06.CAB-Dieppe.cab" # 参考 SHA256 a4d32daae2cdd6bc23a0660285c4e32e3a098034731eb257172ed7aaef9052d5 ``` **其他可用版本(经测试返回 HTTP 200):** | 版本 | URL | |---|---| | 9.844 | `http://download.tomtom.com/sweet/navcore/9844.634510.Carminat_TomTom.cab` | | 9.845 RC10 | `http://download.tomtom.com/sweet/navcore/9.845_1115399_RC10.CAB-Camiron-RC10.cab` | | 9.846 RC12 | `http://download.tomtom.com/sweet/navcore/9.846_1165624_RC12.CAB-Camiron-RC12.cab` | | 9.847 RC14 | `http://download.tomtom.com/sweet/navcore/9.847.1302316_RC14.CAB-Camiron-RC14.cab` | | **9.884 RC06** | `http://download.tomtom.com/sweet/navcore/9.884.1609031_RC06.CAB-Dieppe.cab` | ### 4.2 提取 CAB ``` brew install cabextract # macOS mkdir extracted && cabextract 9.884.1609031_RC06.CAB-Dieppe.cab -d extracted/ ls extracted/ # → splashw.bmp ttsystem TomTom-Cfg/release.nfo ``` ### 4.3 提取完整 rootfs ``` cd extracted/ mkdir rootfs && 7z x ttsystem -o rootfs/ # 实际的 rootfs 在 userfs_partition.tar.gz 中 cd rootfs/ tar xzf userfs_partition.tar.gz # 内容: # _zImage → Linux kernel ARM zImage # rootfs.img → 完整的 Linux filesystem (ext2, 67 MB) # WISMO218_*.cla → modem 固件 mkdir rootfs_mnt # 在 Linux 上: sudo mount -o loop rootfs.img rootfs_mnt/ # 在 macOS 上(只读): 7z x rootfs.img -o rootfs_mnt/ ``` ### 4.4 提取的固件结构 ``` rootfs_mnt/ ├── bin/ │ ├── ttn ← NavCore principal (11.7 MB, ELF ARM dynamique) │ ├── telttn ← wrapper IPC vers ttn │ ├── fakettn ← fallback si ttn absent │ └── gprscomd ← daemon GPRS ├── etc/ │ ├── inittab │ ├── fstab │ ├── passwd ← root:Twu6z6F/voF0Q (DES crypt) │ ├── init/jobs.d/ ← 20+ jobs Upstart │ └── udev/ ├── lib/ │ ├── libosal.so.0 ← TomTom OS Abstraction Layer │ ├── libhal.so.0 ← Hardware Abstraction (pilote fb0) │ ├── libttmp.so.0 ← TomTom Multimedia │ └── LoquendoTTS/ ← moteur TTS Loquendo ├── sbin/ │ ├── init ← script shell → exec /sbin/upstart │ ├── mount_sd_loopback │ ├── mount_sd │ ├── run_gprscomd │ └── ttsystem_present └── (sur partition userfs au runtime) └── /mnt/sdcard/script/ ├── TTTaskList.lua ← liste complète des TASK_* (300+) └── liblua.so ← VM Lua chargée par ttn via dlopen ``` ## 5. 文件系统架构 ### 5.1 eMMC 分区表 (mmcblk0) | 分区 | 挂载点 | 类型 | 选项 | |---|---|---|---| | `mmcblk0p3` | `/mnt/flash` | ext3 | defaults,sync,noauto | | `mmcblk0p5` | `/content` | ext3 | defaults,sync,noauto | | (非 fstab) | `/mnt/sdcard` | ext3 | 具体机制未验证 | ### 5.2 外部 SD 卡 (mmcblk1) SD 卡通过 `unionfs` 挂载到 `/mnt/movi`,配置如下: ``` # Script /sbin/mount_sd_loopback (简化版) sd_mount="/media/sdcard" # FAT32, RO loop_mount="/media/loopback" # ext3_loopback, RW upper union_mount="/mnt/movi" # unionfs des deux mount -t vfat /dev/mmcblk1p1 $sd_mount \ -o rw,noatime,nodiratime,nosuid,nodev,noexec,sync mount -o loop $sd_mount/loopdir/ext3_loopback $loop_mount \ -o rw,noexec,data=journal,commit=3600,async mount -t unionfs unionfs $union_mount \ -o rw,async,noexec,dirs=$loop_mount:$sd_mount=ro ``` ### 5.3 SD 卡内容 (FAT32) ``` / ├── splashw.bmp ← splash boot (480×272 24-bit BMP3) ├── autorun.inf ← Windows uniquement, ignoré par Linux ├── loopdir/ │ └── ext3_loopback ← upper layer unionfs (15 MiB, ext3 RW) │ ├── ttgo.bif ← config runtime principale │ ├── CurrentMap.dat ← chemin carte courante │ ├── UserPatch.dat ← patches MapShare │ └── Europe/ │ └── mapsettings.cfg ← favoris, domicile, historique ├── Europe/ ← carte TeleAtlas 2012.12 v905.4796 ├── VAutoTTS/ ← voix TTS Loquendo (~384 MB) ├── voices/ ← voix pré-enregistrées .chk ├── ephem/ ← éphémérides QuickGPSfix ├── photos/ ← skins voiture BMP 480×272 ├── art/cars/ ← skins voiture 3D ├── sounds/ ← klaxons et alertes WAV ├── raster/ ← tuiles satellite JPEG ├── poi/ ← radars premium .tlv └── zones-dangereuses/ ← POI zones de danger FR ``` ## 6. 启动链 ``` Mise sous tension │ ▼ U-Boot (bootloader) Signé RSA-2048 · verrouillé Toute tentative Ctrl+C/ESC : ignorée │ ▼ Kernel Linux 2.6.28.10-tt1574740 (rapport communautaire : module signedloop vérifierait rootfs.img par Merkle tree, non vérifié) │ ▼ /sbin/init (script shell) mount /proc /sys /dev /tmp /var mount /dev/pts mount /var/log mount /mnt/flash (mmcblk0p3, ext3) ifconfig lo 127.0.0.1 exec /sbin/upstart │ │ /content est monté plus tard par mount_internal │ (via service_mount_userfs : remount,rw) ▼ Upstart state machine state_initial └── service_udevd, service_apm └── modprobe /etc/modules └── state_initial_finished │ ▼ state_boot_mode_select USB détecté ? ──yes──→ state_mass_storage non ──────────────→ state_check_for_updates │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ /mnt/movi/ttsystem loadmodem ttntools/ttntool.sh (valid_update) (modem upd) (factory_tool) │ ▼ (aucun des triggers) state_navcore └── service_gps (clmapp/glgps) └── service_ttn_beaumont ├── si /mnt/sdcard/ttn existe → exec celui-là ├── sinon /bin/ttn └── sinon /bin/fakettn ``` ### `state_check_for_updates` 中的 SD 卡触发器 | SD 卡上的文件 | Upstart 事件 | 效果 | |---|---|---| | `/mnt/movi/ttsystem` | `valid_update_found` | 重启进入 flash 模式 | | `/mnt/sdcard/loadmodem` | `ttmodem_update_found` | 更新 WISMO218 固件 | | `/mnt/sdcard/ttntools/ttntool.sh` | `factory_tool_found` | 以 root 身份执行脚本 (内部 NAND) | | `/sbin/sirfimg.ver` ≠ `/content/sirffirmwaupdated.dat` | `sirf_update_found` | 更新 GPS SiRF 固件 | | 无 | `no_valid_update_found` | 正常启动 navcore | ## 7. 进程与服务 ### 完整的 Upstart 任务 (`/etc/init/jobs.d/`) | 任务 | 作用 | |---|---| | `state_initial` | 初始化 udev + 模块 | | `state_boot_mode_select` | 检测 USB/navcore | | `state_check_for_updates` | 测试 SD 卡文件 | | `state_navcore` | 启动 ttn + GPS | | `state_mass_storage` | USB gadget 模式 | | `state_factory_tool` | `exec /mnt/sdcard/ttntools/ttntool.sh` | | `service_ttn_beaumont` | 启动 `/bin/ttn` | | `service_gps` | GPS (clmapp 或 glgps) | | `service_gprs_beaumont` | GPRS 守护进程 | | `service_console` | ttySAC0 上的 getty | | `service_bluetooth` | Bluetooth 协议栈 | | `service_coldbootcounter` | 内部 NAND 上的启动计数器 (`/mnt/sdcard/counter.coldboot`) | | `change_handler` | Upstart 状态机 | | `task_insert_sdcard` | 挂载 SD + ttevent mounted | ### udev 规则 (`/etc/udev/rules.d/`) `10_local.rules`,SD 管理: ``` KERNEL=="mmcblk?", ACTION=="add", RUN+="/sbin/ttevent inserted &" KERNEL=="mmcblk?", ACTION=="add", RUN+="/sbin/emit_sd_detected" KERNEL=="mmcblk?", ACTION=="remove", RUN+="/sbin/emit_sd_removed" ``` `20_local-s5p6440.rules`,USB gadget 和 GPS 管理: ``` KERNEL=="s3c-usbgadget", ACTION=="add", RUN+="/sbin/load_g_file_storage" KERNEL=="ttyBCM0", ACTION=="add", SYMLINK+="ttyBCM0 gpsdevice" ``` ## 8. `ttn` 二进制分析 **文件**:`/bin/ttn` · 11,714,356 字节 · ELF 32-bit LSB ARM EABI5 · 动态链接 · stripped ### 依赖项 ``` ld-linux.so.3 · libc.so.6 · libpthread · librt · libdl · libm libstdc++.so.6 · libgcc_s · libasound.so.2 · libts-0.0.so.0 libosal.so.0 · libhal.so.0 · libttmp.so.0 · libhf.so LoquendoTTS/libLoqTTS7.so · LTTS7AudioBoard.so pphwre.so · vautov5.so ``` ### 运行时通过 `dlopen` 加载的插件 ``` /mnt/sdcard/setup.so ← point d'entrée setup() /mnt/sdcard/script/liblua.so ← VM Lua ``` ### 从 SD 卡读取的文件 (QEMU strace) ``` /mnt/sdcard/setup.so → ENOENT au boot /mnt/sdcard/newsettings.dat → ENOENT /mnt/sdcard/cleanup.txt → ENOENT /mnt/sdcard/fleetecd/ttw.bif → ENOENT /mnt/sdcard/randomized_zone_country.dat → ENOENT /mnt/sdcard/data.chk → ENOENT /dev/fb0 → ouvert avec succès (O_RDWR) /dev/input/event0 → ouvert avec succès ``` ### ttn 识别的标记文件 根据文件不同,放置在 `/mnt/sdcard/`(内部 NAND)或 `/mnt/movi/` 中: | 文件 | 效果 | |---|---| | `framerate.txt` | 在屏幕上显示 FPS | | `noautosuspend.dat` | 禁用待机 | | `nowatchdog` | 禁用看门狗 | | `noautosuicide.dat` | 禁用自杀看门狗 | | `coredumpsenable.dat` | 启用核心转储 | | `salesdemo.script` | 商业演示模式 | | `debugsigusr.dat` | 调试 USR 信号 | | `TTExceptiontrace.dat` | 异常追踪 | | `routeprofiler.dat` | 路径分析器 | | `coldbootcounter` | 启动时递增的计数器 (位于 `/mnt/movi/`) | | `restart.dat` | 崩溃后被检测到 | ### 重要的 C++ 类(还原的符号) ``` // Framebuffer (libhal.so) MLinuxScreen::SwitchFrameBuffer() MLinuxScreen::ClearFrameBufferScreen() MLinuxScreen::GetFrameBufferByteCount() // SDK / Menu CSDKRequestHandler CMicroBrowserSDKController::RunSDKCommand(const char*, const char*&) CScriptSDKCommand::Execute(CScriptManager&) CFileManager::PDLegacySDKRegistry(Tbuf<512>&) // HMAC (ValueRatio = HMAC-SHA1 tronqué 80 bits) HMACSha1_80 Sha1 MD5_CTX // Services réseau CHerculesServicesManager::SetServerURL(Tptr&) CServiceDiscovery::SetServiceDiscoveryData(PKh, j) CScriptDownload::ExecuteRemote() ← download script HTTP ``` ### 完整的 TASK_* 列表(摘自 `TTTaskList.lua`) 文件 `TTTaskList.lua`(在运行时位于 userfs 分区上,通过 Lua VM 由 `ttn` 加载)包含 `SdkRegistry/tomtom.mnu` 可用的 300 多个任务。主要示例: ``` TASK_BROWSE_MAP = 700000 TASK_MICROBROWSER = 708001 -- navigateur HTML embarqué TASK_IMAGE_BROWSER = 19778 -- visionneuse images TASK_DOC_BROWSER = 197782 TASK_DARK_SCREEN = 6000200 -- écran noir TASK_PREFERENCES = 19507 TASK_NAVIGATE_TO_FREQUENT_DESTINATION = 850025 ``` ## 9. GPRS 调制解调器与连接 ### 配置 ``` # 硬编码在 /bin/gprscomd 中的 APN APN: tomtom.m2m.ch ← SIM TomTom LIVE (désactivée) # 配置文件 /mnt/flash/sysfile/gprsantennatype ← type d'antenne /mnt/sdcard/gprsstamp ← timestamp dernier sync /mnt/sdcard/datausage.txt ← compteur data /etc/ppp/peers/gprscom.options ← généré runtime ``` ### 服务器 URL(硬编码在 ttn 中) ``` http://t.tt1.nl/services/directory.php ← bootstrap services LIVE http://t.tt1.nl/proxy/directory.php ← proxy LIVE ``` 服务发现流程: 1. 启动 → GET `http://t.tt1.nl/services/directory.php` 2. 响应 = 真实服务器列表 (Hercules, Weather, Traffic…) 3. `CHerculesServicesManager::SetServerURL()` 记录 URL 4. URL 缓存在 `ttgo.bif` 中用于后续启动 ### GPRS 覆盖(需要 NAND 访问权限) ``` # /sbin/run_gprscomd (简化版) gprscmdline="/mnt/sdcard/gprscomd.cmdline" if [ -x ${gprscmdline} ] ; then gprsexecutable="`tail -n 1 ${gprscmdline}`" fi exec ${gprsexecutable} -i ``` 如果 `/mnt/sdcard/gprscomd.cmdline` 可执行且其最后一行指向自定义二进制文件 → **启动时实现 root RCE**。需要对 `/mnt/sdcard/`(内部 NAND)具有写入权限。 ## 10. 来自 SD 卡的攻击面 ### ✅ 无需 UART 即可实现 #### 1. 自定义启动画面 替换 SD 卡 FAT32 根目录下的 `/splashw.bmp`: - SD 卡中存在的格式**BMP Windows 3.x · 480×272 · 24 位** - 系统使用的位置(根据固件分析) - 未测试 #### 2. 通过 `SdkRegistry` 自定义 UI 菜单 在 SD 卡根目录创建 `SdkRegistry/tomtom.mnu`。在提取的 `ttgo.bif` 的 `Features=` 字段中出现了 `SDK` 功能。其在设备盒子上的运行时激活仍有待确认。 ``` BLOCK_MAIN MENUITEM|TASK_BROWSE_MAP|Carte|map.bmp MENUITEM|TASK_MICROBROWSER|Browser|web.bmp MENUITEM|TASK_PREFERENCES|Réglages|prefs.bmp MENUITEM|TASK_DARK_SCREEN|Écran noir|dark.bmp BTM_DONE ``` #### 3. 设置覆盖 在 SD 卡上创建 `overridesettings.ini`。在 `ttgo.bif` 中出现了 `SettingsOverride` 功能: - INI 格式,需从 `ttn` 的字符串中逆向工程获取键名 - 可能在不修改 `ttgo.bif` 的情况下覆盖行为(避免 `ValueRatio` 陷阱) - 运行时行为未测试 #### 4. 自定义 POI 和危险区域 标准 TomTom OV2 格式: ``` Europe/mes_poi.ov2 ← données de position Europe/mes_poi.bmp ← icône 22×22 Europe/mes_poi.ogg ← alerte audio ``` #### 5. 自定义语音 替换 `voices/` 中的语音包(格式:`.chk` = 封装的 OGG Vorbis)。 ### ❌ 没有 UART 则无法实现 - 从 SD 卡执行 ARM 二进制文件(双重 noexec + 未验证的内核钩子) - 通过 dlopen 从 `/mnt/movi/` 加载 `.so` 库(mmap PROT_EXEC 被阻止) - 修改 rootfs(RSA bootloader + 社区报告的 rootfs 保护) - 从物理 SD 卡访问 `ttntool.sh`(`/mnt/sdcard` ≠ 外部 SD) - 重新刷入修改过的 CAB(RSA-2048 签名) ## 11. UART root 访问 ### 从固件中提取的凭证 ``` /etc/passwd : root:Twu6z6F/voF0Q:0:0:root:/mnt/sdcard:/bin/sh Hash type : DES crypt (Unix classique) Sel : Tw Mot de passe: palmtop1 Home dir : /mnt/sdcard (NAND interne, pas la SD physique) Shell : /bin/sh ``` ### 预计所需硬件 根据社区反馈 ([gpspower.net](https://www.gpspower.net/tomtom-tutorials/330988-tomtom-carminat-live-uart.html)): - **USB-TTL 3.3V** 线缆 (CH340 或 CP2102) - 测试点夹具或弹簧针 (pogo pins) ### 预计的串口参数 ``` Baudrate : 115200 Data : 8 bits Parity : None Stop : 1 bit → 115200 8N1 ``` beaumont PCB 上的 UART 焊盘 (TX/RX/GND) 在 gpspower.net 上有照片提及。确切位置需在物理硬件上确认。 ### 终端 ``` screen /dev/ttyUSB0 115200 # 或 minicom -D /dev/ttyUSB0 -b 115200 ``` ### 连接后可能的命令(理论) ``` # 验证访问权限 whoami && uname -a # 查看所有已挂载的 filesystems cat /proc/mounts # 访问 framebuffer ls -la /dev/fb0 cat /proc/fb # 以 RW 模式重新挂载 NAND mount -o remount,rw /mnt/sdcard # 查看 kernel 模块 lsmod cat /proc/modules | grep signedloop ``` ### 理论上通过 UART 解锁的攻击向量 基于对脚本和二进制文件的静态分析,**如果**通过 UART 的 root 访问有效: | 操作 | 在固件中观察到的机制 | |---|---| | **完全替换 NavCore** | `service_ttn_beaumont` 优先执行 `/mnt/sdcard/ttn`(如果存在)(在 `/bin/ttn` 之前) | | 启动时执行自定义程序 | `state_factory_tool` 执行 `/mnt/sdcard/ttntools/ttntool.sh` | | GPRS RCE | `/sbin/run_gprscomd` 如果带有 `-x` 则读取 `/mnt/sdcard/gprscomd.cmdline` | | NavCore 插件 | `ttn` 在启动时执行 `dlopen("/mnt/sdcard/setup.so")` | | fb0 显示 | `/dev/fb0` 在 QEMU strace 中成功打开 | ## 12. 无 UART 的个性化定制 ### 推荐的 SD 卡结构 ``` SD:/ ├── splashw.bmp ← Boot screen custom (480×272 24-bit) ├── SdkRegistry/ │ └── tomtom.mnu ← Menu UI custom ├── overridesettings.ini ← Override settings ├── Europe/ │ ├── mes_poi.ov2 ← POI personnalisés │ ├── mes_poi.bmp ← Icône POI │ └── mes_poi.ogg ← Alerte sonore ├── zones-dangereuses/ ← Radars FR (format OV2) └── loopdir/ └── ext3_loopback ← À modifier avec R-Link Explorer ├── ttgo.bif ← Config (attention: ValueRatio) └── Europe/ └── mapsettings.cfg ← Favoris et préférences ``` ### 必备工具 | 工具 | 用途 | 平台 | |---|---|---| | **R-Link Explorer 1.4** (Djeman) | 读写 ext3_loopback | Windows/Wine | | `cabextract` | 提取固件 CAB | macOS/Linux | | `7z` | 提取 ext2/ext3 | 跨平台 | | `john` / `hashcat` | 破解 DES 哈希 | 跨平台 | | `arm-linux-gnueabihf-gcc` | 编译 ARM 二进制文件 | macOS/Linux | | `strace` | 在 QEMU 中进行运行时分析 | Linux | | **Ghidra** | 逆向工程 `ttn` | 跨平台 | ## 13. 工具与资源 ### 有用的 GitHub 仓库 - [cedricp/ddt4all](https://github.com/cedricp/ddt4all):雷诺 OBD 诊断 - [george-hopkins/opentom](https://github.com/george-hopkins/opentom):TomTom 逆向工程工具 - [raulbalanza/OpenTom](https://github.com/raulbalanza/OpenTom):近期的 OpenTom 分支 ### 参考论坛 - [gpspower.net: Carminat LIVE UART](https://www.gpspower.net/tomtom-tutorials/330988-tomtom-carminat-live-uart.html):UART 访问,noexec,rootfs - [navitotal.com: Carminat Live patching](https://www.navitotal.com/general-discussions-about-tomtom/carminat-live-navcore-844-patching-and-map-activation-t7180-165.html) - [gpsurl.com: Cracking the non-Live Carminat](https://www.gpsurl.com/tomtom-discussions/187882-cracking-live-carminat-17.html) - [gps-carminat.com](https://www.gps-carminat.com):法语参考资源 - [forumlaguna3.com](https://www.forumlaguna3.com) ### 为 ARM1176JZF-S / S5P6440 编译 ``` brew install arm-linux-gnueabihf-gcc # 针对 ARMv6 (S5P6440) 的 Cross-compilation arm-linux-gnueabihf-gcc -static -march=armv6 \ -o fbtest fbtest.c # 注意: ARMv5 (-march=armv5tej) 保持兼容但并非最优 ``` ## 14. 本项目中的 AI 使用 为了保持透明度,我在此说明,在整个逆向工程项目中,**Claude (Anthropic)** 被用作辅助工具。 **AI 提供的帮助:** - 协助研究和定位某些技术点(Upstart 机制、TomTom 二进制格式、嵌入式 Linux 约定) - 通过建议探索方向加速固件探索 - 根据我的笔记和发现撰写并规范格式化本 README **由我本人完成的工作:** - 整体思路及项目方向 - 具体的提取、分析和测试工作 - 发布前对每条信息的验证和核实 - 编辑和技术选择 AI 是一个用于节省时间和构建工作结构的助手,但逆向工程调查本身是由我亲自进行的。如果没有这种辅助,这个项目将不复存在,但仅靠 AI 也无法产出这些成果。 ## 15. 法律免责声明 本逆向工程工作**完全在个人设备**(雷诺 Laguna 3 Monaco GP 2012)上进行,目的仅限于研究和社区文档。 - CAB 固件可从 TomTom 官方服务器无需身份验证下载 - 未绕过任何技术保护措施以获取此固件 - 本仓库不包含任何盗版的 TomTom 地图或绕过 DRM 的内容 - 在非您所有的设备上使用这些信息的责任由您自行承担 出于互操作性和研究目的进行的软件逆向工程受欧洲指令 2009/24/EC(第 6 条)及其在法国法律中的同等规定管辖。 *基于对官方固件静态分析的 NavCore 9.884 beaumont 文档*
Linux 2.6.28 verrouillé] B --> C[NAND interne] B --> D[Carte SD externe] C --> E[Verrouillé] D --> F[Modifiable] E -.->|UART| G[shell root théorique ?] F -.->|fichiers SD| H[Personnalisations
splash · menus · POI] style A fill:#5B4FBE,color:#fff style E fill:#A32D2D,color:#fff style F fill:#3B6D11,color:#fff style G fill:#EF9F27,color:#000 style H fill:#1D9E75,color:#fff ``` ## 目录 1. [背景与目标](#1-contexte-et-objectif) 2. [系统识别](#2-identification-du-système) 3. [硬件](#3-hardware) 4. [固件提取](#4-extraction-du-firmware) 5. [文件系统架构](#5-architecture-du-filesystem) 6. [启动链](#6-boot-chain) 7. [进程与服务](#7-processus-et-services) 8. [ttn 二进制文件分析](#8-analyse-du-binaire-ttn) 9. [GPRS 调制解调器与连接](#9-modem-gprs-et-connectivité) 10. [来自 SD 卡的攻击面](#10-surface-dattaque-depuis-la-carte-sd) 11. [UART root 访问](#11-accès-uart-root) 12. [无 UART 的个性化定制](#12-personnalisations-sans-uart) 13. [工具与资源](#13-outils-et-ressources) 14. [本项目中的 AI 使用](#14-utilisation-de-lia-dans-ce-projet) 15. [法律免责声明](#15-disclaimer-légal) ## 1. 背景与目标 **Carminat TomTom LIVE** 是雷诺(Renault)为 2009-2014 年款车型(Laguna 3、Mégane 3、Scénic 3、Espace 4、Fluence、Latitude、Koleos 等)配备的车载导航系统。它与非 Live 版的 Carminat TomTom 的区别在于: - 固件存储在**内部 NAND** 中(而不是 SD 卡上) - 内置 **GPRS 调制解调器**,用于提供实时服务(交通、天气、雷达测速) - **RSA 签名**且锁定的 bootloader - 根据社区反馈,一个名为 **`signedloop`** 的 kernel 模块会通过默克尔树(Merkle tree)验证 rootfs 的完整性(本次分析未证实,见第 3 节) 本仓库记录了对 NavCore 9.884 beaumont 固件的分析,包括文件系统映射、NavCore 二进制文件的静态分析,以及通过 QEMU/strace 进行的运行时分析。 **使用的方法:** - 通过**从车辆中提取的 SD 卡**识别系统(读取 `ttgo.bif`、`loopdir/ext3_loopback` 文件) - 通过 **TomTom 官方 CDN** 获取固件(参见 [固件提取](#4-extraction-du-firmware) 章节) - 对从 CAB 中提取的 rootfs 进行静态分析 - **搭建 QEMU 模拟器**,重现设备盒子的 ARM/Linux 环境以便对 `ttn` 二进制文件进行动态分析(strace 系统调用、观察打开的文件、运行时行为) 未对车辆的物理设备盒子进行任何修改。所有分析均是在 SD 卡文件副本和下载的固件上进行的。 **此处记录的所有工作均基于个人 SD 卡(从车辆中取出用于分析)以及从 TomTom CDN 下载的官方固件完成。** ## 2. 系统识别 | 字段 | 值 | |---|---| | **DeviceName** | TomTom Carminat LIVE | | **硬件代号** | `beaumont` (rev 11) | | **NavCore 版本** | `9.884`,build `9.884.1609031` | | **官方发布** | `NFA2.8-RC06`,于 2014 年 6 月 27 日在 Dieppe 编译 | | **Linux 内核** | `2.6.28.10-tt1574740` | | **工具链** | `gcc 4.3.3 TomTom CipherWizardry 2009q1_203-474426` | | **Libc** | uClibc | | **Init 系统** | Upstart (通过 shell 脚本 `/sbin/init` → `exec /sbin/upstart`) | 这些信息来源于从 SD 卡的 `loopdir/ext3_loopback` 镜像中提取的 `ttgo.bif` 以及 `TomTom-Cfg/release.nfo` 文件。 ``` # 提取 ttgo.bif [TomTomGo] DeviceName=TomTom Carminat LIVE DeviceVersionHW=beaumont ApplicationVersionVersionNumber=9884 ApplicationVersion=1609031.550 RamDiskVersion=20140626 BootLoaderVersion=839378 LinuxVersion=1574740 ``` ## 3. 硬件 | 组件 | 识别 | |---|---| | **SoC** | Samsung S5P6440 (通过 `/etc/udev/rules.d/20_local-s5p6440.rules` 确认) | | **CPU** | ARM1176JZF-S · ARMv6 · little-endian · EABI | | **RAM** | 无法通过静态分析确定 | | **内部存储** | NAND flash · eMMC (`/dev/mmcblk0`) | | **用户 SD 卡** | `/dev/mmcblk1` (可访问插槽) | | **屏幕** | Samsung LCD `LTA058B3L0F` (根据 DTB) · 480×272 | | **Framebuffer** | `/dev/fb0` · RGB16/24 | | **GPS** | SiRF3 PRIMA · `/dev/ttySAC2` | | **GSM/GPRS 调制解调器** | Wavecom WISMO218 · `/dev/ttyS0` | | **RDS-TMC 调谐器** | BCM4750 · `bcm4750_spi` | | **Bluetooth** | 内置 · `hci_uart` · 仅限 HFP + PBAP (不支持 A2DP) | | **触摸屏** | `libts` · `/dev/input/event0` | ### 已加载的内核模块(摘自 `/etc/modules`) ``` unionfs · ppp_async · ppp_generic · slhc · hidp · hid · rfcomm sco · hci_uart · l2cap · bluetooth · bcm4750_spi · vfat · msdos fat · evdev ``` ## 4. 固件提取 ### 4.1 下载官方 CAB 固件可**无需身份验证**从 TomTom 的 Akamai CDN 下载: ``` curl -A "TomTom HOME/2.24.11.8" -O \ "http://download.tomtom.com/sweet/navcore/9.884.1609031_RC06.CAB-Dieppe.cab" # 参考 SHA256 a4d32daae2cdd6bc23a0660285c4e32e3a098034731eb257172ed7aaef9052d5 ``` **其他可用版本(经测试返回 HTTP 200):** | 版本 | URL | |---|---| | 9.844 | `http://download.tomtom.com/sweet/navcore/9844.634510.Carminat_TomTom.cab` | | 9.845 RC10 | `http://download.tomtom.com/sweet/navcore/9.845_1115399_RC10.CAB-Camiron-RC10.cab` | | 9.846 RC12 | `http://download.tomtom.com/sweet/navcore/9.846_1165624_RC12.CAB-Camiron-RC12.cab` | | 9.847 RC14 | `http://download.tomtom.com/sweet/navcore/9.847.1302316_RC14.CAB-Camiron-RC14.cab` | | **9.884 RC06** | `http://download.tomtom.com/sweet/navcore/9.884.1609031_RC06.CAB-Dieppe.cab` | ### 4.2 提取 CAB ``` brew install cabextract # macOS mkdir extracted && cabextract 9.884.1609031_RC06.CAB-Dieppe.cab -d extracted/ ls extracted/ # → splashw.bmp ttsystem TomTom-Cfg/release.nfo ``` ### 4.3 提取完整 rootfs ``` cd extracted/ mkdir rootfs && 7z x ttsystem -o rootfs/ # 实际的 rootfs 在 userfs_partition.tar.gz 中 cd rootfs/ tar xzf userfs_partition.tar.gz # 内容: # _zImage → Linux kernel ARM zImage # rootfs.img → 完整的 Linux filesystem (ext2, 67 MB) # WISMO218_*.cla → modem 固件 mkdir rootfs_mnt # 在 Linux 上: sudo mount -o loop rootfs.img rootfs_mnt/ # 在 macOS 上(只读): 7z x rootfs.img -o rootfs_mnt/ ``` ### 4.4 提取的固件结构 ``` rootfs_mnt/ ├── bin/ │ ├── ttn ← NavCore principal (11.7 MB, ELF ARM dynamique) │ ├── telttn ← wrapper IPC vers ttn │ ├── fakettn ← fallback si ttn absent │ └── gprscomd ← daemon GPRS ├── etc/ │ ├── inittab │ ├── fstab │ ├── passwd ← root:Twu6z6F/voF0Q (DES crypt) │ ├── init/jobs.d/ ← 20+ jobs Upstart │ └── udev/ ├── lib/ │ ├── libosal.so.0 ← TomTom OS Abstraction Layer │ ├── libhal.so.0 ← Hardware Abstraction (pilote fb0) │ ├── libttmp.so.0 ← TomTom Multimedia │ └── LoquendoTTS/ ← moteur TTS Loquendo ├── sbin/ │ ├── init ← script shell → exec /sbin/upstart │ ├── mount_sd_loopback │ ├── mount_sd │ ├── run_gprscomd │ └── ttsystem_present └── (sur partition userfs au runtime) └── /mnt/sdcard/script/ ├── TTTaskList.lua ← liste complète des TASK_* (300+) └── liblua.so ← VM Lua chargée par ttn via dlopen ``` ## 5. 文件系统架构 ### 5.1 eMMC 分区表 (mmcblk0) | 分区 | 挂载点 | 类型 | 选项 | |---|---|---|---| | `mmcblk0p3` | `/mnt/flash` | ext3 | defaults,sync,noauto | | `mmcblk0p5` | `/content` | ext3 | defaults,sync,noauto | | (非 fstab) | `/mnt/sdcard` | ext3 | 具体机制未验证 | ### 5.2 外部 SD 卡 (mmcblk1) SD 卡通过 `unionfs` 挂载到 `/mnt/movi`,配置如下: ``` # Script /sbin/mount_sd_loopback (简化版) sd_mount="/media/sdcard" # FAT32, RO loop_mount="/media/loopback" # ext3_loopback, RW upper union_mount="/mnt/movi" # unionfs des deux mount -t vfat /dev/mmcblk1p1 $sd_mount \ -o rw,noatime,nodiratime,nosuid,nodev,noexec,sync mount -o loop $sd_mount/loopdir/ext3_loopback $loop_mount \ -o rw,noexec,data=journal,commit=3600,async mount -t unionfs unionfs $union_mount \ -o rw,async,noexec,dirs=$loop_mount:$sd_mount=ro ``` ### 5.3 SD 卡内容 (FAT32) ``` / ├── splashw.bmp ← splash boot (480×272 24-bit BMP3) ├── autorun.inf ← Windows uniquement, ignoré par Linux ├── loopdir/ │ └── ext3_loopback ← upper layer unionfs (15 MiB, ext3 RW) │ ├── ttgo.bif ← config runtime principale │ ├── CurrentMap.dat ← chemin carte courante │ ├── UserPatch.dat ← patches MapShare │ └── Europe/ │ └── mapsettings.cfg ← favoris, domicile, historique ├── Europe/ ← carte TeleAtlas 2012.12 v905.4796 ├── VAutoTTS/ ← voix TTS Loquendo (~384 MB) ├── voices/ ← voix pré-enregistrées .chk ├── ephem/ ← éphémérides QuickGPSfix ├── photos/ ← skins voiture BMP 480×272 ├── art/cars/ ← skins voiture 3D ├── sounds/ ← klaxons et alertes WAV ├── raster/ ← tuiles satellite JPEG ├── poi/ ← radars premium .tlv └── zones-dangereuses/ ← POI zones de danger FR ``` ## 6. 启动链 ``` Mise sous tension │ ▼ U-Boot (bootloader) Signé RSA-2048 · verrouillé Toute tentative Ctrl+C/ESC : ignorée │ ▼ Kernel Linux 2.6.28.10-tt1574740 (rapport communautaire : module signedloop vérifierait rootfs.img par Merkle tree, non vérifié) │ ▼ /sbin/init (script shell) mount /proc /sys /dev /tmp /var mount /dev/pts mount /var/log mount /mnt/flash (mmcblk0p3, ext3) ifconfig lo 127.0.0.1 exec /sbin/upstart │ │ /content est monté plus tard par mount_internal │ (via service_mount_userfs : remount,rw) ▼ Upstart state machine state_initial └── service_udevd, service_apm └── modprobe /etc/modules └── state_initial_finished │ ▼ state_boot_mode_select USB détecté ? ──yes──→ state_mass_storage non ──────────────→ state_check_for_updates │ ┌───────────────┼───────────────┐ ▼ ▼ ▼ /mnt/movi/ttsystem loadmodem ttntools/ttntool.sh (valid_update) (modem upd) (factory_tool) │ ▼ (aucun des triggers) state_navcore └── service_gps (clmapp/glgps) └── service_ttn_beaumont ├── si /mnt/sdcard/ttn existe → exec celui-là ├── sinon /bin/ttn └── sinon /bin/fakettn ``` ### `state_check_for_updates` 中的 SD 卡触发器 | SD 卡上的文件 | Upstart 事件 | 效果 | |---|---|---| | `/mnt/movi/ttsystem` | `valid_update_found` | 重启进入 flash 模式 | | `/mnt/sdcard/loadmodem` | `ttmodem_update_found` | 更新 WISMO218 固件 | | `/mnt/sdcard/ttntools/ttntool.sh` | `factory_tool_found` | 以 root 身份执行脚本 (内部 NAND) | | `/sbin/sirfimg.ver` ≠ `/content/sirffirmwaupdated.dat` | `sirf_update_found` | 更新 GPS SiRF 固件 | | 无 | `no_valid_update_found` | 正常启动 navcore | ## 7. 进程与服务 ### 完整的 Upstart 任务 (`/etc/init/jobs.d/`) | 任务 | 作用 | |---|---| | `state_initial` | 初始化 udev + 模块 | | `state_boot_mode_select` | 检测 USB/navcore | | `state_check_for_updates` | 测试 SD 卡文件 | | `state_navcore` | 启动 ttn + GPS | | `state_mass_storage` | USB gadget 模式 | | `state_factory_tool` | `exec /mnt/sdcard/ttntools/ttntool.sh` | | `service_ttn_beaumont` | 启动 `/bin/ttn` | | `service_gps` | GPS (clmapp 或 glgps) | | `service_gprs_beaumont` | GPRS 守护进程 | | `service_console` | ttySAC0 上的 getty | | `service_bluetooth` | Bluetooth 协议栈 | | `service_coldbootcounter` | 内部 NAND 上的启动计数器 (`/mnt/sdcard/counter.coldboot`) | | `change_handler` | Upstart 状态机 | | `task_insert_sdcard` | 挂载 SD + ttevent mounted | ### udev 规则 (`/etc/udev/rules.d/`) `10_local.rules`,SD 管理: ``` KERNEL=="mmcblk?", ACTION=="add", RUN+="/sbin/ttevent inserted &" KERNEL=="mmcblk?", ACTION=="add", RUN+="/sbin/emit_sd_detected" KERNEL=="mmcblk?", ACTION=="remove", RUN+="/sbin/emit_sd_removed" ``` `20_local-s5p6440.rules`,USB gadget 和 GPS 管理: ``` KERNEL=="s3c-usbgadget", ACTION=="add", RUN+="/sbin/load_g_file_storage" KERNEL=="ttyBCM0", ACTION=="add", SYMLINK+="ttyBCM0 gpsdevice" ``` ## 8. `ttn` 二进制分析 **文件**:`/bin/ttn` · 11,714,356 字节 · ELF 32-bit LSB ARM EABI5 · 动态链接 · stripped ### 依赖项 ``` ld-linux.so.3 · libc.so.6 · libpthread · librt · libdl · libm libstdc++.so.6 · libgcc_s · libasound.so.2 · libts-0.0.so.0 libosal.so.0 · libhal.so.0 · libttmp.so.0 · libhf.so LoquendoTTS/libLoqTTS7.so · LTTS7AudioBoard.so pphwre.so · vautov5.so ``` ### 运行时通过 `dlopen` 加载的插件 ``` /mnt/sdcard/setup.so ← point d'entrée setup() /mnt/sdcard/script/liblua.so ← VM Lua ``` ### 从 SD 卡读取的文件 (QEMU strace) ``` /mnt/sdcard/setup.so → ENOENT au boot /mnt/sdcard/newsettings.dat → ENOENT /mnt/sdcard/cleanup.txt → ENOENT /mnt/sdcard/fleetecd/ttw.bif → ENOENT /mnt/sdcard/randomized_zone_country.dat → ENOENT /mnt/sdcard/data.chk → ENOENT /dev/fb0 → ouvert avec succès (O_RDWR) /dev/input/event0 → ouvert avec succès ``` ### ttn 识别的标记文件 根据文件不同,放置在 `/mnt/sdcard/`(内部 NAND)或 `/mnt/movi/` 中: | 文件 | 效果 | |---|---| | `framerate.txt` | 在屏幕上显示 FPS | | `noautosuspend.dat` | 禁用待机 | | `nowatchdog` | 禁用看门狗 | | `noautosuicide.dat` | 禁用自杀看门狗 | | `coredumpsenable.dat` | 启用核心转储 | | `salesdemo.script` | 商业演示模式 | | `debugsigusr.dat` | 调试 USR 信号 | | `TTExceptiontrace.dat` | 异常追踪 | | `routeprofiler.dat` | 路径分析器 | | `coldbootcounter` | 启动时递增的计数器 (位于 `/mnt/movi/`) | | `restart.dat` | 崩溃后被检测到 | ### 重要的 C++ 类(还原的符号) ``` // Framebuffer (libhal.so) MLinuxScreen::SwitchFrameBuffer() MLinuxScreen::ClearFrameBufferScreen() MLinuxScreen::GetFrameBufferByteCount() // SDK / Menu CSDKRequestHandler CMicroBrowserSDKController::RunSDKCommand(const char*, const char*&) CScriptSDKCommand::Execute(CScriptManager&) CFileManager::PDLegacySDKRegistry(Tbuf<512>&) // HMAC (ValueRatio = HMAC-SHA1 tronqué 80 bits) HMACSha1_80 Sha1 MD5_CTX // Services réseau CHerculesServicesManager::SetServerURL(Tptr&) CServiceDiscovery::SetServiceDiscoveryData(PKh, j) CScriptDownload::ExecuteRemote() ← download script HTTP ``` ### 完整的 TASK_* 列表(摘自 `TTTaskList.lua`) 文件 `TTTaskList.lua`(在运行时位于 userfs 分区上,通过 Lua VM 由 `ttn` 加载)包含 `SdkRegistry/tomtom.mnu` 可用的 300 多个任务。主要示例: ``` TASK_BROWSE_MAP = 700000 TASK_MICROBROWSER = 708001 -- navigateur HTML embarqué TASK_IMAGE_BROWSER = 19778 -- visionneuse images TASK_DOC_BROWSER = 197782 TASK_DARK_SCREEN = 6000200 -- écran noir TASK_PREFERENCES = 19507 TASK_NAVIGATE_TO_FREQUENT_DESTINATION = 850025 ``` ## 9. GPRS 调制解调器与连接 ### 配置 ``` # 硬编码在 /bin/gprscomd 中的 APN APN: tomtom.m2m.ch ← SIM TomTom LIVE (désactivée) # 配置文件 /mnt/flash/sysfile/gprsantennatype ← type d'antenne /mnt/sdcard/gprsstamp ← timestamp dernier sync /mnt/sdcard/datausage.txt ← compteur data /etc/ppp/peers/gprscom.options ← généré runtime ``` ### 服务器 URL(硬编码在 ttn 中) ``` http://t.tt1.nl/services/directory.php ← bootstrap services LIVE http://t.tt1.nl/proxy/directory.php ← proxy LIVE ``` 服务发现流程: 1. 启动 → GET `http://t.tt1.nl/services/directory.php` 2. 响应 = 真实服务器列表 (Hercules, Weather, Traffic…) 3. `CHerculesServicesManager::SetServerURL()` 记录 URL 4. URL 缓存在 `ttgo.bif` 中用于后续启动 ### GPRS 覆盖(需要 NAND 访问权限) ``` # /sbin/run_gprscomd (简化版) gprscmdline="/mnt/sdcard/gprscomd.cmdline" if [ -x ${gprscmdline} ] ; then gprsexecutable="`tail -n 1 ${gprscmdline}`" fi exec ${gprsexecutable} -i ``` 如果 `/mnt/sdcard/gprscomd.cmdline` 可执行且其最后一行指向自定义二进制文件 → **启动时实现 root RCE**。需要对 `/mnt/sdcard/`(内部 NAND)具有写入权限。 ## 10. 来自 SD 卡的攻击面 ### ✅ 无需 UART 即可实现 #### 1. 自定义启动画面 替换 SD 卡 FAT32 根目录下的 `/splashw.bmp`: - SD 卡中存在的格式**BMP Windows 3.x · 480×272 · 24 位** - 系统使用的位置(根据固件分析) - 未测试 #### 2. 通过 `SdkRegistry` 自定义 UI 菜单 在 SD 卡根目录创建 `SdkRegistry/tomtom.mnu`。在提取的 `ttgo.bif` 的 `Features=` 字段中出现了 `SDK` 功能。其在设备盒子上的运行时激活仍有待确认。 ``` BLOCK_MAIN MENUITEM|TASK_BROWSE_MAP|Carte|map.bmp MENUITEM|TASK_MICROBROWSER|Browser|web.bmp MENUITEM|TASK_PREFERENCES|Réglages|prefs.bmp MENUITEM|TASK_DARK_SCREEN|Écran noir|dark.bmp BTM_DONE ``` #### 3. 设置覆盖 在 SD 卡上创建 `overridesettings.ini`。在 `ttgo.bif` 中出现了 `SettingsOverride` 功能: - INI 格式,需从 `ttn` 的字符串中逆向工程获取键名 - 可能在不修改 `ttgo.bif` 的情况下覆盖行为(避免 `ValueRatio` 陷阱) - 运行时行为未测试 #### 4. 自定义 POI 和危险区域 标准 TomTom OV2 格式: ``` Europe/mes_poi.ov2 ← données de position Europe/mes_poi.bmp ← icône 22×22 Europe/mes_poi.ogg ← alerte audio ``` #### 5. 自定义语音 替换 `voices/` 中的语音包(格式:`.chk` = 封装的 OGG Vorbis)。 ### ❌ 没有 UART 则无法实现 - 从 SD 卡执行 ARM 二进制文件(双重 noexec + 未验证的内核钩子) - 通过 dlopen 从 `/mnt/movi/` 加载 `.so` 库(mmap PROT_EXEC 被阻止) - 修改 rootfs(RSA bootloader + 社区报告的 rootfs 保护) - 从物理 SD 卡访问 `ttntool.sh`(`/mnt/sdcard` ≠ 外部 SD) - 重新刷入修改过的 CAB(RSA-2048 签名) ## 11. UART root 访问 ### 从固件中提取的凭证 ``` /etc/passwd : root:Twu6z6F/voF0Q:0:0:root:/mnt/sdcard:/bin/sh Hash type : DES crypt (Unix classique) Sel : Tw Mot de passe: palmtop1 Home dir : /mnt/sdcard (NAND interne, pas la SD physique) Shell : /bin/sh ``` ### 预计所需硬件 根据社区反馈 ([gpspower.net](https://www.gpspower.net/tomtom-tutorials/330988-tomtom-carminat-live-uart.html)): - **USB-TTL 3.3V** 线缆 (CH340 或 CP2102) - 测试点夹具或弹簧针 (pogo pins) ### 预计的串口参数 ``` Baudrate : 115200 Data : 8 bits Parity : None Stop : 1 bit → 115200 8N1 ``` beaumont PCB 上的 UART 焊盘 (TX/RX/GND) 在 gpspower.net 上有照片提及。确切位置需在物理硬件上确认。 ### 终端 ``` screen /dev/ttyUSB0 115200 # 或 minicom -D /dev/ttyUSB0 -b 115200 ``` ### 连接后可能的命令(理论) ``` # 验证访问权限 whoami && uname -a # 查看所有已挂载的 filesystems cat /proc/mounts # 访问 framebuffer ls -la /dev/fb0 cat /proc/fb # 以 RW 模式重新挂载 NAND mount -o remount,rw /mnt/sdcard # 查看 kernel 模块 lsmod cat /proc/modules | grep signedloop ``` ### 理论上通过 UART 解锁的攻击向量 基于对脚本和二进制文件的静态分析,**如果**通过 UART 的 root 访问有效: | 操作 | 在固件中观察到的机制 | |---|---| | **完全替换 NavCore** | `service_ttn_beaumont` 优先执行 `/mnt/sdcard/ttn`(如果存在)(在 `/bin/ttn` 之前) | | 启动时执行自定义程序 | `state_factory_tool` 执行 `/mnt/sdcard/ttntools/ttntool.sh` | | GPRS RCE | `/sbin/run_gprscomd` 如果带有 `-x` 则读取 `/mnt/sdcard/gprscomd.cmdline` | | NavCore 插件 | `ttn` 在启动时执行 `dlopen("/mnt/sdcard/setup.so")` | | fb0 显示 | `/dev/fb0` 在 QEMU strace 中成功打开 | ## 12. 无 UART 的个性化定制 ### 推荐的 SD 卡结构 ``` SD:/ ├── splashw.bmp ← Boot screen custom (480×272 24-bit) ├── SdkRegistry/ │ └── tomtom.mnu ← Menu UI custom ├── overridesettings.ini ← Override settings ├── Europe/ │ ├── mes_poi.ov2 ← POI personnalisés │ ├── mes_poi.bmp ← Icône POI │ └── mes_poi.ogg ← Alerte sonore ├── zones-dangereuses/ ← Radars FR (format OV2) └── loopdir/ └── ext3_loopback ← À modifier avec R-Link Explorer ├── ttgo.bif ← Config (attention: ValueRatio) └── Europe/ └── mapsettings.cfg ← Favoris et préférences ``` ### 必备工具 | 工具 | 用途 | 平台 | |---|---|---| | **R-Link Explorer 1.4** (Djeman) | 读写 ext3_loopback | Windows/Wine | | `cabextract` | 提取固件 CAB | macOS/Linux | | `7z` | 提取 ext2/ext3 | 跨平台 | | `john` / `hashcat` | 破解 DES 哈希 | 跨平台 | | `arm-linux-gnueabihf-gcc` | 编译 ARM 二进制文件 | macOS/Linux | | `strace` | 在 QEMU 中进行运行时分析 | Linux | | **Ghidra** | 逆向工程 `ttn` | 跨平台 | ## 13. 工具与资源 ### 有用的 GitHub 仓库 - [cedricp/ddt4all](https://github.com/cedricp/ddt4all):雷诺 OBD 诊断 - [george-hopkins/opentom](https://github.com/george-hopkins/opentom):TomTom 逆向工程工具 - [raulbalanza/OpenTom](https://github.com/raulbalanza/OpenTom):近期的 OpenTom 分支 ### 参考论坛 - [gpspower.net: Carminat LIVE UART](https://www.gpspower.net/tomtom-tutorials/330988-tomtom-carminat-live-uart.html):UART 访问,noexec,rootfs - [navitotal.com: Carminat Live patching](https://www.navitotal.com/general-discussions-about-tomtom/carminat-live-navcore-844-patching-and-map-activation-t7180-165.html) - [gpsurl.com: Cracking the non-Live Carminat](https://www.gpsurl.com/tomtom-discussions/187882-cracking-live-carminat-17.html) - [gps-carminat.com](https://www.gps-carminat.com):法语参考资源 - [forumlaguna3.com](https://www.forumlaguna3.com) ### 为 ARM1176JZF-S / S5P6440 编译 ``` brew install arm-linux-gnueabihf-gcc # 针对 ARMv6 (S5P6440) 的 Cross-compilation arm-linux-gnueabihf-gcc -static -march=armv6 \ -o fbtest fbtest.c # 注意: ARMv5 (-march=armv5tej) 保持兼容但并非最优 ``` ## 14. 本项目中的 AI 使用 为了保持透明度,我在此说明,在整个逆向工程项目中,**Claude (Anthropic)** 被用作辅助工具。 **AI 提供的帮助:** - 协助研究和定位某些技术点(Upstart 机制、TomTom 二进制格式、嵌入式 Linux 约定) - 通过建议探索方向加速固件探索 - 根据我的笔记和发现撰写并规范格式化本 README **由我本人完成的工作:** - 整体思路及项目方向 - 具体的提取、分析和测试工作 - 发布前对每条信息的验证和核实 - 编辑和技术选择 AI 是一个用于节省时间和构建工作结构的助手,但逆向工程调查本身是由我亲自进行的。如果没有这种辅助,这个项目将不复存在,但仅靠 AI 也无法产出这些成果。 ## 15. 法律免责声明 本逆向工程工作**完全在个人设备**(雷诺 Laguna 3 Monaco GP 2012)上进行,目的仅限于研究和社区文档。 - CAB 固件可从 TomTom 官方服务器无需身份验证下载 - 未绕过任何技术保护措施以获取此固件 - 本仓库不包含任何盗版的 TomTom 地图或绕过 DRM 的内容 - 在非您所有的设备上使用这些信息的责任由您自行承担 出于互操作性和研究目的进行的软件逆向工程受欧洲指令 2009/24/EC(第 6 条)及其在法国法律中的同等规定管辖。 *基于对官方固件静态分析的 NavCore 9.884 beaumont 文档*
标签:Bootloader, Carminat, GPRS, IoT安全, NAND闪存, NavCore, Renault, rizin, SD卡攻击面, TomTom, UART, 二进制分析, 云安全运维, 云资产清单, 固件分析, 固件提取, 嵌入式Linux, 文档安全, 汽车安全, 汽车黑客, 物联网安全, 硬件 hacking, 身份验证强制, 车机系统, 车载导航, 逆向工程, 雷诺