def find_partconfig(self, cf): partconfig_id = None defaultprop = cf.get_file('default.prop') if defaultprop: lines = fileio.bytes_to_lines(defaultprop.content) for line in lines: if line.startswith('ro.patcher.patched'): partconfig_id = line.partition('=')[1] mountscript = cf.get_file('init.multiboot.mounting.sh') if mountscript: lines = fileio.bytes_to_lines(mountscript.content) for line in lines: if line.startswith('TARGET_DATA='): match = re.search(r'/raw-data/([^/"]+)', line) if match: partconfig_id = match.group(1) configs = partitionconfigs.get() for config in configs: if config.id == partconfig_id: return config return None
def modify_init_rc(cpiofile): cpioentry = cpiofile.get_file('init.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() in_mediaserver = False for line in lines: if re.search(r"^.*setprop.*selinux.reload_policy.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif 'check_icd' in line: buf += fileio.encode(re.sub(r"^", "#", line)) elif version == 'kk44' and \ line.startswith('service'): in_mediaserver = '/system/bin/mediaserver' in line buf += fileio.encode(line) elif in_mediaserver and re.search(r'^\s*user', line): buf += fileio.encode(fileio.whitespace(line) + 'user root\n') else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_rc(cpiofile): cpioentry = cpiofile.get_file('init.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if re.search(r"mkdir /system(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/system", "/raw-system", line)) elif re.search(r"mkdir /data(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/data", "/raw-data", line)) elif re.search(r"mkdir /cache(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/cache", "/raw-cache", line)) elif 'yaffs2' in line: buf += fileio.encode(re.sub(r"^", "#", line)) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_rc(cpiofile): cpioentry = cpiofile.get_file('init.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if 'export ANDROID_ROOT' in line: buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "export ANDROID_CACHE /cache\n") elif re.search(r"mkdir /system(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/system", "/raw-system", line)) elif re.search(r"mkdir /data(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/data", "/raw-data", line)) elif re.search(r"mkdir /cache(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/cache", "/raw-cache", line)) elif 'yaffs2' in line: buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^.*setprop.*selinux.reload_policy.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file("init.target.rc") lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if re.search(r"^\s+wait\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+check_fs\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount\s+ext4\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount_all\s+fstab.jgedlte.*$", line) and re.search( r"^on\s+fs(_selinux)?.*$", previous_line ): buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") else: buf += fileio.encode(line) previous_line = line cpioentry.set_content(buf)
def modify_fstab(cpiofile, partition_config): # Ignore all contents for TouchWiz cpioentry = cpiofile.get_file('fstab.qcom') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() system = "/dev/block/platform/msm_sdcc.1/by-name/system /raw-system ext4 ro,errors=panic wait\n" cache = "/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 nosuid,nodev,barrier=1 wait,check\n" data = "/dev/block/platform/msm_sdcc.1/by-name/userdata /raw-data ext4 nosuid,nodev,noatime,noauto_da_alloc,discard,journal_async_commit,errors=panic wait,check,encryptable=footer\n" system_fourth = 'ro,barrier=1,errors=panic' system_fifth = 'wait' cache_fourth = 'nosuid,nodev,barrier=1' cache_fifth = 'wait,check' # Target cache on /system partition target_cache_on_system = "/dev/block/platform/msm_sdcc.1/by-name/system /raw-system ext4 %s %s\n" % (cache_fourth, cache_fifth) # Target system on /cache partition target_system_on_cache = "/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 %s %s\n" % (system_fourth, system_fifth) # Target system on /data partition target_system_on_data = "/dev/block/platform/msm_sdcc.1/by-name/userdata /raw-data ext4 %s %s\n" % (system_fourth, system_fifth) has_cache_line = False for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/system\s+.*$", line): if '/raw-system' in partition_config.target_cache: buf += fileio.encode(target_cache_on_system) else: buf += fileio.encode(system) elif re.search(r"^/dev[^\s]+\s+/cache\s+.*$", line): if '/raw-cache' in partition_config.target_system: buf += fileio.encode(target_system_on_cache) else: buf += fileio.encode(cache) has_cache_line = True elif re.search(r"^/dev[^\s]+\s+/data\s+.*$", line): if '/raw-data' in partition_config.target_system: buf += fileio.encode(target_system_on_data) else: buf += fileio.encode(data) else: buf += fileio.encode(line) if not has_cache_line: if '/raw-cache' in partition_config.target_system: buf += fileio.encode(target_system_on_cache) else: buf += fileio.encode(cache) cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file("init.target.rc") lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if "init.dualboot.mounting.sh" in line: buf += fileio.encode(re.sub("init.dualboot.mounting.sh", "init.multiboot.mounting.sh", line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_MSM8960_lpm_rc(cpiofile): cpioentry = cpiofile.get_file('MSM8960_lpm.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if re.search(r"^\s+mount.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file('init.target.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if 'init.dualboot.mounting.sh' in line: buf += fileio.encode(line.replace('init.dualboot.mounting.sh', 'init.multiboot.mounting.sh')) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_qcom_rc(cpiofile): cpioentry = cpiofile.get_file('init.qcom.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: # Change /data/media to /raw-data/media if re.search(r"/data/media(\s|$)", line): buf += fileio.encode(re.sub('/data/media', '/raw-data/media', line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file('init.target.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if 'init.dualboot.mounting.sh' in line: buf += fileio.encode( line.replace('init.dualboot.mounting.sh', 'init.multiboot.mounting.sh')) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_qcom_rc(cpiofile): for i in ["init.qcom.rc", "init.jgedlte.rc"]: cpioentry = cpiofile.get_file(i) lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: # Change /data/media to /raw-data/media if re.search(r"/data/media(\s|$)", line): buf += fileio.encode(re.sub("/data/media", "/raw-data/media", line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_MSM8960_lpm_rc(cpiofile): if version == 'kk44': return cpioentry = cpiofile.get_file('MSM8960_lpm.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if re.search(r"^\s+mount.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_ueventd_rc(cpiofile): if version != 'kk44': return cpioentry = cpiofile.get_file('ueventd.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if '/dev/snd/*' in line: buf += fileio.encode(line.replace('0660', '0666')) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_target_rc(cpiofile, filename='init.target.rc', insert_apnhlos=False, insert_mdm=False): cpioentry = cpiofile.get_file(filename) lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if re.search(r"^\s+wait\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+check_fs\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount\s+ext4\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount_all\s+(\./)?fstab\..*$", line): buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + common.EXEC_MOUNT) elif re.search(r"/data/media(\s|$)", line): buf += fileio.encode( re.sub('/data/media', '/raw-data/media', line)) elif re.search(r"^\s+setprop\s+ro.crypto.fuse_sdcard\s+true", line): buf += fileio.encode(line) voldargs = 'shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337' if insert_apnhlos: buf += fileio.encode(fileio.whitespace(line) + "wait %s\n" % APNHLOS_PART) buf += fileio.encode(fileio.whitespace(line) + "mount vfat %s /firmware ro %s\n" % (APNHLOS_PART, voldargs)) if insert_mdm: buf += fileio.encode(fileio.whitespace(line) + "wait %s\n" % MDM_PART) buf += fileio.encode(fileio.whitespace(line) + "mount vfat %s /firmware-mdm ro %s\n" % (MDM_PART, voldargs)) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_fstab(cpiofile, partition_config): cpioentry = cpiofile.get_file('fstab.hammerhead') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() system_fourth = 'ro,barrier=1' system_fifth = 'wait' cache_fourth = 'noatime,nosuid,nodev,barrier=1,data=ordered,noauto_da_alloc,journal_async_commit,errors=panic' cache_fifth = 'wait,check' for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/raw-system\s+.*$", line): if '/raw-system' in partition_config.target_cache: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], cache_fourth, cache_fifth) buf += fileio.encode(line) elif re.search(r"^/dev[^\s]+\s+/raw-cache\s+.*$", line): if '/raw-cache' in partition_config.target_system: # /raw-cache needs to always be mounted rw so OpenDelta can write to # /cache/recovery args = system_fourth if 'ro' in args: args = re.sub('ro', 'rw', args) else: args = 'rw,' + args r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], args, system_fifth) buf += fileio.encode(line) elif re.search(r"^/dev[^\s]+\s+/raw-data\s+.*$", line): if '/raw-data' in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(line) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_fstab(cpiofile, partition_config): cpioentry = cpiofile.get_file('fstab.g2') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() system_fourth = 'ro,barrier=1' system_fifth = 'wait' cache_fourth = 'nosuid,nodev,barrier=1,noauto_da_alloc,errors=continue' cache_fifth = 'wait' for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/system\s+.*$", line): temp = re.sub("\s/system\s", " /raw-system ", line) if '/raw-system' in partition_config.target_cache: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], cache_fourth, cache_fifth) buf += fileio.encode(temp) elif re.search(r"^/dev[^\s]+\s+/cache\s+.*$", line): temp = re.sub("\s/cache\s", " /raw-cache ", line) if '/raw-cache' in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(temp) elif re.search(r"^/dev[^\s]+\s+/data\s+.*$", line): temp = re.sub("\s/data\s", " /raw-data ", line) if '/raw-data' in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(temp) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_init_qcom_rc(cpiofile): cpioentry = cpiofile.get_file('init.qcom.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: if 'export EMULATED_STORAGE_TARGET' in line: buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "export EXTERNAL_SD /storage/sdcard1\n") # Change /data/media to /raw-data/media elif re.search(r"/data/media(\s|$)", line): buf += fileio.encode(re.sub('/data/media', '/raw-data/media', line)) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_fstab(cpiofile, partition_config): cpioentry = cpiofile.get_file("fstab.qcom") lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() system_fourth = "ro,barrier=1,errors=panic" system_fifth = "wait" cache_fourth = "noatime,nosuid,nodev,journal_async_commit" cache_fifth = "wait,check" for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/raw-system\s+.*$", line): if "/raw-system" in partition_config.target_cache: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], cache_fourth, cache_fifth) buf += fileio.encode(line) elif re.search(r"^/dev[^\s]+\s+/raw-cache\s+.*$", line): if "/raw-cache" in partition_config.target_system: # /raw-cache needs to always be mounted rw so OpenDelta can write to # /cache/recovery args = system_fourth if "ro" in args: args = re.sub("ro", "rw", args) else: args = "rw," + args r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], args, system_fifth) buf += fileio.encode(line) elif re.search(r"^/dev[^\s]+\s+/raw-data\s+.*$", line): if "/raw-data" in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", line) line = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(line) else: buf += fileio.encode(line) cpioentry.set_content(buf)
def modify_init_rc(cpiofile): cpioentry = cpiofile.get_file('init.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if version == 'kk44' \ and re.search(r"mount.*/system", line) \ and re.search(r"on\s+charger", previous_line): buf += fileio.encode(" mount_all fstab.jgedlte\n") buf += fileio.encode(" " + common.EXEC_MOUNT) else: buf += fileio.encode(line) previous_line = line cpioentry.content = buf
def modify_init_qcom_rc(cpiofile, additional=None): files = ['init.qcom.rc'] if additional: files.extend(additional) for f in files: cpioentry = cpiofile.get_file(f) lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: # Change /data/media to /raw-data/media if re.search(r"/data/media(\s|$)", line): buf += fileio.encode( re.sub('/data/media', '/raw-data/media', line)) else: buf += fileio.encode(line) cpioentry.content = buf
def modify_ueventd_qcom_rc(cpiofile): if version != 'kk44': return cpioentry = cpiofile.get_file('ueventd.qcom.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() for line in lines: # More funny business: even with mm-qcamera-daemon running as root, # the daemon and the default camera application are unable access the # camera hardware unless it's writable to everyone. Baffles me... # # More, more funny business: chmod'ing the /dev/video* devices to # anything while mm-qcamera-daemon is running causes a kernel panic. # **Wonderful** /s if '/dev/video*' in line: buf += fileio.encode(line.replace('0660', '0666')) elif '/dev/media*' in line: buf += fileio.encode(line.replace('0660', '0666')) elif '/dev/v4l-subdev*' in line: buf += fileio.encode(line.replace('0660', '0666')) elif '/dev/msm_camera/*' in line: buf += fileio.encode(line.replace('0660', '0666')) # Bah... even with the daemon running as root, it can't access the # hardware encoder elif '/dev/msm_vidc_enc' in line: buf += fileio.encode(line.replace('0660', '0666')) else: buf += fileio.encode(line) buf += fileio.encode('/dev/ion 0666 system system\n') cpioentry.content = buf
def modify_init_rc(cpiofile): cpioentry = cpiofile.get_file('init.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if 'export ANDROID_ROOT' in line: buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "export ANDROID_CACHE /cache\n") elif re.search(r"mkdir /system(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/system", "/raw-system", line)) elif re.search(r"mkdir /data(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/data", "/raw-data", line)) elif re.search(r"mkdir /cache(\s|$)", line): buf += fileio.encode(line) buf += fileio.encode(re.sub("/cache", "/raw-cache", line)) elif 'yaffs2' in line: buf += fileio.encode(re.sub(r"^", "#", line)) elif version == 'kk44' \ and re.search(r"mount.*/system", line) \ and re.search(r"on\s+charger", previous_line): buf += fileio.encode(" mount_all fstab.jgedlte\n") buf += fileio.encode(" exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") else: buf += fileio.encode(line) previous_line = line cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file('init.target.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if re.search(r"^\s+wait\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+check_fs\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount\s+ext4\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount_all\s+fstab.qcom.*$", line) and \ re.search(r"^on\s+fs\s*$", previous_line): buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") elif re.search(r"^\s+setprop\s+ro.crypto.fuse_sdcard\s+true", line): buf += fileio.encode(line) if move_apnhlos_mount: buf += fileio.encode(fileio.whitespace(line) + "wait /dev/block/platform/msm_sdcc.1/by-name/apnhlos\n") buf += fileio.encode(fileio.whitespace(line) + "mount vfat /dev/block/platform/msm_sdcc.1/by-name/apnhlos /firmware ro shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337\n") if move_mdm_mount: buf += fileio.encode(fileio.whitespace(line) + "wait /dev/block/platform/msm_sdcc.1/by-name/mdm\n") buf += fileio.encode(fileio.whitespace(line) + "mount vfat /dev/block/platform/msm_sdcc.1/by-name/mdm /firmware-mdm ro shortname=lower,uid=1000,gid=1000,dmask=227,fmask=337\n") else: buf += fileio.encode(line) previous_line = line cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file('init.target.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() in_qcam = False for line in lines: if version == 'kk44' and \ re.search(r"^on\s+fs_selinux\s*$", line): buf += fileio.encode(line) buf += fileio.encode(" mount_all fstab.qcom\n") buf += fileio.encode(" " + common.EXEC_MOUNT) elif re.search(r"^.*setprop.*selinux.reload_policy.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif version == 'kk44' and \ line.startswith('service'): in_qcam = 'qcamerasvr' in line buf += fileio.encode(line) # This is not exactly safe, but it's the best we can do. TouchWiz is # doing some funny business where a process running under a certain # user or group (confirmed by /proc/<pid>/status) cannot access files # by that group. Not only that, mm-qcamera-daemon doesn't work if the # process has multiple groups and root is not the primary group. Oh # well, I'm done debugging proprietary binaries. elif in_qcam and re.search(r'^\s*user', line): buf += fileio.encode(fileio.whitespace(line) + 'user root\n') elif in_qcam and re.search(r'^\s*group', line): buf += fileio.encode(fileio.whitespace(line) + 'group root\n') else: buf += fileio.encode(line) cpioentry.content = buf
def modify_init_g2_rc(cpiofile): cpioentry = cpiofile.get_file('init.g2.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if re.search(r"^\s+mount_all\s+./fstab.g2.*$", line) and \ re.search(r"^on\s+fs\s*$", previous_line): buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") # Change /data/media to /raw-data/media elif re.search(r"/data/media(\s|$)", line): buf += fileio.encode(re.sub('/data/media', '/raw-data/media', line)) else: buf += fileio.encode(line) previous_line = line cpioentry.set_content(buf)
def modify_init_target_rc(cpiofile): cpioentry = cpiofile.get_file('init.target.rc') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() previous_line = "" for line in lines: if re.search(r"^\s+wait\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+check_fs\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif re.search(r"^\s+mount\s+ext4\s+/dev/.*/cache.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) elif version == 'kk44' and \ re.search(r"^on\s+fs_selinux\s*$", line): buf += fileio.encode(line) buf += fileio.encode(" mount_all fstab.qcom\n") buf += fileio.encode(" exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") elif re.search(r"^\s+mount_all\s+fstab.qcom.*$", line) and \ re.search(r"^on\s+fs(_selinux)?.*$", previous_line): buf += fileio.encode(line) buf += fileio.encode(fileio.whitespace(line) + "exec /sbin/busybox-static sh /init.multiboot.mounting.sh\n") elif re.search(r"^.*setprop.*selinux.reload_policy.*$", line): buf += fileio.encode(re.sub(r"^", "#", line)) else: buf += fileio.encode(line) previous_line = line cpioentry.set_content(buf)
def modify_fstab(cpiofile, partition_config, additional=None, force_system_rw=False, force_cache_rw=False, force_data_rw=False, keep_mountpoints=False, system_mountpoint='/system', cache_mountpoint='/cache', data_mountpoint='/data', default_system_mountargs='ro,barrier=1,errors=panic', default_system_voldargs='wait', default_cache_mountargs='nosuid,nodev,barrier=1', default_cache_voldargs='wait,check'): move_apnhlos_mount = False move_mdm_mount = False fstabs = list() for m in cpiofile.members: if m.name.startswith('fstab.'): fstabs.append(m.name) if additional: fstabs.extend(additional) for fstab in fstabs: cpioentry = cpiofile.get_file(fstab) lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() mount_line = '%s%s %s %s %s %s\n' # For Android 4.2 ROMs has_cache_line = False # Find mount options and vold options for the system and cache # partitions system_mountargs = dict() system_voldargs = dict() cache_mountargs = dict() cache_voldargs = dict() for line in lines: m = re.search(common.FSTAB_REGEX, line) if not m: continue comment = m.group(1) blockdev = m.group(2) mountpoint = m.group(3) fstype = m.group(4) mountargs = m.group(5) voldargs = m.group(6) if comment is None: comment = '' if blockdev == SYSTEM_PART: system_mountargs[comment] = mountargs system_voldargs[comment] = voldargs elif blockdev == CACHE_PART: cache_mountargs[comment] = mountargs cache_voldargs[comment] = voldargs # If, for whatever reason, these aren't in the fstab, then choose some # sensible defaults if not system_mountargs: system_mountargs[''] = default_system_mountargs if not system_voldargs: system_voldargs[''] = default_system_voldargs if not cache_mountargs: cache_mountargs[''] = default_cache_mountargs if not cache_voldargs: cache_voldargs[''] = default_cache_voldargs for line in lines: m = re.search(common.FSTAB_REGEX, line) if m: comment = m.group(1) blockdev = m.group(2) mountpoint = m.group(3) fstype = m.group(4) mountargs = m.group(5) voldargs = m.group(6) if comment is None: comment = '' if m and blockdev == SYSTEM_PART and \ mountpoint == system_mountpoint: if not keep_mountpoints: mountpoint = '/raw-system' if '/raw-system' in partition_config.target_cache: cache_comment = difflib.get_close_matches( comment, cache_mountargs, 1, 0)[0] mountargs = cache_mountargs[cache_comment] voldargs = cache_voldargs[cache_comment] if force_system_rw: mountargs = _make_writable(mountargs) temp = mount_line % (comment, blockdev, mountpoint, fstype, mountargs, voldargs) buf += fileio.encode(temp) elif m and blockdev == CACHE_PART and \ mountpoint == cache_mountpoint: if not keep_mountpoints: mountpoint = '/raw-cache' has_cache_line = True if '/raw-cache' in partition_config.target_system: system_comment = difflib.get_close_matches( comment, system_mountargs, 1, 0)[0] mountargs = system_mountargs[system_comment] voldargs = system_voldargs[system_comment] if force_cache_rw: mountargs = _make_writable(mountargs) temp = mount_line % (comment, blockdev, mountpoint, fstype, mountargs, voldargs) buf += fileio.encode(temp) elif m and blockdev == DATA_PART and \ mountpoint == data_mountpoint: if not keep_mountpoints: mountpoint = '/raw-data' if '/raw-data' in partition_config.target_system: system_comment = difflib.get_close_matches( comment, system_mountargs, 1, 0)[0] mountargs = system_mountargs[system_comment] voldargs = system_voldargs[system_comment] if force_data_rw: mountargs = _make_writable(mountargs) temp = mount_line % (comment, blockdev, mountpoint, fstype, mountargs, voldargs) buf += fileio.encode(temp) elif m and blockdev == APNHLOS_PART: move_apnhlos_mount = True continue elif m and blockdev == MDM_PART: move_mdm_mount = True continue else: buf += fileio.encode(line) if not has_cache_line: cache_line = '%s /raw-cache ext4 %s %s\n' if '/raw-cache' in partition_config.target_system: mountargs = system_mountargs[''] voldargs = system_voldargs[''] else: mountargs = cache_mountargs[''] voldargs = cache_voldargs[''] buf += fileio.encode(cache_line % (CACHE_PART, mountargs, voldargs)) cpioentry.content = buf return (move_apnhlos_mount, move_mdm_mount)
def modify_fstab(cpiofile, partition_config): cpioentry = cpiofile.get_file('fstab.qcom') lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() system_fourth = 'ro,barrier=1,errors=panic' system_fifth = 'wait' cache_fourth = 'nosuid,nodev,barrier=1' cache_fifth = 'wait,check' # For Android 4.2 ROMs has_cache_line = False for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/system\s+.*$", line): temp = re.sub("\s/system\s", " /raw-system ", line) if '/raw-system' in partition_config.target_cache: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], cache_fourth, cache_fifth) buf += fileio.encode(temp) elif re.search(r"^/dev[^\s]+\s+/cache\s+.*$", line): temp = re.sub("\s/cache\s", " /raw-cache ", line) has_cache_line = True if '/raw-cache' in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(temp) elif re.search(r"^/dev[^\s]+\s+/data\s+.*$", line): temp = re.sub("\s/data\s", " /raw-data ", line) if '/raw-data' in partition_config.target_system: r = re.search(r"^([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)\s+([^\ ]+)", temp) temp = "%s %s %s %s %s\n" % (r.groups()[0], r.groups()[1], r.groups()[2], system_fourth, system_fifth) buf += fileio.encode(temp) elif re.search(r"^/dev/[^\s]+apnhlos\s", line): global move_apnhlos_mount move_apnhlos_mount = True continue elif re.search(r"^/dev/[^\s]+mdm\s", line): global move_mdm_mount move_mdm_mount = True continue else: buf += fileio.encode(line) if not has_cache_line: if '/raw-cache' in partition_config.target_system: buf += fileio.encode("/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 %s %s\n" % (system_fourth, system_fifth)) else: buf += fileio.encode("/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 nosuid,nodev,barrier=1 wait,check\n") cpioentry.set_content(buf)
def modify_fstab(cpiofile, partition_config): # Ignore all contents for Google Edition for i in ["fstab.qcom", "fstab.jgedlte"]: cpioentry = cpiofile.get_file(i) lines = fileio.bytes_to_lines(cpioentry.content) buf = bytes() if version == "kk44": system = "/dev/block/platform/msm_sdcc.1/by-name/system /raw-system ext4 ro,barrier=1 wait\n" cache = "/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 nosuid,nodev,barrier=1 wait,check\n" data = "/dev/block/platform/msm_sdcc.1/by-name/userdata /raw-data ext4 nosuid,nodev,barrier=1,noauto_da_alloc wait,check,encryptable=footer\n" system_fourth = "ro,barrier=1" system_fifth = "wait" cache_fourth = "nosuid,nodev,barrier=1" cache_fifth = "wait,check" elif version == "jb43": system = "/dev/block/platform/msm_sdcc.1/by-name/system /raw-system ext4 ro,errors=panic wait\n" cache = "/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 nosuid,nodev,barrier=1 wait,check\n" data = "/dev/block/platform/msm_sdcc.1/by-name/userdata /raw-data ext4 nosuid,nodev,noatime,noauto_da_alloc,discard,journal_async_commit,errors=panic wait,check,encryptable=footer\n" system_fourth = "ro,barrier=1,errors=panic" system_fifth = "wait" cache_fourth = "nosuid,nodev,barrier=1" cache_fifth = "wait,check" # Target cache on /system partition target_cache_on_system = "/dev/block/platform/msm_sdcc.1/by-name/system /raw-system ext4 %s %s\n" % ( cache_fourth, cache_fifth, ) # Target system on /cache partition target_system_on_cache = "/dev/block/platform/msm_sdcc.1/by-name/cache /raw-cache ext4 %s %s\n" % ( system_fourth, system_fifth, ) # Target system on /data partition target_system_on_data = "/dev/block/platform/msm_sdcc.1/by-name/userdata /raw-data ext4 %s %s\n" % ( system_fourth, system_fifth, ) has_cache_line = False for line in lines: if re.search(r"^/dev[a-zA-Z0-9/\._-]+\s+/system\s+.*$", line): if "/raw-system" in partition_config.target_cache: buf += fileio.encode(target_cache_on_system) else: buf += fileio.encode(system) elif re.search(r"^/dev[^\s]+\s+/cache\s+.*$", line): if "/raw-cache" in partition_config.target_system: buf += fileio.encode(target_system_on_cache) else: buf += fileio.encode(cache) has_cache_line = True elif re.search(r"^/dev[^\s]+\s+/data\s+.*$", line): if "/raw-data" in partition_config.target_system: buf += fileio.encode(target_system_on_data) else: buf += fileio.encode(data) else: buf += fileio.encode(line) if not has_cache_line: if "/raw-cache" in partition_config.target_system: buf += fileio.encode(target_system_on_cache) else: buf += fileio.encode(cache) cpioentry.set_content(buf)
def patch_boot_image(self): path = self.file_info.filename OS.ui.set_task(self.tasks['PATCHING_RAMDISK']) tempdir = tempfile.mkdtemp() self.tempdirs.append(tempdir) OS.ui.details('Unpacking boot image ...') try: bootimageinfo = bootimage.extract(path, tempdir) except bootimage.ExtractError as e: OS.ui.failed(str(e)) return None target_ramdisk = os.path.join(tempdir, 'ramdisk.cpio') # Minicpio OS.ui.details('Loading ramdisk with minicpio ...') cf = minicpio.CpioFile() with gzip.open(bootimageinfo.ramdisk, 'rb') as f: cf.load(f.read()) os.remove(bootimageinfo.ramdisk) OS.ui.details('Modifying ramdisk ...') # Update partconfig = self.find_partconfig(cf) if partconfig and cf.get_file('init.multiboot.mounting.sh'): temp = tempfile.mkstemp() shutil.copyfile( os.path.join(OS.ramdiskdir, 'init.multiboot.mounting.sh'), temp[1] ) autopatcher.insert_partition_info( temp[1], partconfig, target_path_only=True ) cf.add_file(temp[1], name='init.multiboot.mounting.sh', perms=0o750) os.close(temp[0]) os.remove(temp[1]) # Add syncdaemon to init.rc if it doesn't already exist if not cf.get_file('sbin/syncdaemon'): common.add_syncdaemon(cf) else: # Make sure 'oneshot' (added by previous versions) is removed initrc = cf.get_file('init.rc') lines = fileio.bytes_to_lines(initrc.content) buf = bytes() in_syncdaemon = False for line in lines: if line.startswith('service'): in_syncdaemon = '/sbin/syncdaemon' in line buf += fileio.encode(line) elif in_syncdaemon and 'oneshot' in line: continue else: buf += fileio.encode(line) initrc.content = buf # Copy syncdaemon cf.add_file( os.path.join(OS.ramdiskdir, 'syncdaemon'), name='sbin/syncdaemon', perms=0o750 ) # Create gzip compressed ramdisk OS.ui.details('Creating gzip compressed ramdisk with minicpio ...') target_ramdisk = target_ramdisk + ".gz" with gzip.open(target_ramdisk, 'wb') as f_out: data = cf.create() if data is not None: f_out.write(data) else: OS.ui.failed('Failed to create gzip compressed ramdisk') return None OS.ui.details('Running mkbootimg ...') bootimageinfo.ramdisk = target_ramdisk new_boot_image = tempfile.mkstemp() try: bootimage.create(bootimageinfo, new_boot_image[1]) except bootimage.CreateError as e: OS.ui.failed('Failed to create boot image: ' + str(e)) os.close(new_boot_image[0]) os.remove(new_boot_image[1]) return None os.remove(target_ramdisk) os.close(new_boot_image[0]) return new_boot_image[1]
def patch_boot_image(self): path = self.file_info.filename OS.ui.set_task(self.tasks['PATCHING_RAMDISK']) tempdir = tempfile.mkdtemp() self.tempdirs.append(tempdir) OS.ui.details('Unpacking boot image ...') try: bootimageinfo = bootimage.extract(path, tempdir) except bootimage.ExtractError as e: OS.ui.failed(str(e)) return None target_ramdisk = os.path.join(tempdir, 'ramdisk.cpio') # Minicpio OS.ui.details('Loading ramdisk with minicpio ...') cf = minicpio.CpioFile() with gzip.open(bootimageinfo.ramdisk, 'rb') as f: cf.load(f.read()) os.remove(bootimageinfo.ramdisk) OS.ui.details('Modifying ramdisk ...') # Update partconfig = self.find_partconfig(cf) if partconfig and cf.get_file('init.multiboot.mounting.sh'): temp = tempfile.mkstemp() shutil.copyfile( os.path.join(OS.ramdiskdir, 'init.multiboot.mounting.sh'), temp[1]) autopatcher.insert_partition_info(temp[1], partconfig, target_path_only=True) cf.add_file(temp[1], name='init.multiboot.mounting.sh', perms=0o750) os.close(temp[0]) os.remove(temp[1]) # Add syncdaemon to init.rc if it doesn't already exist if not cf.get_file('sbin/syncdaemon'): common.add_syncdaemon(cf) else: # Make sure 'oneshot' (added by previous versions) is removed initrc = cf.get_file('init.rc') lines = fileio.bytes_to_lines(initrc.content) buf = bytes() in_syncdaemon = False for line in lines: if line.startswith('service'): in_syncdaemon = '/sbin/syncdaemon' in line buf += fileio.encode(line) elif in_syncdaemon and 'oneshot' in line: continue else: buf += fileio.encode(line) initrc.content = buf # Copy syncdaemon cf.add_file(os.path.join(OS.ramdiskdir, 'syncdaemon'), name='sbin/syncdaemon', perms=0o750) # Create gzip compressed ramdisk OS.ui.details('Creating gzip compressed ramdisk with minicpio ...') target_ramdisk = target_ramdisk + ".gz" with gzip.open(target_ramdisk, 'wb') as f_out: data = cf.create() if data is not None: f_out.write(data) else: OS.ui.failed('Failed to create gzip compressed ramdisk') return None OS.ui.details('Running mkbootimg ...') bootimageinfo.ramdisk = target_ramdisk new_boot_image = tempfile.mkstemp() try: bootimage.create(bootimageinfo, new_boot_image[1]) except bootimage.CreateError as e: OS.ui.failed('Failed to create boot image: ' + str(e)) os.close(new_boot_image[0]) os.remove(new_boot_image[1]) return None os.remove(target_ramdisk) os.close(new_boot_image[0]) return new_boot_image[1]