25.21 红米updater-script详解 https://scz.617.cn/android/201404101148.txt A: scz@nsfocus 2014-04-10 下面对红米移动13.0自带META-INF\com\google\android\updater-script进行详解: -------------------------------------------------------------------------- assert(getprop("ro.product.device") == "HM2013022" || getprop("ro.build.product") == "HM2013022"); assert()检查它的参数,如果为真则继续执行,否则中止执行 getprop()取/system/build.prop中的设置 format("ext4", "EMMC", "/dev/block/mmcblk0p3", "0", "/system"); mount("ext4", "EMMC", "/dev/block/mmcblk0p3", "/system"); unmount("/system"); 将/system分区格式化成ext4文件系统、挂载、卸载。如果/system已经格式化成 ext4文件系统,不必再次format()。 package_extract_dir("recovery", "/system"); package_extract_dir("system", "/system"); 将卡刷包中recovery、system目录下的内容释放到/system分区,比如recovery目 录下有etc子目录,释放后出现/system/etc/,而不是/system/recovery/etc/。 package_extract_file("boot.img", "/tmp/boot.img"); 将卡刷包中的boot.img释放成/tmp/boot.img。注意,这个/tmp是Recovery模式下 才有的,Normal模式下没有这个目录。 write_raw_image("/tmp/boot.img", "bootimg"); 灌装BOOTIMG,参看scatter文件。应该是封装: dd if=/tmp/boot.img of=/dev/bootimg ... 第二形参可以是recovery、uboot等等,第一形参换成相应的IMG文件。 delete("/tmp/boot.img"); 删除/tmp/boot.img symlink("mksh", "/system/bin/sh"); 相当于"ln -s mksh /system/bin/sh" symlink("toolbox", "/system/bin/cat", "/system/bin/chmod", ...); 同上,为toolbox创建多个符号链接 set_perm(0, 0, 06755, "/system/xbin/su"); 第一形参对应属主,chown 第二形参对应属组,busybox chgrp 第三形参对应文件权限,chmod set_perm_recursive(0, 2000, 0755, 0644, "/system/vendor/lib/hw"); 类似set_perm(),只不过处理对象扩大成整个目录 第一形参对应属主,chown,0对应root 第二形参对应属组,busybox chgrp,2000对应shell 第三形参对应目录权限,chmod 第四形参对应文件权限,chmod run_program("/system/bin/dd", "if=/dev/zero", "of=/proc/driver/mtd_writeable", "bs=3c", "count=1"); /system/bin/dd if=/dev/zero of=/proc/driver/mtd_writeable bs=3c count=1 有run_program(),前面很多函数都可以不要 show_progress(0.200000, 10); 进度条在10秒内前进整体的20% -------------------------------------------------------------------------- updater-script只是一个描述性脚本,它的解释器是同目录下的update-binary,后者 负责对updater-script的解释执行。 从update-binary的源码中可以看到一些未在updater-script中出现的可用函数: -------------------------------------------------------------------------- void RegisterInstallFunctions() { RegisterFunction("mount", MountFn); RegisterFunction("is_mounted", IsMountedFn); RegisterFunction("unmount", UnmountFn); RegisterFunction("format", FormatFn); RegisterFunction("show_progress", ShowProgressFn); RegisterFunction("set_progress", SetProgressFn); RegisterFunction("delete", DeleteFn); RegisterFunction("delete_recursive", DeleteFn); RegisterFunction("package_extract_dir", PackageExtractDirFn); RegisterFunction("package_extract_file", PackageExtractFileFn); RegisterFunction("symlink", SymlinkFn); RegisterFunction("set_perm", SetPermFn); RegisterFunction("set_perm_recursive", SetPermFn); RegisterFunction("getprop", GetPropFn); RegisterFunction("file_getprop", FileGetPropFn); RegisterFunction("write_raw_image", WriteRawImageFn); RegisterFunction("apply_patch", ApplyPatchFn); RegisterFunction("apply_patch_check", ApplyPatchCheckFn); RegisterFunction("apply_patch_space", ApplyPatchSpaceFn); RegisterFunction("read_file", ReadFileFn); RegisterFunction("sha1_check", Sha1CheckFn); RegisterFunction("wipe_cache", WipeCacheFn); RegisterFunction("ui_print", UIPrintFn); RegisterFunction("run_program", RunProgramFn); } -------------------------------------------------------------------------- is_mounted("/system"); 检查/system分区是否已挂载,一般与assert()配合使用 set_progress(0.200000); show_progress()与set_progress()用来显示进度: printf("progress %f %d\n", frac, sec); printf("set_progress %f\n", frac); 得人工估计frac、sec的值。 delete_recursive("/system/xbin"); 相当于"rm -rf /system/xbin" file_getprop("/system/build.prop", "ro.build.type"); 与getprop()的区别在于可以指定待读取的配置文件 apply_patch(srcfile, tgtfile, tgtsha1, tgtsize, sha1_1, patch_1, ...); 这个函数比较复杂,没完全搞明白,参看/system/etc/install-recovery.sh 第一形参 EMMC:boot:5099520:c3a298b32699be5a07854f3e648b03d6b0b6cfa4 5099520是boot.img的大小 c3a298b32699be5a07854f3e648b03d6b0b6cfa4是boot.img的SHA1 第二形参 EMMC:recovery 第三形参 af16ed0bb3f11f973aa831f9a258dbf58a0474be 这是recovery.img的SHA1 第四形参 5601280 这是recovery.img的大小 第五形参 Patch_1的SHA1 第六形参 Patch_1 apply_patch_check(file, [sha1_1, ...]); 有点不明白,为什么会有可能的第三形参?好像是挨个试,任一匹配即可。 apply_patch_space(bytes); 完全不明白,分配空间用? read_file("/system/build.prop"); 不知道这个函数有什么实际用处,读取文件内容,然后呢? sha1_check(data, sha1_hex, [sha1_hex, ...]); 对一段数据进行SHA1检查,看上去是与read_file()配合使用 wipe_cache(); 自解释 ui_print("anything"); 自解释 -------------------------------------------------------------------------- 红米的update-binary有改动,用IDA逆向分析,多了一个special_factory_reset(): -------------------------------------------------------------------------- void sub_A468() { sub_1B068("mount", sub_A43C); sub_1B068("is_mounted", sub_9E5C); sub_1B068("unmount", sub_9ED4); sub_1B068("format", sub_9E30); sub_1B068("show_progress", sub_9888); sub_1B068("set_progress", sub_9830); sub_1B068("delete", sub_8B60); sub_1B068("delete_recursive", sub_8B60); sub_1B068("package_extract_dir", sub_978C); sub_1B068("package_extract_file", sub_95C8); sub_1B068("symlink", sub_9460); sub_1B068("set_perm", sub_8890); sub_1B068("set_perm_recursive", sub_8890); sub_1B068("getprop", sub_93F8); sub_1B068("file_getprop", sub_8628); sub_1B068("write_raw_image", sub_8F20); sub_1B068("apply_patch", sub_8D7C); sub_1B068("apply_patch_check", sub_8524); sub_1B068("apply_patch_space", sub_85B4); sub_1B068("read_file", sub_8C3C); sub_1B068("sha1_check", sub_81A0); sub_1B068("wipe_cache", sub_8D38); sub_1B068("special_factory_reset", sub_8CF4); sub_1B068("ui_print", sub_8458); sub_1B068("run_program", sub_8320); } -------------------------------------------------------------------------- special_factory_reset(); 无形参,自解释 --------------------------------------------------------------------------