TA的每日心情 | 开心 2021-2-4 17:39 |
---|
签到天数: 2 天 连续签到: 1 天 [LV.1]初来乍到
|
续接上篇文章:基于nxp MCIMX6S6AVM08AC的汽车电子主板解析之硬件系统、调试串口(两篇文章衔接的有点久,还望谅解)
3、UBoot Hack
他的这个UBoot并不是SDK里面的Uboot,毕竟硬件设计上与参考板设计不同,Uboot代码有所改动是理所应当的。但这个Uboot不能被打断引导,令我很头疼。万一我折腾折腾着,把Kernel搞死了,这块主板就变成了一块砖。由于我没有NAND编程器,没办法对Flash烧写恢复,一旦成砖我还怎么研究下去?
我需要准备一个PlanB……
首先我要想办法打断Uboot的引导,进入uboot提示符,然后使用uboot指令,用命令传输数据,就有可能对砖机进行修复。
我首先查看了他的Flash布局:cat/proc/mtd
I have no name!@(none) /$ cat /proc/mtd
dev: size erasesize namemtd0: 00400000 00020000 "bootloader"mtd1: 00c00000 00020000 "nand.kernel"mtd2: 0d000000 00020000 "nand.rootfs"mtd3: 00a00000 00020000 "pss1"mtd4: 00a00000 00020000 "pss2"mtd5: 00c00000 00020000 "logo"
可以发现并没有uboot环境变量分区,那么环境变量可能是固定写死在uboot固件里面的,WinHex确实找到了这部分区域。
有一个变量叫bootdelay,值为0。
怪不得不能被打断引导,我把这个值改为3,想着把他刷进去试一下看看。接下来怎么把uboot刷进去又成了一个问题。
最简单暴力的办法是用dd命令直接从/dev/mtd0或者/dev/mtdblock0写进去,那万一写成砖怎么办?这个方法太危险,NAND Flash的操作与SPIFlash可能不同,因为NAND是有OOB区域的,里面有ECC校验,我不能冒险。
接下来我分析了这个系统的更新程序,/opt/sysupdate。这个程序虽然去掉了一些符号表,私有函数在IDA里面看来都是sub_XXXX,但是由于他使用了一套日志接口,log_optional,里面打印了源文件名,函数名,行号等信息,一些函数可能被编译器整合优化成一个函数,但还是可以猜出绝大多数函数的功能。
经过一番分析,确定了他更新uboot使用了外部命令kobs-nginit -v ./uboot.bin。这个命令可能来源于NXP i.MX6 SDK,不管了,先把uboot复制到优盘,插入车机,输命令更新uboot。完成重启,发现bootdelay没生效,并没有出现等待用户3秒输入打断引导的环节……
我X,厂商竟然把bootdelay这部分代码注释掉了吗?这不科学啊!
不过我又想到了一个办法,把bootcmd这个变量擦掉,这样uboot没有了启动命令,自然就无法引导了吧。于是上WinHex,找到bootcmd=,修改成aootcmd=。刷机,重启,发现确实中断了引导。
但是这种办法带来的后果就是,每次启动,都需要手动输入命令才能引导系统,不是什么大问题,准备记事本每次复制粘贴启动命令就可以了…
nand read0x10007FC0 0x400000 0x300000; bootm0x10007FC0现在可以在uboot提示符下操作了,help查看帮助,看看支持哪些命令,没有网络相关的,因为这主板上没有导出以太网IC……那用什么命令恢复变砖的主板呢。
MX6SOLO STDPLUS U-Boot> help? - alias for 'help'autoscr - DEPRECATED - use "source" command insteadbase - print or set address offsetbdinfo - print Board Info structurebld_his -boot - boot default, i.e., run 'bootcmd'bootd - boot default, i.e., run 'bootcmd'bootm - boot application image from memoryclk - Clock sub systemcmp - memory compareconinfo - print console devices and informationcp - memory copycrc32 - checksum calculationdestroyenv- destroy enviroment variables stored in mediumecho - echo args to consoleerase - erase FLASH memoryflinfo - print FLASH memory informationgo - start application at address 'addr'help - print online helpi2c - I2C sub-systemiminfo - print header information for application imageimxotp - One-Time Programable sub-systemimxtract- extract a part of a multi-imageitest - return true/false on integer compareloadb - load binary file over serial line (kermit mode)loads - load S-Record file over serial lineloady - load binary file over serial line (ymodem mode)loop - infinite loop on address rangemd - memory displaymm - memory modify (auto-incrementing address)mtest - simple RAM read/write testmw - memory write (fill)nand - NAND sub-systemnboot - boot from NAND devicenm - memory modify (constant address)printenv- print environment variablesprotect - enable or disable FLASH write protectionregul - Regulator sub systemreset - Perform RESET of the CPUrun - run commands in an environment variablesaveenv - save environment variables to persistent storagesaveenv_wjs- print saveenv infosdma - memory transfer using the i.MX SDMA Engine <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<------setenv - set environment variablessleep - delay execution for some timesource - run script from memoryversion - print monitor version有一个sdma命令,好像是从sd卡传输数据?
找了下NXP官方uboot,并没有这个命令,网上也找不到这个命令的详细用法,但是我随便敲了下,想要测试下这个命令看看出现什么结果,却发现这个命令是无效的。因为给出的提示是这样的。
MX6SOLO STDPLUS U-Boot> sdma 1sdma - memory transfer using the i.MX SDMA EngineMX6SOLO STDPLUS U-Boot> sdma 1 1sdma - memory transfer using the i.MX SDMA EngineMX6SOLO STDPLUS U-Boot> sdma 1 1 1SDMA initialization failed.MX6SOLO STDPLUS U-Boot> sdma 1 1 1 1sdma - memory transfer using the i.MX SDMA EngineMX6SOLO STDPLUS U-Boot> sdma 1 1 1 1 1sdma - memory transfer using the i.MX SDMA Engine可以看到这个命令应该是3个参数的命令,但是这一行SDMA initialization failed表示命令失败了。看来没戏,按照之前对开发者的理解,他一定是在uboot发行版本中,把这个功能阉割掉了,或者是根本没实现。
那还有哪些命令可以从外部传输数据呢?
loadb - load binary file over serial line (kermit mode)loady - load binary file over serial line (ymodem mode)从串口传输数据,协议是kermit和ymodem,这俩我很熟悉,以前救路由砖的时候用过,WinXP的超级终端就支持这种文件传输协议。其中一个比另一个传输速率稍快一些。但是快能快到哪?理想状态下115200/8 = 14.4KB/s,实际上达到10KB/s就烧高香了。
虽然速度奇慢,这毕竟是一个救砖的PlanB,在缺少NAND编程器的情况下,也许这两条命令就是最后的救命稻草了。或许我可以从固件升级包提取文件,制作一个最简的rootfs,加上内核,估计也就5MB左右&hellip;&hellip;先通过这个内核引导,然后有了USB支持,就可以用USB传输了。
接下来我还思考了下,通常情况下,制造商如何烧入镜像。我查询了NXP的开发资料,可以配置CPU的BOOTMODE,让CPU从USB引导,然后使用一个叫mfgtools的工具,传输bootstrap镜像到RAM,然后再通过USB或以太网传输文件,写入Flash。这个bootstrap镜像其实就是我刚才所想到的,kernel和精简的rootfs。
这种方法的关键在于如何将CPU配置从USB引导,这其实也是一个问题,因为这个配置是可以被制造商通过烧eFuse区域写死的(或者说OTP区域,One Time Programmable),也就是说,这个USB引导,在工厂生产阶段能用,用完之后把这个配置区域写死,就没人能改变CPU的引导方式了。
在uboot提示符使用md命令查看看了eFuse区域寄存器,确实已经被写死了。除非买一片新的CPU换上去,但是新CPU没有eFuse配置,需要从外部引脚配置BOOTMODE,电路改动难度非常大,几乎不可能完成。所以通过改变BOOTMODE,从USB引导,利用mfgtools烧固件救砖这个思路,没戏了。
我想,我已经有了一个PlanB,就是有提示符的uboot,就算搞成砖,也有办法修复,但是事情事实上远没有这么简单&hellip;&hellip;我发现UBOOT中断引导后,系统每隔60秒就重启。那如果我用串口猫协议传输文件,60秒能传输多少数据!况且还有后面的kernel引导!60秒什么都做不了!
这种情况一定是有看门狗。
看门狗是什么?看门狗是一种预防机制,可以防止CPU或程序异常,导致产品失去正常功能。原理其实很简单,做一个定时器,定时器溢出了,就给CPU发送复位信号。为了防止定时器溢出,就必须有一个程序负责清空定时器,这个环节就叫做“喂狗”。如果因为CPU或程序异常因素,导致这段喂狗程序无法正常运行,那么CPU就会被看门狗无情的复位!
一开始,我觉得可能就是CPU内部集成的看门狗吧,反汇编uboot,把放狗的代码屏蔽掉就好了&hellip;&hellip;用IDA确实找到了一处写看门狗寄存器的代码:
ROM:178037F0 sub_178037F0 ; CODE XREF: sub_17802044+14ROM:178037F0 ; sub_1780229C+1CROM:178037F0 LDR R3, =0x20BC000 <<<<<<<<<<<看门狗1的控制寄存器ROM:178037F4 MOV R2, #4ROM:178037F8 STRH R2, [R3]ROM:178037FC BX LR寄存器0x20BC000在datasheet上就是 WatchdogControl Register (WDOG1_WCR)(这CPU有两个狗),uboot写了狗1的寄存器,写入的4恰好是WDE(Watchdog Enable),没错,跑不了,这个函数绝对叫EnableWatchdog!
可惜当我HACK掉这个函数,把第一句改为BX LR,让其直接返回。实验结果是狗并没有被关闭!后来研究代码发现这段代码根本就没有在启动流程被调用&hellip;&hellip;这段代码的作用其实是ResetCPU(uboot reset命令)。
4、看门狗
没想到费劲研究出的uboot救砖方案,竟被一只疯狗给破坏了!既然不是CPU内部的狗,那就一定是外部的狗!
这回没错,跑不了,肯定是瑞萨那个MCU干的!
首先我想弄清楚他是怎么复位CPU的。这个CPU没有RST引脚,只有一个POR_B引脚,其实就是个低电平的PowerOn Reset,POR引脚通常不是设计用来复位CPU的。系统在刚开始上电时,供电电路电压还不稳定,CPU不能正常启动。这一般就需要由供电芯片的PG(Power Good)引脚输出,来通知CPU的POR引脚。大致可以理解为是电源IC给CPU说:“大哥,我的电压稳定了,你可以正常工作了!”不过,一旦电压失稳,PG电平改变,CPU一样是会复位的!
我自信满满的认为是瑞萨的MCU通过拉低POR_B引脚来复位CPU的,于是用表开始找,找了小半天,竟然没找到,这个POR_B没有与MCU直接相连。
在这里分享个寻线小窍门,数字表调整到欧姆档,SELECT启用短路告警,这样一旦探测到短路的位置,表的蜂鸣器就会哔~~,于是寻找的方法就变成了,一个表笔按在POR_B的测试点上,一个表笔在MCU引脚上划来划去。
可惜没找到!难道不是通过拉低POR_B来实现复位的?
后来我发现,在复位的时候,机器的按钮背光灯,短暂的熄灭了零点几秒,难道复位的方法是关掉整机电源然后再打开!没错,这个MCU一定兼职了电源管理芯片的功能!
于是我开始找那几个电源IC的Datasheet,找到他们的EN使能引脚,然后找这些引脚与MCU的哪些引脚直接相连。
可惜又没找到!这不科学!难道不是直接相连,难道中间串了MOS管或三极管什么的?这没必要啊!难道中间串了电阻,电阻拉高,MCU开漏输出?查了下,使能引脚是高电平有效,那电阻是拉低,MCU输出高电平呗!在MCU附近寻找,果然发现了一些布局类似的电阻,然后你猜怎么着,我真的找到了与所有电源IC的EN引脚相连的MCU引脚!
现在事情清晰了,整套系统的供电都受MCU控制,MCU内部还实现了一只看门狗,来复位整套系统,并且复位的方式是控制所有供电IC的EN引脚。
我想,可以直接把这些供电IC的EN引脚全都改一下,全都拉高,不过这很麻烦。CPU的上电其实是有时序要求的,哪个电压先来哪个电压后来,都是有讲究的。除非是在CPU上电之后再去HACK EN引脚。不过这么一堆EN引脚,贸然去改动硬件来bypass看门狗,说不定还有其他什么我没发现的坑,有一定失败风险,直接在硬件上做改动,难度较高。
除非搞到喂狗指令,不然这个狗是很难绕过去了,我决定先放弃寻找关狗的方案。
5、软件系统
接下来我主要研究的内容就是分析整套软件。分析其软件构成,软件包,库,驱动,内核模块。
看看挂载点
I have no name!@(none) ~$ df -kFilesystem 1K-blocks Used Available Use% Mounted onubi0:rootfs 182808 155908 22064 88% /mdev 86372 0 86372 0% /devnone 5120 12 5108 0% /tmpshm 86372 8 86364 0% /dev/shmrwfs 512 236 276 46% /mnt/rwfsrwfs 512 236 276 46% /varubi1:pss1 5960 64 5556 1% /pss1ubi2:pss2 5960 32 5588 1% /pss2Ubi0:rootfs是根文件系统,他的文件系统是ubifs,这是一套专门为NAND Flash设计的文件系统,具有坏块管理功能。
pss1和pss2里面文件不多,结构一样,估计2是1的备份。
I have no name!@(none) ~$ ls -li /pss1total 52 65 -rwx------ 1 root root 33 Jan 1 00:00 DIAG_PSS_CODING.pss 66 -rwx------ 1 root root 33 Jan 1 00:00 FEATURE_MANAGER_PSS_BLK.pss 67 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_A2DP_ONOFF_STATUS_PSS_BLK.pss 68 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_ONOFF_STATUS_PSS_BLK.pss 69 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_VISIBLE_ONOFF_STATUS_PSS_BLK.pss 119 -rwx------ 1 root root 9 Jan 1 00:00 HMI_EXLAP_SERVER_ONOFF_PSS_BLK.pss 150 -rwx------ 1 root root 2298 Jan 1 00:01 HMI_SYSTEM_APP_CONNECTION_PLIST_PSS_BLK.pss 118 -rwx------ 1 root root 10 Jan 1 00:00 HMI_SYSTEM_SAFECODE_ASSEMBLY_UNLOCK_PSS_BLK.pss 117 -rwx------ 1 root root 9 Jan 1 00:00 HMI_SYSTEM_SAFECODE_REMAINING_ATTEMPT_PSS_BLK.pss 70 -rwx------ 1 root root 28 Jan 1 00:00 HMI_SYSTEM_SETUP_PSS_NEWBLK.pss 71 -rwx------ 1 root root 78 Jan 1 00:00 TM_PSS_BT_FRIENDLY_NAME_PSS_BLK.pss 75 drwx--x--x 2 messageb messageb 1408 Jan 1 00:00 config 90 -rwxr-xr-x 1 messageb messageb 22 Nov 23 2016 hmi_autotest.ini 146 -rw-r--r-- 1 root root 393 Jan 1 00:00 stdplus.iniI have no name!@(none) ~$ ls -li /pss2total 52 65 -rwx------ 1 root root 33 Jan 1 00:00 DIAG_PSS_CODING.pss 66 -rwx------ 1 root root 33 Jan 1 00:00 FEATURE_MANAGER_PSS_BLK.pss 67 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_A2DP_ONOFF_STATUS_PSS_BLK.pss 68 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_ONOFF_STATUS_PSS_BLK.pss 69 -rwx------ 1 root root 9 Jan 1 00:00 HMI_BT_VISIBLE_ONOFF_STATUS_PSS_BLK.pss 70 -rwx------ 1 root root 9 Jan 1 00:00 HMI_EXLAP_SERVER_ONOFF_PSS_BLK.pss 71 -rwx------ 1 root root 2298 Jan 1 00:00 HMI_SYSTEM_APP_CONNECTION_PLIST_PSS_BLK.pss 72 -rwx------ 1 root root 10 Jan 1 00:00 HMI_SYSTEM_SAFECODE_ASSEMBLY_UNLOCK_PSS_BLK.pss 73 -rwx------ 1 root root 9 Jan 1 00:00 HMI_SYSTEM_SAFECODE_REMAINING_ATTEMPT_PSS_BLK.pss 74 -rwx------ 1 root root 28 Jan 1 00:00 HMI_SYSTEM_SETUP_PSS_NEWBLK.pss 75 -rwx------ 1 root root 78 Jan 1 00:00 TM_PSS_BT_FRIENDLY_NAME_PSS_BLK.pss 78 drwxr-xr-x 2 root root 304 Jan 1 00:00 app_data 76 -rwxr-xr-x 1 root root 22 Jan 1 00:00 hmi_autotest.ini 77 -rw-r--r-- 1 root root 393 Jan 1 00:00 stdplus.iniI have no name!@(none) ~$看文件名猜测应该是与软件配置相关的一些东西。
再看看/dev目录,都有什么设备。
I have no name!@(none) ~$ ls /devapm_bios loop7 mxc_vpu ttymxc3console mem mxs_viim ttymxc4cpu_dma_latency mtd0 network_latency ttyp0crypto mtd0ro network_throughput ttyp1event0 mtd1 null tuner_knobevent1 mtd1ro pts ubi0fb mtd2 ptyp0 ubi0_0fb0 mtd2ro ptyp1 ubi1fb1 mtd3 ram0 ubi1_0full mtd3ro ram1 ubi2galcore mtd4 ram2 ubi2_0i2c-0 mtd4ro ram3 ubi_ctrli2c-2 mtd5 random uinputi2c-3 mtd5ro sda urandomkmem mtdblock0 sda1 usbdev1.1kmsg mtdblock1 shm usbdev1.2loop0 mtdblock2 snd v850srqloop1 mtdblock3 spidev0.0 videoloop2 mtdblock4 tracebuf video0loop3 mtdblock5 tty video1loop4 mxc_asrc ttymxc0 video16loop5 mxc_ipu ttymxc1 video17loop6 mxc_mem ttymxc2 zerofb(framebuffer)是显存。
event0和event1可能是键盘和触摸板。
3个i2c接口,用途不明,可能是配置功放芯片,摄像头芯片或者触摸板,收音机等用途。
一个spi接口,通过分析/opt/libHAL.so发现是与MCU通信用的。
tuner_knob,可能与前面板两个旋钮相关。
v850srq,这个看名称就知道肯定也和MCU相关,因为那个瑞萨的MCU代号是RH850,而这个MCU的指令集就是NECV850,IDA恰好支持这个指令集。
video设备可能就是倒车摄像头芯片ADV7182的接口。
再看看etc/rc.d目录,有一些系统引导脚本,文件不多,很好分析。
I have no name!@(none) ~$ ls /etc/rc.d/init.d rc.local rc.serial rcS rc_gpu.Src.conf rc.modules rc.ts rc_mxc.SI have no name!@(none) ~$ ls /etc/rc.d/init.dboa dropbear mdev portmap udevdepmod filesystems mdev_bak settimedevfsd hostname modules smbdhcp hotplug mount-proc-sys sshddhcpd inetd network syslogI have no name!@(none) ~$我可以修改其中的rcS脚本,在里面插入一个read-t 指令,这样我就可以打断Linux系统的引导,来制造一个failsafe模式。这个模式有什么用呢?其实就是为了防止后面的修改出错,导致系统直接崩溃掉了。有这个failsafe模式,我就可以回退修改。例如还没进入终端系统就崩溃了,我只能在uboot模式恢复系统了,会很麻烦的。
但是暂时这个修改没有用,因为需要喂狗程序,这个程序在哪,是哪个程序,我都不能确定&hellip;&hellip;先算是一个思路吧。
看看/opt目录
I have no name!@(none) ~$ ls /optAndroidAuto g_ether.ko mfidaoa_adapter g_file_storage.ko net_windows.shasix.ko g_hid.ko nw_vmf_ctrl.dataudio_proc g_iap_ncm_audio.ko nw_vmf_trace.datbt g_iap_ncm_eap.ko psscamera gresfiles pwr_agentcarlife_daemon hal_init ringtonecarplay_App hmi sc_db.dbcarplay_testmode.sh hmi.bak screenshotcarplayd hmi_autotest.ini sourceme.shcdc_ncm.ko i2cdetect start_carlife.shclear-cache.sh iap2d start_carplay.shconfig iperf start_mdnsd.shconnect_mgr launch.sh stdplus.inidata launch_aa.sh sysupdatediag lib test.shdiag_eol libcidb_sdk.so toolseol_test.wav md_adapter usbnet.koexlap mdnsd vgwfeature_config.ini media vmfftpdup2.sh memtool
这里面都是车机的应用程序,有库,配置,图片字体资源文件,各种脚本&hellip;&hellip;
先看看正在跑的都有哪些程序吧。ps -ef
I have no name!@(none) ~$ ps -efPID USER TIME COMMAND 1 root 0:00 init 2 root 0:00 [kthreadd] 3 root 0:00 [ksoftirqd/0] 4 root 0:00 [kworker/0:0] 5 root 0:00 [kworker/u:0] 6 root 0:00 [migration/0] 7 root 0:00 [khelper] 8 root 0:00 [kworker/u:1] 235 root 0:00 [sync_supers] 237 root 0:00 [bdi-default] 239 root 0:00 [kblockd] 271 root 0:00 [imx6q-ecspi.0] 274 root 0:00 [imx6q-ecspi.1] 281 root 0:00 [khubd] 298 root 0:00 [ipu1_task] 299 root 0:00 [ipu1_task] 327 root 0:00 [usb_wakeup thre] 329 root 0:00 [otg_switch] 341 root 0:00 [kswapd0] 402 root 0:00 [fsnotify_mark] 411 root 0:00 [crypto] 467 root 0:00 [kapmd] 507 root 0:00 [mtdblock0] 512 root 0:00 [mtdblock1] 517 root 0:00 [mtdblock2] 522 root 0:00 [mtdblock3] 527 root 0:00 [mtdblock4] 532 root 0:00 [mtdblock5] 540 root 0:00 [ubi_bgt0d] 572 root 0:00 [vpu_wq] 577 root 0:00 [galcore workque] 578 root 0:00 [kworker/0:1] 579 root 0:00 [galcore daemon ] 580 root 0:00 [galcore daemon ] 646 root 0:00 [scsi_eh_0] 647 root 0:00 [usb-storage] 723 root 0:00 [kworker/u:2] 725 root 0:00 [kworker/0:2] 756 root 0:00 race_daemon sda true /devices/platform/fsl-ehci.0/usb1/1- 788 root 0:00 [ubi_bgt1d] 792 root 0:00 [ubi_bgt2d] 795 root 0:00 [ubifs_bgt1_0] 798 root 0:00 [ubifs_bgt2_0] 808 root 0:00 ./vmf 811 root 0:00 ./pwr_agent -o -v 812 root 0:00 ./sysupdate 825 root 0:00 ./mfid 833 root 0:00 -sh 842 root 0:00 ./vgw 848 root 0:00 [irq/283-atmel_m] 872 root 0:02 ./hmi 874 root 0:03 ./media 876 root 0:00 ./pss 880 root 0:00 ./audio_proc 919 root 0:02 ./bt 921 root 0:00 ./exlap 958 root 0:02 /usr/bin/devicemanager 5 0 /usr/bin 239 393247 1 1 0 0 0 967 root 0:00 [race_daemon] 981 root 0:00 ./diag 983 root 0:00 ./diag_eol 987 root 0:00 ./screenshot 992 root 0:00 [flush-ubifs_1_0] 993 root 0:00 [flush-ubifs_2_0] 998 root 0:00 ./mdnsd -debug 1009 root 0:00 ./connect_mgr 1014 root 0:00 ./carplay_App 1021 root 0:00 ./iap2d 1024 root 0:00 ./carlife_daemon 1026 root 0:00 ./carplayd 1050 root 0:00 {clear-cache.sh} /bin/sh ./clear-cache.sh 1095 root 0:00 [flush-8:0] 1106 root 0:00 sleep 2 1107 root 0:00 ps -ef发现有很多进程,由于名字都是缩写,很难直接猜出这些程序的用途。例如vmf、mfid、vgw、hmi、exlap、diag等等这些都是鬼?他们大多没有-h –help 之类能显示信息的参数可用,想知道他们的用途,估计是要上IDA逆向一下&hellip;&hellip;
经过了几天的研究,我终于知道了部分核心程序的用途。
他这套软件,大部分都是在后台工作的,只有少部分是QT编写的,有界面的。例如hmi和sysupdate。其中hmi体积最大,他就是界面主程序,他包含了所有的图形资源,多国语言字符串。
其他程序基本都没有界面,界面其实都是在hmi中。UI进程和逻辑进程之间使用类似IPC的消息机制,这个机制在这套系统中称为vmf。
那个vmf程序,起到一个消息中转站的作用,vmf可能是Virtual Message Function的缩写?他有Usage信息,显示的是vmffor linux version DOMAIN-SOCKET。
/opt/lib/libvmf_client.so这个就是vmf客户端支持库,很多程序通过调用libvmf_client.so的nw_vmf_send/receive函数来实现跨进程的IPC消息传递,这套消息机制是基于socket。在/tmp/目录有很多127.X.X.X文件,可能与此相关。在文章后面,我将详细分析这套API的原型和消息数据结构。
I have no name!@(none) ~$ ls /tmp127.0.0.1 127.3.215.1 allgorpccomm1127.3.104.1 127.3.219.1 carlife127.3.106.1 127.3.241.1 devmgr_debug.txt127.3.106.2 127.3.246.1 diag_enter_main127.3.106.3 127.3.246.2 diag_initialize_OK127.3.106.4 127.3.40.1 eol_enter_main127.3.106.5 127.3.40.2 hdd127.3.106.6 127.3.40.4 icr_device_process.txt127.3.106.7 127.3.43.1 keyGenerationFile127.3.106.8 127.3.44.1 race127.3.106.9 127.3.74.1 race_key_gen_file.txt127.3.108.1 127.3.74.2 shm_key_gen.txt127.3.112.1 127.4.0.1 shm_key_index.txt127.3.112.2 127.4.2.1 vaf_comm_mirrorlink127.3.151.1 DevMgrRunning.txt var127.3.153.1 MFISocket vmf_trace_startup127.3.153.2 RPCClient1026127.3.213.1 RPCSocketpwr_agent,从名字看,显然是电源管理相关,我一直认为就是这个进程,在不断地与MCU通信,喂狗。
我用IDA把他逆了个遍,他确实有这个动作,但是他只是构造了个消息包,包发给了谁并不知道&hellip;&hellip;他其实不光是电源管理,在/opt/launch.sh脚本中可以发现,脚本执行了vmf hal_init pwr_agent sysupdate mfid,就没有了。其实大多数进程,都是由pwr_agent带起来的,这在IDA逆向中能发现。
.rodata:00011183 ALIGN 4.rodata:00011184 DCD a_Diag+8 ; "".rodata:00011188 DCD a_VgwDevNull21 ; "./vgw > /dev/null 2>&1 &".rodata:0001118C DCD a_PssDevNull21 ; "./pss > /dev/null 2>&1 &".rodata:00011190 DCD a_MediaDevNull2 ; "./media > /dev/null 2>&1 &".rodata:00011194 DCD a_Diag+8 ; "".rodata:00011198 DCD a_Audio_procDev ; "./audio_proc > /dev/null 2>&1 &".rodata:0001119C DCD a_BtDevNull21 ; "./bt > /dev/null 2>&1 &".rodata:000111A0 DCD a_Diag+8 ; "".rodata:000111A4 DCD a_HmiDevNull21 ; "./hmi > /dev/null 2>&1 &".rodata:000111A8 DCD a_WifiDevNull21 ; "./wifi > /dev/null 2>&1 &".rodata:000111AC DCD aCatProcDeferre ; "cat /proc/deferred_initcalls".rodata:000111B0 DCD a_Diag_eolDevNu ; "./diag_eol > /dev/null 2>&1 &".rodata:000111B4 DCD a_Audio_procDev ; "./audio_proc > /dev/null 2>&1 &".rodata:000111B8 DCD a_DiagDevNull21 ; "./diag > /dev/null 2>&1 &".rodata:000111BC DCD a_ScreenshotDev ; "./screenshot > /dev/null 2>&1 &".rodata:000111C0 DCD a_Start_carplay ; " ./start_carplay.sh > /dev/null 2>&1 & ".rodata:000111C4 DCD a_Connect_mgrDe ; "./connect_mgr > /dev/null 2>&1 &".rodata:000111C8 DCD a_Carlife_daemo ; "./carlife_daemon > /dev/null 2>&1 &".rodata:000111CC DCD a_ExlapDevNull2 ; "./exlap > /dev/null 2>&1 &".rodata:000111D0 DCD a_Launch_aa_shD ; "./launch_aa.sh > /dev/null 2>&1 &".rodata:000111D4 DCD a_Net_windows_s ; "./net_windows.sh > /dev/null 2>&1 &".rodata:000111D8 DCD a_ClearCache_sh ; "./clear-cache.sh > /dev/null 2>&1 &".rodata:000111DC DCD a_Start_mdnsd_s ; "./start_mdnsd.sh > /dev/null 2>&1 &"hal_init,这个进程很简单,只是调用了libHAL.so库中的一些初始化函数就结束了。
int __cdecl main(int argc, const char **argv, const char **envp){ int v3; // r0@1 int v4; // r0@1 int v5; // r0@1 v3 = hal_gpio_init(argc, (int)argv, (int)envp); v4 = hal_i2c_init(v3); v5 = hal_spi_init(v4); hal_uart_init(v5); return 0;}vgw,这是关键进程,我发现把他杀了,系统过一会就重启,所以他是喂狗嫌疑对象。通过逆向,发现他调用了libHAL.so里面的spi_ipcl_read、spi_ipcl_write等函数,通过Search And Replace搜索整个opt目录也证实,只有vgw程序调用了上面的spi_ipcl_read/write接口。这个vgw是什么缩写,我没找到,可能是Vehicle Gateway或者VIP Gateway?感觉这种解释不太靠谱&hellip;&hellip;
/opt/lib目录就是这套程序的库文件了。
I have no name!@(none) ~$ ls /opt/libbt libOSAL.solibAirPlay.so libOSAL.so.1libAirPlaySupport.so libOSAL.so.1.0libCarPlayAudio.so libOSAL.so.1.0.0libCarPlayClient.so libdns_sd.solibCarPlayDevice.so libiap2.solibCarPlayPlatform.so libmfi.solibCarPlayPlatformDevice.so libprotobuf-c.solibCarPlayPlatformMFI.so libprotobuf-c.so.1libCarPlayPlatformScreen.so libvmf_client.solibCarPlayPlatformSystem.so libvmf_trace.solibHAL.so libximage.solibHAL.so.1 libximage.so.1libHAL.so.1.0 libximage.so.1.0libHAL.so.1.0.0 libximage.so.1.0.0libHAL.so.1.0.0.bak medialibHAL.so.1.0.0.read mirrorlinklibHAL.so.1.0.0.write screenshot重点关注其中的2个,libOSAL.so和libHAL.so,前者是操作系统支持库,可能是为了方便跨平台开发,将一些系统级API重新封装了一下,例如线程,定时器,互斥锁等。后者是硬件层面的接口,包括uart,spi,gpio,i2c等接口的读写函数封装。其他都是carplay carlifemirrorlink等程序的支持库。
/opt里面很多程序都被strip掉了符号表。在IDA分析时没有符号帮助,很难搞懂一些函数的作用,还好这些程序都调用了日志接口log_optional来打印日志,因此能获知一些函数的真实名字,以及他们的用途。比如下面这个例子:
显然,得知这个函数名字叫pwr_agent_vmf_rcv_handle_round_comm,日志类别是radio_updown。
log_optional的消息打印是受配置文件控制的,这些配置文件以进程名作为区分,位于/opt/config或/pss1/config
例如下面这个pwr_agent的config
I have no name!@(none) ~$ cat /pss1/config/pwr_agent.conf[OPTION]ENABLE=1 <<<<<<<<<<注意这里CATALOG=0FILE=0FUNC=1LINE=0PROCNAME=0TIME=1SEC_DIGIT=2TIME_FMTSTR=%M:%SSAVESD=0[OUTPUT] <<<<<<<<<<注意这个小节start_trap=1OPTION=1INI=1radio_updown=1 <<<<<<<<<<注意这里的名字radio_updownnet_rtc=1VIP=1debug=1health=1DTC=1msg=0sync=0[TEXT]health=39radio_updown=39start_trap=39OPTION=39INI=39DTC=39VIP=39[BACKGROUD]health=49radio_updown=49start_trap=49OPTION=49INI=49DTC=49VIP=49[ATTRIBUTE]health=-1radio_updown=-1start_trap=-1OPTION=-1INI=-1DTC=-1VIP=-1可见有很多开关,控制了哪些debug消息需要打印,哪些不打印。把一些需要的开关打开,可以方便逆向分析工作。主要开关就是ENABLE=1,OUTPUT是类别控制,控制对应的类别的日志要打印出来。
/opt/ftpdup2.sh这个脚本很有意思,他insmod了asix.ko,然后用ifconfig配置了ip地址,还启动了ftp服务。看来是开发人员为了方便网络传输文件留下来的。这个asix.ko是ASIX的usb转以太网芯片的驱动,很多常见的USB转网口的产品都是用ASIX芯片方案,例如绿联的USB百兆网卡。
I have no name!@(none) ~$ cat /opt/ftpdup2.sh#!/bin/sh#insmod mii.ko#insmod usbnet.koinsmod asix.koifconfig eth0 192.168.5.1 upwhile [ $? -ne 0 ]dosleep 1sifconfig eth0 192.168.5.1 updoneecho network up at 192.168.5.1cd /binif [ ! -e /bin/ftpd ]thenln -s busybox ftpdfiif [ ! -e /bin/tcpsvd ]thenln -s busybox tcpsvdficd /opttcpsvd -vE 0.0.0.0 21 ftpd -w &
我试着运行了一下,确实把网卡带起来了&hellip;&hellip;
/opt还有一些usbgadget驱动程序,例如g_ether.ko和g_file_storage.ko,由于这台机器前面板的USB接口实际上是CPU的USB_OTG接口,因此我怀疑开发人员用这个驱动,直接把USBOTG虚拟成MassStorage或者网卡,与开发机用USB线连起来就能传文件了,是不是很有意思&hellip;&hellip;
另外我 |
|