查看: 3581|回复: 0

基于nxp MCIMX6S6AVM08AC的汽车电子主板解析之软件系统等设置!

[复制链接]
  • TA的每日心情
    开心
    2021-2-4 17:39
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    发表于 2017-10-17 16:42:49 | 显示全部楼层 |阅读模式
    分享到:
    续接上篇文章:基于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左右……先通过这个内核引导,然后有了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,就算搞成砖,也有办法修复,但是事情事实上远没有这么简单……我发现UBOOT中断引导后,系统每隔60秒就重启。那如果我用串口猫协议传输文件,60秒能传输多少数据!况且还有后面的kernel引导!60秒什么都做不了!
    这种情况一定是有看门狗。
    看门狗是什么?看门狗是一种预防机制,可以防止CPU或程序异常,导致产品失去正常功能。原理其实很简单,做一个定时器,定时器溢出了,就给CPU发送复位信号。为了防止定时器溢出,就必须有一个程序负责清空定时器,这个环节就叫做“喂狗”。如果因为CPU或程序异常因素,导致这段喂狗程序无法正常运行,那么CPU就会被看门狗无情的复位!
    一开始,我觉得可能就是CPU内部集成的看门狗吧,反汇编uboot,把放狗的代码屏蔽掉就好了……用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,让其直接返回。实验结果是狗并没有被关闭!后来研究代码发现这段代码根本就没有在启动流程被调用……这段代码的作用其实是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模式恢复系统了,会很麻烦的。
    但是暂时这个修改没有用,因为需要喂狗程序,这个程序在哪,是哪个程序,我都不能确定……先算是一个思路吧。
    看看/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

    这里面都是车机的应用程序,有库,配置,图片字体资源文件,各种脚本……
    先看看正在跑的都有哪些程序吧。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逆向一下……
    经过了几天的研究,我终于知道了部分核心程序的用途。
    他这套软件,大部分都是在后台工作的,只有少部分是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把他逆了个遍,他确实有这个动作,但是他只是构造了个消息包,包发给了谁并不知道……他其实不光是电源管理,在/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?感觉这种解释不太靠谱……
    /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 &
    我试着运行了一下,确实把网卡带起来了……
    /opt还有一些usbgadget驱动程序,例如g_ether.ko和g_file_storage.ko,由于这台机器前面板的USB接口实际上是CPU的USB_OTG接口,因此我怀疑开发人员用这个驱动,直接把USBOTG虚拟成MassStorage或者网卡,与开发机用USB线连起来就能传文件了,是不是很有意思……
    另外我
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-4-20 04:03 , Processed in 0.133361 second(s), 18 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.