25.21 红米updater-script详解
http://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();
无形参,自解释