Android sn 号修改

news/2024/11/9 10:06:16/

 SN码是Serial Number的缩写,有时也叫SerialNo,也就是产品序列号,和imed 号一样都是手机的唯一标识符,ODM 厂商都会生成一套自己的SN 规则.要想修改,首先得了解原生的流程.

1,ro.serialno

打开USB 调试模式后,通过命令adb devices,发现输出一段 字符序列号

这是Android 系统默认生成的.

以高通为例,查看下是如何赋值的.

默认值是怎么来的,init 阶段会启动这个脚本文件进行赋值

vendor/qcom/opensource/usb/etc/init.qcom.usb.rcon boot#省略无关代码      write /config/usb_gadget/g1/strings/0x409/serialnumber ${ro.serialno}write /config/usb_gadget/g2/strings/0x409/serialnumber ${ro.serialno} #可以发现读
取的就是ro.serialno号.................exec u:r:vendor_qti_init_shell:s0 -- /vendor/bin/init.qcom.usb.sh

我们发现,Android 启动过后,会先写入serialnumber 节点 为 ro.serialno的值,然后执行下面脚本,判断是否为空,重新写入.

所以我们要保证adb devices 和 ro.serialno 一致的话,必须先写入相关的值,如何定制写入后面会说.

vendor/qcom/opensource/usb/etc/init.qcom.usb.sh# check configfs is mounted or not
if [ -d /config/usb_gadget ]; then# Chip-serial is used for unique MSM identification in Product stringmsm_serial=`cat /sys/devices/soc0/serial_number`;# If MSM serial number is not available, then keep it blank instead of 0x00000000if [ "$msm_serial" != "" ]; thenmsm_serial_hex=`printf %08X $msm_serial`fimachine_type=`cat /sys/devices/soc0/machine`setprop vendor.usb.product_string "$machine_type-$soc_hwplatform _SN:$msm_serial_hex"# ADB requires valid iSerialNumber; if ro.serialno is missing, use dummyserialnumber=`cat /config/usb_gadget/g1/strings/0x409/serialnumber 2> /dev/null`if [ "$serialnumber" == "" ]; thenserialno=1234567echo $serialno > /config/usb_gadget/g1/strings/0x409/serialnumberfisetprop vendor.usb.configfs 1
fi

那么ro.serialno  又是从哪里来的呢

init 进程起来后,后解析系统预设的propery 参数,property_service.cpp

void PropertyInit() {selinux_callback cb;cb.func_audit = PropertyAuditCallback;selinux_set_callback(SELINUX_CB_AUDIT, cb);mkdir("/dev/__properties__", S_IRWXU | S_IXGRP | S_IXOTH);CreateSerializedPropertyInfo();if (__system_property_area_init()) {LOG(FATAL) << "Failed to initialize property area";}if (!property_info_area.LoadDefaultPath()) {LOG(FATAL) << "Failed to load serialized property info file";}// If arguments are passed both on the command line and in DT,// properties set in DT always have priority over the command-line ones.ProcessKernelDt();//解析系统lk 阶段设置的cmdline 参数ProcessKernelCmdline();// Propagate the kernel variables to internal variables// used by init as well as the current required properties.//把解析的参数赋值给对应的propertyExportKernelBootProps();PropertyLoadBootDefaults();
}

我们看command line 是如何解析的,这些网上也有教程

我们查看一个cmdline 参数看下里面有什么

xxxxxx:/ # cat proc/cmdline                                                                                                                                                                           
cgroup_disable=pressure rcupdate.rcu_expedited=1 rcu_nocbs=0-7 kpti=off console=ttyMSM0,115200n8 earlycon=msm_geni_serial,0x4a90000 androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 service_locator.enable=1 swiotlb=2048 vmalloc=115M loop.max_part=7 buildvariant=userdebug androidboot.verifiedbootstate=orange androidboot.keymaster=1 androidboot.vbmeta.device=PARTUUID=6c24e00d-dc5d-b4e7-9c04-f07cbc16f9d2 androidboot.vbmeta.avb_version=1.0 androidboot.vbmeta.device_state=unlocked androidboot.vbmeta.hash_alg=sha256 androidboot.vbmeta.size=7104 androidboot.vbmeta.digest=d1f458cd643e66eb46ebd4f92f96a93f972e1cfa8cd9dbb5251cf8ee8da7ac97 androidboot.vbmeta.invalidate_on_error=yes androidboot.veritymode=enforcing androidboot.bootdevice=4744000.sdhci androidboot.fstab_suffix=emmc androidboot.boot_devices=soc/4744000.sdhci androidboot.serialno=e5f0655 androidboot.serialno2=2222222 androidboot.baseband=msm msm_drm.dsi_display0=qcom,mdss_dsi_ili9881c_eqt_720p_video: androidboot.dtbo_idx=14 androidboot.dtb_idx=9

androidboot.serialno  的值是和 sn 号是一样的,前面也说了sn 的值是ro.serial,那么它们是如何关联起来的呢,看下解析comand lin的就明白了

static void ProcessKernelCmdline() {bool for_emulator = false;ImportKernelCmdline([&](const std::string& key, const std::string& value) {if (key == "qemu") {for_emulator = true;} else if (StartsWith(key, "androidboot.")) {InitPropertySet("ro.boot." + key.substr(12), value);//androidboot.serialno  截取后赋值serial no 的地方}});if (for_emulator) {ImportKernelCmdline([&](const std::string& key, const std::string& value) {// In the emulator, export any kernel option with the "ro.kernel." prefix.InitPropertySet("ro.kernel." + key, value);});}
}

上面我们分析解析后最终赋值的是ro.boot.serialno ,还不是我们想要的ro.serialno,再往下看,原来Google 又做了转换

static void ExportKernelBootProps() {constexpr const char* UNSET = "";struct {const char* src_prop;const char* dst_prop;const char* default_value;} prop_map[] = {// clang-format off{ "ro.boot.serialno",   "ro.serialno",   UNSET, },{ "ro.boot.xxxx",  "ro.xxxx",   UNSET, },{ "ro.boot.mode",       "ro.bootmode",   "unknown", },{ "ro.boot.baseband",   "ro.baseband",   "unknown", },{ "ro.boot.bootloader", "ro.bootloader", "unknown", },{ "ro.boot.hardware",   "ro.hardware",   "unknown", },{ "ro.boot.revision",   "ro.revision",   "0", },// clang-format on};for (const auto& prop : prop_map) {std::string value = GetProperty(prop.src_prop, prop.default_value);if (value != UNSET) InitPropertySet(prop.dst_prop, value);}
}

这个逻辑是把左边的属性值付给右边的,我们可以看出原来ro.serialno  的值是来源于ro.boot.serialno,这样就形成了一整套的SN 赋值流程.

整理下

cmdline->android.serialno->ro.boot.serialno->ro.serialno

2,SN修改

上面分析了sn 号的完成流程,如何修改其实也显而易见了,就是修改cmdline 中 android.serialno 的值.

这就涉及到cmdline 是如何产生,里面的属性是如何拼接的了.

cmdline 中android.serials是在lk(系统启动的引导程序)阶段动态赋值的,同样以高通为例,看下面代码(bootable/bootloader/edk2/)

STATIC CONST CHAR8 *UsbSerialCmdLine = " androidboot.serialno=";/*Update command line: appends boot information to the original commandline*that is taken from boot image header*/
EFI_STATUS
UpdateCmdLine (CONST CHAR8 *CmdLine,CHAR8 *FfbmStr,BOOLEAN Recovery,BOOLEAN AlarmBoot,CONST CHAR8 *VBCmdLine,CHAR8 **FinalCmdLine,UINT32 HeaderVersion)
{// 省略其他代码....CHAR8 StrSerialNum[SERIAL_NUM_SIZE];Status = BoardSerialNum (StrSerialNum, sizeof (StrSerialNum));if (Status != EFI_SUCCESS) {DEBUG ((EFI_D_ERROR, "Error Finding board serial num: %x\n", Status));return Status;}CmdLineLen += AsciiStrLen (UsbSerialCmdLine);CmdLineLen += AsciiStrLen (StrSerialNum);// 拼接android.serialno=StrSerialNum}

通过BoardSerialNum 函数给StrSerialNum  赋值,然后拼接,我们再看下这个函数是如何实现的

EFI_STATUS
BoardSerialNum (CHAR8 *StrSerialNum, UINT32 Len)
{UINT32 SerialNo;static char serialno[NVSN_BUF_LEN + 1] = "";// 可以发现默认serialno 是没有赋值的,所有会走下面高通提供的sn 生成规则if (strlen(serialno) != 0) {AsciiStrnCpy((char *)StrSerialNum, serialno, sizeof(serialno));DEBUG ((DEBUG_INFO, "BoardSerialNum, static serialno: %s.\n", StrSerialNum));} // ODM 厂商如果想改写自己的规则,就在这里加else 判断,生成自己的一套规则else {if (CardInfo->GetCardInfo (CardInfo, &CardInfoData) == EFI_SUCCESS) {if (Type == UFS) {Status = gBS->CalculateCrc32 (CardInfoData.product_serial_num,CardInfoData.serial_num_len, &SerialNo);if (Status != EFI_SUCCESS) {DEBUG ((EFI_D_ERROR,"Error calculating Crc of the unicode serial number: %x\n",Status));return Status;}AsciiSPrint (StrSerialNum, Len, "%x", SerialNo);} else {AsciiSPrint (StrSerialNum, Len, "%x",*(UINT32 *)CardInfoData.product_serial_num);}/* adb is case sensitive, convert the serial number to lower case* to maintain uniformity across the system. */ToLower (StrSerialNum);}}return Status;
}

  ODM 厂商如果想改写自己的规则,就在上面加else 判断,生成自己的一套规则,赋值StrSerialNum 即可

ps:如果需要在lk 阶段设置也一些固定的property 或者动态的property ,那么可以参考serialno 流程自己加一个属于自己的property .

当然固定的property 只需要在mk,BOARD_KERNEL_CMDLINE 后面拼接自己的就ok 啦,

总结:

1,电脑端 adb devices 的值来源于节点 /config/usb_gadget/g1/strings/0x409/serialnumber,如果修改ro.serialno 值过后,发现与adb devices 显示的不一致,大概率是因为没有重新写入该节点的值.

2,ro.serialno 值系统默认来源于lk 阶段设置的cmdline,该值在lk 阶段会动态写入.

参考:输入adb devices 显示设备序列号_学习中的农民工的博客-CSDN博客_adb devices序列号


http://www.ppmy.cn/news/833863.html

相关文章

Spring Security 验证码

原理、存在问题、解决思路 我们知道Spring Security是通过过滤器链来完成了&#xff0c;所以它的解决方案是创建一个过滤器放到Security的过滤器链中&#xff0c;在自定义的过滤器中比较验证码 1 添加依赖&#xff08;生成验证码&#xff09; <!--引入hutool--> <de…

c语言sn求和问题

第一种&#xff1a;求Snaaaaaa…aa…aaa&#xff08;有n个a&#xff09;之值&#xff0c;其中a是一个数字&#xff0c;为2。 例如&#xff0c;n5时222222222222222&#xff0c;n由键盘输入。 此想法是先用循环计算出第n个数有几个a&#xff0c;再把前面的所有数相加 第二种&…

unpkg 与 npm 的基本介绍

目录 定义 特点 原理 使用 npm安装流程 npm install npm update registry 区别 总结 定义 UNPKG是一个基于npm registry 的静态资源 CDN 服务&#xff0c;它可以快速获取和使用任何JavaScript包&#xff0c;无需安装任何软件或包。UNPKG可以从NPM仓库中获取任何包&am…

RabbitMQ集群搭建与高可用实现(未完待续)

文章目录 一、RabbitMQ集群概述1、为什么要使用RabbitMQ集群2、RabbitMQ如何支持集群3、RabbitMQ的节点类型 二、普通集群1、什么是普通集群2、Docker搭建普通集群模式&#xff08;1&#xff09;安装docker&#xff08;2&#xff09;安装RabbitMQ&#xff08;3&#xff09;检验…

Acrobat Pro DC 18.011.20040 完整破解版

此版特点 by vposy # 集成AMTLIB模拟授权(v0.9.2)&#xff0c;免序列号&#xff0c;破解激活永久授权完整版&#xff01; # 集成最新AAMv10(CS10)/ACCC SP&#xff0c;集成软件所需的VC运行库&#xff1b; # 移除自动更新&#xff0c;移除试用提示&#xff0c;移除菜单更新&am…

最好用的pdf阅读软件 Acrobat Reader DC安装教程(无需破解)

下载在线安装的小文件 直通车 若无法打开&#xff08;FQ&#xff09;可以下载我已经下载好了的 https://pan.baidu.com/s/1jzd8CnB4sHLCCwQvztLmYg 就这个小文件&#xff0c;双击便会在线下载安装。默认安装在C盘 由于我已经安装了&#xff0c;所以只是检测我的是否为最新…

Soft-ICE使用说明及实例——破解ACDSee

http://blog.csdn.net/he_rong/archive/2004/06/25/25906.aspx 为了以后说话方便, 这里把 Soft-ICE 的一些简单使用方法说一下, 以免不通 E 文的同志们找不到中文的 Soft-ICE 说明而抓瞎.   Soft-ICE 由三部分 (以后说的 Soft-ICE, 如果不加特殊说明, 均指 Soft-ICE for Wind…

ACDSee Pro 6.0.169 (x86) crack by XenoCoder

http://www.datafilehost.com/download-f12967bb.html