21款凯美瑞车机系统安装软件及OTA升级包浅析

概要

本文分两个部分:
1、分析21款凯美瑞车机系统安装软件;
2、浅析OTA升级包,以车机固件v1.000062版本为例。
声明:
1、本文刷机包来源于 西窗浪人分享 https://www.bigxd.com/2023/04/1093.html
2、解包工具来源:https://github.com/bassrock/AVIC-NEX

一、安装软件教程

前言

21款凯美瑞车整体体验尚可,但是对车机不甚满意,尝试各种方法无果,为了这个车机也是操碎了心。无意间发现网上有卖这车机的emmc数据,于是购买了一份来研究。

车机配置

通过解析emmc数据,发现车机硬件配置:采用恩智浦的I.MX6Q处理器,辅以 4GB内存、32GB硬盘,集成4G上网模块,运行深度定制的安卓7.1.2-user版本系统,这个配置在合资车中还算不错。

进入正题

深入分析emmc数据,发现系统脚本有打开和关闭adb 的脚本,脚本比较简单就不具体分析了,代码如下:
打开adb脚本:role_to_adb.sh

#!/bin/bash

#CDP CB1 pin
echo 0 > /sys/class/gpio/gpio145/value
sleep 1

#start adbd
echo 1 > /sys/class/gpio/gpio34/value
setprop sys.usb.config mtp,adb
setprop persist.sys.usb.config adb
setprop sys.usb.config adb
setprop sys.usb.state adb

echo 0 > /sys/class/gpio/gpio111/value

关闭adb的脚本:role_to_dio.sh

#!/bin/bash

#CDP CB1 pin
echo 1 > /sys/class/gpio/gpio145/value

#stop adbd
echo 0 > /sys/class/gpio/gpio34/value
echo 1 > /sys/class/gpio/gpio111/value

通过这两个脚本就可以分析,系统是有打开adb的方法的,只是没发现而已,一般隐藏菜单都是在系统设置里面,于是分析系统app,找到setting.apk,反编译定位到jp.pioneer.ceam.setting.debugmode,具体代码如下:

package jp.pioneer.ceam.setting.debugmode;

import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.lang.ref.WeakReference;
import jp.pioneer.ceam.KeyManager.KeyManagerController;
import jp.pioneer.ceam.KeyManager.KeyManagerListener;

/* compiled from: DebugMode_PasswordInput.java */
/* loaded from: classes.dex */
public class U extends Fragment {

    /* renamed from: a  reason: collision with root package name */
    private static String f871a = "DebugMode_PasswordInput";

    /* renamed from: b  reason: collision with root package name */
    private static String f872b = "piodevelopdbg";

    /* renamed from: c  reason: collision with root package name */
    private TextView f873c;
    private EditText d;
    private Button e = null;
    private KeyManagerListener f = new Q(this);
    WeakReference<KeyManagerListener> g = new WeakReference<>(this.f);

    /* JADX INFO: Access modifiers changed from: private */
    public void c() {
        Log.d(f871a, "DebugMode_PasswordInput transactionToMainFrag");
        try {
            FragmentTransaction beginTransaction = getFragmentManager().beginTransaction();
            beginTransaction.replace(getId(), (P) P.class.newInstance());
            beginTransaction.addToBackStack(null);
            beginTransaction.commit();
        } catch (IllegalAccessException | InstantiationException unused) {
        }
    }

    @Override // android.app.Fragment
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        Log.d(f871a, "DebugMode_PasswordInput onCreate");
    }

    @Override // android.app.Fragment
    public View onCreateView(LayoutInflater layoutInflater, ViewGroup viewGroup, Bundle bundle) {
        Log.d(f871a, "DebugMode_PasswordInput onCreateView");
        ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(-1, -1);
        RelativeLayout relativeLayout = new RelativeLayout(getContext());
        relativeLayout.setLayoutParams(layoutParams);
        this.f873c = new TextView(getContext());
        this.f873c.setWidth(200);
        this.f873c.setHeight(50);
        this.f873c.setX(100.0f);
        this.f873c.setY(100.0f);
        this.f873c.setTextColor(-1);
        this.f873c.setTextSize(20.0f);
        relativeLayout.addView(this.f873c);
        this.f873c.setGravity(17);
        this.f873c.setText("请输入密码:");
        this.e = new Button(getContext());
        this.e.setX(880.0f);
        this.e.setY(100.0f);
        this.e.setWidth(150);
        this.e.setHeight(50);
        relativeLayout.addView(this.e);
        this.e.setText("确定");
        this.d = new EditText(getContext());
        this.d.setX(300.0f);
        this.d.setY(100.0f);
        this.d.setWidth(580);
        this.d.setHeight(50);
        relativeLayout.addView(this.d);
        this.d.setImeOptions(6);
        this.d.setEms(10);
        this.d.setSingleLine();
        return relativeLayout;
    }

    @Override // android.app.Fragment
    public void onDestroy() {
        super.onDestroy();
        Log.d(f871a, "DebugMode_PasswordInput onDestroy");
    }

    @Override // android.app.Fragment
    public void onDestroyView() {
        super.onDestroyView();
        this.f873c = null;
        this.d = null;
        this.e = null;
        Log.d(f871a, "DebugMode_PasswordInput onDestroyView");
    }

    @Override // android.app.Fragment
    public void onPause() {
        super.onPause();
        Log.d(f871a, "DebugMode_PasswordInput onPause");
    }

    @Override // android.app.Fragment
    public void onResume() {
        super.onResume();
        Log.d(f871a, "DebugMode_PasswordInput onResume");
        this.e.setOnClickListener(new S(this));
        this.d.setOnEditorActionListener(new T(this));
    }

    @Override // android.app.Fragment
    public void onStart() {
        super.onStart();
        KeyManagerController.getInstance(getContext()).registerKeyManagerListener(this.g, -1);
        Log.d(f871a, "DebugMode_PasswordInput onStart");
    }

    @Override // android.app.Fragment
    public void onStop() {
        super.onStop();
        KeyManagerController.getInstance(getContext()).unregisterKeyManagerListener(this.g);
        Log.d(f871a, "DebugMode_PasswordInput onStop");
    }
}

分析代码就找到了进入诊断模式的密码为:piodevelopdbg ,进一步分析知道,打开车机设置——系统——OSS——系统信息——连续点击蓝牙地址 10 次跳出密码框,输入以上密码就可以进去了。如图:
输入密码界面
诊断模式界面
点击ADB On USB 就可以打开adb调试,满天欢喜使用双公头数据线连接电脑安装软件,给我来了个报错,错误代码如下:
Performing Streamed Install
adb: failed to install D:\BaiduNetdiskDownload\qqmusiccar_1.9.8.22.apk: Failure [INSTALL_FAILED_VERIFICATION_FAILURE: app is not in the whitelist. packageName:com.tencent.qqmusiccar]

居然有白名单验证,查看emmc数据,发现白名单文件在system\etcwhitelistapps.txt里面,得替换系统文件才行,由于是安卓7.1.2系统,有分区验证,打开原生安卓设置,没有oem选项,adb 无法打开fastboot模式。尝试三方root软件无果,目前只能安装白名单里面的软件,或者卸载白名单内三方软件,修改包名(跳转)安装其他三方软件,网上有方法这里就不再赘述。

二、浅析OTA升级包解包打包(未测试通过)

adb方式走不通,网上有大佬分享的刷机包,于是下载来看看。
刷机包格式与安卓常用的刷机包不一样,无法使用常规方式解包,网上一搜,国外有大佬研究过先锋的安卓导航系统,于是下载来学习解包。
解包工具来源:https://github.com/bassrock/AVIC-NEX

根据21款凯美瑞车型刷机文件夹NVF-9108ZT,修改NVF.sh脚本,关键代码如下:

#this function is called when system is not Linux, user is not root, or user did not specify a file
function usage() {
  echo "usage:"
  echo "  NVF.sh /path_to/firmware.zip [NVF Model] [NVF firmware version]"
  echo "where NVF Model = 9108"
  echo "where NVF firmware version = 190" 
  exit
}
function generateVERFile() {
	originalVerFile=$1
	prgFile=$2

	dd if="$originalVerFile" of="$originalVerFile.part1" bs=172 skip=0 count=1
	
	SIZE="$(stat -c%s $prgFile)"
	echo "$prgFile size is: $SIZE"
	UNSWAPPEDHEXSIZE="$(printf '%x\n' $SIZE)"
	vSIZE="$UNSWAPPEDHEXSIZE"
	SWAPPEDHEXSIZE="${vSIZE:6:2}${vSIZE:4:2}${vSIZE:2:2}${vSIZE:0:2}"
	LEN=$(echo ${#SWAPPEDHEXSIZE})
	if [ $LEN -eq 6 ]; then
        SWAPPEDHEXSIZE=${SWAPPEDHEXSIZE}00
	fi
	UNSWAPPEDHEXCRC="$(crc32 $prgFile)"
	vCRC="$UNSWAPPEDHEXCRC"
	SWAPPEDHEXCRC="${vCRC:6:2}${vCRC:4:2}${vCRC:2:2}${vCRC:0:2}"

	echo "$prgFile Unswapped prg size hex is: $UNSWAPPEDHEXSIZE"
	echo "$prgFile Swapped prg size hex is: $SWAPPEDHEXSIZE"
	echo "$prgFile Unswapped prg crc hex is: $UNSWAPPEDHEXCRC"
	echo "$prgFile Swapped prg crc hex is: $SWAPPEDHEXCRC"
	
	#perl -e "print pack 'H*', '${defaultheaderver}${SWAPPEDHEXSIZE}${SWAPPEDHEXCRC}A55A5AA5'" > PJ${version}PLT.VERSTART

	
	perl -e "print pack 'H*', '${SWAPPEDHEXSIZE}${SWAPPEDHEXCRC}A55A5AA5'" > "$originalVerFile.part2"

	cat "$originalVerFile.part1" "$originalVerFile.part2" > "$originalVerFile.combined"



	UNSWAPPEDHEXCRC="$(crc32 $originalVerFile.combined)"
	vCRC="$UNSWAPPEDHEXCRC"
	SWAPPEDHEXCRC="${vCRC:6:2}${vCRC:4:2}${vCRC:2:2}${vCRC:0:2}"
	echo "$originalVerFile.combined Unswapped verstart crc hex is: $UNSWAPPEDHEXCRC"
	echo "$originalVerFile.combined Swapped verstart crc hex is: $SWAPPEDHEXCRC"

	perl -e "print pack 'H*', '${SWAPPEDHEXCRC}'" > "$originalVerFile.combined1"
	
	cat "$originalVerFile.combined" "$originalVerFile.combined1" > "$originalVerFile.new"
	

	
	mv "$originalVerFile.new" "$originalVerFile"
}

function generatePRGFile() {
	originalPRGFile=$1
	imgToMakePRG=$2

	dd if=$originalPRGFile of=originalPRGFile.header bs=4 skip=3 count=125
	#get image size
	# for mac
	# SIZE="$(stat -f%z PJ${version}PLT.IMG)"
	#for linux
	SIZE="$(stat -c%s ${imgToMakePRG})"
	echo "${imgToMakePRG} size is: $SIZE"
	
	#We have to swap the hex values from big endian to little endian cause the ZT is arm.
	UNSWAPPEDHEXSIZE="$(printf '%x\n' $SIZE)"
	vSIZE="$UNSWAPPEDHEXSIZE"
	SWAPPEDHEXSIZE="${vSIZE:6:2}${vSIZE:4:2}${vSIZE:2:2}${vSIZE:0:2}"	
	LEN=$(echo ${#SWAPPEDHEXSIZE})
	if [ $LEN -eq 6 ]; then
        SWAPPEDHEXSIZE=${SWAPPEDHEXSIZE}00
	fi
	UNSWAPPEDHEXCRC="$(crc32 ${imgToMakePRG})"
	vCRC="$UNSWAPPEDHEXCRC"
	SWAPPEDHEXCRC="${vCRC:6:2}${vCRC:4:2}${vCRC:2:2}${vCRC:0:2}"

	echo "${imgToMakePRG} Unswapped size hex is: $UNSWAPPEDHEXSIZE"
	echo "${imgToMakePRG} Swapped size hex is: $SWAPPEDHEXSIZE"
	echo "${imgToMakePRG} Unswapped crc hex is: $UNSWAPPEDHEXCRC"
	echo "${imgToMakePRG} Swapped crc hex is: $SWAPPEDHEXCRC"
	
	#create new header
	perl -e "print pack 'H*', 'A55A5AA5${SWAPPEDHEXSIZE}${SWAPPEDHEXCRC}'" > firstheaderhalf.header
	cat firstheaderhalf.header originalPRGFile.header "$imgToMakePRG" > "$originalPRGFile.new"
	rm -rf firstheaderhalf.header
	rm -rf originalPRGFile.header
	
	rm -rf "$originalPRGFile"
	rm -rf "$imgToMakePRG"
	mv "$originalPRGFile.new" "$originalPRGFile"
}

function createImgFile() {
	prgFile=$1
	newImgFile=$2		
	dd if="$prgFile" of="$newImgFile" bs=512 skip=1

修改后打包即可。这种方式目前未走通,最后刷机校验有点问题,有时间折腾再续…

小结

**提示: 1.有兴趣的可以继续研究刷机方式,以及反汇编libNPSysCtrlHandler.so 文件,找到正确的TESTMODE.KEY进入工厂模式绕过验证刷机。 2、目前西窗浪人已研究出:一条代码关闭APP白名单配置,任意安装APP**

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
OTA(Over-the-Air)是一种通过无线网络自动下载和安装软件更新的方式。在安卓系统中,OTA升级包通过这种方式提供给用户。以下是关于安卓OTA升级包下载的回答。 首先,安卓OTA升级包是由手机制造商或者操作系统开发者推出的新软件版本。当含新功能、修复漏洞或者改进性能时,他们会将这些更新封装到OTA升级包中并通过无线网络分发给用户。 要下载安卓OTA升级包,用户需要确保手机连接到互联网。当有新的OTA升级包可用时,手机会自动收到通知。用户可以通过点击通知或者前往手机设置中的"系统更新"选项来查看和下载升级包。 在OTA升级包下载中,用户需要确保手机电量足够,并且连接到一个稳定的Wi-Fi网络,以避免下载中断。OTA升级包通常是大型文件,使用Wi-Fi下载不仅更快,还能避免使用手机数据。 用户下载OTA升级包后,手机会自动进行下载和安装。这个过程可能需要一些时间,取决于升级包的大小和手机性能。在下载和安装过程中,用户可以继续正常使用手机,但最好不要进行其他大型网络下载或者占用手机资源过多的操作。 升级完成后,手机会自动重启并应用新的升级。用户可以在设置中查看系统的新特性和改进,以及修复的漏洞。确保在升级前备份重要数据是一个明智的选择,以防万一升级过程中出现问题。 总的来说,安卓OTA升级包下载是一种方便的方式,使用户能够及时获得最新的软件功能和安全补丁。通过连接到互联网,确保足够的电量和稳定的Wi-Fi连接,用户可以轻松下载和安装OTA升级包,并提升手机的性能和安全性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值