├── .gitignore ├── CHANGELOG.md ├── CHANGELOG_CN.md ├── LICENSE ├── README.md ├── README_CN.md ├── __init__.py ├── aapt ├── adb ├── apktool ├── autopatch ├── __init__.py ├── autopatch.py ├── autopatch.xsd ├── changelist.py ├── config.py ├── decode_ota.py ├── diff_patch.py ├── error.py ├── precondition.py ├── rejector.py └── target_finder.py ├── baksmali ├── bootimgpack ├── .gitignore ├── CONTRIBUTORS.md ├── LICENSE ├── README.md ├── __init__.py ├── flash.py ├── internal │ ├── __init__.py │ ├── bootimg.py │ ├── common-v1 │ │ ├── README.md │ │ ├── abootimg │ │ ├── abootimg-pack-initrd │ │ ├── abootimg-unpack-initrd │ │ ├── lz4 │ │ ├── lz4-pack-initrd │ │ ├── lz4-unpack-initrd │ │ ├── pack.sh │ │ └── unpack.sh │ ├── common │ │ ├── README.md │ │ ├── minigzip │ │ ├── mkbootfs │ │ ├── mkbootimg │ │ ├── pack.sh │ │ ├── unpack-bootimg.pl │ │ ├── unpack.sh │ │ └── unpackbootimg │ ├── imgformat.py │ ├── mtk-v1 │ │ ├── mkbootfs │ │ ├── mkbootimg │ │ ├── pack.sh │ │ ├── readme │ │ ├── repack.pl │ │ ├── unpack.pl │ │ └── unpack.sh │ ├── mtk │ │ ├── README.md │ │ ├── mkimage │ │ ├── mkmtkbootimg │ │ ├── mtkbootroot.sh │ │ ├── pack.sh │ │ ├── unpack-mtk-bootimg.pl │ │ └── unpack.sh │ ├── param.py │ ├── qcom │ │ ├── ARM │ │ │ ├── README.md │ │ │ ├── bash │ │ │ ├── cpio │ │ │ ├── file │ │ │ ├── grep │ │ │ ├── gzip │ │ │ ├── lz4 │ │ │ ├── lzma │ │ │ ├── lzop │ │ │ ├── magic.mgc │ │ │ ├── mkboot │ │ │ ├── mkbootfs │ │ │ ├── mkbootimg │ │ │ ├── od │ │ │ ├── wrapper │ │ │ └── xz │ │ ├── README.md │ │ ├── dtbTool │ │ ├── dtbToolCM │ │ ├── dtbtool.txt │ │ ├── dtc │ │ ├── lz4 │ │ ├── mkboot │ │ ├── mkbootfs │ │ ├── mkbootimg │ │ ├── pack.sh │ │ └── unpack.sh │ ├── sony │ │ ├── README.md │ │ ├── mkelf.py │ │ ├── pack.sh │ │ ├── unpack.sh │ │ └── unpack_boot_sony.py │ └── toolkit.xml ├── pack_bootimg.py ├── pull │ ├── __init__.py │ ├── command.py │ ├── fstab.py │ ├── imagetype.py │ ├── kk_fstab.xml │ ├── mtk_fstab.xml │ ├── mtkpull.py │ ├── mtkpush.py │ ├── normal_fstab.xml │ ├── pull.py │ ├── push.py │ └── utils.py ├── pull_boot_recovery.py ├── ui │ ├── __init__.py │ └── main.py └── unpack_bootimg.py ├── check-su ├── classtobosp ├── common ├── __init__.py └── andprop.py ├── config ├── Makefile.other ├── Makefile.template ├── cert.py ├── config_prebuilt.py ├── density.cfg ├── getresolution ├── gitignore.template └── makeconfig ├── decode_all ├── dedat ├── fastboot ├── flyme ├── formatters ├── __init__.py ├── android_manifest.py ├── common.py ├── format.py ├── idtoname.py ├── log.py ├── name2num.py ├── nametoid.py ├── num2name.py └── rmline.sh ├── helpdoc ├── README.md ├── __init__.py ├── en │ ├── help.xml │ ├── help_autofix.xml │ ├── help_config.xml │ ├── help_fullota.xml │ ├── help_newproject.xml │ ├── help_patchall.xml │ └── help_upgrade.xml ├── help.py ├── locale ├── locale_cn └── zh_CN │ ├── help.xml │ ├── help_autofix.xml │ ├── help_config.xml │ ├── help_fullota.xml │ ├── help_newproject.xml │ ├── help_patchall.xml │ └── help_upgrade.xml ├── idtoname ├── lib64 └── libc++.so ├── log ├── makeconfig ├── methodtobosp ├── name2num ├── nametoid ├── num2name ├── otadiff ├── otanormalize ├── pack_bootimg ├── pull ├── pull_boot_recovery ├── push ├── reverses ├── README.md ├── __init__.py ├── apktool.jar ├── apktool.sh ├── common.py ├── de-dat │ ├── README.md │ ├── blockimgdiff.py │ ├── dedat.sh │ ├── img2sdat.py │ ├── make_ext4fs │ ├── rangelib.py │ ├── rimg2sdat │ ├── sdat2img.py │ └── sparse_img.py ├── de-oat │ ├── README.md │ ├── oat2dex.jar │ └── oat2dex.sh ├── de-odex │ ├── README.md │ ├── baksmali.jar │ ├── baksmali.sh │ ├── deodex.sh │ ├── smali.jar │ └── smali.sh ├── decode_all.sh ├── deoat.py ├── deodex.py ├── otanormalize.py └── zipformatter.py ├── rmline ├── sepolicy_inject ├── smali ├── smaliparser ├── Content.py ├── EntryUsed.py ├── FormatSmaliLib.py ├── LibUtils.py ├── Replace.py ├── SAutoCom.py ├── SCheck ├── SCheck.py ├── Smali.py ├── SmaliClass.py ├── SmaliEntry.py ├── SmaliEntryFactory.py ├── SmaliField.py ├── SmaliFileReplace.py ├── SmaliLib.py ├── SmaliLine.py ├── SmaliMethod.py ├── SmaliParser.py ├── SmaliSubClass.py ├── SmaliTest.py ├── __init__.py ├── autocomplete.xml ├── classtobosp ├── help │ ├── reject_advice │ ├── reject_success │ ├── smalitobosp_advice │ └── smalitobosp_success ├── methodtobosp ├── reject.py ├── tobosp.py └── utils.py ├── su-chmod ├── su-pull ├── su-push ├── su-tools ├── check-su ├── phone-check-su ├── phone-chmod ├── phone-cp ├── su-chmod ├── su-pull └── su-push ├── unpack_bootimg ├── workflow ├── __init__.py ├── coron.py ├── workflow.py └── workflow.xml └── zipalign /.gitignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | *.pyc 3 | .project 4 | .pydevproject 5 | .idea 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./CHANGELOG_CN.md) 2 | 3 | - To be translated. 4 | -------------------------------------------------------------------------------- /CHANGELOG_CN.md: -------------------------------------------------------------------------------- 1 | [English](./CHANGELOG.md) | 简体中文 2 | 3 | 4 | #### Flyme 6.7.6.13 (2017-06-13) 5 | 6 | - 【优化】更新 `smali.jar` 到版本 `v2.1.3`。 7 | - 【优化】更新 `baksmali.jar` 到版本 `v2.1.3`。 8 | - 【优化】更新 `apktool.jar` 到版本 `v2.2.2`。 9 | - 【优化】更新 `aapt`, 取自于 `apktool.jar`。 10 | 11 | 12 | #### Flyme 6.7.5.15 (2017-05-16) 13 | 14 | - 【新增】支持在 `sepolicy` 中注入新的权限规则。根据机型的需要,可以在机型目录使用 `custom_sepolicy` 脚本自行定制需要注入的权限规则。根据机型的需要,可以在 `Makefile` 文件中自行配置是否注入 `sepolicy` 新的权限规则。 15 | 16 | 17 | #### Flyme 6.7.5.8 (2017-05-09) 18 | 19 | - 【修复】某些情况下合并 odex 时出错的问题。 20 | - 【修复】修复 `autopatch` 时没有备份 `smali_classes2` 文件夹到 `autopatch` 文件夹的问题(感谢 `wuxianlin` 的反馈)。 21 | 22 | 23 | #### Flyme 6.7.5.2 (2017-05-02) 24 | 25 | - 初始发布。 26 | - 【新增】支持 `Android Marshmallow`(6.0.1)。 27 | - 【新增】适配 Flyme 6。 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | English | [简体中文](./README_CN.md) 2 | 3 | ### tools Introduction 4 | 5 | * autopatch 6 | Flyme changes will be merged into the vendor model tool for the first time to 7 | perform `patchall` or late upgrade `upgrade`. 8 | 9 | * bootimgpack 10 | Pack or unpack boot.img/recovery.img tool. 11 | 12 | * common 13 | Some common tools. 14 | 15 | * config 16 | `makeconfig` or `flyme config` to execute the call of the tools used to create the configuration. 17 | 18 | * formatters 19 | Formatted text, such as deleting `smali` in `.line`, or `id` and `name` conversion. 20 | 21 | * helpdoc 22 | Help document, and return the cause of the error when the program executes an error. 23 | 24 | * reverses 25 | Pack or unpack apk/jar and unpack the block package and odex2dex tool. 26 | 27 | * smaliparser 28 | smali file analyzer, used to deal with the smali file to better patch. 29 | 30 | * su-tools 31 | Root permissions with `adb pull` or `adb push` can facilitate the push file to the phone system. 32 | 33 | * workflow 34 | Workflow configuration tool. 35 | 36 | * aapt adb fastboot zipalign 37 | From the corresponding Android version of the AOSP tools. 38 | 39 | * otadiff 40 | Scripts used to generate differential packages. 41 | 42 | ### Changelog 43 | 44 | [CHANGELOG.md](./CHANGELOG.md) 45 | 46 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | [English](./README.md) | 简体中文 2 | 3 | ### tools 介绍 4 | 5 | * autopatch 6 | 将Flyme的改动合并到厂商机型的工具,用于首次执行`patchall`或后期升级`upgrade`. 7 | 8 | * bootimgpack 9 | boot.img/recovery.img解包打包工具. 10 | 11 | * common 12 | 一些共用工具. 13 | 14 | * config 15 | 执行`makeconfig`或`flyme config`时调用的工具,用于创建配置. 16 | 17 | * formatters 18 | 格式化文本,例如删`smali`中的`.line`,或`id`与`name`的转换. 19 | 20 | * helpdoc 21 | 帮助文档,在程序执行错误时返回可能导致错误的原因. 22 | 23 | * reverses 24 | 对apk/jar解包打包,对block包进行解包,odex合并工具. 25 | 26 | * smaliparser 27 | smali文件分析器,用于处理smali文件以更好的插桩. 28 | 29 | * su-tools 30 | 拥有root权限的`adb pull/push 可以方便的push文件到手机系统. 31 | 32 | * workflow 33 | 工作流配置工具. 34 | 35 | * aapt adb fastboot zipalign 36 | 来自于对应安卓版本的aosp工具. 37 | 38 | * otadiff 39 | 用于生成差分包的脚本. 40 | 41 | ### 更新记录 42 | 43 | [CHANGELOG_CN.md](./CHANGELOG_CN.md) 44 | 45 | -------------------------------------------------------------------------------- /__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/__init__.py -------------------------------------------------------------------------------- /aapt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/aapt -------------------------------------------------------------------------------- /adb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/adb -------------------------------------------------------------------------------- /apktool: -------------------------------------------------------------------------------- 1 | reverses/apktool.sh -------------------------------------------------------------------------------- /autopatch/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/autopatch/__init__.py -------------------------------------------------------------------------------- /autopatch/autopatch.xsd: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /autopatch/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Configuration 5 | """ 6 | 7 | __author__ = 'duanqz@gmail.com' 8 | 9 | 10 | import os 11 | from os import sys, path 12 | 13 | sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) 14 | 15 | class Config: 16 | """ Configuration. 17 | """ 18 | 19 | ### Root directory 20 | # Root directory of current project 21 | PRJ_ROOT = os.curdir 22 | 23 | ### AUTOPATCH Directory 24 | # We need to hold three directory because diff3 25 | # incorporate changes from newer to older into target. 26 | 27 | AUTOPATCH = os.path.join(PRJ_ROOT, "autopatch/") 28 | 29 | # AOSP root directory 30 | AOSP_ROOT = os.path.join(AUTOPATCH, "aosp/") 31 | 32 | # BOSP root directory 33 | BOSP_ROOT = os.path.join(AUTOPATCH, "bosp/") 34 | 35 | # Last BOSP root directory 36 | LAST_BOSP_ROOT = os.path.join(AUTOPATCH, "last_bosp/") 37 | 38 | # Vendor original root directory 39 | VENDOR_ORIGINAL_ROOT = os.path.join(AUTOPATCH, "vendor_original") 40 | 41 | # Vendor patched root directory 42 | VENDOR_PATCHED_ROOT = os.path.join(AUTOPATCH, "vendor_patched") 43 | 44 | # Root directory of reject files 45 | REJ_ROOT = os.path.join(AUTOPATCH, "reject/") 46 | 47 | ### Patch XML 48 | PATCHALL_XML = os.path.join(AUTOPATCH, "patchall.xml") 49 | 50 | UPGRADE_XML = os.path.join(AUTOPATCH, "upgrade.xml") 51 | 52 | PORTING_XML = os.path.join(AUTOPATCH, "porting.xml") 53 | 54 | @staticmethod 55 | def toString(): 56 | print "-----------------------------------------------------------" 57 | print "PRJ_ROOT:\t" + Config.PRJ_ROOT 58 | print "AOSP_DIR:\t" + Config.AOSP_ROOT 59 | print "BOSP_DIR:\t" + Config.BOSP_ROOT 60 | print "---" 61 | print "PATCHALL_XML:\t" + Config.PATCHALL_XML 62 | print "-----------------------------------------------------------" 63 | 64 | # End of class Config 65 | 66 | if __name__ == "__main__": 67 | Config.toString() 68 | -------------------------------------------------------------------------------- /autopatch/decode_ota.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Usage: $decode_ota.py ota.zip output 5 | decode ota.zip to output 6 | """ 7 | 8 | __author__ = 'duanqz@gmail.com' 9 | 10 | 11 | import sys 12 | from precondition import Utils 13 | 14 | if __name__ == "__main__": 15 | 16 | argc = len(sys.argv) 17 | 18 | if argc < 3: 19 | print __doc__ 20 | 21 | Utils.decode(sys.argv[1], sys.argv[2]) -------------------------------------------------------------------------------- /autopatch/error.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | 4 | __author__ = 'duanqz@gmail.com' 5 | 6 | 7 | import os 8 | from config import Config 9 | from formatters.log import Paint 10 | 11 | class Error: 12 | 13 | FAILED_LIST = [] 14 | 15 | TOTAL_FILENOTFOUND = 0 16 | FILENOTFOUND_STATISTIC = {} 17 | 18 | TOTAL_CONFLICTS = 0 19 | CONFLICT_FILE_NUM = 0 20 | CONFLICT_STATISTIC = {} 21 | 22 | 23 | @staticmethod 24 | def fileNotFound(target): 25 | # Add to FAILED_LIST 26 | Error.fail(" * File not found: %s" % target) 27 | 28 | # Increment total file not found 29 | Error.TOTAL_FILENOTFOUND += 1 30 | 31 | # Increment file not found of each part 32 | key = Error.getStatisticKey(target) 33 | if not Error.FILENOTFOUND_STATISTIC.has_key(key): 34 | Error.FILENOTFOUND_STATISTIC[key] = 0 35 | 36 | Error.FILENOTFOUND_STATISTIC[key] += 1 37 | 38 | 39 | @staticmethod 40 | def conflict(conflictNum, target): 41 | # Add to FAILED_LIST 42 | Error.fail(" %3d conflicts in: %s" %(conflictNum, target)) 43 | 44 | # Increment total conflicts 45 | Error.TOTAL_CONFLICTS += conflictNum; 46 | Error.CONFLICT_FILE_NUM += 1 47 | 48 | # Increment conflicts of each part 49 | key = Error.getStatisticKey(target) 50 | if not Error.CONFLICT_STATISTIC.has_key(key): 51 | Error.CONFLICT_STATISTIC[key] = 0 52 | 53 | Error.CONFLICT_STATISTIC[key] += conflictNum 54 | 55 | @staticmethod 56 | def getStatisticKey(target): 57 | relpath = os.path.relpath(target, Config.PRJ_ROOT) 58 | key = relpath[0:relpath.find("/")] 59 | 60 | return key 61 | 62 | @staticmethod 63 | def fail(message): 64 | Error.FAILED_LIST.append(message) 65 | 66 | 67 | @staticmethod 68 | def showStatistic(): 69 | for key in Error.FILENOTFOUND_STATISTIC.keys(): 70 | print "%3d files not found in %s" % (Error.FILENOTFOUND_STATISTIC[key], key) 71 | 72 | if Error.TOTAL_FILENOTFOUND > 0: 73 | print Paint.bold("%3d files not found totally, they might be removed or moved to other place by vendor?" % Error.TOTAL_FILENOTFOUND) 74 | print " " 75 | 76 | for key in Error.CONFLICT_STATISTIC.keys(): 77 | print "%3d conflicts in %s " % (Error.CONFLICT_STATISTIC[key], key) 78 | 79 | if Error.TOTAL_CONFLICTS > 0: 80 | print Paint.bold("%3d conflicts in %d files, go through the reject files in 'autopatch/reject' to find them out" % (Error.TOTAL_CONFLICTS, Error.CONFLICT_FILE_NUM)) 81 | print Paint.red("\n Ask for advice? Please type 'flyme help CONFLICTS_HAPPENED' \n") 82 | 83 | 84 | @staticmethod 85 | def report(): 86 | 87 | if len(Error.FAILED_LIST) == 0: 88 | print Paint.green("\n Ask for advice? Please type 'flyme help NO_CONFLICT' \n") 89 | else: 90 | Error.createAllRejects() 91 | 92 | Error.printDivide() 93 | for failed in Error.FAILED_LIST: print failed 94 | 95 | Error.printDivide() 96 | Error.showStatistic() 97 | 98 | 99 | @staticmethod 100 | def printDivide(): 101 | print " ____________________________________________________________________________________" 102 | print " " 103 | 104 | 105 | @staticmethod 106 | def createAllRejects(): 107 | if not os.path.exists(Config.REJ_ROOT): 108 | os.makedirs(Config.REJ_ROOT) 109 | allrejects = os.path.join(Config.REJ_ROOT, "allrejects.txt") 110 | handle = open(allrejects, "w") 111 | handle.write("\n".join(Error.FAILED_LIST)) 112 | handle.close() 113 | 114 | 115 | -------------------------------------------------------------------------------- /autopatch/rejector.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """ 19 | rejector. 20 | 21 | """ 22 | 23 | __author__ = 'duanqz@gmail.com' 24 | 25 | 26 | import os 27 | import fnmatch 28 | from config import Config 29 | 30 | 31 | class Collector: 32 | """ Collect the conflicts 33 | """ 34 | 35 | CONFILCT_START = "<<<<<<<" 36 | CONFLICT_MID = "=======" 37 | CONFILCT_END = ">>>>>>>" 38 | 39 | def __init__(self, target): 40 | self.mTarget = target 41 | self.mConflictNum = 0 42 | 43 | def get_conflict_num(self): 44 | return self.mConflictNum 45 | 46 | def collect_conflict(self): 47 | """ Check whether conflict happen or not in the target 48 | """ 49 | 50 | self.mConflictNum = 0 51 | 52 | top = 0 53 | 54 | # delLinesNumbers record the lines of conflicts 55 | del_line_numbers = [] 56 | need_to_del = False 57 | 58 | target_file = open(self.mTarget, "r+") 59 | 60 | line_num = 0 61 | lines = target_file.readlines() 62 | 63 | for line in lines: 64 | size = self.mConflictNum 65 | if line.startswith(Collector.CONFILCT_START): 66 | 67 | top += 1 68 | 69 | # Modify the conflict in the original 70 | lines[line_num] = "%s #Conflict %d\n" % (line.rstrip(), size) 71 | self.mConflictNum += 1 72 | 73 | del_line_numbers.append(line_num) 74 | 75 | elif line.startswith(Collector.CONFILCT_END): 76 | 77 | # Modify the conflict in the original 78 | lines[line_num] = "%s #Conflict %d\n" % (line.rstrip(), size-top) 79 | 80 | del_line_numbers.append(line_num) 81 | need_to_del = False 82 | 83 | if top == 0: 84 | break 85 | 86 | top -= 1 87 | 88 | else: 89 | if top > 0: 90 | 91 | if line.startswith(Collector.CONFLICT_MID): 92 | need_to_del = True 93 | 94 | if need_to_del: 95 | del_line_numbers.append(line_num) 96 | 97 | line_num += 1 98 | 99 | # Create a reject file if conflict happen 100 | if self.mConflictNum > 0: 101 | rej_file_path = create_reject_file(self.mTarget) 102 | f = open(rej_file_path, "wb") 103 | f.writelines(lines) 104 | f.close() 105 | 106 | # Remove conflict blocks, and write back target. 107 | for line_num in del_line_numbers[::-1]: 108 | del lines[line_num] 109 | 110 | target_file.seek(0) 111 | target_file.truncate() 112 | target_file.writelines(lines) 113 | target_file.close() 114 | 115 | return self 116 | 117 | # Deprecated 118 | def resolve_conflict(self): 119 | 120 | f = open(self.mTarget, "r+") 121 | 122 | top = 0 123 | line_num = 0 124 | 125 | del_line_numbers = [] 126 | need_to_del = True 127 | 128 | lines = f.readlines() 129 | for line in lines: 130 | if line.startswith(Collector.CONFILCT_START): 131 | top += 1 132 | del_line_numbers.append(line_num) 133 | 134 | elif line.startswith(Collector.CONFILCT_END): 135 | top -= 1 136 | del_line_numbers.append(line_num) 137 | need_to_del = True 138 | 139 | if top < 0: break; 140 | else: 141 | if top > 0: 142 | if need_to_del: 143 | del_line_numbers.append(line_num) 144 | 145 | if line.startswith(Collector.CONFLICT_MID): 146 | need_to_del = False 147 | 148 | line_num += 1 149 | 150 | for line_num in del_line_numbers[::-1]: 151 | del lines[line_num] 152 | 153 | f.seek(0) 154 | f.truncate() 155 | f.writelines(lines) 156 | f.close() 157 | 158 | 159 | def create_reject_file(target): 160 | """ create a reject file 161 | :param target: the target might have conflicts 162 | :return: reject file path 163 | """ 164 | rel_target = os.path.relpath(target, Config.PRJ_ROOT) 165 | rej_file_path = os.path.join(Config.REJ_ROOT, rel_target) 166 | d = os.path.dirname(rej_file_path) 167 | if not os.path.exists(d): 168 | os.makedirs(d) 169 | 170 | return rej_file_path 171 | 172 | 173 | def process_conflicts(target): 174 | """ process conflicts of the target 175 | :param target: the target might have conflicts 176 | :return: number of conflicts 177 | """ 178 | 179 | return Collector(target).collect_conflict().get_conflict_num() -------------------------------------------------------------------------------- /baksmali: -------------------------------------------------------------------------------- 1 | reverses/de-odex/baksmali.sh -------------------------------------------------------------------------------- /bootimgpack/.gitignore: -------------------------------------------------------------------------------- 1 | # Gradle 2 | .gradle/ 3 | bin/ 4 | 5 | # Build 6 | **/build/ 7 | *.pyc 8 | 9 | # Eclipse 10 | **/nbproject/private/ 11 | *.project 12 | *.classpath 13 | *.settings 14 | *.setting 15 | 16 | # Tmp Files 17 | *.kate-swp 18 | *~ 19 | 20 | # IntelliJ 21 | *.iml 22 | .idea/* 23 | /out 24 | 25 | 26 | -------------------------------------------------------------------------------- /bootimgpack/CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # bootimgpack Contributors 2 | Copyright 2015 duanqz 3 | 4 | This product includes software developed by: 5 | 6 | * duanqz (duanqz@gmail.com) 7 | * The Apache Software Foundation (http://www.apache.org/) 8 | -------------------------------------------------------------------------------- /bootimgpack/README.md: -------------------------------------------------------------------------------- 1 | ### 介绍 2 | 3 | ***bootimgpack*** 是一个智能解包和打包 Android boot.img 的工具, 4 | 采用 Python 和 Shell 语言实现, 目前仅支持类 Unix 系统. 5 | 6 | ### 特点 7 | 8 | * 自适应不同手机厂商的 boot.img 格式,智能完成解包 9 | * 提供命令和图形界面两种操作方式 10 | 11 | ### 使用 12 | 13 | * 命令方式 14 | 15 | ***解包:*** unpack_bootimg.py boot.img output/ 16 | 17 | ***打包:*** pack_bootimg.py BOOT/ boot.img 18 | 19 | * 图形界面 20 | 21 | 运行 ui/main.py 将会启动操作界面 22 | 23 | ### 类型 24 | 25 | 目前,bootimgpack支持大部分厂商的boot.img类型: 26 | 27 | * SONY (Sony的boot.img类型) 28 | * MTK (MTK的boot.img类型) 29 | * QCOM (高通的boot.img类型,包括dt.img) 30 | * COMMON-V1 (Android 4.3+的boot.img类型) 31 | * COMMON (Android 2.3~4.3的boot.img类型) 32 | 33 | ### 版本 34 | 35 | v1.0 36 | 37 | ------------------------------------------------------------------------------- 38 | 39 | ### Introduction 40 | 41 | ***bootimgpack*** is a smart tool for unpack or pack boot.img of Android, 42 | implemented in Python and Shell, now only for Unix-like OS. 43 | 44 | ### Features 45 | * Hide format differences of boot.img of different manufactors 46 | * Both command and graphic mode are provided 47 | 48 | ### Usages 49 | * Command Mode 50 | 51 | ***Unpack :*** unpack_bootimg.py boot.img output/ 52 | 53 | ***Pack :*** pack_bootimg.py BOOT/ boot.img 54 | 55 | * Graphic Mode 56 | 57 | Run ui/main.py to launch the UI 58 | 59 | ### Types 60 | 61 | Bootimgpack support for a broad range types of boot.img including: 62 | 63 | * SONY (Support boot.img of Sony) 64 | * MTK (Support boot.img of MTK 2.3~4.2) 65 | * QCOM (Support boot.img of QCOM 4.3+, especially for dt.img of QCOM) 66 | * COMMON-V1 (Support boot.img of Android 4.3+) 67 | * COMMON (Support boot.img of Android 2.3 ~ Android 4.2) 68 | 69 | ### Version 70 | 71 | V1.0 72 | -------------------------------------------------------------------------------- /bootimgpack/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/__init__.py -------------------------------------------------------------------------------- /bootimgpack/flash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | ''' 3 | USAGE: flash device recovery.fstab device.img [fstab_version] 4 | device: [boot|recovery] 5 | device.img: [boot.img|recovery.img] 6 | fstab_version: [1|2] 7 | 1 for android 4.0 - 4.2 (DEFAULT) 8 | 2 for android 4.3 - * 9 | 10 | Created on Jul 31, 2014 11 | 12 | @author: tangliuxiang 13 | ''' 14 | import sys 15 | import os 16 | import traceback 17 | from pull import utils 18 | 19 | if __name__ == '__main__': 20 | 21 | try: 22 | if len(sys.argv) == 4: 23 | utils.PushUtils.push(sys.argv[1], sys.argv[2], sys.argv[3]) 24 | elif len(sys.argv) >= 5: 25 | utils.PushUtils.push(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4]) 26 | else: 27 | print __doc__ 28 | except Exception as e: 29 | traceback.print_exc() 30 | # See help.xml ERR_PULL_BOOT_RECOVERY_FAILED 31 | sys.exit(156) -------------------------------------------------------------------------------- /bootimgpack/internal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/__init__.py -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/README.md: -------------------------------------------------------------------------------- 1 | abootimg is an open source project on https://github.com/coruus/abootimg 2 | 3 | Extension of abootimg, LZ4 - Extremely fast compression: https://github.com/Cyan4973/lz4 4 | From Android 5.0, lz4 compression instead of gzip for many devices. 5 | 6 | Current version of LZ4 used here is [r128]. 7 | 8 | Support Android 4.3+ 9 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/abootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common-v1/abootimg -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/abootimg-pack-initrd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | 4 | if [ "$1" = "-f" ]; then 5 | forcewrite=yes 6 | shift 7 | fi 8 | 9 | initrd=${1:-initrd.img} 10 | ramdisk=${2:-RAMDISK} 11 | 12 | if [ ! -d $ramdisk ]; then 13 | echo "$ramdisk does not exist." 14 | exit 1 15 | fi 16 | 17 | if [ -f $initrd -a -z "$forcewrite" ]; then 18 | echo "$initrd already exist." 19 | exit 1 20 | fi 21 | 22 | ( cd $ramdisk; find | sort | cpio --quiet -o -H newc ) | gzip > $initrd 23 | 24 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/abootimg-unpack-initrd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | 4 | initrd=${1:-initrd.img} 5 | ramdisk=${2:-RAMDISK} 6 | 7 | if [ ! -f $initrd ]; then 8 | echo "$initrd does not exist." 9 | exit 1 10 | fi 11 | 12 | if [ -d $ramdisk ]; then 13 | rm $ramdisk -rf 14 | fi 15 | 16 | mkdir -p $ramdisk 17 | 18 | zcat $initrd | ( cd $ramdisk; cpio -i ) 19 | 20 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common-v1/lz4 -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/lz4-pack-initrd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | 4 | old_pwd=`pwd` 5 | basepath=`cd $(dirname $0); pwd` 6 | cd $old_pwd 7 | LZ4=$basepath/lz4 8 | 9 | if [ "$1" = "-f" ]; then 10 | forcewrite=yes 11 | shift 12 | fi 13 | 14 | initrd=${1:-initrd.img} 15 | ramdisk=${2:-RAMDISK} 16 | 17 | if [ ! -d $ramdisk ]; then 18 | echo "$ramdisk does not exist." 19 | exit 1 20 | fi 21 | 22 | if [ -f $initrd -a -z "$forcewrite" ]; then 23 | echo "$initrd already exist." 24 | exit 1 25 | fi 26 | 27 | ( cd $ramdisk; find | sort | cpio --quiet -H newc -o ) | $LZ4 28 | mv stdin.lz4 $initrd 29 | 30 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/lz4-unpack-initrd: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # 3 | 4 | old_pwd=`pwd` 5 | basepath=`cd $(dirname $0); pwd` 6 | cd $old_pwd 7 | 8 | LZ4=$basepath/lz4 9 | initrd=${1:-initrd.img} 10 | ramdisk=${2:-RAMDISK} 11 | 12 | if [ ! -f $initrd ]; then 13 | echo "$initrd does not exist." 14 | exit 1 15 | fi 16 | 17 | if [ -d $ramdisk ]; then 18 | rm $ramdisk -rf 19 | fi 20 | 21 | echo $initrd 22 | 23 | mkdir -p $ramdisk 24 | cd $ramdisk 25 | $LZ4 -d ../$initrd | cpio -i 26 | cd - > /dev/null 27 | 28 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # pack_boot.sh 4 | # Pack the directory to boot.img 5 | 6 | BOOTDIR=$1 7 | OUTPUT=$2 8 | 9 | function usage() 10 | { 11 | echo "Usage pack_boot.sh BOOTDIR [OUTPUT]" 12 | echo " BOOTDIR: the directory containing boot files to be pack" 13 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 14 | } 15 | 16 | function init_tools() 17 | { 18 | local old_pwd=`pwd` 19 | TOOL_DIR=`cd $(dirname $0); pwd` 20 | ABOOTIMG=$TOOL_DIR/abootimg 21 | ABOOTIMG_PACK_INITRD=$TOOL_DIR/abootimg-pack-initrd 22 | LZ4_PACK_INITRD=$TOOL_DIR/lz4-pack-initrd 23 | cd $old_pwd 24 | } 25 | 26 | function pack_bootimg() 27 | { 28 | local old_pwd=`pwd` 29 | 30 | cd $BOOTDIR 31 | 32 | $ABOOTIMG_PACK_INITRD -f newinitrd.img 33 | [ $? != 0 ] && exit 1 34 | 35 | if [ -e secondstage ]; then 36 | $ABOOTIMG --create pack.img -f bootimg.cfg -k zImage -r newinitrd.img -s secondstage 37 | [ $? != 0 ] && exit 1 38 | else 39 | $ABOOTIMG --create pack.img -f bootimg.cfg -k zImage -r newinitrd.img 40 | [ $? != 0 ] && exit 1 41 | fi 42 | rm -f newinitrd.img 43 | 44 | cd $old_pwd 45 | mv $BOOTDIR/pack.img $OUTPUT 46 | } 47 | 48 | # Check parameters 49 | [ $# -eq 0 ] && usage && exit 1; 50 | [ -z $2 ] && OUTPUT=out.img; 51 | 52 | init_tools; 53 | pack_bootimg; 54 | -------------------------------------------------------------------------------- /bootimgpack/internal/common-v1/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqz@gmail.com 7 | # 8 | 9 | BOOTIMG=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage unpack_boot.sh BOOTIMG [OUTPUT]" 15 | echo " BOOTIMG: the file path of the boot.img to be unpack" 16 | echo " OUTPUT: the output directory. if not present, the OUT/ directory will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | ABOOTIMG=$TOOL_DIR/abootimg 24 | ABOOTIMG_UNPACK_INITRD=$TOOL_DIR/abootimg-unpack-initrd 25 | LZ4_UNPACK_INITRD=$TOOL_DIR/lz4-unpack-initrd 26 | cd $old_pwd 27 | } 28 | 29 | function unpack_bootimg() 30 | { 31 | local old_pwd=`pwd` 32 | mkdir -p $OUTPUT 33 | cp $BOOTIMG $OUTPUT/boot.img 34 | cd $OUTPUT 35 | 36 | # Open the macro variable to filter " *** glibc detected *** " error 37 | # local tmp_stderr=$LIBC_FATAL_STDERR_ 38 | # export LIBC_FATAL_STDERR_=1 39 | 40 | # Unpack boot image 41 | $ABOOTIMG -x boot.img 42 | [ $? != 0 ] && exit 1 43 | 44 | $ABOOTIMG_UNPACK_INITRD 45 | if [ $? != 0 ]; then 46 | # Failed, try lz4 to unpack ramdisk 47 | $LZ4_UNPACK_INITRD 48 | [ $? != 0 ] && exit 1 49 | fi 50 | 51 | rm -f initrd.img boot.img 52 | 53 | # Remove the bootsize 54 | sed -i {1d} bootimg.cfg 55 | 56 | # export LIBC_FATAL_STDERR_=$tmp_stderr 57 | cd $old_pwd 58 | } 59 | 60 | function check_result() 61 | { 62 | [ ! -e $OUTPUT/zImage ] && exit 1 63 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 64 | } 65 | 66 | 67 | ### Start Script ### 68 | 69 | # Check parameters 70 | [ $# -eq 0 ] && usage && exit 1; 71 | [ -z $2 ] && OUTPUT="OUT/"; 72 | 73 | init_tools; 74 | unpack_bootimg; 75 | check_result; 76 | exit 0 77 | -------------------------------------------------------------------------------- /bootimgpack/internal/common/README.md: -------------------------------------------------------------------------------- 1 | 2 | Support Android 2.3 ~ Android 4.2 3 | -------------------------------------------------------------------------------- /bootimgpack/internal/common/minigzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common/minigzip -------------------------------------------------------------------------------- /bootimgpack/internal/common/mkbootfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common/mkbootfs -------------------------------------------------------------------------------- /bootimgpack/internal/common/mkbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common/mkbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/common/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # pack_boot.sh 4 | # Pack the directory to boot.img 5 | 6 | BOOTDIR=$1 7 | OUTPUT=$2 8 | 9 | function usage() 10 | { 11 | echo "Usage pack_boot.sh BOOTDIR [OUTPUT]" 12 | echo " BOOTDIR: the directory containing boot files to be pack" 13 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 14 | } 15 | 16 | function init_tools() 17 | { 18 | local old_pwd=`pwd` 19 | TOOL_DIR=`cd $(dirname $0); pwd` 20 | MKBOOTFS=$TOOL_DIR/mkbootfs 21 | MINIGZIP=$TOOL_DIR/minigzip 22 | MKBOOTIMG=$TOOL_DIR/mkbootimg 23 | cd $old_pwd 24 | } 25 | 26 | function pack_bootimg() 27 | { 28 | local old_pwd=`pwd` 29 | 30 | cd $BOOTDIR 31 | $MKBOOTFS ./RAMDISK | $MINIGZIP > ramdisk.img 32 | [ $? != 0 ] && exit 1 33 | 34 | BOOTBASE=$(cat ./base) 35 | BOOTCMDLINE=$(cat ./cmdline) 36 | BOOTPAGESIZE=$(cat ./pagesize) 37 | $MKBOOTIMG --kernel ./kernel --cmdline "$BOOTCMDLINE" --pagesize "$BOOTPAGESIZE" --base "$BOOTBASE" --ramdisk ./ramdisk.img --output pack.img 38 | [ $? != 0 ] && exit 1 39 | 40 | rm ramdisk.img 41 | cd $old_pwd 42 | mv $BOOTDIR/pack.img $OUTPUT 43 | } 44 | 45 | # Check parameters 46 | [ $# -eq 0 ] && usage && exit 1; 47 | [ -z $2 ] && OUTPUT=out.img; 48 | 49 | init_tools; 50 | pack_bootimg; 51 | -------------------------------------------------------------------------------- /bootimgpack/internal/common/unpack-bootimg.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -W 2 | 3 | use strict; 4 | use bytes; 5 | use File::Path; 6 | 7 | die "did not specify boot img file\n" unless $ARGV[0]; 8 | 9 | my $bootimgfile = $ARGV[0]; 10 | 11 | my $slurpvar = $/; 12 | undef $/; 13 | open (BOOTIMGFILE, "$bootimgfile") or die "could not open boot img file: $bootimgfile\n"; 14 | my $bootimg = ; 15 | close BOOTIMGFILE; 16 | $/ = $slurpvar; 17 | 18 | # chop off the header 19 | $bootimg = substr($bootimg,2048); 20 | 21 | # we'll check how many ramdisks are embedded in this image 22 | my $numfiles = 0; 23 | 24 | # we look for the hex 00 00 00 00 1F 8B because we expect some trailing padding zeroes from the kernel or previous ramdisk, followed by 1F 8B (the gzip magic number) 25 | while ($bootimg =~ m/\x00\x00\x00\x00\x1F\x8B/g) { 26 | $numfiles++; 27 | } 28 | 29 | if ($numfiles == 0) { 30 | die "Could not find any embedded ramdisk images. Are you sure this is a full boot image?\n"; 31 | } elsif ($numfiles > 1) { 32 | die "Found a secondary file after the ramdisk image. According to the spec (mkbootimg.h) this file can exist, but this script is not designed to deal with this scenario.\n"; 33 | } 34 | 35 | $bootimg =~ /(.*\x00\x00\x00\x00)(\x1F\x8B.*)/s; 36 | 37 | my $kernel = $1; 38 | my $ramdisk = $2; 39 | 40 | 41 | open (KERNELFILE, ">$ARGV[0]-kernel"); 42 | print KERNELFILE $kernel or die; 43 | close KERNELFILE; 44 | 45 | open (RAMDISKFILE, ">$ARGV[0]-ramdisk.cpio.gz"); 46 | print RAMDISKFILE $ramdisk or die; 47 | close RAMDISKFILE; 48 | 49 | print "\nkernel written to $ARGV[0]-kernel\nramdisk written to $ARGV[0]-ramdisk.cpio.gz\n"; 50 | if (-e "$ARGV[0]-ramdisk") { 51 | rmtree "$ARGV[0]-ramdisk"; 52 | print "\nremoved old directory $ARGV[0]-ramdisk\n"; 53 | } 54 | 55 | mkdir "$ARGV[0]-ramdisk" or die; 56 | chdir "$ARGV[0]-ramdisk" or die; 57 | system ("gunzip -c ../$ARGV[0]-ramdisk.cpio.gz | cpio -i"); 58 | 59 | print "\nextracted ramdisk contents to directory $ARGV[0]-ramdisk/\n"; 60 | -------------------------------------------------------------------------------- /bootimgpack/internal/common/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqz@gmail.com 7 | # 8 | 9 | BOOTIMG=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage unpack_boot.sh BOOTIMG [OUTPUT]" 15 | echo " BOOTIMG: the file path of the boot.img to be unpack" 16 | echo " OUTPUT: the output directory. if not present, the OUT/ directory will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | UNPACKBOOTIMG=$TOOL_DIR/unpackbootimg 24 | UNPACKBOOTIMGPL=$TOOL_DIR/unpack-bootimg.pl 25 | cd $old_pwd 26 | } 27 | 28 | function unpack_bootimg() 29 | { 30 | local old_pwd=`pwd` 31 | mkdir -p $OUTPUT 32 | cp $BOOTIMG $OUTPUT/boot.img 33 | cd $OUTPUT 34 | 35 | # Open the macro variable to filter " *** glibc detected *** " error 36 | local tmp_stderr=$LIBC_FATAL_STDERR_ 37 | export LIBC_FATAL_STDERR_=1 38 | 39 | # Unpack boot image 40 | $UNPACKBOOTIMG -i boot.img -o ./ 41 | [ $? != 0 ] && exit 1 42 | 43 | $UNPACKBOOTIMGPL boot.img 44 | [ $? != 0 ] && exit 1 45 | 46 | mv boot.img-ramdisk RAMDISK 47 | mv boot.img-zImage kernel 48 | mv boot.img-cmdline cmdline 49 | mv boot.img-base base 50 | mv boot.img-pagesize pagesize 51 | rm -rf boot.img* 52 | 53 | export LIBC_FATAL_STDERR_=$tmp_stderr 54 | 55 | cd $old_pwd 56 | } 57 | 58 | function check_result() 59 | { 60 | [ ! -e $OUTPUT/kernel ] && exit 1 61 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 62 | } 63 | 64 | 65 | ### Start Script ### 66 | 67 | # Check parameters 68 | [ $# -eq 0 ] && usage && exit 1; 69 | [ -z $2 ] && OUTPUT="OUT/"; 70 | 71 | init_tools; 72 | unpack_bootimg; 73 | check_result; 74 | exit 0 75 | -------------------------------------------------------------------------------- /bootimgpack/internal/common/unpackbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/common/unpackbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/imgformat.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 25, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import sys 8 | 9 | class ImgFormat(object): 10 | ''' 11 | classdocs 12 | ''' 13 | 14 | IMAGE_HEAD_STR = "ANDROID" 15 | 16 | def __init__(self, bootfile): 17 | ''' 18 | Constructor 19 | ''' 20 | self.bootfile = bootfile 21 | 22 | def format(self): 23 | f = open(self.bootfile, "r+") 24 | hstr = f.read(len(ImgFormat.IMAGE_HEAD_STR)) 25 | 26 | if hstr == ImgFormat.IMAGE_HEAD_STR: 27 | return 28 | 29 | f.seek(0) 30 | fstr = f.read() 31 | 32 | try: 33 | idx = fstr.index(ImgFormat.IMAGE_HEAD_STR) 34 | if idx < 0: 35 | return 36 | except: 37 | #print "Unknown boot image type: " + self.bootfile 38 | return 39 | 40 | f.seek(0) 41 | f.truncate() 42 | f.write(fstr[idx:]) 43 | f.close() 44 | 45 | if __name__ == '__main__': 46 | ImgFormat("/home/tangliuxiang/tmp/boot-sign-test/boot.img").format() -------------------------------------------------------------------------------- /bootimgpack/internal/mtk-v1/mkbootfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/mtk-v1/mkbootfs -------------------------------------------------------------------------------- /bootimgpack/internal/mtk-v1/mkbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/mtk-v1/mkbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/mtk-v1/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqizhi(duanqz@gmail.com) 7 | # 8 | 9 | BOOTDIR=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage pack_boot.sh BOOTDIR [OUTPUT]" 15 | echo " BOOTDIR: the directory containing boot files to be pack" 16 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | REPACK_PL=$TOOL_DIR/repack.pl 24 | cd $old_pwd 25 | } 26 | 27 | function pack_bootimg() 28 | { 29 | $REPACK_PL -boot $BOOTDIR/kernel $BOOTDIR/RAMDISK $OUTPUT 30 | } 31 | 32 | ### Start Script ### 33 | 34 | # Check parameters 35 | [ $# -eq 0 ] && usage && exit 1; 36 | [ -z $2 ] && OUTPUT=out.img; 37 | 38 | init_tools; 39 | pack_bootimg; 40 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk-v1/readme: -------------------------------------------------------------------------------- 1 | 1、unpack command: 2 | boot.img: 3 | ./unpack.pl boot.img 4 | 5 | recovery.img: 6 | ./unpack.pl recovery.img 7 | 8 | 2、repack command: 9 | repack boot.img: 10 | ./repack.pl -boot kernel ramdisk/ boot-new.img 11 | 12 | repack recovery.img: 13 | ./repack.pl -recovery kernel ramdisk/ recovery-new.img 14 | 15 | 16 | 17 | ### bootimgpack 18 | 19 | mtk-v1, support mt6752. https://github.com/cofface/android-mtk-tools.git 20 | 21 | We made changes: 22 | 23 | 1. Capitalize ramdisk after unpack.pl 24 | 25 | 2. Do NOT clean_files after repack 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk-v1/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqizhi(duanqz@gmail.com) 7 | # 8 | 9 | BOOTIMG=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage unpack_boot.sh BOOTIMG [OUTPUT]" 15 | echo " BOOTIMG: the file path of the boot.img to be unpack" 16 | echo " OUTPUT: the output directory. if not present, the OUT/ directory will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | UNPACK_PL=$TOOL_DIR/unpack.pl 24 | cd $old_pwd 25 | } 26 | 27 | function unpack_bootimg() 28 | { 29 | # Unpack boot image 30 | local abs_bootimg=$(readlink -f $BOOTIMG) 31 | 32 | rm -rf $OUTPUT 33 | mkdir -p $OUTPUT 34 | cd $OUTPUT 35 | $UNPACK_PL $abs_bootimg 36 | [ $? != 0 ] && exit 1 37 | # Capitalize ramdisk 38 | [ -e ramdisk ] && mv ramdisk RAMDISK 39 | cd - > /dev/null 40 | } 41 | 42 | function check_result() 43 | { 44 | #[ ! -e $OUTPUT/dt.img ] && exit 1 45 | [ ! -e $OUTPUT/kernel ] && exit 1 46 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 47 | } 48 | 49 | 50 | ### Start Script ### 51 | 52 | # Check parameters 53 | [ $# -eq 0 ] && usage && exit 1; 54 | [ -z $2 ] && OUTPUT="OUT/"; 55 | 56 | init_tools; 57 | unpack_bootimg; 58 | check_result; 59 | exit 0 -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/README.md: -------------------------------------------------------------------------------- 1 | 2 | Support boot.img of MTK 2.3~4.2 3 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/mkimage: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/mtk/mkimage -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/mkmtkbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/mtk/mkmtkbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/mtkbootroot.sh: -------------------------------------------------------------------------------- 1 | #/bin/sh 2 | ramdisk="$1-ramdisk" 3 | bootheader="$1-bootheader" 4 | bootkernel="$1-kernel" 5 | cpio="$1-ramdisk.cpio.gz" 6 | 7 | defaultprop="$ramdisk/default.prop" 8 | kernelnotroot="ro.secure=1" 9 | kernelroot="ro.secure=0" 10 | startline="5" 11 | rpath="`dirname $0`" 12 | 13 | if [ $# -lt "1" ];then 14 | echo "usage:$0 bootimage" 15 | exit 0 16 | fi 17 | $rpath/unpack-mtk-bootimg.pl $1 18 | if [ -f $defaultprop ];then 19 | sed -i "/$kernelnotroot/d" $defaultprop 20 | sed -i "/$kernelroot/d" $defaultprop 21 | echo "$kernelroot" >> $defaultprop 22 | fi 23 | 24 | $rpath/mkbootfs $ramdisk | minigzip > .ramdisk.ori 25 | $rpath/mkimage .ramdisk.ori ROOTFS > .ramdisk.img 26 | rm .ramdisk.ori 27 | echo "generate the root bootimage to $1.boot" 28 | cat $bootheader $bootkernel .ramdisk.img > $1.boot 29 | rm $bootheader $bootkernel .ramdisk.img $cpio 30 | rm -rf $ramdisk 31 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # pack_boot_mtk.sh 4 | # Pack the directory to boot.img 5 | 6 | BOOTDIR=$1 7 | OUTPUT=$2 8 | 9 | function usage() 10 | { 11 | echo "Usage pack_boot_mtk.sh BOOTDIR [OUTPUT]" 12 | echo " BOOTDIR: the directory containing boot files to be pack" 13 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 14 | } 15 | 16 | function init_tools() 17 | { 18 | local old_pwd=`pwd` 19 | TOOL_DIR=`cd $(dirname $0); pwd` 20 | MKMTKBOOTIMG=$TOOL_DIR/mkmtkbootimg 21 | MKIMAGE=$TOOL_DIR/mkimage 22 | 23 | local common_dir=`cd $TOOL_DIR; cd ../common; pwd` 24 | MKBOOTFS=$common_dir/mkbootfs 25 | MINIGZIP=$common_dir/minigzip 26 | MKBOOTIMG=$common_dir/mkbootimg 27 | 28 | cd $old_pwd 29 | } 30 | 31 | function pack_bootimg() 32 | { 33 | local old_pwd=`pwd` 34 | 35 | cd $BOOTDIR 36 | $MKBOOTFS ./RAMDISK | $MINIGZIP > ramdisk.img 37 | [ $? != 0 ] && exit 1 38 | 39 | if [ -f ./RAMDISK/etc/recovery.fstab ];then 40 | $MKIMAGE ./ramdisk.img RECOVERY > ramdisk_root.img 41 | [ $? != 0 ] && exit 1 42 | else 43 | $MKIMAGE ./ramdisk.img ROOTFS > ramdisk_root.img 44 | [ $? != 0 ] && exit 1 45 | fi 46 | 47 | $MKMTKBOOTIMG --kernel ./kernel --ramdisk ./ramdisk_root.img --output pack.img 48 | [ $? != 0 ] && exit 1 49 | 50 | rm ramdisk.img ramdisk_root.img 51 | cd $old_pwd 52 | mv $BOOTDIR/pack.img $OUTPUT 53 | } 54 | 55 | # Check parameters 56 | [ $# -eq 0 ] && usage && exit 1; 57 | [ -z $2 ] && OUTPUT=out.img; 58 | 59 | init_tools; 60 | pack_bootimg; 61 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/unpack-mtk-bootimg.pl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/perl -W 2 | 3 | use strict; 4 | use bytes; 5 | use File::Path; 6 | 7 | die "did not specify boot img file\n" unless $ARGV[0]; 8 | 9 | my $bootimgfile = $ARGV[0]; 10 | 11 | my $slurpvar = $/; 12 | undef $/; 13 | open (BOOTIMGFILE, "$bootimgfile") or die "could not open boot img file: $bootimgfile\n"; 14 | my $bootimg = ; 15 | close BOOTIMGFILE; 16 | $/ = $slurpvar; 17 | 18 | my $bootheader = substr($bootimg, 0, 2048); 19 | 20 | # chop off the header 21 | $bootimg = substr($bootimg,2048); 22 | 23 | # we'll check how many ramdisks are embedded in this image 24 | my $numfiles = 0; 25 | 26 | # we look for the hex 00 00 00 00 1F 8B because we expect some trailing padding zeroes from the kernel or previous ramdisk, followed by 1F 8B (the gzip magic number) 27 | while ($bootimg =~ m/\xFF\xFF\xFF\xFF\x1F\x8B/g) { 28 | $numfiles++; 29 | } 30 | 31 | if ($numfiles == 0) { 32 | die "Could not find any embedded ramdisk images. Are you sure this is a full boot image?\n"; 33 | } elsif ($numfiles > 1) { 34 | die "Found a secondary file after the ramdisk image. According to the spec (mkbootimg.h) this file can exist, but this script is not designed to deal with this scenario.\n"; 35 | } 36 | 37 | $bootimg =~ /(.*\xFF\xFF\xFF\xFF)(\x1F\x8B.*)/s; 38 | 39 | my $kernel = $1; 40 | my $ramdisk = $2; 41 | 42 | $kernel = substr($kernel, 0, length($kernel) - 512); 43 | 44 | open (BOOTHEADERLFILE, ">$ARGV[0]-bootheader"); 45 | print BOOTHEADERLFILE $bootheader or die; 46 | close BOOTHEADERLFILE; 47 | 48 | open (KERNELFILE, ">$ARGV[0]-kernel"); 49 | print KERNELFILE $kernel or die; 50 | close KERNELFILE; 51 | 52 | open (RAMDISKFILE, ">$ARGV[0]-ramdisk.cpio.gz"); 53 | print RAMDISKFILE $ramdisk or die; 54 | close RAMDISKFILE; 55 | 56 | print "\nbootheader written to $ARGV[0]-bootheader\nkernel written to $ARGV[0]-kernel\nramdisk written to $ARGV[0]-ramdisk.cpio.gz\n"; 57 | if (-e "$ARGV[0]-ramdisk") { 58 | rmtree "$ARGV[0]-ramdisk"; 59 | print "\nremoved old directory $ARGV[0]-ramdisk\n"; 60 | } 61 | 62 | mkdir "$ARGV[0]-ramdisk" or die; 63 | chdir "$ARGV[0]-ramdisk" or die; 64 | system ("gunzip -c ../$ARGV[0]-ramdisk.cpio.gz | cpio -i"); 65 | 66 | print "\nextracted ramdisk contents to directory $ARGV[0]-ramdisk/\n"; 67 | -------------------------------------------------------------------------------- /bootimgpack/internal/mtk/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot_mtk.sh 4 | # Unpack the boot.img or recovery.img of MTK format 5 | # 6 | # @author: duanqz@gmail.com 7 | # 8 | 9 | BOOTIMG=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage unpack_boot_mtk.sh BOOTIMG [OUTPUT]" 15 | echo " BOOTIMG: the file path of the boot.img to be unpack" 16 | echo " OUTPUT: the output directory. if not present, the OUT/ directory will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | UNPACKBOOTIMG=$TOOL_DIR/unpack-mtk-bootimg.pl 24 | cd $old_pwd 25 | } 26 | 27 | function unpack_bootimg() 28 | { 29 | local old_pwd=`pwd` 30 | mkdir -p $OUTPUT 31 | cp $BOOTIMG $OUTPUT/boot.img 32 | cd $OUTPUT 33 | 34 | # Unpack boot image 35 | $UNPACKBOOTIMG boot.img 36 | [ $? != 0 ] && exit 1 37 | 38 | mv boot.img-ramdisk RAMDISK 39 | mv boot.img-kernel kernel 40 | rm -rf boot.img* 41 | 42 | cd $old_pwd 43 | } 44 | 45 | function check_result() 46 | { 47 | [ ! -e $OUTPUT/kernel ] && exit 1 48 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 49 | } 50 | 51 | 52 | ### Start Script ### 53 | 54 | # Check parameters 55 | [ $# -eq 0 ] && usage && exit 1; 56 | [ -z $2 ] && OUTPUT="OUT/"; 57 | 58 | init_tools; 59 | unpack_bootimg; 60 | check_result; 61 | exit 0 62 | -------------------------------------------------------------------------------- /bootimgpack/internal/param.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 26, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import getopt 8 | import sys 9 | 10 | class Options(object): pass 11 | OPTIONS = Options() 12 | 13 | OPTIONS.quiet = False 14 | 15 | def ParseOptions(argv, 16 | extra_opts="", extra_long_opts=(), 17 | extra_option_handler=None): 18 | try: 19 | opts, args = getopt.getopt( 20 | argv, "q" + extra_opts, 21 | ["quiet"] + 22 | list(extra_long_opts)) 23 | except getopt.GetoptError, err: 24 | print "**", str(err), "**" 25 | sys.exit(2) 26 | 27 | for o, a in opts: 28 | if o in ("-q", "--quiet"): 29 | OPTIONS.quiet = True 30 | else: 31 | if extra_option_handler is None or not extra_option_handler(o, a): 32 | assert False, "unknown option \"%s\"" % (o,) 33 | return args -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/README.md: -------------------------------------------------------------------------------- 1 | 1. Built to be used on Arm devices. 2 | 3 | 2. All binaries are statically compiled using the arm-linux-androideabi and arm-linux-gnueabi toolchains. 4 | 5 | 3. Run the mkboot script and have fun (mkboot script is a shebang manipulator) 6 | 7 | NOTE: This project (ARM) is designed to work on Android (ARM) devices, however, it will also work on Linux as well. Tested and confirmed working on Ubuntu 15.04. 8 | 9 | ### Unpack Boot.img or Recovery.img: 10 | root@android:/data/local/tmp/mkbootimg_tool/ARM # ./mkboot boot.img bootfolder 11 | 12 | Unpack & decompress boot.img to bootfolder 13 | 14 | ****** WARNING ******* WARNING ******* WARNING ****** 15 | 16 | This image is built using NON-standard mkbootimg! 17 | 18 | BASE is 0x80400000 19 | RAMDISK_OFFSET is 0x01408000 20 | 21 | You can modify mkbootimg.c with the above value(s) 22 | 23 | ****** WARNING ******* WARNING ******* WARNING ****** 24 | 25 | kernel : zImage 26 | ramdisk : ramdisk 27 | page size : 2048 28 | kernel size : 5690888 29 | ramdisk size : 520206 30 | base : 0x80400000 (Non Standard) 31 | kernel offset : 0x00008000 32 | ramdisk offset : 0x01408000 (Non Standard) 33 | second offset : 0x00f00000 34 | tags offset : 0x00000100 35 | cmd line : console=ttyHSL0,115200,n8 user_debug=31 36 | 37 | Ramdisk is gzip format. 38 | 1851 blocks 39 | Unpack completed. 40 | 41 | root@android:/data/local/tmp/mkbootimg_tools-master/ARM # 42 | 43 | ### Repack Boot.img or Recovery.img: 44 | root@android:/data/local/tmp/mkbootimg_tools-master/ARM # ./mkboot bootfolder boot.img 45 | 46 | mkbootimg from bootfolder/img_info. 47 | 48 | kernel : zImage 49 | ramdisk : new_ramdisk.gzip 50 | page size : 2048 51 | kernel size : 5690888 52 | ramdisk size : 521739 53 | base : 0x80400000 54 | kernel offset : 0x00008000 55 | ramdisk offset : 0x01408000 56 | second offset : 0x00f00000 57 | tags offset : 0x00000100 58 | cmd line : console=ttyHSL0,115200,n8 user_debug=31 59 | 60 | Kernel size: 5690888, new ramdisk size: 521739, boot.img: 6215680. 61 | 62 | boot.img has been created. 63 | 64 | root@android:/data/local/tmp/mkbootimg_tools-master/ARM # 65 | 66 | ### Repack Boot.img or Recovery.img with larger build than original: 67 | root@android:/data/local/tmp/mkbootimg_tools-master/ARM # ./mkboot bootfolder boot.img 68 | 69 | mkbootimg from bootfolder/img_info. 70 | 71 | kernel : zImage 72 | ramdisk : new_ramdisk.gzip 73 | page size : 2048 74 | kernel size : 5690888 75 | ramdisk size : 11233890 76 | base : 0x80400000 77 | kernel offset : 0x00008000 78 | ramdisk offset : 0x01408000 79 | second offset : 0x00f00000 80 | tags offset : 0x00000100 81 | cmd line : console=ttyHSL0,115200,n8 user_debug=31 82 | 83 | Kernel size: 5690888, new ramdisk size: 11233890, boot.img: 16928768. 84 | 85 | boot.img has been created. 86 | 87 | 88 | ****** CAUTION ******* CAUTION ******* CAUTION ****** 89 | 90 | boot.img is 151552 bytes larger than 91 | the original build! Make sure this new 92 | size is not larger than the actual partition! 93 | 94 | ****** CAUTION ******* CAUTION ******* CAUTION ****** 95 | 96 | root@android:/data/local/tmp/mkbootimg_tools-master/ARM # 97 | -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/bash: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/bash -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/cpio: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/cpio -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/file: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/file -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/grep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/grep -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/gzip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/gzip -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/lz4 -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/lzma -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/lzop: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/lzop -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/magic.mgc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/magic.mgc -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/mkboot: -------------------------------------------------------------------------------- 1 | # This is a wrapper script which basically manipulates the boundaries of an already limited shebang. 2 | # This allows the execution of the real mkboot (aka wrapper) script using bash from the project directory whether it be on Linux or an ARM device. 3 | 4 | target=$(pwd) 5 | script="${target}/wrapper" 6 | shebang=$(head -1 "$script") 7 | buildit="$@" 8 | 9 | # Use an array in case a argument is there too 10 | interp=( ${shebang#\#!} ) 11 | 12 | # Now run it, passing in the remaining command line arguments 13 | # EXAMPLE 1: Unpacking: ./mkboot recovery.img recoveryfolder 14 | # EXAMPLE 2: Packing: ./mkboot recoveryfolder recovery.img 15 | shift 1 16 | exec "${target}/${interp[@]}" "$script" ${buildit} 17 | -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/mkbootfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/mkbootfs -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/mkbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/mkbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/od: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/od -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/ARM/xz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/ARM/xz -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/README.md: -------------------------------------------------------------------------------- 1 | mkbootimg_tools 2 | =============== 3 | 4 | ### Unpack and repack boot.img,support dtb(dt.img): 5 | xiaolu@xiaolu-ubuntu64:~/e330s$ mkboot recoveryksuamg5.img ksuamg 6 | Unpack & decompress recoveryksuamg5.img to ksuamg 7 | kernel : /home/xiaolu/work/initramfs/s4/e330s/ksuamg5/zImage 8 | ramdisk : /home/xiaolu/work/initramfs/s4/e330s/ksuamg5/ramdisk.gz 9 | page_size : 2048 10 | base_addr : 0x00000000 11 | kernel size : 6911360 12 | kernel_addr : 0x00008000 13 | ramdisk_size : 2685222 14 | ramdisk_addr : 0x02000000 15 | second_size : 0 16 | second_addr : 0x00f00000 17 | dtb_size : 1427456 18 | tags_addr : 0x01e00000 19 | cmdline : console=null androidboot.hardware=qcom user_debug=31 maxcpus=2 msm_rtb.filter=0x3F 20 | Unpack completed. 21 | 22 | xiaolu@xiaolu-ubuntu64:~/e330s$ mkboot ksuamg5 recovery.img 23 | mkbootimg from ksuamg5/img_info. 24 | kernel : /home/xiaolu/work/initramfs/s4/e330s/ksuamg5/zImage 25 | ramdisk : /home/xiaolu/work/initramfs/s4/e330s/ksuamg5/new_ramdisk.gz 26 | page_size : 27 | base_addr : 0x00000000 28 | kernel size : 6911360 29 | kernel_addr : 0x00008000 30 | ramdisk_size : 2685222 31 | ramdisk_addr : 0x02000000 32 | second_size : 33 | second_addr : 34 | dtb_size : 1427456 35 | dtb_img : dt.img 36 | tags_addr : 0x01e00000 37 | cmdline : console=null androidboot.hardware=qcom user_debug=31 maxcpus=2 msm_rtb.filter=0x3F 38 | Kernel size: 6911360, new ramdisk size: 3416778, recovery.img: 11759616. 39 | recovery.img has been created. 40 | ... 41 | 42 | ### Create a dt.img: 43 | xiaolu@xiaolu-ubuntu64:/media/diskd/kernel/SHV-E330S_JB_Opensource/Kernel$ scripts/dtbTool -s 2048 -o arch/arm/boot/dt.img -p scripts/dtc/ arch/arm/boot/ 44 | DTB combiner: 45 | Input directory: '/media/diskd/kernel/SHV-E330S_JB_Opensource/Kernel/arch/arm/boot/' 46 | Output file: '/media/diskd/kernel/SHV-E330S_JB_Opensource/Kernel/arch/arm/boot/dt.img' 47 | Found file: msm8974-sec-ks01-r03.dtb ... chipset: 2114015745, platform: 3, rev: 0 48 | Found file: msm8974-sec-ks01-r07.dtb ... chipset: 2114015745, platform: 7, rev: 0 49 | Found file: msm8974-sec-ks01-r06.dtb ... chipset: 2114015745, platform: 6, rev: 0 50 | Found file: msm8974-sec-ks01-r04.dtb ... chipset: 2114015745, platform: 4, rev: 0 51 | Found file: msm8974-sec-ks01-r11.dtb ... chipset: 2114015745, platform: 11, rev: 0 52 | Found file: msm8974-sec-ks01-r02.dtb ... chipset: 2114015745, platform: 2, rev: 0 53 | Found file: msm8974-sec-ks01-r00.dtb ... chipset: 2114015745, platform: 0, rev: 0 54 | Found file: msm8974-sec-ks01-r05.dtb ... chipset: 2114015745, platform: 5, rev: 0 55 | Found file: msm8974-sec-ks01-r01.dtb ... chipset: 2114015745, platform: 1, rev: 0 56 | => Found 9 unique DTB(s) 57 | 58 | Generating master DTB... completed 59 | 60 | 61 | ### dtbToolCM support dt-tag & dtb v2(https://github.com/CyanogenMod/android_device_qcom_common/tree/cm-11.0/dtbtool): 62 | 63 | dtbToolCM -s 2048 -d "htc,project-id = <" -o arch/arm/boot/dt.img -p scripts/dtc/ arch/arm/boot/ 64 | 65 | 66 | ### bootimgpack 67 | 68 | mkboot is an open source project on https://github.com/xiaolu/mkbootimg_tools. 69 | 70 | We make some changes on mkboot: 71 | 1. Capitalize ramdisk 72 | 2. Suppress logs 73 | 74 | Support QCOM 4.3+, especially for dt.img of QCOM 75 | -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/dtbTool: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/dtbTool -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/dtbToolCM: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/dtbToolCM -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/dtc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/dtc -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/lz4 -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/mkbootfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/mkbootfs -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/mkbootimg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/internal/qcom/mkbootimg -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqizhi(duanqz@gmail.com) 7 | # 8 | 9 | BOOTDIR=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage pack_boot.sh BOOTDIR [OUTPUT]" 15 | echo " BOOTDIR: the directory containing boot files to be pack" 16 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | MKBOOT=$TOOL_DIR/mkboot 24 | cd $old_pwd 25 | } 26 | 27 | function pack_bootimg() 28 | { 29 | $MKBOOT $BOOTDIR $OUTPUT 30 | } 31 | 32 | ### Start Script ### 33 | 34 | # Check parameters 35 | [ $# -eq 0 ] && usage && exit 1; 36 | [ -z $2 ] && OUTPUT=out.img; 37 | 38 | init_tools; 39 | pack_bootimg; 40 | -------------------------------------------------------------------------------- /bootimgpack/internal/qcom/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # unpack_boot.sh 4 | # Unpack the standard boot.img or recovery.img of Android 5 | # 6 | # @author: duanqizhi(duanqz@gmail.com) 7 | # 8 | 9 | BOOTIMG=$1 10 | OUTPUT=$2 11 | 12 | function usage() 13 | { 14 | echo "Usage unpack_boot.sh BOOTIMG [OUTPUT]" 15 | echo " BOOTIMG: the file path of the boot.img to be unpack" 16 | echo " OUTPUT: the output directory. if not present, the OUT/ directory will be used" 17 | } 18 | 19 | function init_tools() 20 | { 21 | local old_pwd=`pwd` 22 | TOOL_DIR=`cd $(dirname $0); pwd` 23 | MKBOOT=$TOOL_DIR/mkboot 24 | cd $old_pwd 25 | } 26 | 27 | function unpack_bootimg() 28 | { 29 | # Unpack boot image 30 | $MKBOOT $BOOTIMG $OUTPUT 31 | [ $? != 0 ] && exit 1 32 | } 33 | 34 | function check_result() 35 | { 36 | #[ ! -e $OUTPUT/dt.img ] && exit 1 37 | [ ! -e $OUTPUT/kernel ] && exit 1 38 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 39 | } 40 | 41 | 42 | ### Start Script ### 43 | 44 | # Check parameters 45 | [ $# -eq 0 ] && usage && exit 1; 46 | [ -z $2 ] && OUTPUT="OUT/"; 47 | 48 | init_tools; 49 | unpack_bootimg; 50 | check_result; 51 | exit 0 -------------------------------------------------------------------------------- /bootimgpack/internal/sony/README.md: -------------------------------------------------------------------------------- 1 | 2 | Support boot.img of Sony 2.3~4.2 3 | -------------------------------------------------------------------------------- /bootimgpack/internal/sony/pack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #**************************************************# 3 | # Make sony's boot.img 4 | # Xperia 5 | #**************************************************# 6 | 7 | BOOTDIR=$1 8 | OUTPUT=$2 9 | 10 | function usage() 11 | { 12 | echo "Usage pack_boot_sony.sh BOOTDIR [OUTPUT]" 13 | echo " BOOTDIR: the directory containing boot files to be pack" 14 | echo " OUTPUT: the output directory. if not present, the out.img will be used" 15 | } 16 | 17 | function init_tools() 18 | { 19 | local old_pwd=`pwd` 20 | TOOL_DIR=`cd $(dirname $0); pwd` 21 | TOOL_MKELF=$TOOL_DIR/mkelf.py 22 | cd $old_pwd 23 | } 24 | 25 | function pack_bootimg() 26 | { 27 | local old_pwd=`pwd` 28 | cd $BOOTDIR 29 | 30 | # Files 31 | ADDR_TAG='addr' 32 | 33 | ls kernel 2>&1 > /dev/null 34 | if [ "$?" != "0" ];then 35 | echo ">>> ERROR, kernel doesn't exist!" 36 | exit 1 37 | fi 38 | 39 | FILE_KERNEL="kernel" 40 | FILE_KERNEL_ADDR=$(cat "$ADDR_TAG"_"$FILE_KERNEL") 41 | 42 | DIR_RAMDISK="RAMDISK" 43 | FILE_RAMDISK="ramdisk.img" 44 | FILE_RAMDISK_ADDR=$(cat "$ADDR_TAG"_"ramdisk.img") 45 | 46 | FILE_RPM="RPM.bin" 47 | FILE_RPM_ADDR=$(cat "$ADDR_TAG"_"$FILE_RPM") 48 | 49 | OTHER_PARAM="" 50 | for file in `ls *-[0-9]*` 51 | do 52 | addrValue=$(cat "$ADDR_TAG"_"$file") 53 | OTHER_PARAM="$OTHER_PARAM $file\@$addrValue" 54 | done 55 | 56 | # Generate ramdisk file 57 | cd $DIR_RAMDISK && find . | cpio -o -H newc | gzip > ../$FILE_RAMDISK && cd .. 58 | 59 | # Make kernel-updated.elf 60 | python $TOOL_MKELF -o pack.img \ 61 | $FILE_KERNEL@$FILE_KERNEL_ADDR \ 62 | $FILE_RAMDISK@$FILE_RAMDISK_ADDR,ramdisk \ 63 | $FILE_RPM@$FILE_RPM_ADDR,rpm \ 64 | $OTHER_PARAM 65 | [ $? != 0 ] && exit 1 66 | 67 | # Clear temporary files 68 | rm $FILE_RAMDISK 69 | cd $old_pwd 70 | mv $BOOTDIR/pack.img $OUTPUT 71 | } 72 | 73 | # Check parameters 74 | [ $# -eq 0 ] && usage && exit 1; 75 | [ -z $2 ] && OUTPUT=out.img; 76 | 77 | init_tools; 78 | pack_bootimg; 79 | -------------------------------------------------------------------------------- /bootimgpack/internal/sony/unpack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #!/bin/bash 4 | 5 | # unpack_boot_sony.sh 6 | # Unpack the boot.img or recovery.img of MTK format 7 | # 8 | # @author: duanqz@gmail.com 9 | # 10 | 11 | BOOTIMG=$1 12 | OUTPUT=$2 13 | 14 | function usage() 15 | { 16 | echo "Usage unpack_boot_sony.sh BOOTIMG [OUTPUT]" 17 | echo " BOOTIMG: the file path of the boot.img to be unpack" 18 | echo " OUTPUT: the output directory. if not present, the current OUT/ will be used" 19 | } 20 | 21 | function init_tools() 22 | { 23 | local old_pwd=`pwd` 24 | TOOL_DIR=`cd $(dirname $0); pwd` 25 | UNPACKBOOTIMG=$TOOL_DIR/unpack_boot_sony.py 26 | cd $old_pwd 27 | } 28 | 29 | function unpack_bootimg() 30 | { 31 | # Unpack boot image 32 | $UNPACKBOOTIMG $BOOTIMG $OUTPUT 33 | [ $? != 0 ] && exit 1 34 | } 35 | 36 | function check_result() 37 | { 38 | [ ! -e $OUTPUT/kernel ] && exit 1 39 | [ ! -e $OUTPUT/RAMDISK/init.rc ] && exit 1 40 | } 41 | 42 | 43 | ### Start Script ### 44 | 45 | # Check parameters 46 | [ $# -eq 0 ] && usage && exit 1; 47 | [ -z $2 ] && OUTPUT="OUT/"; 48 | 49 | init_tools; 50 | unpack_bootimg; 51 | check_result; 52 | exit 0 53 | -------------------------------------------------------------------------------- /bootimgpack/internal/sony/unpack_boot_sony.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # vim:fileencoding=utf-8 3 | 4 | import sys 5 | import os 6 | import struct 7 | import shutil 8 | 9 | outName = ("kernel","ramdisk.img","RPM.bin") 10 | 11 | def getSegNum(f): 12 | f.seek(44) 13 | d = f.read(2) 14 | return struct.unpack(' 100: 33 | return -1 # not a sony img, just return 34 | f.seek(52) 35 | 36 | fBaseName = os.path.split(fname)[1] 37 | segs = [readSegInfo(f) for i in range(n)] 38 | for i, seg in enumerate(segs): 39 | f.seek(seg[1]) 40 | data = f.read(seg[0]) 41 | 42 | if i < 3: 43 | outFileName = "%s" %(outName[i]) 44 | else: 45 | outFileName = "%s-%s" %(fBaseName,i) 46 | 47 | with open(outFileName, 'wb') as wf: 48 | wf.write(data) 49 | 50 | addrFileName="addr_%s" %(outFileName) 51 | with open(addrFileName, 'wb') as wfaddr: 52 | wfaddr.write(hex(seg[2])) 53 | 54 | if i == 1: 55 | ramdiskDir = "RAMDISK" 56 | os.mkdir(ramdiskDir) 57 | os.system("cd %s && gunzip < ../%s | cpio -i" %(ramdiskDir, outFileName)) 58 | os.remove(outFileName) 59 | 60 | if __name__ == '__main__': 61 | if len(sys.argv) < 2: 62 | print('Which boot.img need to be unpack') 63 | else: 64 | main(*sys.argv[1:]) 65 | -------------------------------------------------------------------------------- /bootimgpack/internal/toolkit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | common/unpack.sh 7 | common/pack.sh 8 | 9 | 10 | common-v1/unpack.sh 11 | common-v1/pack.sh 12 | 13 | 14 | qcom/unpack.sh 15 | qcom/pack.sh 16 | 17 | 18 | mtk/unpack.sh 19 | mtk/pack.sh 20 | 21 | 22 | mtk-v1/unpack.sh 23 | mtk-v1/pack.sh 24 | 25 | 26 | sony/unpack.sh 27 | sony/pack.sh 28 | 29 | 30 | -------------------------------------------------------------------------------- /bootimgpack/pack_bootimg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 duanqz 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """ 19 | Usage: pack_bootimg.py BOOT_IMG_DIR [OUTPUT_IMG] 20 | - BOOT_IMG_DIR : the directory of boot image files. 21 | - OUTPUT_IMG : the output image after pack. If not present, BOOT_IMG_DIR.img will be used 22 | """ 23 | 24 | 25 | __author__ = 'duanqz@gmail.com' 26 | 27 | 28 | from internal import bootimg 29 | import sys 30 | import traceback 31 | 32 | 33 | if __name__ == '__main__': 34 | argc = len(sys.argv) 35 | if argc <= 1: 36 | print __doc__ 37 | exit(1) 38 | 39 | if argc > 1: 40 | boot_dir = sys.argv[1] 41 | output = boot_dir + ".img" 42 | 43 | if argc > 2: 44 | output = sys.argv[2] 45 | 46 | try: 47 | bootimg.pack(boot_dir, output) 48 | except ValueError as ve: 49 | traceback.print_exc() 50 | # See help.xml ERR_PACK_BOOTIMG_FAILED 51 | sys.exit(154) 52 | -------------------------------------------------------------------------------- /bootimgpack/pull/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/pull/__init__.py -------------------------------------------------------------------------------- /bootimgpack/pull/fstab.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 31, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | from xml.dom import minidom 8 | import os 9 | from command import AndroidFile 10 | import sys 11 | 12 | sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 13 | from formatters.log import Log 14 | 15 | class entry(object): 16 | ERROR_VALUE = -1 17 | 18 | def __init__(self, strline, fsconfig): 19 | self.mFsconfig = fsconfig 20 | self.mSplitArr = strline.split() 21 | 22 | def length(self): 23 | return len(self.mSplitArr) 24 | 25 | def getByKey(self, key): 26 | return self.get(self.mFsconfig.position(key)) 27 | 28 | def get(self, idx=None): 29 | if idx < 0 or idx >= len(self.mSplitArr): 30 | return None 31 | return self.mSplitArr[idx] 32 | 33 | class fstabconfig(object): 34 | ARRAY_TAG = "array" 35 | ITEM_TAG = "item" 36 | BLOCK_TAG = "block" 37 | 38 | ATTR_NAME = "attr" 39 | NAME = "name" 40 | ERROR_VALUE = -1 41 | 42 | ATTR_BLOCK = "block" 43 | ATTR_FSTYPE = "fstype" 44 | ATTR_MP = "mp" 45 | ATTR_LENGTH = "length" 46 | ATTR_SIZE = "size" 47 | ATTR_START = "start" 48 | ATTR_PROP = "prop" 49 | ATTR_STAT = "stat" 50 | 51 | def __init__(self, config): 52 | self.mConfig = config 53 | self.mParsed = False 54 | self.mAttrArray = [] 55 | self.mBlockDict = {} 56 | self.__parse__() 57 | 58 | def __parse__(self): 59 | if self.mParsed is True: 60 | return 61 | 62 | root = minidom.parse(self.mConfig).documentElement 63 | for array in root.getElementsByTagName(fstabconfig.ARRAY_TAG): 64 | if array.nodeType == minidom.Node.ELEMENT_NODE: 65 | if array.getAttribute(fstabconfig.NAME) == fstabconfig.ATTR_NAME: 66 | for item in array.getElementsByTagName(fstabconfig.ITEM_TAG): 67 | if item.nodeType == minidom.Node.ELEMENT_NODE: 68 | self.mAttrArray.append(item.childNodes[0].nodeValue) 69 | 70 | for block in root.getElementsByTagName(fstabconfig.BLOCK_TAG): 71 | if block.nodeType == minidom.Node.ELEMENT_NODE: 72 | self.mBlockDict[block.getAttribute(fstabconfig.NAME)] = block.childNodes[0].nodeValue.strip('"') 73 | 74 | self.mParsed = True 75 | 76 | def position(self, name): 77 | if self.mAttrArray is None or name is None: 78 | return fstabconfig.ERROR_VALUE 79 | 80 | idx = 0 81 | while idx < len(self.mAttrArray): 82 | if self.mAttrArray[idx] == name: 83 | return idx 84 | idx = idx + 1 85 | return fstabconfig.ERROR_VALUE 86 | 87 | def getRealName(self, block): 88 | if self.mBlockDict.has_key(block): 89 | return self.mBlockDict[block] 90 | else: 91 | return None 92 | 93 | def getBlockByRealName(self, realName): 94 | for bn in self.mBlockDict.keys(): 95 | if self.mBlockDict[bn] == realName: 96 | return bn 97 | return None 98 | 99 | 100 | class fstab(object): 101 | ''' 102 | classdocs 103 | ''' 104 | 105 | def __init__(self, fsfile, fsconfig): 106 | ''' 107 | Constructor 108 | ''' 109 | self.mFsconfig = fsconfig 110 | self.mFile = fsfile 111 | self.mEntryDict = {} 112 | self.mParsed = False 113 | self.parse() 114 | 115 | def parse(self): 116 | if self.mParsed: 117 | return 118 | 119 | for line in self.mFile.read().splitlines(): 120 | strpLine = line.strip() 121 | if len(strpLine) > 0 and strpLine[0] != "#": 122 | etr = entry(strpLine, self.mFsconfig) 123 | realName = etr.getByKey(fstabconfig.ATTR_BLOCK) 124 | if realName is not None: 125 | block = self.mFsconfig.getBlockByRealName(realName) 126 | if block is not None: 127 | self.mEntryDict[block] = etr 128 | 129 | self.mParsed = True 130 | 131 | def getEntry(self, block): 132 | if self.mEntryDict.has_key(block): 133 | return self.mEntryDict[block] 134 | else: 135 | return None 136 | 137 | def getMp(self, block): 138 | return self.get(block, fstabconfig.ATTR_MP) 139 | 140 | def get(self, block, attr): 141 | etr = self.getEntry(block) 142 | if etr is not None: 143 | return etr.getByKey(attr) 144 | else: 145 | return None 146 | 147 | if __name__ == "__main__": 148 | fsconfig = fstabconfig(os.path.join(os.path.dirname(os.path.abspath(__file__)), "mtk_fstab.xml")) 149 | fs = fstab(AndroidFile("/proc/dumchar_info"), fsconfig) 150 | print fs.getMp("boot") 151 | print fs.getMp("recovery") 152 | print fs.getMp("system") -------------------------------------------------------------------------------- /bootimgpack/pull/imagetype.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Aug 1, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import tempfile 8 | import os 9 | import shutil 10 | 11 | import sys 12 | 13 | from internal import bootimg 14 | 15 | sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 16 | from common.andprop import andprop 17 | 18 | BOOT = "boot" 19 | RECOVERY = "recovery" 20 | SYSTEM = "system" 21 | CACHE = "cache" 22 | DATA = "data" 23 | 24 | class imagetype(object): 25 | ''' 26 | classdocs 27 | ''' 28 | STAT_NONE = 0 29 | STAT_UNPACKED = 1 30 | STAT_WRONG_IMG = -1 31 | 32 | RAMDISK = "RAMDISK" 33 | INIT = os.path.join(RAMDISK, "init") 34 | INIT_RC = os.path.join(RAMDISK, "init.rc") 35 | DEFAULT_PROP = os.path.join(RAMDISK, "default.prop") 36 | 37 | ETC = os.path.join(RAMDISK, "etc") 38 | RECOVERY_FSTAB = os.path.join(ETC, "recovery.fstab") 39 | 40 | SBIN = os.path.join(RAMDISK, "sbin") 41 | RECOVERY_BIN = os.path.join(SBIN, "recovery") 42 | 43 | DEVICE_PROP = "ro.product.device" 44 | 45 | def __init__(self, img): 46 | ''' 47 | Constructor 48 | ''' 49 | self.mImg = img 50 | self.mUnpackDir = None 51 | self.mStatus = imagetype.STAT_NONE 52 | 53 | def unpack(self): 54 | if self.mUnpackDir is None: 55 | self.mUnpackDir = tempfile.mkdtemp() 56 | os.removedirs(self.mUnpackDir) 57 | 58 | try: 59 | bootimg.unpack(self.mImg, self.mUnpackDir) 60 | except: 61 | self.mStatus = imagetype.STAT_WRONG_IMG 62 | 63 | return self.mUnpackDir 64 | 65 | def __getFile__(self, f): 66 | return os.path.join(self.mUnpackDir, f) 67 | 68 | def getunpackdir(self): 69 | return self.mUnpackDir 70 | 71 | def getType(self): 72 | if self.mStatus == imagetype.STAT_NONE: 73 | self.unpack() 74 | 75 | if self.mStatus < imagetype.STAT_NONE: 76 | return None 77 | 78 | iType = None 79 | if os.path.isdir(self.mUnpackDir): 80 | if os.path.isfile(self.__getFile__(imagetype.INIT)) \ 81 | and os.path.isfile(self.__getFile__(imagetype.INIT_RC)) \ 82 | and os.path.isfile(self.__getFile__(imagetype.DEFAULT_PROP)): 83 | if os.path.isfile(self.__getFile__(imagetype.RECOVERY_BIN)) \ 84 | and os.path.isfile(self.__getFile__(imagetype.RECOVERY_FSTAB)) \ 85 | and andprop(self.__getFile__(imagetype.DEFAULT_PROP)).get(imagetype.DEVICE_PROP) is not None: 86 | iType = RECOVERY 87 | else: 88 | iType = BOOT 89 | return iType 90 | 91 | def exit(self): 92 | if self.mUnpackDir is not None and os.path.isdir(self.mUnpackDir): 93 | shutil.rmtree(self.mUnpackDir) 94 | -------------------------------------------------------------------------------- /bootimgpack/pull/kk_fstab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | mp 6 | block 7 | fstype 8 | prop 9 | stat 10 | 11 | 12 | "/boot" 13 | "/recovery" 14 | "/system" 15 | "/cache" 16 | "/data" 17 | 18 | -------------------------------------------------------------------------------- /bootimgpack/pull/mtk_fstab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | block 6 | size 7 | start 8 | fstype 9 | mp 10 | length 11 | 12 | 13 | "bootimg" 14 | "recovery" 15 | "android" 16 | "cache" 17 | "usrdata" 18 | 19 | -------------------------------------------------------------------------------- /bootimgpack/pull/mtkpull.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 31, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import os 7 | import sys 8 | import imagetype 9 | 10 | from fstab import fstabconfig 11 | from fstab import fstab 12 | from command import AndroidFile 13 | from fstab import entry 14 | from pull import pull 15 | 16 | sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 17 | from formatters.log import Log 18 | 19 | LOG_TAG = "mtkpull" 20 | 21 | class mtkEntry(entry): 22 | def __init__(self, name, etr): 23 | self.mName = name 24 | self.mEntry = etr 25 | 26 | assert self.mEntry is not None, "Wrong block mount info ....." 27 | 28 | self.mBlockName = self.getByKey(fstabconfig.ATTR_BLOCK) 29 | self.mMp = self.getByKey(fstabconfig.ATTR_MP) 30 | self.mSize = int(self.getByKey(fstabconfig.ATTR_SIZE), 16) 31 | self.mStart = int(self.getByKey(fstabconfig.ATTR_START), 16) 32 | self.mFstype = self.getByKey(fstabconfig.ATTR_FSTYPE) 33 | 34 | def length(self): 35 | return self.mEntry.length() 36 | 37 | def getByKey(self, key): 38 | return self.mEntry.getByKey(key) 39 | 40 | def get(self, idx=None): 41 | return self.mEntry.get(idx) 42 | 43 | class mtkpull(pull): 44 | ''' 45 | classdocs 46 | ''' 47 | MTK_DUMCHAR_INFO = "/proc/dumchar_info" 48 | MTK_FSTAB_CONFIG = os.path.join(os.path.dirname(os.path.abspath(__file__)), "mtk_fstab.xml") 49 | mPull = None 50 | 51 | def __init__(self): 52 | ''' 53 | Constructor 54 | ''' 55 | super(mtkpull, self).__init__() 56 | self.mFstabConfig = fstabconfig(mtkpull.getFstabconfigFile()) 57 | self.mFstab = fstab(AndroidFile(mtkpull.MTK_DUMCHAR_INFO), self.mFstabConfig) 58 | 59 | Log.d(LOG_TAG, "work dir: %s" %(self.mWorkdir)) 60 | 61 | self.mBootImg = os.path.join(self.mWorkdir, "boot.img") 62 | self.mRecoveryImg = os.path.join(self.mWorkdir, "recovery.img") 63 | 64 | @staticmethod 65 | def getFstabconfigFile(): 66 | return mtkpull.MTK_FSTAB_CONFIG 67 | 68 | @staticmethod 69 | def getInstance(): 70 | if mtkpull.mPull is None: 71 | mtkpull.mPull = mtkpull() 72 | return mtkpull.mPull 73 | 74 | @staticmethod 75 | def do(outDir=None): 76 | p = mtkpull.getInstance() 77 | p.__pull__() 78 | 79 | if os.path.isfile(p.mBootImg): 80 | bootimg = imagetype.imagetype(p.mBootImg) 81 | assert bootimg.getType() == imagetype.BOOT, "Wrong boot.img....." 82 | p.mImgDict[imagetype.BOOT] = p.mBootImg 83 | bootimg.exit() 84 | 85 | if os.path.isfile(p.mRecoveryImg): 86 | recoveryimg = imagetype.imagetype(p.mRecoveryImg) 87 | assert recoveryimg.getType() == imagetype.RECOVERY, "Wrong recovery.img....." 88 | p.mImgDict[imagetype.RECOVERY] = p.mRecoveryImg 89 | recoveryimg.exit() 90 | p.out(outDir) 91 | if os.path.isfile(os.path.join(outDir, "boot.img")) \ 92 | and os.path.isfile(os.path.join(outDir, "recovery.img")): 93 | return True 94 | return False 95 | 96 | def __pull__(self): 97 | bootEntry = mtkEntry(imagetype.BOOT, self.mFstab.getEntry(imagetype.BOOT)) 98 | Log.i(LOG_TAG, "Try to pull boot partition from device ...") 99 | adBoot = AndroidFile(bootEntry.mMp) 100 | adBoot.pull(self.mBootImg, bootEntry.mStart, bootEntry.mSize) 101 | 102 | recoveryEntry = mtkEntry(imagetype.RECOVERY, self.mFstab.getEntry(imagetype.RECOVERY)) 103 | Log.i(LOG_TAG, "Try to pull recovery partition from device ...") 104 | adRecovery = AndroidFile(recoveryEntry.mMp) 105 | adRecovery.pull(self.mRecoveryImg, recoveryEntry.mStart, recoveryEntry.mSize) 106 | 107 | @staticmethod 108 | def isMtkDevice(): 109 | return AndroidFile(mtkpull.MTK_DUMCHAR_INFO).exist() 110 | -------------------------------------------------------------------------------- /bootimgpack/pull/mtkpush.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Sep 17, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | from bootimgpack.pull.fstab import fstab 7 | from bootimgpack.pull.command import AndroidFile 8 | from bootimgpack.pull.fstab import fstabconfig 9 | from bootimgpack.pull.mtkpull import mtkpull, mtkEntry 10 | 11 | class mtkpush(object): 12 | ''' 13 | classdocs 14 | ''' 15 | def __init__(self, device, fstabFile, inFile, fstab_version=1): 16 | ''' 17 | Constructor 18 | ''' 19 | self.mDevice = device 20 | self.mFstab = fstab(AndroidFile(mtkpull.MTK_DUMCHAR_INFO), fstabconfig(mtkpull.getFstabconfigFile())) 21 | 22 | self.mEntry = mtkEntry(self.mDevice, self.mFstab.getEntry(self.mDevice)) 23 | self.mInFile = inFile 24 | 25 | 26 | def do(self): 27 | mp = self.mEntry.mMp 28 | adImage = AndroidFile(mp) 29 | print ">>> start flash %s from %s to %s, start: %s, size: %s" %(self.mDevice, self.mInFile, mp, self.mEntry.mStart, self.mEntry.mSize) 30 | return adImage.dd_write(self.mInFile, self.mEntry.mStart, self.mEntry.mSize) 31 | -------------------------------------------------------------------------------- /bootimgpack/pull/normal_fstab.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | block 6 | fstype 7 | mp 8 | length 9 | 10 | 11 | "/boot" 12 | "/recovery" 13 | "/system" 14 | "/cache" 15 | "/data" 16 | 17 | -------------------------------------------------------------------------------- /bootimgpack/pull/pull.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 31, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | from command import AndroidFile 7 | import tempfile 8 | import os 9 | import imagetype 10 | import shutil 11 | import string 12 | import sys 13 | 14 | sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 15 | from formatters.log import Log 16 | 17 | LOG_TAG = "pull" 18 | 19 | class pull(object): 20 | ''' 21 | classdocs 22 | ''' 23 | mPull = None 24 | PROC_PARTITIONS = "/proc/partitions" 25 | BLOCK_DIR = "/dev/block" 26 | 27 | MIN_SIZE = 4096 28 | MAX_SIZE = 51200 29 | 30 | def __init__(self): 31 | ''' 32 | Constructor 33 | ''' 34 | self.mWorkdir = tempfile.mkdtemp() 35 | self.mImgDict = {} 36 | self.mOutDir = os.getcwd() 37 | 38 | @staticmethod 39 | def getInstance(): 40 | if pull.mPull is None: 41 | pull.mPull = pull() 42 | return pull.mPull 43 | 44 | def getAdPartitions(self, minsize, maxsize): 45 | adPt = AndroidFile(pull.PROC_PARTITIONS) 46 | assert adPt.exist(), "File %s is not exist in phone!" %(pull.PROC_PARTITIONS) 47 | 48 | outAdDict = {} 49 | Log.i(LOG_TAG, "Try to create block of partitions ...") 50 | for etr in adPt.read().splitlines(): 51 | stripEtr = etr.strip("\n") 52 | if len(stripEtr) > 0 and stripEtr[0] != "#": 53 | splitArray = stripEtr.split() 54 | if len(splitArray) == 4: 55 | try: 56 | blkSize = string.atoi(splitArray[2]) 57 | except: 58 | continue 59 | blkName = splitArray[3] 60 | adBlk = AndroidFile("%s/%s" %(pull.BLOCK_DIR, blkName)) 61 | if blkSize >= minsize and blkSize <= maxsize and adBlk.exist(): 62 | outAdDict[blkName] = adBlk 63 | Log.i(LOG_TAG, "Create block of partitions done!") 64 | return outAdDict 65 | 66 | def __pull__(self, adDict): 67 | Log.i(LOG_TAG, "Pull blocks from device ...") 68 | for blkName in adDict.keys(): 69 | pcOut = os.path.join(self.mWorkdir, blkName) 70 | Log.i(LOG_TAG, "Pull %s to %s" %(blkName, pcOut)) 71 | if adDict[blkName].pull(pcOut): 72 | Log.i(LOG_TAG, "...") 73 | img = imagetype.imagetype(pcOut) 74 | itype = img.getType() 75 | if itype is not None: 76 | self.mImgDict[itype] = pcOut 77 | img.exit() 78 | if len(self.mImgDict.keys()) >= 2: # both boot and rec had found 79 | return 80 | 81 | def out(self, outDir = None): 82 | if outDir is None: 83 | outDir = self.mOutDir 84 | for itype in self.mImgDict.keys(): 85 | outFile = os.path.join(outDir, "%s.img" %(itype)) 86 | shutil.copyfile(self.mImgDict[itype], outFile) 87 | Log.i(LOG_TAG, "Out: %s" %(outFile)) 88 | shutil.rmtree(self.mWorkdir) 89 | 90 | @staticmethod 91 | def do(outDir=None): 92 | p = pull.getInstance() 93 | adDict = p.getAdPartitions(pull.MIN_SIZE, pull.MAX_SIZE) 94 | p.__pull__(adDict) 95 | p.out(outDir) 96 | if os.path.isfile(os.path.join(outDir, "boot.img")) \ 97 | and os.path.isfile(os.path.join(outDir, "recovery.img")): 98 | return True 99 | return False 100 | -------------------------------------------------------------------------------- /bootimgpack/pull/push.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Sep 17, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | from bootimgpack.pull.fstab import fstab 7 | from bootimgpack.pull.command import AndroidFile 8 | from bootimgpack.pull.fstab import fstabconfig, entry 9 | import os 10 | 11 | class push(object): 12 | ''' 13 | classdocs 14 | ''' 15 | NORMAL_FSTAB_CONFIG = os.path.join(os.path.dirname(os.path.abspath(__file__)), "normal_fstab.xml") 16 | KK_FSTAB_CONFIG = os.path.join(os.path.dirname(os.path.abspath(__file__)), "kk_fstab.xml") 17 | 18 | def __init__(self, device, fstabFile, inFile, fstab_version=1): 19 | ''' 20 | Constructor 21 | ''' 22 | self.mDevice = device 23 | 24 | if fstab_version == 1: 25 | self.mFstab = fstab(file(fstabFile), fstabconfig(push.NORMAL_FSTAB_CONFIG)) 26 | else: 27 | self.mFstab = fstab(file(fstabFile), fstabconfig(push.KK_FSTAB_CONFIG)) 28 | 29 | self.mEntry = self.mFstab.getEntry(self.mDevice) 30 | self.mInFile = inFile 31 | 32 | 33 | def do(self): 34 | mp = self.mEntry.getByKey(fstabconfig.ATTR_MP) 35 | print ">>> start flash %s from %s to %s" %(self.mDevice, self.mInFile, mp) 36 | adImage = AndroidFile(mp) 37 | return adImage.dd_write(self.mInFile) 38 | -------------------------------------------------------------------------------- /bootimgpack/pull/utils.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 31, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import os 7 | import sys 8 | sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) 9 | sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 10 | 11 | from bootimgpack.pull.push import push 12 | from bootimgpack.pull.mtkpush import mtkpush 13 | from command import AdbShell, SuShell 14 | from formatters.log import Log 15 | from mtkpull import mtkpull 16 | from pull import pull 17 | 18 | import tempfile 19 | 20 | LOG_TAG = "pull_boot_recovery" 21 | 22 | def check(): 23 | AdbShell().waitdevices(True) 24 | 25 | class PullUtils(): 26 | 27 | @staticmethod 28 | def pull(outDir): 29 | ret = False 30 | Log.i(LOG_TAG, "Begin pull boot and recovery, make sure your phone was connected and adb devices is fine!") 31 | Log.i(LOG_TAG, "It may take a few minutes, please wait....") 32 | check() 33 | Log.i(LOG_TAG, "adb connect success.") 34 | #if mtkpull.isMtkDevice() and mtkpull.do(outDir): 35 | # Log.d("pull_boot_recovery", "Success use mtkpull to pull images....") 36 | # ret = True 37 | #else: 38 | if pull.do(outDir): 39 | Log.d("pull_boot_recovery", "Success to pull images....") 40 | ret = True 41 | assert ret == True, "Failed to pull images....." 42 | 43 | class PushUtils(): 44 | 45 | @staticmethod 46 | def push(device, fstabFile, inFile, fstab_version = 1): 47 | ret = False 48 | Log.i("flash boot or recovery", "It may take a few minutes, please wait....") 49 | check() 50 | if mtkpull.isMtkDevice() and mtkpush(device, fstabFile, inFile, fstab_version).do(): 51 | Log.d("flash boot or recovery", "Success use mtkpush to flash images....") 52 | ret = True 53 | else: 54 | if push(device, fstabFile, inFile, fstab_version).do(): 55 | Log.d("flash boot or recovery", "Success to flash images....") 56 | ret = True 57 | assert ret == True, "Failed to flash image %s for %s" %(inFile, device) 58 | 59 | return ret 60 | 61 | 62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /bootimgpack/pull_boot_recovery.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | ''' 3 | Created on Jul 31, 2014 4 | 5 | @author: tangliuxiang 6 | ''' 7 | import sys 8 | import os 9 | import traceback 10 | from pull import utils 11 | 12 | if __name__ == '__main__': 13 | if len(sys.argv) >= 2: 14 | outDir = sys.argv[1] 15 | else: 16 | outDir = os.getcwd() 17 | 18 | try: 19 | utils.PullUtils.pull(outDir) 20 | except Exception as e: 21 | traceback.print_exc() 22 | # See help.xml ERR_PULL_BOOT_RECOVERY_FAILED 23 | sys.exit(156) -------------------------------------------------------------------------------- /bootimgpack/ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/bootimgpack/ui/__init__.py -------------------------------------------------------------------------------- /bootimgpack/ui/main.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Filename main.py 3 | # Main UI of bootimgpack 4 | # 5 | 6 | __author__ = 'duanqz@gmail.com' 7 | 8 | import os 9 | from os import sys, path 10 | sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) 11 | from internal import bootimg 12 | 13 | from Tkinter import * 14 | import tkFileDialog 15 | 16 | 17 | class Main: 18 | 19 | def __init__(self): 20 | root = Tk() 21 | self.__layout(root) 22 | root.mainloop() 23 | 24 | def __layout(self, root): 25 | root.title("BootimgPack") 26 | root.geometry("500x220+400+400") 27 | root.resizable(width=False, height=False) 28 | 29 | self.__layoutBootImgFrame(root) 30 | self.__layoutPackBtnFrame(root) 31 | self.__layoutBootDirFrame(root) 32 | self.__layoutResultFrame(root) 33 | pass 34 | 35 | def __layoutBootImgFrame(self, root): 36 | frame = Frame(root) 37 | 38 | Label(frame, width=12, text="Boot Image: ", anchor=W).pack(side=LEFT) 39 | 40 | self.__bootImgText = StringVar() 41 | Entry(frame, width=40, textvariable=self.__bootImgText).pack(side=LEFT) 42 | 43 | self.__bootImgSelect = Button(frame, text="...") 44 | self.__bindButtonAction(self.__bootImgSelect, self.onClick) 45 | self.__bootImgSelect.pack(padx=5, side=LEFT) 46 | 47 | frame.pack(padx=5, pady=15) 48 | 49 | def __layoutPackBtnFrame(self, root): 50 | frame = Frame(root) 51 | 52 | self.__packBtn = Button(frame, text="PACK ^", width=7, height=1) 53 | self.__bindButtonAction(self.__packBtn, self.onClick) 54 | self.__packBtn.pack(padx=30, side=LEFT) 55 | 56 | self.__unpackBtn = Button(frame, text ="UNPACK v", width=7, height=1) 57 | self.__bindButtonAction(self.__unpackBtn, self.onClick) 58 | self.__unpackBtn.pack(side=LEFT) 59 | 60 | frame.pack(padx=5, pady=5) 61 | 62 | def __layoutBootDirFrame(self, root): 63 | frame = Frame(root) 64 | 65 | Label(frame, width=12, text="Files Directory: ", anchor=W).pack(side=LEFT) 66 | 67 | self.__bootDirText = StringVar() 68 | Entry(frame, width=40, textvariable=self.__bootDirText).pack(side=LEFT) 69 | 70 | self.__bootDirSelect = Button(frame, text="...") 71 | self.__bindButtonAction(self.__bootDirSelect, self.onClick) 72 | self.__bootDirSelect.pack(padx=5, side=LEFT) 73 | 74 | frame.pack(padx=5, pady=5) 75 | 76 | def __layoutResultFrame(self, root): 77 | frame = Frame(root, relief=SUNKEN, borderwidth=1) 78 | 79 | self.__resultText = StringVar() 80 | Label(frame, height=3, textvariable=self.__resultText, wraplength=400, anchor=NW).pack(padx=10, side=LEFT) 81 | self.__resultText.set("Result") 82 | 83 | frame.pack(padx=10, pady=20, fill=X, expand=1) 84 | 85 | def __bindButtonAction(self, btn, command): 86 | btn.bind("", command) 87 | btn.bind("", command) 88 | 89 | def onClick(self, event): 90 | if event.widget == self.__bootImgSelect: 91 | filename = tkFileDialog.askopenfilename(initialdir=os.path.expanduser("~")) 92 | if len(filename) > 0 : 93 | self.__bootImgText.set(filename) 94 | 95 | elif event.widget == self.__bootDirSelect: 96 | directory = tkFileDialog.askdirectory(initialdir=os.path.expanduser("~")) 97 | if len(directory) > 0 : 98 | self.__bootDirText.set(directory) 99 | 100 | elif event.widget == self.__unpackBtn: 101 | bootfile = self.__bootImgText.get() 102 | output = self.__bootDirText.get() 103 | 104 | if len(bootfile) > 0 : 105 | bootimg.unpack(bootfile, output) 106 | result = "Unpack " + bootfile + " --> " + output 107 | self.__resultText.set(result) 108 | 109 | elif event.widget == self.__packBtn: 110 | bootfile = self.__bootDirText.get() 111 | output = self.__bootImgText.get() 112 | 113 | if len(bootfile) > 0 : 114 | bootimg.pack(bootfile, output) 115 | result = "Pack " + bootfile + " --> " + output 116 | self.__resultText.set(result) 117 | 118 | # End of class Main 119 | 120 | ### Start 121 | if __name__ == '__main__': 122 | Main() -------------------------------------------------------------------------------- /bootimgpack/unpack_bootimg.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 duanqz 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """ 19 | Usage: pack_bootimg.py BOOT_IMG [OUTPUT_DIR] 20 | - BOOT_IMG : the input boot image to be unpacked 21 | - OUTPUT_DIR : the output director after unpack. If not present, BOOT_IMG.img will be used 22 | """ 23 | 24 | __author__ = 'duanqz@gmail.com' 25 | 26 | 27 | from internal import bootimg 28 | import sys 29 | import traceback 30 | 31 | 32 | if __name__ == '__main__': 33 | argc = len(sys.argv) 34 | if argc <= 1: 35 | print __doc__ 36 | exit(1) 37 | 38 | if argc > 1: 39 | boot_img = sys.argv[1] 40 | output = boot_img + ".out" 41 | 42 | if argc > 2: 43 | output = sys.argv[2] 44 | 45 | try: 46 | bootimg.unpack(boot_img, output) 47 | except ValueError as ve: 48 | traceback.print_exc() 49 | # See help.xml ERR_UNPACK_BOOTIMG_FAILED 50 | sys.exit(153) 51 | -------------------------------------------------------------------------------- /check-su: -------------------------------------------------------------------------------- 1 | su-tools/check-su -------------------------------------------------------------------------------- /classtobosp: -------------------------------------------------------------------------------- 1 | smaliparser/classtobosp -------------------------------------------------------------------------------- /common/__init__.py: -------------------------------------------------------------------------------- 1 | __author__ = 'tangliuxiang' 2 | -------------------------------------------------------------------------------- /common/andprop.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Aug 1, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | class andprop(object): 8 | def __init__(self, prop): 9 | self.mProp = prop 10 | self.mParsed = False 11 | self.mPropDict = {} 12 | self.__parsed__() 13 | 14 | def __parsed__(self): 15 | if self.mParsed is False: 16 | propfile = file(self.mProp) 17 | for line in propfile.readlines(): 18 | stripline = line.strip() 19 | if len(stripline) > 0 and stripline[0] != "#": 20 | try: 21 | idx = stripline.index('=') 22 | self.mPropDict[stripline[:idx].strip()] = stripline[idx + 1:].strip() 23 | except: 24 | raise "Wrong properties: %s" % (stripline) 25 | 26 | self.mParsed = True 27 | 28 | def get(self, key, defValue = None): 29 | if self.mPropDict.has_key(key): 30 | return self.mPropDict[key] 31 | else: 32 | return defValue 33 | 34 | def set(self, key, value): 35 | self.mPropDict[key] = value 36 | 37 | def out(self, outPath=None): 38 | if outPath == None: 39 | outPath = self.mProp 40 | 41 | outFile = file(outPath, "w+") 42 | for key in self.mPropDict.keys(): 43 | outFile.write("%s=%s" % (key, self.mPropDict[key])) 44 | outFile.close() 45 | -------------------------------------------------------------------------------- /config/Makefile.other: -------------------------------------------------------------------------------- 1 | # Some inactive Configurations can be used in Makefile 2 | 3 | ############################################################################## 4 | # Control whether convert all resource id of #namespace:type@name#t/a form in framework from name to id 5 | # But framework-res and mediatek-res except, as them have been supported. 6 | # The default is false. 7 | # Set true if you actrally use other framework res with name form. 8 | #----------------------------------------------------------------------------- 9 | # ALL_FRW_NAME_TO_ID := true 10 | 11 | -------------------------------------------------------------------------------- /config/cert.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Sep 3, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import re 7 | import os 8 | import sys 9 | 10 | NAME = "name" 11 | CERTIFICATE = "certificate" 12 | PRIVATE_KEY = "private_key" 13 | PRESIGNED = "PRESIGNED" 14 | 15 | class certentry(object): 16 | def __init__(self, line): 17 | self.mLine = re.sub("^[ \t]*|[ \t]*$", "", line) 18 | self.mDict = {} 19 | self.__parse__() 20 | 21 | def __parse__(self): 22 | if len(self.mLine) > 0: 23 | splitArray = self.mLine.replace("=", " ").split() 24 | assert len(splitArray) % 2 == 0, "Wrong apkcerts in line: %s" %(self.mLine) 25 | 26 | i = 0 27 | while (i + 1) < len(splitArray): 28 | self.mDict[splitArray[i]] = splitArray[i + 1].replace('"','') 29 | i = i + 2 30 | 31 | def get(self, key, defValue = None): 32 | if self.mDict.has_key(key): 33 | return self.mDict[key] 34 | else: 35 | return defValue 36 | 37 | class cert(object): 38 | ''' 39 | classdocs 40 | ''' 41 | 42 | def __init__(self, cf): 43 | ''' 44 | Constructor 45 | ''' 46 | self.mApkCerts = cf 47 | self.mEntryDict = {} 48 | self.__parse__() 49 | 50 | def __parse__(self): 51 | for line in file(self.mApkCerts, 'r').readlines(): 52 | entry = certentry(line) 53 | entryName = entry.get(NAME) 54 | if entryName is not None: 55 | self.mEntryDict[entryName] = entry 56 | else: 57 | print "Warning: Wrong apkcerts in line: %s" %(line) 58 | assert entryName is not None, "Wrong apkcerts in line: %s" %(line) 59 | 60 | def getApps(self, tag, value): 61 | appList = [] 62 | for appName in self.mEntryDict.keys(): 63 | if self.mEntryDict[appName].get(tag) == value: 64 | appList.append(appName) 65 | return appList 66 | 67 | def getPresignedApps(self): 68 | return self.getApps(CERTIFICATE, PRESIGNED) 69 | 70 | def getAppCertificate(self, appName): 71 | appName = formatAppName(appName) 72 | if self.mEntryDict.has_key(appName): 73 | return self.mEntryDict[appName].get(CERTIFICATE) 74 | else: 75 | return None 76 | 77 | def getAppPrivateKey(self, appName): 78 | appName = formatAppName(appName) 79 | if self.mEntryDict.has_key(appName): 80 | return self.mEntryDict[appName].get(PRIVATE_KEY) 81 | else: 82 | return None 83 | 84 | def getAppCertType(self, appName): 85 | ct = self.getAppCertificate(appName) 86 | return formatCertType(ct) 87 | 88 | def formatAppName(appName): 89 | if appName is not None: 90 | (root, ext) = os.path.splitext(os.path.basename(appName)) 91 | return "%s.apk" %root 92 | else: 93 | print "Warning: Wrong parameters, appName is None" 94 | return None 95 | 96 | def formatCertType(ct): 97 | if ct is not None: 98 | return re.sub("\..*$", "", os.path.basename(ct)) 99 | else: 100 | return None 101 | 102 | def getPresignedApps(cf): 103 | return cert(cf).getPresignedApps() 104 | 105 | def main(argv): 106 | if len(argv) >= 1: 107 | ct = cert(argv[0]) 108 | print ct.getPresignedApps() 109 | print ct.getAppCertType("BaiduGallery3D") 110 | print ct.getAppCertType("BaiduGallery3D.apk") 111 | print ct.getAppCertType("what/app/BaiduGallery3D.apk") 112 | print ct.getAppCertType("BaiduBrowser.apk") 113 | 114 | if __name__ == '__main__': 115 | main(sys.argv[1:]) 116 | -------------------------------------------------------------------------------- /config/density.cfg: -------------------------------------------------------------------------------- 1 | 120:ldpi 2 | 160:mdpi 3 | 240:hdpi 4 | 320:xhdpi 5 | 480:xxhdpi 6 | 560:xxxhdpi -------------------------------------------------------------------------------- /config/getresolution: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/config/getresolution -------------------------------------------------------------------------------- /config/gitignore.template: -------------------------------------------------------------------------------- 1 | /board/* 2 | /autopatch/* 3 | /out/* 4 | -------------------------------------------------------------------------------- /decode_all: -------------------------------------------------------------------------------- 1 | reverses/decode_all.sh -------------------------------------------------------------------------------- /dedat: -------------------------------------------------------------------------------- 1 | reverses/de-dat/dedat.sh -------------------------------------------------------------------------------- /fastboot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/fastboot -------------------------------------------------------------------------------- /flyme: -------------------------------------------------------------------------------- 1 | workflow/coron.py -------------------------------------------------------------------------------- /formatters/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /formatters/android_manifest.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Aug 26, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | from xml.dom import minidom 7 | import sys 8 | import re 9 | import os 10 | 11 | reload(sys) 12 | sys.setdefaultencoding("utf-8") 13 | 14 | def getPackageName(androidManifest): 15 | manDom = minidom.parse(androidManifest) 16 | return manDom.documentElement.getAttribute("package") 17 | 18 | def getPackageNameFromPublicXml(publicXml): 19 | androidManifest = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(publicXml))), "AndroidManifest.xml") 20 | if os.path.isfile(androidManifest): 21 | pkgName = getPackageName(androidManifest) 22 | else: 23 | publicXml = minidom.parse(publicXml) 24 | root = publicXml.documentElement 25 | pkgName = "" 26 | for item in root.childNodes: 27 | if item.nodeType == minidom.Node.ELEMENT_NODE: 28 | itemId = item.getAttribute("id").replace(r'0x0', r'') 29 | if len(itemId) == 7 and itemId[0] == '1': 30 | pkgName = 'android' 31 | break 32 | assert pkgName is not None and len(pkgName) > 0, "Wrong package name in %s, make sure %s is exist and correct!" % (publicXml, androidManifest) 33 | return pkgName 34 | -------------------------------------------------------------------------------- /formatters/log.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | """ 4 | Usage: log LEVEL TAG MESSAGE 5 | LEVEL : d(debug), i(info), w(warning), e(error) 6 | TAG : log tag 7 | MESSAGE : log message 8 | """ 9 | 10 | 11 | import sys 12 | 13 | class Log: 14 | 15 | DEBUG = False 16 | 17 | @staticmethod 18 | def d(tag, message): 19 | if Log.DEBUG: print "D/%s: %s" %(tag, message) 20 | 21 | @staticmethod 22 | def i(tag, message): 23 | print "I/%s: %s" %(tag, message) 24 | 25 | @staticmethod 26 | def w(tag, message): 27 | print "W/%s: %s" %(tag, message) 28 | 29 | @staticmethod 30 | def e(tag, message): 31 | print "E/%s: %s" %(tag, message) 32 | 33 | 34 | class Paint: 35 | 36 | @staticmethod 37 | def bold(s): 38 | return "%s[01m%s%s[0m" % (chr(27), s.rstrip(), chr(27)) 39 | 40 | @staticmethod 41 | def red(s): 42 | return "%s[33;31m%s%s[0m" % (chr(27), s.rstrip(), chr(27)) 43 | 44 | @staticmethod 45 | def green(s): 46 | return "%s[31;32m%s%s[0m" % (chr(27), s.rstrip(), chr(27)) 47 | 48 | @staticmethod 49 | def blue(s): 50 | return "%s[34;01m%s%s[0m" % (chr(27), s.rstrip(), chr(27)) 51 | 52 | @staticmethod 53 | def yellow(s): 54 | return "%s[31;33m%s%s[0m" % (chr(27), s.rstrip(), chr(27)) 55 | 56 | 57 | if __name__ == "__main__": 58 | if len(sys.argv) < 4: 59 | print __doc__ 60 | sys.exit() 61 | 62 | level = sys.argv[1] 63 | tag = sys.argv[2] 64 | message = sys.argv[3] 65 | 66 | if level in ("d", "debug"): Log.d(tag, message) 67 | elif level in ("i", "info") : Log.i(tag, message) 68 | elif level in ("w", "warn") : Log.w(tag, message) 69 | elif level in ("e", "error"): Log.e(tag, message) 70 | -------------------------------------------------------------------------------- /formatters/name2num.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | __author__ = 'zhangweiping@baiyi-mobile.com' 4 | 5 | import os 6 | import sys 7 | 8 | from common import Smali 9 | from common import Java 10 | from common import File 11 | from common import DataFile 12 | from common import AccessSmali 13 | 14 | class NameToNum: 15 | def __init__(self, name, path, smaliList): 16 | self.name = name 17 | self.path = path 18 | self.smaliList = smaliList 19 | self.accessSmaliSet = {} 20 | self.getAccessSmaliSet() 21 | 22 | def getAccessSmaliSet(self): 23 | dFile = open(os.path.join(self.path, self.name+".data"), 'r') 24 | for line in dFile.readlines(): 25 | tList = line.split() 26 | sName = tList[0] 27 | name = tList[1] 28 | num = tList[2] 29 | if (sName not in self.accessSmaliSet.keys()): 30 | self.accessSmaliSet[sName] = AccessSmali(sName) 31 | self.accessSmaliSet[sName].readMethod(name, num) 32 | dFile.close() 33 | 34 | def printAccessSmaliSet(self): 35 | for sName in self.accessSmaliSet.keys(): 36 | self.accessSmaliSet[sName].printMethodNameSet() 37 | 38 | def doNameToNum(self): 39 | allMethodCallNameMap = {} 40 | for aSmali in self.accessSmaliSet.keys(): 41 | self.accessSmaliSet[aSmali].createNameMap() 42 | callNameMap = self.accessSmaliSet[aSmali].methodCallNameMap 43 | for callName in callNameMap.keys(): 44 | if callName not in allMethodCallNameMap.keys(): 45 | allMethodCallNameMap[callName] = callNameMap[callName] 46 | else: 47 | raise ValueError("method call name map duplicate") 48 | 49 | for s in self.smaliList: 50 | sFile = File(os.path.join(self.path, s)) 51 | sName = Smali.getSmaliName(s) 52 | if sName in self.accessSmaliSet.keys(): 53 | sFile.replaces(self.accessSmaliSet[sName].methodDefNameMap) 54 | sFile.replaces(allMethodCallNameMap) 55 | #End of NameToNum 56 | 57 | 58 | def NameToNumForOneFile(path): 59 | if Smali.isSmali(path): 60 | path = Smali.getDataFilePath(path) #change smali path to data file path 61 | if DataFile.isDataFile(path) and os.path.exists(path): 62 | fDir = os.path.dirname(path) 63 | if cmp(fDir, "") == 0: 64 | fDir = "." 65 | name = DataFile.getDataFileName(path) 66 | else: 67 | return 68 | 69 | java = Java(fDir, name) 70 | #java.printJava() 71 | if java.getListLen() == 0: 72 | print "Can not find data file: "+os.path.join(java.path, java.name)+".data" 73 | return 74 | 75 | if False: print "NameToNum: "+os.path.join(java.path, java.name)+".data" 76 | toNum = NameToNum(java.name, java.path, java.smaliList) 77 | #toNum.printAccessSmaliSet() 78 | toNum.doNameToNum() 79 | 80 | os.remove(path) 81 | 82 | 83 | def Usage(): 84 | print "Usage: name2num.py aa/bb/A.data" 85 | print " name2num.py aa/bb/A.smali" 86 | print " name2num.py aa/bb" 87 | 88 | if __name__ == '__main__': 89 | argLen = len(sys.argv) 90 | if argLen == 2: 91 | path = sys.argv[1] 92 | if os.path.isfile(path) and (DataFile.isDataFile(path) or Smali.isSmali(path)): 93 | NameToNumForOneFile(path) 94 | 95 | elif os.path.isdir(path): 96 | for root, dirs, files in os.walk(path): 97 | for sfile in files: 98 | fPath = os.path.join(root, sfile) 99 | if DataFile.isDataFile(fPath): 100 | NameToNumForOneFile(fPath) 101 | 102 | else: 103 | Usage() 104 | else: 105 | Usage() 106 | -------------------------------------------------------------------------------- /formatters/rmline.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | who=`whoami` 4 | tmp_loc=/tmp/rmline_$who 5 | 6 | # $2 is the file name with the full absolute path 7 | function rm_line() { 8 | local action=$1 9 | local file=$2 10 | local diff_file=$tmp_loc$file.line 11 | 12 | if [ "$action" == "remove" ]; then 13 | mv $file $file.original 14 | more $file.original | sed -e '/^\s*\.line.*$/d' | sed -e 's/\/jumbo//' > $file 15 | diff $file $file.original > /dev/null || { 16 | mkdir -p `dirname $diff_file` 17 | diff -B -c $file $file.original > $diff_file 18 | } 19 | rm $file.original 20 | else 21 | if [ -f $diff_file ]; then 22 | patch -f $file -r /dev/null < $diff_file >/dev/null 2>&1 23 | rm -f $diff_file 24 | else 25 | echo "Warning: line info file ($diff_file) does not exist" >&2 26 | fi 27 | fi 28 | } 29 | 30 | action=remove 31 | if [ "$1" == "-r" ]; then 32 | action=add 33 | shift 34 | fi 35 | 36 | p=`pwd` 37 | full=`echo $1 | sed -e "s#\(^[^\/]\)#$p/\1#"` 38 | if [ -f "$full" ]; then 39 | echo $full | grep .smali$ > /dev/null && rm_line $action $full 40 | exit 0 41 | fi 42 | 43 | for file in `find $full -name "*.smali"` 44 | do 45 | rm_line $action $file 46 | done 47 | -------------------------------------------------------------------------------- /helpdoc/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/helpdoc/__init__.py -------------------------------------------------------------------------------- /helpdoc/en/help_autofix.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /helpdoc/en/help_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Error: makeconfig, command not found 8 | 9 | 10 | 1. Make sure you have setup environment: 11 | $ source build/envsetup.sh 12 | 13 | 2. makeconfig must be executable, to check it: 14 | $ ls -l build/tools/makeconfig 15 | 16 | 3. you might make it executable by: 17 | $ chmod a+x build/tools/makeconfig 18 | 19 | You should download the tools by "git clone" instead of copying. 20 | 21 | 22 | 23 | 24 | 25 | Makefile already exist! Did you already configure you device ? 26 | 27 | 28 | If you want to configure again, just remove the existing Makefile. 29 | 30 | 31 | 32 | 33 | 34 | The ota.zip is a incompatible ota package. 35 | 36 | 37 | Check whether META-INF and system directory are in ota.zip 38 | 39 | 40 | 41 | 42 | 43 | Mission Failed, as catching a Runtime Error. 44 | 45 | 46 | Check the build log ! 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /helpdoc/en/help_fullota.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Failed to run ota_from_target_files to generate an ota zip from target-files.zip 8 | 9 | 10 | 11 | 12 | 13 | Failed to generate the system.img from target-files.zip. 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /helpdoc/en/help_newproject.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Can not find recovery.fstab ! 7 | 8 | 9 | Prepare a recovery.fstab in current project directory ! 10 | 11 | 12 | 13 | 14 | 15 | Can not find ota.zip ! 16 | 17 | 18 | Prepare a ota.zip in current project directory ! 19 | 20 | 21 | 22 | 23 | 24 | The ota.zip is a incompatible ota package. 25 | 26 | 27 | Check whether META-INF and system directory are in ota.zip 28 | 29 | 30 | 31 | 32 | 33 | Can not find out/oem_target_files.zip ! 34 | 35 | 36 | Make clean, and Retry ! 37 | 38 | 39 | 40 | 41 | 42 | Mission Failed, as catching a Runtime Error. 43 | 44 | 45 | Check the build log ! 46 | 47 | 48 | 49 | 50 | 51 | Can not find recovery.img ! 52 | 53 | 54 | Prepare a recovery.img or recovery.fstab in current project directory ! 55 | 56 | 57 | 58 | 59 | 60 | Can not find boot.img ! 61 | 62 | 63 | Prepare a boot.img in current project directory, Or not set boot in vendor_modify_images[Makefile] ! 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /helpdoc/en/help_patchall.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /helpdoc/en/help_upgrade.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /helpdoc/locale: -------------------------------------------------------------------------------- 1 | en -------------------------------------------------------------------------------- /helpdoc/locale_cn: -------------------------------------------------------------------------------- 1 | zh_CN 2 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_autofix.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_config.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 未能进行: makeconfig, 找不到命令 8 | 9 | 10 | 1. 请确认你是否运行了环境安装命令: 11 | $ source build/envsetup.sh 12 | 13 | 2. 请确保makeconfig文件必须是可执行的: 14 | $ ls -l build/tools/makeconfig 15 | 16 | 你可以这样让makeconfig变成可执行文件: 17 | $ chmod a+x build/tools/makeconfig 18 | 19 | 你应该使用git clone下载tools目录. 20 | 21 | 22 | 23 | 24 | 25 | Makefile已经存在! 确认已经配置好你的设备? 26 | 27 | 28 | 如果你想重新配置Makefile,请把Makefile文件删除并再次执行. 29 | 30 | 31 | 32 | 33 | 34 | 这不是一个标准格式的卡刷包,不兼容该卡刷包! 35 | 36 | 37 | 请检查META-INF和system文件夹是否在卡刷包里! 38 | 39 | 40 | 41 | 42 | 43 | 任务失败了,抓到一个运行时发生的错误. 44 | 45 | 46 | 请检查日志! 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_fullota.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 未能运行ota_from_target_files从target-files.zip生成一个ota.zip 8 | 9 | 10 | 11 | 12 | 13 | 未能从target-files.zip上生成一个system.img. 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_newproject.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 找不到recovery分区表文件 recovery.fstab ! 7 | 8 | 9 | 请准备好一个recovery分区表文件(recovery.fstab)放入当前工程目录! 10 | 11 | 12 | 13 | 14 | 15 | 找不到 ota.zip ! 16 | 17 | 18 | 请准备好一个recovery卡刷包(ota.zip)放在当前工程目录下 ! 19 | 20 | 21 | 22 | 23 | 24 | 这不是一个标准格式的卡刷包,不兼容该卡刷包! 25 | 26 | 27 | 请检查META-INF和system文件夹是否在卡刷包里! 28 | 29 | 30 | 31 | 32 | 33 | 找不到 out/oem_target_files.zip ! 34 | 35 | 36 | 输入make clean, 并再次执行 ! 37 | 38 | 39 | 40 | 41 | 42 | 任务失败了,抓到一个运行时发生的错误. 43 | 44 | 45 | 请检查日志! 46 | 47 | 48 | 49 | 50 | 51 | 找不到 recovery.img ! 52 | 53 | 54 | 请准备好一个recovery镜像文件(recovery.img)或者recovery分区表文件(recovery.fstab)放在当前工程目录 ! 55 | 56 | 57 | 58 | 59 | 60 | 找不到 boot.img ! 61 | 62 | 63 | 请准备好一个boot.img内核镜像放在当前工程目录或者不要在Makefile的vendor_modify_images上配置boot ! 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_patchall.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /helpdoc/zh_CN/help_upgrade.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /idtoname: -------------------------------------------------------------------------------- 1 | formatters/idtoname.py -------------------------------------------------------------------------------- /lib64/libc++.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/lib64/libc++.so -------------------------------------------------------------------------------- /log: -------------------------------------------------------------------------------- 1 | formatters/log.py -------------------------------------------------------------------------------- /makeconfig: -------------------------------------------------------------------------------- 1 | config/makeconfig -------------------------------------------------------------------------------- /methodtobosp: -------------------------------------------------------------------------------- 1 | smaliparser/methodtobosp -------------------------------------------------------------------------------- /name2num: -------------------------------------------------------------------------------- 1 | formatters/name2num.py -------------------------------------------------------------------------------- /nametoid: -------------------------------------------------------------------------------- 1 | formatters/nametoid.py -------------------------------------------------------------------------------- /num2name: -------------------------------------------------------------------------------- 1 | formatters/num2name.py -------------------------------------------------------------------------------- /otadiff: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | REMOVE_PRE_ZIP=false 4 | BOARD_META=$PORT_ROOT/board/release/META 5 | OTA_FROM_TARGET=$PORT_BUILD/tools/releasetools/ota_from_target_files 6 | TEST_KEY=$PORT_BUILD/security/testkey 7 | OUT_DIR=out 8 | 9 | function getsignotapara() 10 | { 11 | unzip -j -o $POST_ZIP META/misc_info.txt -d $OUT_DIR > /dev/null 2>&1 12 | if [ $? == 0 -a -f $OUT_DIR/misc_info.txt ];then 13 | if [ $(cat $OUT_DIR/misc_info.txt | grep "not_sign_ota=true" | wc -l) = 1 ];then 14 | # SIGN_OTA_PARA=--no_sign 15 | echo ">>> Won't sign Incremental OTA Package." 16 | return 0 17 | fi 18 | rm -f $OUT_DIR/misc_info.txt 19 | fi 20 | SIGN_OTA_PARA="" 21 | return 1 22 | } 23 | 24 | function getversionnum() 25 | { 26 | target_file=$1 27 | version="" 28 | name="" 29 | unzip -j -o $target_file SYSTEM/build.prop -d $OUT_DIR > /dev/null 2>&1 30 | if [ $? == 0 -a -f $OUT_DIR/build.prop ];then 31 | if [ $(cat $OUT_DIR/build.prop | grep "ro.build.display.id" | wc -l) == 1 ];then 32 | version=$(cat $OUT_DIR/build.prop | grep "ro.build.display.id" | awk -F= '{print $2}') 33 | fi 34 | if [ $(cat $OUT_DIR/build.prop | grep "ro.product.name" | wc -l) == 1 ];then 35 | name=$(cat $OUT_DIR/build.prop | grep "ro.product.name" | awk -F= '{print $2}') 36 | fi 37 | rm -f $OUT_DIR/build.prop 38 | fi 39 | if [ x"$version" = x"" ];then 40 | version=$(basename $target_file) 41 | version=${version%%.zip*} 42 | fi 43 | } 44 | 45 | function otadiff() 46 | { 47 | getsignotapara 48 | OUT_ZIP=${OUT_ZIP// /_} 49 | echo "$OTA_FROM_TARGET $SIGN_OTA_PARA -n -k $TEST_KEY -i $PRE_ZIP $POST_ZIP $OUT_ZIP" 50 | $OTA_FROM_TARGET $SIGN_OTA_PARA -n -k $TEST_KEY -i $PRE_ZIP $POST_ZIP $OUT_ZIP 51 | echo ">>> Out ==> $OUT_ZIP" 52 | } 53 | 54 | function ota2target() 55 | { 56 | unzip -t $PRE_ZIP SYSTEM/build.prop > /dev/null 2>&1 57 | if [ $? == 0 ];then 58 | return 0 59 | fi 60 | 61 | echo ">>> create a target package from ota package ..." 62 | preTmpDir=`mktemp -dt pre.target.XXXX` 63 | unzip -q -o $PRE_ZIP -d $preTmpDir 64 | 65 | if [ -d $preTmpDir/system ]; then 66 | mv $preTmpDir/system $preTmpDir/SYSTEM 67 | ls $preTmpDir/*.img 68 | if [ $? == 0 ]; then 69 | mkdir $preTmpDir/BOOTABLE_IMAGES 70 | mv $preTmpDir/*.img $preTmpDir/BOOTABLE_IMAGES 71 | fi 72 | 73 | postTmpDir=`mktemp -dt post.target.XXXX` 74 | unzip -q -o $POST_ZIP -d $postTmpDir 75 | 76 | if [ -d $postTmpDir/META ]; then 77 | cp -rf $postTmpDir/META $preTmpDir 78 | else 79 | cp -rf $BOARD_META $preTmpDir 80 | fi 81 | 82 | newTarget=`mktemp -tu new.target.XXXX.zip` 83 | cd $preTmpDir 84 | zip $newTarget * -rqy 85 | cd - 86 | 87 | PRE_ZIP=$newTarget 88 | REMOVE_PRE_ZIP=true 89 | 90 | rm -rf $postTmpDir 91 | fi 92 | #echo "preTmpDir: $preTmpDir" 93 | rm -rf $preTmpDir 94 | } 95 | 96 | function getotadiffname() 97 | { 98 | if [ x"$OUT_ZIP" == x"" ]; then 99 | getversionnum $PRE_ZIP 100 | pre_version=$version 101 | getversionnum $POST_ZIP 102 | post_version=$version 103 | OUT_ZIP=$OUT_DIR/ota-diff-$name-$pre_version-$post_version.zip 104 | echo ">>> Create ota package name: $OUT_ZIP" 105 | fi 106 | } 107 | 108 | function main() 109 | { 110 | ota2target 111 | getotadiffname 112 | otadiff $PRE_ZIP $POST_ZIP $OUT_ZIP 113 | 114 | if [ $REMOVE_PRE_ZIP == true ]; then 115 | rm $PRE_ZIP 116 | fi 117 | } 118 | 119 | if [ $# -lt 2 ]; then 120 | echo "Usage: otadiff pre-target-files.zip/ota.zip target-files.zip [ota-diff.zip]" 121 | echo " pre-target-files.zip: the previous target files or ota.zip" 122 | echo " target-files.zip: the current target files" 123 | echo " [ota-diff.zip]: the ota update zip" 124 | exit 1 125 | fi 126 | 127 | PRE_ZIP=$1 128 | POST_ZIP=$2 129 | OUT_ZIP=$3 130 | 131 | main 132 | -------------------------------------------------------------------------------- /otanormalize: -------------------------------------------------------------------------------- 1 | reverses/otanormalize.py -------------------------------------------------------------------------------- /pack_bootimg: -------------------------------------------------------------------------------- 1 | bootimgpack/pack_bootimg.py -------------------------------------------------------------------------------- /pull: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: tangliuxiang 3 | 4 | function usage() 5 | { 6 | echo "USAGE: pull " 7 | echo " - copy file/dir from device to pc" 8 | echo "Just like the usage of adb pull" 9 | } 10 | 11 | if [ "$#" -lt 2 ]; then 12 | usage 13 | exit 1 14 | fi 15 | 16 | progdir=`dirname $0`/su-tools 17 | 18 | check-su 2>&1 > /dev/null 19 | 20 | if [ $? == 0 ]; then 21 | su-pull $@ || exit $? 22 | else 23 | adb root 24 | echo "wait for devices..." 25 | adb wait-for-devices 26 | adb remount 27 | adb wait-for-devices 28 | adb pull $@ || exit $? 29 | 30 | echo ">>> Success pulled $1 to $2" 31 | fi 32 | -------------------------------------------------------------------------------- /pull_boot_recovery: -------------------------------------------------------------------------------- 1 | bootimgpack/pull_boot_recovery.py -------------------------------------------------------------------------------- /push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: tangliuxiang 3 | 4 | PERMISSION="" 5 | if [ "x$1" == "x-p" ]; then 6 | PERMISSION=$2 7 | shift 8 | shift 9 | fi 10 | 11 | function usage() 12 | { 13 | echo "USAGE: push " 14 | echo " - copy file/dir to device" 15 | echo "Just like the usage of adb push" 16 | } 17 | 18 | if [ "$#" -lt 2 ]; then 19 | usage 20 | exit 1 21 | fi 22 | 23 | progdir=`dirname $0`/su-tools 24 | 25 | check-su 2>&1 > /dev/null 26 | 27 | if [ $? == 0 ]; then 28 | if [ "x$PERMISSION" != "x" ]; then 29 | PERMISSION="-p $PERMISSION" 30 | fi 31 | su-push $PERMISSION $@ || exit $? 32 | else 33 | adb root 34 | echo "wait for devices..." 35 | adb wait-for-devices 36 | adb remount 37 | adb wait-for-devices 38 | adb push $@ || exit $? 39 | 40 | if [ "x$PERMISSION" != "x" ]; then 41 | p_chmod="$progdir/phone-chmod" 42 | phone_chmod=/data/local/tmp/phone-chmod 43 | adb push $p_chmod $phone_chmod 44 | adb shell chmod 777 $phone_chmod 45 | 46 | adb shell $phone_chmod --after-push $1 $PERMISSION $2 || exit $? 47 | fi 48 | echo ">>> Success pushed $1 to $2" 49 | fi 50 | -------------------------------------------------------------------------------- /reverses/README.md: -------------------------------------------------------------------------------- 1 | Android 6.0 23 Marshmallow 2 | Android 5.1 22 Lollipop 3 | Android 5.0 21 Lollipop 4 | Android 4.4 19 KITKAT 5 | Android 4.3 18 JELLY_BEAN_MR2 6 | Android 4.2, 4.2.2 17 JELLY_BEAN_MR1 7 | Android 4.1, 4.1.1 16 JELLY_BEAN 8 | Android 4.0.3, 4.0.4 15 ICE_CREAM_SANDWICH_MR1 9 | Android 4.0, 4.0.1, 4.0.2 14 ICE_CREAM_SANDWICH 10 | Android 3.2 13 HONEYCOMB_MR2 11 | Android 3.1.x 12 HONEYCOMB_MR1 12 | Android 3.0.x 11 HONEYCOMB 13 | Android 2.3.4 14 | Android 2.3.3 10 GINGERBREAD_MR1 15 | Android 2.3.2 16 | Android 2.3.1 17 | Android 2.3 9 GINGERBREAD 18 | Android 2.2.x 8 FROYO 19 | Android 2.1.x 7 ECLAIR_MR1 20 | Android 2.0.1 6 ECLAIR_0_1 21 | Android 2.0 5 ECLAIR 22 | Android 1.6 4 DONUT 23 | Android 1.5 3 CUPCAKE 24 | Android 1.1 2 BASE_1_1 25 | Android 1.0 1 BASE 26 | -------------------------------------------------------------------------------- /reverses/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /reverses/apktool.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/apktool.jar -------------------------------------------------------------------------------- /reverses/apktool.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2007 The Android Open Source Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This script is a wrapper for smali.jar, so you can simply call "smali", 18 | # instead of java -jar smali.jar. It is heavily based on the "dx" script 19 | # from the Android SDK 20 | 21 | # Set up prog to be the path of this script, including following symlinks, 22 | # and set up progdir to be the fully-qualified pathname of its directory. 23 | prog="$0" 24 | while [ -h "${prog}" ]; do 25 | newProg=`/bin/ls -ld "${prog}"` 26 | #echo ${newProg} 27 | 28 | 29 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 30 | if expr "x${newProg}" : 'x/' >/dev/null; then 31 | prog="${newProg}" 32 | else 33 | progdir=`dirname "${prog}"` 34 | prog="${progdir}/${newProg}" 35 | fi 36 | done 37 | oldwd=`pwd` 38 | progdir=`dirname "${prog}"` 39 | cd "${progdir}" 40 | progdir=`pwd` 41 | prog="${progdir}"/`basename "${prog}"` 42 | cd "${oldwd}" 43 | 44 | 45 | jarfile=apktool.jar 46 | libdir="$progdir" 47 | if [ ! -r "$libdir/$jarfile" ] 48 | then 49 | echo `basename "$prog"`": can't find $jarfile" 50 | exit 1 51 | fi 52 | 53 | javaOpts="" 54 | 55 | # If you want DX to have more memory when executing, uncomment the following 56 | # line and adjust the value accordingly. Use "java -X" for a list of options 57 | # you can pass here. 58 | # 59 | javaOpts="-Xmx512M" 60 | 61 | # Alternatively, this will extract any parameter "-Jxxx" from the command line 62 | # and pass them to Java (instead of to dx). This makes it possible for you to 63 | # add a command-line parameter such as "-JXmx256M" in your ant scripts, for 64 | # example. 65 | while expr "x$1" : 'x-J' >/dev/null; do 66 | opt=`expr "$1" : '-J\(.*\)'` 67 | javaOpts="${javaOpts} -${opt}" 68 | shift 69 | done 70 | 71 | if [ "$OSTYPE" = "cygwin" ] ; then 72 | jarpath=`cygpath -w "$libdir/$jarfile"` 73 | else 74 | jarpath="$libdir/$jarfile" 75 | fi 76 | 77 | ERROR_NO=1 78 | if [ "x$1" == "xb" ]; then 79 | ERROR_NO=161 80 | elif [ "x$1" == "xd" ]; then 81 | ERROR_NO=162 82 | fi 83 | 84 | java $javaOpts -jar $jarpath $@ 85 | RET=$? 86 | if [ $RET == 1 ]; then 87 | exit $ERROR_NO 88 | fi 89 | -------------------------------------------------------------------------------- /reverses/common.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | __author__ = 'duanqz@gmail.com' 19 | 20 | 21 | """ 22 | Android has different VMs, each might has its own format. 23 | From 2.3 to 4.3, DALVIK VM is used, and the format ODEX is introduced for efficiency. 24 | From 4.4, ART comes out, the format ELF is designed for ART. 25 | 26 | For easy use, CORON only treat standard OTA package, so we need to convert different OTA 27 | package to the unified format. 28 | 29 | Usage: $shell [-a|-f|-l|-c] -i input.zip -o output.zip 30 | --app, -a: only format the system apps 31 | --framework, -f: only format the framework jars 32 | --apiLevel, -l: set the API Level to deodex 33 | --classpath, -c: set the classpath to deodex 34 | """ 35 | 36 | 37 | import os 38 | import sys 39 | import getopt 40 | import subprocess 41 | 42 | TAG="reverse" 43 | 44 | class Options(object): 45 | 46 | def usage(self): 47 | print __doc__ 48 | 49 | def __init__(self): 50 | self.apiLevel = None 51 | self.classpath = None 52 | 53 | # Only handle system APKs 54 | self.formatApp = False 55 | 56 | # Only handle framework JARS 57 | self.formatFrw = False 58 | 59 | self.inZip = None 60 | self.outZip = None 61 | 62 | 63 | def handle(self, argv): 64 | """ Handle input arguments. 65 | """ 66 | 67 | if len(argv) <= 1: 68 | self.usage() 69 | sys.exit(1) 70 | 71 | try: 72 | (opts, args) = getopt.getopt(argv[1:], "hafl:c:i:o:", \ 73 | [ "help", "app", "framework", "apilevel=", "classpath=", "input=", "output=" ]) 74 | Log.d(TAG, "Program args = %s" %args) 75 | except getopt.GetoptError: 76 | Options.usage() 77 | 78 | for name, value in opts: 79 | if name in ("--help", "-h"): 80 | self.usage() 81 | sys.exit(0) 82 | 83 | elif name in ("--app", "-a"): 84 | self.formatApp = True 85 | 86 | elif name in ("--framework", "-f"): 87 | self.formatFrw = True 88 | 89 | elif name in ("--apilevel", "-l"): 90 | self.apiLevel = value 91 | 92 | elif name in ("--classpath", "-c"): 93 | self.classpath = value 94 | 95 | elif name in ("--input", "-i"): 96 | self.inZip = os.path.abspath(value) 97 | 98 | elif name in ("--output", "-o"): 99 | self.outZip = os.path.abspath(value) 100 | 101 | if self.inZip == None: 102 | Log.e(TAG, "No ota package is presented, nothing to be normalized.") 103 | self.usage 104 | sys.exit(1) 105 | 106 | if self.outZip == None: 107 | self.outZip = self.inZip + ".std.zip" 108 | 109 | if self.formatApp == False and self.formatFrw == False: 110 | self.formatApp = self.formatFrw = True 111 | 112 | def dump(self): 113 | Log.d(TAG, "input=%s, output=%s, apiLevel=%s" % (self.inZip, self.outZip, self.apiLevel)) 114 | 115 | 116 | 117 | class Utils: 118 | 119 | @staticmethod 120 | def runWithOutput(args): 121 | subp = Utils.run(args, stdout=subprocess.PIPE) 122 | Utils.printSubprocessOut(subp) 123 | 124 | 125 | @staticmethod 126 | def run(args, **kwargs): 127 | """Create and return a subprocess.Popen object, printing the command 128 | line on the terminal 129 | """ 130 | 131 | return subprocess.Popen(args, **kwargs) 132 | 133 | 134 | @staticmethod 135 | def printSubprocessOut(subp): 136 | while True: 137 | buff = subp.stdout.readline().strip('\n') 138 | if buff == '' and subp.poll() != None: 139 | break 140 | if len(buff) > 0: 141 | Log.d(TAG, buff) 142 | 143 | 144 | 145 | class Log: 146 | 147 | DEBUG = False 148 | 149 | @staticmethod 150 | def d(tag, message): 151 | if Log.DEBUG: print "D/%s: %s" %(tag, message) 152 | 153 | @staticmethod 154 | def i(tag, message): 155 | print "I/%s: %s" %(tag, message) 156 | 157 | @staticmethod 158 | def w(tag, message): 159 | print "W/%s: %s" %(tag, message) 160 | 161 | @staticmethod 162 | def e(tag, message): 163 | print "E/%s: %s" %(tag, message) -------------------------------------------------------------------------------- /reverses/de-dat/README.md: -------------------------------------------------------------------------------- 1 | Android 5.0 (Lollipop) compiled roms (aosp,cm,stock) are not compressed anymore the way they 2 | used to be on previous android versions. On previous versions all content inside /system folder 3 | that has to be extracted within our device was either uncompressed (simple /system folder inside our flashable zip) 4 | or compressed in a system.img file, which it is a ext4 compressed file; both of these, 5 | anyway, were readable and we could see all system files (app,framework, etc). 6 | 7 | Android 5.0 zip structure: 8 | * META-INF (folder containing scripts) 9 | * system.new.dat (compressed /system partition) 10 | * system.patch.dat 11 | * system.transfer.list (see explanation below) 12 | 13 | # sdat2img 14 | Convert sparse Android data image (.dat) to filesystem ext4 image (.img) 15 | 16 | # img2sdat 17 | img2sdat binary for Android 18 | 19 | ## Requirements 20 | This binary requires Python 3.x installed on your system. 21 | 22 | It currently supports Windows x86/x64, Linux x86/x64 & arm/arm64 architectures. 23 | 24 | 25 | 26 | ## Usage 27 | ``` 28 | sdat2img.py 29 | ``` 30 | - `transfer_list` = input, system.transfer.list from rom zip 31 | - `system_new_file` = input, system.new.dat from rom zip 32 | - `system_ext4` = output ext4 raw image file 33 | 34 | 35 | 36 | ## Example 37 | This is a simple example on a Linux system: 38 | ``` 39 | ~$ ./sdat2img.py system.transfer.list system.new.dat system.img 40 | ``` 41 | 42 | 43 | ## Github 44 | 45 | 46 | 47 | 48 | ## Info 49 | For more information about this binary, visit . 50 | -------------------------------------------------------------------------------- /reverses/de-dat/dedat.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | ROOT=$1 19 | SYS_TRANS_LIST=$ROOT/system.transfer.list 20 | SYS_NEW_DAT=$ROOT/system.new.dat 21 | SYS_EXT4_IMG=$ROOT/system.img 22 | SYS_DIR=$ROOT/system 23 | 24 | function usage() 25 | { 26 | echo "Usage: $0 ROOT_DIRECTORY_OF_UNZIPED_OTA_PACKAGE" 27 | } 28 | 29 | 30 | function convert_dat_to_img() 31 | { 32 | 33 | [ ! -e $SYS_TRANS_LIST ] && return 34 | [ ! -e $SYS_NEW_DAT ] && return 35 | 36 | $SDAT2IMG $SYS_TRANS_LIST $SYS_NEW_DAT $SYS_EXT4_IMG 37 | } 38 | 39 | 40 | function unpack_sys_ext4_img() 41 | { 42 | [ ! -e $SYS_EXT4_IMG ] && return 43 | 44 | local name=`whoami` 45 | local outdir=`mktemp -d /tmp/dedat.mount.XXXXX` 46 | sudo mount -t ext4 -o loop $SYS_EXT4_IMG $outdir 47 | sudo cp -r $outdir $SYS_DIR 48 | sudo chown -R $name:$name $SYS_DIR 49 | sudo umount $outdir 50 | rm -rf $outdir 51 | 52 | echo "DEDAT ===> $SYS_DIR" 53 | } 54 | 55 | prog="$0" 56 | while [ -h "${prog}" ]; do 57 | newProg=`/bin/ls -ld "${prog}"` 58 | 59 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 60 | if expr "x${newProg}" : 'x/' >/dev/null; then 61 | prog="${newProg}" 62 | else 63 | progdir=`dirname "${prog}"` 64 | prog="${progdir}/${newProg}" 65 | fi 66 | done 67 | oldwd=`pwd` 68 | progdir=`dirname "${prog}"` 69 | cd "${progdir}" 70 | progdir=`pwd` 71 | prog="${progdir}"/`basename "${prog}"` 72 | cd "${oldwd}" 73 | 74 | SDAT2IMG=sdat2img.py 75 | if [ ! -r "$progdir/$SDAT2IMG" ] 76 | then 77 | echo `basename "$prog"`": can't find $SDAT2IMG" 78 | exit 1 79 | fi 80 | 81 | if [ "$OSTYPE" = "cygwin" ] ; then 82 | SDAT2IMG=`cygpath -w "$progdir/$SDAT2IMG"` 83 | else 84 | SDAT2IMG="$progdir/$SDAT2IMG" 85 | fi 86 | 87 | [ ! -d "$ROOT" ] && usage && exit 1 88 | 89 | convert_dat_to_img 90 | unpack_sys_ext4_img 91 | 92 | -------------------------------------------------------------------------------- /reverses/de-dat/img2sdat.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | #encoding:utf8 3 | #==================================================== 4 | # FILE: img2sdat.py 5 | # AUTHORS: xpirt - luxi78 - howellzhu 6 | # DATE: 2015-10-11 14:37:22 CST 7 | #==================================================== 8 | 9 | import sys, blockimgdiff, sparse_img, os 10 | 11 | def main(sysimg, outdir): 12 | tgt = sparse_img.SparseImage(sysimg) 13 | bif = blockimgdiff.BlockImageDiff(tgt, None) 14 | bif.Compute(outdir) 15 | return 16 | 17 | if __name__ == '__main__': 18 | sysimg = 'system.img' 19 | outdir = './' 20 | if len(sys.argv) == 1: 21 | print ("\nimg2sdat - usage is: \n\n img2sdat [system.img] [outdir]\n\n") 22 | print ("Visit xda thread for more information.\n") 23 | try: 24 | input = raw_input 25 | except NameError: pass 26 | input ("Press ENTER to exit...\n") 27 | sys.exit(1) 28 | if len(sys.argv) >= 2: 29 | sysimg = sys.argv[1] 30 | if len(sys.argv) >= 3: 31 | outdir = sys.argv[2] + '/' 32 | if len(sys.argv) >= 4: 33 | print ("\nimg2sdat - usage is: \n\n img2sdat [system.img] [outdir]" % sys.argv[0]) 34 | print ("Visit xda thread for more information.\n") 35 | try: 36 | input = raw_input 37 | except NameError: pass 38 | input ("Press ENTER to exit...\n") 39 | sys.exit(1) 40 | main(sysimg, outdir) 41 | -------------------------------------------------------------------------------- /reverses/de-dat/make_ext4fs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/de-dat/make_ext4fs -------------------------------------------------------------------------------- /reverses/de-dat/rimg2sdat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/de-dat/rimg2sdat -------------------------------------------------------------------------------- /reverses/de-dat/sdat2img.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | #==================================================== 4 | # FILE: sdat2img.py 5 | # AUTHORS: xpirt - luxi78 - howellzhu 6 | # DATE: 2015-10-11 16:33:32 CST 7 | #==================================================== 8 | 9 | import sys, os 10 | 11 | try: 12 | TRANSFER_LIST_FILE = str(sys.argv[1]) 13 | NEW_DATA_FILE = str(sys.argv[2]) 14 | OUTPUT_IMAGE_FILE = str(sys.argv[3]) 15 | except IndexError: 16 | print ("\nsdat2img - usage is: \n\n sdat2img \n\n") 17 | print ("Visit xda thread for more information.\n") 18 | try: 19 | input = raw_input 20 | except NameError: pass 21 | input ("Press ENTER to exit...\n") 22 | sys.exit() 23 | 24 | BLOCK_SIZE = 4096 25 | 26 | def rangeset(src): 27 | src_set = src.split(',') 28 | num_set = [int(item) for item in src_set] 29 | if len(num_set) != num_set[0]+1: 30 | print ('Error on parsing following data to rangeset:\n%s' % src) 31 | sys.exit(1) 32 | 33 | return tuple ([ (num_set[i], num_set[i+1]) for i in range(1, len(num_set), 2) ]) 34 | 35 | def parse_transfer_list_file(path): 36 | trans_list = open(TRANSFER_LIST_FILE, 'r') 37 | version = int(trans_list.readline()) # 1st line = transfer list version 38 | new_blocks = int(trans_list.readline()) # 2nd line = total number of blocks 39 | 40 | # system.transfer.list: 41 | # - version 1: android-5.0.0_r1 42 | # - version 2: android-5.1.0_r1 43 | # - version 3: android-6.0.0_r1 44 | 45 | # skip next 2 lines. we don't need this stuff now 46 | if version >= 2: 47 | trans_list.readline() # 3rd line = stash entries needed simultaneously 48 | trans_list.readline() # 4th line = number of blocks that will be stashed 49 | 50 | commands = [] 51 | for line in trans_list: 52 | line = line.split(' ') # 5th & next lines should be only commands 53 | cmd = line[0] 54 | if cmd in ['erase', 'new', 'zero']: 55 | commands.append([cmd, rangeset(line[1])]) 56 | else: 57 | # skip lines starting with numbers, they're not commands anyway. 58 | if not cmd[0].isdigit(): 59 | print ('No valid command: %s.' % cmd) 60 | trans_list.close() 61 | sys.exit(1) 62 | 63 | trans_list.close() 64 | return version, new_blocks, commands 65 | 66 | def init_output_file_size(output_file_obj, commands): 67 | all_block_sets = [i for command in commands for i in command[1]] 68 | max_block_num = max(pair[1] for pair in all_block_sets) 69 | output_file_obj.seek(max_block_num*BLOCK_SIZE - 1) 70 | output_file_obj.write('\0'.encode('utf-8')) 71 | output_file_obj.flush() 72 | 73 | def main(argv): 74 | version, new_blocks, commands = parse_transfer_list_file(TRANSFER_LIST_FILE) 75 | output_img = open(OUTPUT_IMAGE_FILE, 'wb') 76 | init_output_file_size(output_img, commands) 77 | new_data_file = open(NEW_DATA_FILE, 'rb') 78 | 79 | for command in commands: 80 | if command[0] == 'new': 81 | for block in command[1]: 82 | begin = block[0] 83 | end = block[1] 84 | block_count = end - begin 85 | data = new_data_file.read(block_count*BLOCK_SIZE) 86 | print('Copying {} blocks into position {}...'.format(block_count, begin)) 87 | output_img.seek(begin*BLOCK_SIZE) 88 | output_img.write(data) 89 | else: 90 | print('Skipping command %s' % command[0]) 91 | 92 | output_img.close() 93 | new_data_file.close() 94 | print ('\nDone! Output image: %s' % os.path.realpath(output_img.name)) 95 | 96 | if __name__ == "__main__": 97 | main(sys.argv) 98 | -------------------------------------------------------------------------------- /reverses/de-oat/README.md: -------------------------------------------------------------------------------- 1 | This is for Android 5.0+. 2 | 3 | De-oat the ota package zip, of which apks and jars are oat format(Android ELF on ART). 4 | 5 | ### Github 6 | 7 | 8 | ### About 9 | This is forked from https://code.google.com/p/smali/ 10 | The additional modification is to support convert oat file to dex. 11 | 12 | Function concept: 13 | boot.oat -> extract optimized boot class dex files -> deoptimize to dex files 14 | app.odex(oat) -> reference boot dex files to deoptimize 15 | 16 | Download latest version: 17 | https://github.com/testwhat/SmaliEx/blob/master/smaliex-bin/oat2dex.jar?raw=true 18 | 19 | Usage: 20 | Deoptimize boot classes (The output will be in "odex" and "dex" folders): 21 |   java -jar oat2dex.jar boot <boot.oat file> 22 | Deoptimize application: 23 |   java -jar oat2dex.jar <app.odex> <boot-class-folder output from above> 24 | Get odex from oat: 25 |   java -jar oat2dex.jar odex <oat file> 26 | Get odex smali (with optimized opcode) from oat/odex: 27 |   java -jar oat2dex.jar smali <oat/odex file> 28 | Deodex /system/framework/ from device (need to connect with adb): 29 |   java -jar oat2dex.jar devfw 30 | 31 | Used by: 32 | [JoelDroid](http://forum.xda-developers.com/android/software-hacking/script-app-joeldroid-lollipop-batch-t2980857) 33 | [SVADeodexerForArt](http://forum.xda-developers.com/galaxy-s5/general/tool-deodex-tool-android-l-t2972025) 34 | [PUMa - Patch Utility Manager](http://forum.xda-developers.com/showthread.php?t=1434946) 35 | 36 |

Original Readme

37 | ### About 38 | 39 | smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation. The syntax is loosely based on Jasmin's/dedexer's syntax, and supports the full functionality of the dex format (annotations, debug info, line info, etc.) 40 | 41 | Downloads are at https://bitbucket.org/JesusFreke/smali/downloads. If you are interested in submitting a patch, feel free to send me a pull request here. 42 | 43 | #### Support 44 | - [github Issue tracker](https://github.com/JesusFreke/smali/issues) - For any bugs/issues/feature requests 45 | - [#smali on freenode](http://webchat.freenode.net/?channels=smali) - Free free to drop by and ask a question. Don't expect an instant response, but if you hang around someone will respond. 46 | 47 | 48 | #### Some useful links for getting started with smali 49 | 50 | - [Official dex bytecode reference](https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html) 51 | - [Registers wiki page](https://github.com/JesusFreke/smali/wiki/Registers) 52 | - [Types, Methods and Fields wiki page](https://github.com/JesusFreke/smali/wiki/TypesMethodsAndFields) 53 | - [Official dex format reference](https://source.android.com/devices/tech/dalvik/dex-format.html) 54 | -------------------------------------------------------------------------------- /reverses/de-oat/oat2dex.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/de-oat/oat2dex.jar -------------------------------------------------------------------------------- /reverses/de-oat/oat2dex.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | prog="$0" 19 | while [ -h "${prog}" ]; do 20 | newProg=`/bin/ls -ld "${prog}"` 21 | #echo ${newProg} 22 | 23 | 24 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 25 | if expr "x${newProg}" : 'x/' >/dev/null; then 26 | prog="${newProg}" 27 | else 28 | progdir=`dirname "${prog}"` 29 | prog="${progdir}/${newProg}" 30 | fi 31 | done 32 | oldwd=`pwd` 33 | progdir=`dirname "${prog}"` 34 | cd "${progdir}" 35 | progdir=`pwd` 36 | prog="${progdir}"/`basename "${prog}"` 37 | cd "${oldwd}" 38 | 39 | 40 | jarfile=oat2dex.jar 41 | libdir="$progdir" 42 | if [ ! -r "$libdir/$jarfile" ] 43 | then 44 | echo `basename "$prog"`": can't find $jarfile" 45 | exit 1 46 | fi 47 | 48 | javaOpts="" 49 | 50 | # If you want DX to have more memory when executing, uncomment the following 51 | # line and adjust the value accordingly. Use "java -X" for a list of options 52 | # you can pass here. 53 | # 54 | javaOpts="-Xmx512M" 55 | 56 | # Alternatively, this will extract any parameter "-Jxxx" from the command line 57 | # and pass them to Java (instead of to dx). This makes it possible for you to 58 | # add a command-line parameter such as "-JXmx256M" in your ant scripts, for 59 | # example. 60 | while expr "x$1" : 'x-J' >/dev/null; do 61 | opt=`expr "$1" : '-J\(.*\)'` 62 | javaOpts="${javaOpts} -${opt}" 63 | shift 64 | done 65 | 66 | if [ "$OSTYPE" = "cygwin" ] ; then 67 | jarpath=`cygpath -w "$libdir/$jarfile"` 68 | else 69 | jarpath="$libdir/$jarfile" 70 | fi 71 | 72 | exec java $javaOpts -jar "$jarpath" "$@" 73 | -------------------------------------------------------------------------------- /reverses/de-odex/README.md: -------------------------------------------------------------------------------- 1 | This is for Android 2.3~4.4. 2 | 3 | De-odex the ota package zip, of which apks and jars are odexed (Optimized dex on DALVIKVM). 4 | 5 | ### Github 6 | 7 | 8 | ### About 9 | 10 | smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation. The syntax is loosely based on Jasmin's/dedexer's syntax, and supports the full functionality of the dex format (annotations, debug info, line info, etc.) 11 | 12 | Downloads are at https://bitbucket.org/JesusFreke/smali/downloads. If you are interested in submitting a patch, feel free to send me a pull request here. 13 | 14 | See [the wiki](https://github.com/JesusFreke/smali/wiki) for more info/news/release notes/etc. 15 | 16 | #### Support 17 | - [github Issue tracker](https://github.com/JesusFreke/smali/issues) - For any bugs/issues/feature requests 18 | - [#smali on freenode](http://webchat.freenode.net/?channels=smali) - Free free to drop by and ask a question. Don't expect an instant response, but if you hang around someone will respond. 19 | 20 | 21 | #### Some useful links for getting started with smali 22 | 23 | - [Official dex bytecode reference](https://source.android.com/devices/tech/dalvik/dalvik-bytecode.html) 24 | - [Registers wiki page](https://github.com/JesusFreke/smali/wiki/Registers) 25 | - [Types, Methods and Fields wiki page](https://github.com/JesusFreke/smali/wiki/TypesMethodsAndFields) 26 | - [Official dex format reference](https://source.android.com/devices/tech/dalvik/dex-format.html) 27 | -------------------------------------------------------------------------------- /reverses/de-odex/baksmali.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/de-odex/baksmali.jar -------------------------------------------------------------------------------- /reverses/de-odex/baksmali.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2007 The Android Open Source Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This script is a wrapper around baksmali.jar, so you can simply call 18 | # "baksmali", instead of java -jar baksmali.jar. It is heavily based on 19 | # the "dx" script from the Android SDK 20 | 21 | # Set up prog to be the path of this script, including following symlinks, 22 | # and set up progdir to be the fully-qualified pathname of its directory. 23 | prog="$0" 24 | while [ -h "${prog}" ]; do 25 | newProg=`/bin/ls -ld "${prog}"` 26 | #echo ${newProg} 27 | 28 | 29 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 30 | if expr "x${newProg}" : 'x/' >/dev/null; then 31 | prog="${newProg}" 32 | else 33 | progdir=`dirname "${prog}"` 34 | prog="${progdir}/${newProg}" 35 | fi 36 | done 37 | oldwd=`pwd` 38 | progdir=`dirname "${prog}"` 39 | cd "${progdir}" 40 | progdir=`pwd` 41 | prog="${progdir}"/`basename "${prog}"` 42 | cd "${oldwd}" 43 | 44 | 45 | jarfile=baksmali.jar 46 | libdir="$progdir" 47 | if [ ! -r "$libdir/$jarfile" ] 48 | then 49 | echo `basename "$prog"`": can't find $jarfile" 50 | exit 1 51 | fi 52 | 53 | javaOpts="" 54 | 55 | # If you want DX to have more memory when executing, uncomment the following 56 | # line and adjust the value accordingly. Use "java -X" for a list of options 57 | # you can pass here. 58 | # 59 | javaOpts="-Xmx256M" 60 | 61 | # Alternatively, this will extract any parameter "-Jxxx" from the command line 62 | # and pass them to Java (instead of to dx). This makes it possible for you to 63 | # add a command-line parameter such as "-JXmx256M" in your ant scripts, for 64 | # example. 65 | while expr "x$1" : 'x-J' >/dev/null; do 66 | opt=`expr "$1" : '-J\(.*\)'` 67 | javaOpts="${javaOpts} -${opt}" 68 | shift 69 | done 70 | 71 | if [ "$OSTYPE" = "cygwin" ] ; then 72 | jarpath=`cygpath -w "$libdir/$jarfile"` 73 | else 74 | jarpath="$libdir/$jarfile" 75 | fi 76 | 77 | exec java $javaOpts -jar "$jarpath" "$@" 78 | -------------------------------------------------------------------------------- /reverses/de-odex/smali.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/reverses/de-odex/smali.jar -------------------------------------------------------------------------------- /reverses/de-odex/smali.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Copyright (C) 2007 The Android Open Source Project 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This script is a wrapper for smali.jar, so you can simply call "smali", 18 | # instead of java -jar smali.jar. It is heavily based on the "dx" script 19 | # from the Android SDK 20 | 21 | # Set up prog to be the path of this script, including following symlinks, 22 | # and set up progdir to be the fully-qualified pathname of its directory. 23 | prog="$0" 24 | while [ -h "${prog}" ]; do 25 | newProg=`/bin/ls -ld "${prog}"` 26 | #echo ${newProg} 27 | 28 | 29 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 30 | if expr "x${newProg}" : 'x/' >/dev/null; then 31 | prog="${newProg}" 32 | else 33 | progdir=`dirname "${prog}"` 34 | prog="${progdir}/${newProg}" 35 | fi 36 | done 37 | oldwd=`pwd` 38 | progdir=`dirname "${prog}"` 39 | cd "${progdir}" 40 | progdir=`pwd` 41 | prog="${progdir}"/`basename "${prog}"` 42 | cd "${oldwd}" 43 | 44 | 45 | jarfile=smali.jar 46 | libdir="$progdir" 47 | if [ ! -r "$libdir/$jarfile" ] 48 | then 49 | echo `basename "$prog"`": can't find $jarfile" 50 | exit 1 51 | fi 52 | 53 | javaOpts="" 54 | 55 | # If you want DX to have more memory when executing, uncomment the following 56 | # line and adjust the value accordingly. Use "java -X" for a list of options 57 | # you can pass here. 58 | # 59 | javaOpts="-Xmx512M" 60 | 61 | # Alternatively, this will extract any parameter "-Jxxx" from the command line 62 | # and pass them to Java (instead of to dx). This makes it possible for you to 63 | # add a command-line parameter such as "-JXmx256M" in your ant scripts, for 64 | # example. 65 | while expr "x$1" : 'x-J' >/dev/null; do 66 | opt=`expr "$1" : '-J\(.*\)'` 67 | javaOpts="${javaOpts} -${opt}" 68 | shift 69 | done 70 | 71 | if [ "$OSTYPE" = "cygwin" ] ; then 72 | jarpath=`cygpath -w "$libdir/$jarfile"` 73 | else 74 | jarpath="$libdir/$jarfile" 75 | fi 76 | 77 | exec java $javaOpts -jar "$jarpath" "$@" 78 | -------------------------------------------------------------------------------- /reverses/decode_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ##################################################### 4 | # 5 | # use to decode all of the apk and jar in the system 6 | # note: unzip the zip first 7 | # 8 | ##################################################### 9 | 10 | CUR_DIR=$(dirname $0) 11 | APKTOOL=$CUR_DIR/apktool 12 | THREAD_NUM=4 13 | 14 | IN_DIR="" 15 | OUT_DIR="" 16 | 17 | # echo the usage of decode_all 18 | function usage 19 | { 20 | echo "usage: decode_all [OPTIONS] SYSTEM_DIR [OUT_DIR]" 21 | echo " OPTIONS: -j[0-9]* jobs number" 22 | echo " SYSTEM_DIR: the apk/jar's directory which will be decoded" 23 | echo " OUT_DIR: output directory for decoded, current directory is default." 24 | echo "eg: decode_all system/framework ." 25 | } 26 | 27 | # setup the parameters 28 | function setParam 29 | { 30 | if [ $# -eq 0 ] 31 | then 32 | usage 33 | exit 1 34 | fi 35 | 36 | set -- `getopt "j:" "$@"` 37 | 38 | while : 39 | do 40 | case "$1" in 41 | -j) shift; THREAD_NUM=$1 ;; 42 | --) break ;; 43 | esac 44 | shift 45 | done 46 | shift 47 | 48 | IN_DIR=$1 49 | 50 | if [ $# -eq 1 ] 51 | then 52 | OUT_DIR="." 53 | else 54 | OUT_DIR=$2 55 | if [ ! -d $OUT_DIR ] 56 | then 57 | mkdir -p $OUT_DIR 58 | fi 59 | fi 60 | } 61 | 62 | # init multi build jobs through fifo 63 | function initMultiJobs 64 | { 65 | tmp_fifofile="/tmp/$$.fifo" 66 | 67 | mkfifo "$tmp_fifofile" 68 | exec 6<>"$tmp_fifofile" 69 | rm $tmp_fifofile 70 | 71 | for ((i=0;i<$THREAD_NUM;i++));do 72 | echo 73 | done >&6 74 | } 75 | 76 | # decode all apks 77 | function decodeApks 78 | { 79 | for line in `find $IN_DIR -name "*.apk"` 80 | do 81 | read -u6 82 | { 83 | echo ">>> begin decode $line" 84 | out_file=${line:${#IN_DIR}:${#line}} 85 | let "len=${#out_file}-4" 86 | out_file=${out_file:0:$len} 87 | $APKTOOL d $line -o $OUT_DIR"/"$out_file 88 | echo "<<< decode $line done" 89 | echo >&6 90 | } & 91 | done 92 | } 93 | 94 | # decode all jars 95 | function decodeJars 96 | { 97 | for line in `find $IN_DIR -name "*.jar"` 98 | do 99 | read -u6 100 | { 101 | echo ">>> begin decode $line" 102 | out_file=${line:${#IN_DIR}:${#line}} 103 | let "len=${#out_file}" 104 | #out_file=${line:${#file_path}:${#line}} 105 | out_file=${out_file:0:$len} 106 | $APKTOOL d $line -o $OUT_DIR"/"$out_file".out" 107 | echo "<<< decode $line done" 108 | echo >&6 109 | } & 110 | done 111 | } 112 | 113 | # wait for the end 114 | function waitToEnd 115 | { 116 | # wait it for done 117 | for ((i=0;i<$THREAD_NUM;i++));do 118 | read -u6 119 | done 120 | } 121 | 122 | function main 123 | { 124 | setParam $@ 125 | initMultiJobs 126 | decodeApks 127 | decodeJars 128 | waitToEnd 129 | } 130 | 131 | main $@ 132 | -------------------------------------------------------------------------------- /reverses/deodex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """ 19 | Deodex 20 | TODO 21 | """ 22 | 23 | __author__ = 'duanqz@gmail.com' 24 | 25 | 26 | import os 27 | import tempfile 28 | import commands 29 | import shutil 30 | 31 | from common import Options, Log 32 | 33 | # Global 34 | TAG="reverse-deodex" 35 | OPTIONS = Options() 36 | 37 | class OdexZip: 38 | 39 | CLASSPATH="core.jar:ext.jar:framework.jar:android.policy.jar:services.jar" 40 | 41 | def __init__(self, unzipRoot): 42 | self.mRoot = unzipRoot 43 | 44 | self.mFrwDir = os.path.join(self.mRoot, "system/framework") 45 | self.mAppDir = os.path.join(self.mRoot, "system/app") 46 | self.mPrivAppDir = os.path.join(self.mRoot, "system/priv-app") 47 | 48 | if OPTIONS.classpath == None: 49 | OPTIONS.classpath = OdexZip.CLASSPATH 50 | 51 | 52 | def deodex(self): 53 | OdexZip.deodexFrw(self.mFrwDir) 54 | 55 | #OdexZip.deodexApp(self.mAppDir) 56 | #OdexZip.deodexApp(self.mPrivAppDir) 57 | 58 | 59 | @staticmethod 60 | def deodexFrw(odexJarDir): 61 | """ De-odex framework 62 | """ 63 | 64 | if OPTIONS.formatFrw == False: return 65 | 66 | coreOdex = os.path.join(odexJarDir, "core.odex") 67 | if os.path.exists(coreOdex): 68 | Log.i(TAG, "De-odex core.odex") 69 | deodexFile = os.path.join(odexJarDir, "core.jar") 70 | OdexZip.deodexOneFile(coreOdex, deodexFile) 71 | 72 | Log.i(TAG, "De-odex files of odex-format in %s" % odexJarDir) 73 | for item in os.listdir(odexJarDir): 74 | if item.endswith(".odex"): 75 | odexJar = os.path.join(odexJarDir, item) 76 | deodexJar = odexJar[0:-4] + ".jar" 77 | OdexZip.deodexOneFile(odexJar, deodexJar) 78 | break 79 | 80 | 81 | @staticmethod 82 | def deodexApp(odexApkDir): 83 | """ De-oat app 84 | """ 85 | 86 | if OPTIONS.formatApp == False: return 87 | 88 | for item in os.listdir(odexApkDir): 89 | if item.endswith(".odex"): 90 | odexApk = os.path.join(odexApkDir, item) 91 | deodexApk = odexApk[0:-4] + ".apk" 92 | OdexZip.deodexOneFile(odexApk, deodexApk) 93 | 94 | 95 | @staticmethod 96 | def deodexOneFile(odexFile, deodexFile): 97 | """ De-odex one file. 98 | """ 99 | 100 | if not odexFile.endswith(".odex"): return 101 | 102 | temp = tempfile.mktemp() 103 | 104 | # Phase 1: Baksmali the odex file 105 | cmd = ["baksmali", "-x", odexFile, "-d", "framework", "-I", "-o", os.path.join(temp, "out")] 106 | if OPTIONS.apiLevel != None: cmd.extend(["-a", OPTIONS.apiLevel]) 107 | if OPTIONS.classpath != None: cmd.extend(["-c", OPTIONS.classpath]) 108 | 109 | cmd = " ".join(cmd) 110 | Log.d(TAG, cmd) 111 | Log.d(TAG, commands.getoutput(cmd)) 112 | 113 | # Phase 2: Smali the files into dex 114 | oldDir = os.path.abspath(os.curdir) 115 | os.chdir(temp) 116 | 117 | cmd = "smali out/ -o classes.dex" 118 | Log.d(TAG, commands.getoutput(cmd)) 119 | #Utils.runWithOutput(["smali", "out", "-o", "classes.dex"]) 120 | 121 | # Phase 3: Package 122 | if os.path.exists(deodexFile): 123 | #cmd = ["jar", "uf", deodexFile, "classes.dex"] 124 | cmd = "jar uf %s classes.dex" % deodexFile 125 | else: 126 | #cmd = ["jar", "cf", deodexFile, "classes.dex"] 127 | cmd = "jar cf %s classes.dex" % deodexFile 128 | 129 | Log.d(TAG, commands.getoutput(cmd)) 130 | #Utils.runWithOutput(cmd) 131 | os.chdir(oldDir) 132 | 133 | if os.path.exists(odexFile): os.remove(odexFile) 134 | 135 | Log.i(TAG, "Delete %s" %temp) 136 | shutil.rmtree(temp) 137 | 138 | # Phase 4: zipalign 139 | #Utils.runWithOutput(["zipalign", "4", deodexFile, deodexFile+".aligned"]) 140 | #Utils.runWithOutput(["mv", deodexFile+".aligned", deodexFile]) 141 | 142 | cmd = "zipalign 4 %s %s" %(deodexFile, deodexFile+".aligned") 143 | Log.d(TAG, commands.getoutput(cmd)) 144 | 145 | cmd = "mv %s %s" %(deodexFile+".aligned", deodexFile) 146 | Log.d(TAG, cmd) 147 | 148 | 149 | def debug(): 150 | 151 | Log.DEBUG = True 152 | root = "root directory the unziped files" 153 | OdexZip(root).deodex() 154 | 155 | 156 | if __name__ == "__main__": 157 | 158 | debug() 159 | 160 | -------------------------------------------------------------------------------- /reverses/otanormalize.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | __author__ = 'duanqz@gmail.com' 19 | 20 | 21 | from os import sys 22 | 23 | from common import Options, Log 24 | from zipformatter import ZipFormatter 25 | 26 | 27 | # Global 28 | TAG="reverse-oatnormalize" 29 | OPTIONS = Options() 30 | 31 | 32 | if __name__ == "__main__": 33 | 34 | Log.DEBUG = True 35 | 36 | OPTIONS.handle(sys.argv) 37 | 38 | ZipFormatter.create(OPTIONS).format() 39 | 40 | -------------------------------------------------------------------------------- /rmline: -------------------------------------------------------------------------------- 1 | formatters/rmline.sh -------------------------------------------------------------------------------- /sepolicy_inject: -------------------------------------------------------------------------------- 1 | ../build/tools/custom_sepolicy.sh -------------------------------------------------------------------------------- /smali: -------------------------------------------------------------------------------- 1 | reverses/de-odex/smali.sh -------------------------------------------------------------------------------- /smaliparser/Content.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Feb 26, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | from SmaliLine import SmaliLine 7 | 8 | class Content(object): 9 | def __init__(self, contentStr = None): 10 | self.ContentStr = contentStr 11 | 12 | def append(self, contentStr): 13 | if self.ContentStr is not None: 14 | self.ContentStr = "%s\n%s" %(self.ContentStr, contentStr) 15 | else: 16 | self.ContentStr = contentStr 17 | 18 | def clone(self): 19 | return Content(self.getContentStr()) 20 | 21 | def getContentStr(self): 22 | return self.ContentStr 23 | 24 | def setContentStr(self, contentStr): 25 | self.ContentStr = contentStr 26 | 27 | def isMultiLine(self): 28 | firstLine = True 29 | for line in self.ContentStr.split('\n'): 30 | if firstLine is False: 31 | if not SmaliLine(line).isBlank(): 32 | return True 33 | else: 34 | firstLine = True 35 | 36 | return False 37 | 38 | def getFirstLine(self): 39 | if self.ContentStr is not None: 40 | return self.ContentStr.split('\n')[0] 41 | else: 42 | return None 43 | 44 | def getPostContent(self): 45 | postContent = Content() 46 | firstLine = True 47 | for line in self.ContentStr.split('\n'): 48 | if firstLine is False: 49 | postContent.append(line) 50 | else: 51 | firstLine = False 52 | 53 | return postContent -------------------------------------------------------------------------------- /smaliparser/EntryUsed.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jun 25, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import utils 8 | import SmaliEntry 9 | import Smali 10 | 11 | MAX_CHECK_INVOKE_DEEP = 50 12 | 13 | class Used(object): 14 | ''' 15 | classdocs 16 | ''' 17 | 18 | def __init__(self, sLib, aLib): 19 | ''' 20 | Constructor 21 | ''' 22 | self.mSLib = sLib 23 | self.mALib = aLib 24 | self.mMethodParser = MethodUsedParser(sLib, aLib) 25 | self.mFieldParser = FieldUsedParser(sLib, aLib) 26 | 27 | def isUsed(self, entry): 28 | if entry.getType() == SmaliEntry.FIELD: 29 | return self.mFieldParser.isUsed(entry) 30 | elif entry.getType() == SmaliEntry.METHOD: 31 | return self.mMethodParser.isUsed(entry) 32 | else: 33 | return False 34 | 35 | def checkIsUsed(self, entry, deep = 0): 36 | if entry is not None: 37 | clsName = entry.getClassName() 38 | entryName = entry.getName() 39 | aSmali = self.mALib.getSmali(entry.getClassName()) 40 | if aSmali is not None and aSmali.getEntry(SmaliEntry.METHOD, entryName) is not None: 41 | return True 42 | 43 | sSmali = self.mSLib.getSmali(clsName) 44 | usedMethodsList = self.getUsedMethods(sSmali, [entry]) 45 | 46 | if not usedMethodsList.has_key(entryName): 47 | for childClsName in sSmali.getChildren(): 48 | cSmali = self.mSLib.getSmali(childClsName) 49 | if cSmali is not None and self.checkIsUsed(cSmali.getEntry(SmaliEntry.METHOD, entryName)): 50 | return True 51 | else: 52 | if len(usedMethodsList) < Smali.MAX_INVOKE_LEN and deep < MAX_CHECK_INVOKE_DEEP: 53 | isUsed = False 54 | for invokeItem in usedMethodsList[entryName]: 55 | cSmali = self.mSLib.getSmali(invokeItem.belongCls) 56 | if cSmali is not None and self.checkIsUsed(cSmali.getEntry(SmaliEntry.METHOD, invokeItem.belongMethod), deep + 1): 57 | isUsed = True 58 | break 59 | return isUsed 60 | else: 61 | return True 62 | return False 63 | 64 | class MethodUsedParser(Used): 65 | def checkIsUsed(self, entry): 66 | return False 67 | 68 | 69 | class FieldUsedParser(Used): 70 | def checkIsUsed(self, entry): 71 | print "" 72 | -------------------------------------------------------------------------------- /smaliparser/FormatSmaliLib.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 22, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import os, sys 8 | from os import path 9 | import Smali 10 | from SmaliLib import SmaliLib 11 | 12 | sys.path.append(path.dirname(path.dirname(path.abspath(__file__)))) 13 | from formatters.format import Format 14 | 15 | 16 | class FormatSmaliLib(SmaliLib): 17 | ''' 18 | classdocs 19 | ''' 20 | 21 | mFormatList = {} 22 | def __init__(self, libPath, smaliDirMaxDepth=0): 23 | ''' 24 | Constructor 25 | ''' 26 | self.mFieldFormatMap = {} 27 | SmaliLib.__init__(self, libPath, smaliDirMaxDepth) 28 | 29 | def __format(self, root, sPath): 30 | sPath = os.path.abspath(sPath) 31 | if not FormatSmaliLib.mFormatList.has_key(sPath): 32 | sFormat = Format(root, sPath) 33 | sFormat.do(Format.ACCESS_TO_NAME | Format.RESID_TO_NAME | Format.REMOVE_LINE) 34 | FormatSmaliLib.mFormatList[sPath] = sFormat 35 | return True 36 | return False 37 | 38 | def getFormatSmali(self, clsName): 39 | oldSmali = self.getSmali(clsName) 40 | if oldSmali is None: 41 | print "Can not get class: %s in %s" %(clsName, self.getPath()) 42 | return None 43 | if self.__format(self.getPath(), oldSmali.getPath()): 44 | self.setSmali(clsName, Smali.Smali(oldSmali.getPath())) 45 | return self.getSmali(clsName) 46 | 47 | @staticmethod 48 | def undoFormat(): 49 | for fKey in FormatSmaliLib.mFormatList.keys(): 50 | FormatSmaliLib.mFormatList[fKey].undo() -------------------------------------------------------------------------------- /smaliparser/LibUtils.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jul 22, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | from FormatSmaliLib import FormatSmaliLib 8 | from SmaliLib import SmaliLib 9 | import os 10 | 11 | mSmaliLibDict = {} 12 | 13 | LIBTYPE_FORMAT = 1 14 | LIBTYPE_SMALILIB = 0 15 | 16 | def getSmaliLib(libPath, smaliDirMaxDepth = 0, libType = LIBTYPE_FORMAT): 17 | absRoot = os.path.abspath(libPath) 18 | if not mSmaliLibDict.has_key(absRoot) or mSmaliLibDict[absRoot].mSmaliDirMaxDepth != smaliDirMaxDepth: 19 | if libType == LIBTYPE_FORMAT: 20 | mSmaliLibDict[absRoot] = FormatSmaliLib(libPath, smaliDirMaxDepth) 21 | elif libType == LIBTYPE_SMALILIB: 22 | mSmaliLibDict[absRoot] = SmaliLib(libPath, smaliDirMaxDepth) 23 | return mSmaliLibDict[absRoot] 24 | 25 | def getLibPath(path): 26 | if os.path.isdir(path): 27 | children = os.listdir(path) 28 | for child in children: 29 | if os.path.isdir("%s/smali" % child): 30 | return path 31 | while not os.path.isdir("%s/smali" % path): 32 | path = os.path.dirname(path) 33 | if path == "/": 34 | return None 35 | return os.path.dirname(path) 36 | 37 | def getOwnLib(smaliFile): 38 | libPath = getLibPath(smaliFile) 39 | if libPath is not None: 40 | return getSmaliLib(libPath, 1) 41 | return None 42 | 43 | def undoFormat(): 44 | FormatSmaliLib.undoFormat() -------------------------------------------------------------------------------- /smaliparser/SAutoCom.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 4, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import utils 7 | import Replace 8 | 9 | from formatters.log import Paint 10 | 11 | 12 | MAX_CHECK_INVOKE_DEEP = 50 13 | 14 | class SAutoCom(object): 15 | ''' 16 | classdocs 17 | ''' 18 | 19 | @staticmethod 20 | def autocom(vendorDir, aospDir, bospDir, mergedDir, outdir, comModuleList): 21 | sReplace = Replace.Replace(vendorDir, aospDir, bospDir, mergedDir) 22 | 23 | for module in comModuleList: 24 | print Paint.bold(" Complete missed method in %s") % module 25 | needComleteDir = '%s/%s' % (mergedDir, module) 26 | sDict = utils.getSmaliDict(needComleteDir) 27 | for clsName in sDict.keys(): 28 | mSmali = sReplace.mMSLib.getSmali(clsName) 29 | if mSmali is None: 30 | utils.SLog.d("can not get class: %s" % clsName) 31 | continue 32 | 33 | (canReplaceEntryList, canNotReplaceEntryList) = sReplace.preReplaceCheck(mSmali) 34 | 35 | for entry in canReplaceEntryList: 36 | sReplace.replaceEntryInFile(entry, SAutoCom.getAutocomPartPath(sReplace, entry, outdir)) 37 | 38 | for entry in canNotReplaceEntryList: 39 | sReplace.appendBlankEntry(entry, SAutoCom.getAutocomPartPath(sReplace, entry, outdir)) 40 | 41 | @staticmethod 42 | def getAutocomPartPath(sCheck, entry, outdir): 43 | cls = entry.getClassName() 44 | cSmali = sCheck.mVSLib.getSmali(cls) 45 | 46 | if cSmali is None: 47 | utils.SLog.d("can not get class %s from: %s" % (cls, sCheck.mVSLib.getPath())) 48 | return 49 | 50 | jarName = cSmali.getJarName() 51 | pkgName = cSmali.getPackageName() 52 | 53 | return r'%s/%s/smali/%s/%s.smali.part' % (outdir, jarName, pkgName, cSmali.getClassBaseName()) 54 | 55 | -------------------------------------------------------------------------------- /smaliparser/SCheck: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCHECK=`dirname $0`/SCheck.py 4 | 5 | python $SCHECK $@ 6 | -------------------------------------------------------------------------------- /smaliparser/SCheck.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Mar 12, 2014 3 | 4 | @author: tangliuxiang 5 | 6 | ''' 7 | import SmaliEntry 8 | import Smali 9 | import string 10 | import SmaliMethod 11 | import sys 12 | import os 13 | import getopt 14 | import SAutoCom 15 | import SmaliFileReplace 16 | import tobosp 17 | import utils 18 | import Replace 19 | import LibUtils 20 | import traceback 21 | 22 | 23 | class Options(object): pass 24 | OPTIONS = Options() 25 | OPTIONS.autoComplete = False 26 | 27 | OPTIONS.replaceWithCheck = False 28 | OPTIONS.methodToBosp = False 29 | OPTIONS.smaliToBosp = False 30 | 31 | def formatSmali(smaliLib, smaliFileList = None): 32 | utils.SLog.i(" begin format smali files, please wait....") 33 | if smaliFileList is not None: 34 | idx = 0 35 | while idx < len(smaliFileList): 36 | clsName = utils.getClassFromPath(smaliFileList[idx]) 37 | cSmali = smaliLib.getSmali(clsName) 38 | smaliLib.formatUsingField(cSmali) 39 | idx = idx + 1 40 | else: 41 | for clsName in smaliLib.mSDict.keys(): 42 | cSmali = smaliLib.getSmali(clsName) 43 | smaliLib.formatUsingField(cSmali) 44 | utils.SLog.i(" format done") 45 | 46 | def usage(): 47 | print __doc__ 48 | 49 | def main(argv): 50 | options,args = getopt.getopt(argv[1:], "hams", [ "help", "autocomplete", "methodtobosp", "smalitobosp"]) 51 | for name,value in options: 52 | if name in ("-h", "--help"): 53 | usage() 54 | elif name in ("-a", "--autocomplete"): 55 | OPTIONS.autoComplete = True 56 | elif name in ("-m", "--methodtobosp"): 57 | OPTIONS.replaceWithCheck = False 58 | OPTIONS.methodToBosp = True 59 | elif name in ("-s", "--smalitobosp"): 60 | OPTIONS.smaliToBosp = True 61 | else: 62 | utils.SLog.w("Wrong parameters, see the usage....") 63 | usage() 64 | 65 | if OPTIONS.autoComplete: 66 | if len(args) >= 6: 67 | try: 68 | SAutoCom.SAutoCom.autocom(args[0], args[1], args[2], args[3], args[4], args[5:]) 69 | except: 70 | traceback.print_exc() 71 | # see error info in help.xml for ERR_AUTOCOM_FAILED 72 | sys.exit(158) 73 | else: 74 | # see error info in help.xml for ERR_WRONG_PARAMETERS 75 | sys.exit(157) 76 | elif OPTIONS.methodToBosp: 77 | if len(args) >= 2: 78 | try: 79 | Replace.methodtobosp(args[0], args[1], OPTIONS.replaceWithCheck) 80 | except: 81 | traceback.print_exc() 82 | # see error info in help.xml for ERR_METHODTOBOSP_FAILED 83 | sys.exit(159) 84 | else: 85 | # see error info in help.xml for ERR_WRONG_PARAMETERS 86 | sys.exit(157) 87 | elif OPTIONS.smaliToBosp: 88 | if len(args) >= 1: 89 | try: 90 | SmaliFileReplace.smalitobosp(args, False) 91 | except: 92 | traceback.print_exc() 93 | # see error info in help.xml for ERR_SMALITOBOSP_FAILED 94 | sys.exit(160) 95 | else: 96 | # see error info in help.xml for ERR_WRONG_PARAMETERS 97 | sys.exit(157) 98 | 99 | if __name__ == "__main__": 100 | if len(sys.argv) > 2: 101 | main(sys.argv) 102 | else: 103 | usage() 104 | -------------------------------------------------------------------------------- /smaliparser/SmaliClass.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Apr 3, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | from SmaliEntry import SmaliEntry 8 | 9 | class SmaliClass(SmaliEntry): 10 | ''' 11 | classdocs 12 | ''' 13 | 14 | def getSimpleString(self): 15 | return "%s %s" %(self.getType(), self.getClassName()) 16 | -------------------------------------------------------------------------------- /smaliparser/SmaliEntryFactory.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Feb 27, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import SmaliEntry 8 | import SmaliMethod 9 | import SmaliField 10 | import SmaliClass 11 | 12 | def newSmaliEntry(type, content, clsName = None, preContent = None): 13 | #return SmaliEntry.SmaliEntry(type, content, preContent) 14 | 15 | if type is None: 16 | return None 17 | elif type == SmaliEntry.METHOD: 18 | return SmaliMethod.SmaliMethod(type, content, clsName, preContent) 19 | elif type == SmaliEntry.FIELD: 20 | return SmaliField.SmaliField(type, content, clsName, preContent) 21 | # elif type is SmaliEntry.ANNOTATION: 22 | elif type is SmaliEntry.CLASS: 23 | return SmaliClass.SmaliClass(type, content, clsName, preContent) 24 | # elif type is SmaliEntry.SOURCE: 25 | # elif type is SmaliEntry.SUPER: 26 | # elif type is SmaliEntry.IMPLEMENTS: 27 | else: 28 | return SmaliEntry.SmaliEntry(type, content, clsName, preContent) -------------------------------------------------------------------------------- /smaliparser/SmaliField.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Feb 26, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import SmaliEntry 7 | 8 | class SmaliField(SmaliEntry.SmaliEntry): 9 | ''' 10 | classdocs 11 | ''' 12 | 13 | def getName(self): 14 | if self.mName is None: 15 | firstLine = self.getContent().getFirstLine() 16 | splitArray = firstLine.split(r'=')[0].split() 17 | #self.mName = splitArray[len(splitArray) - 1].split(r':')[0] 18 | self.mName = splitArray[len(splitArray) - 1] 19 | return self.mName -------------------------------------------------------------------------------- /smaliparser/SmaliLine.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Feb 26, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | import re 7 | 8 | blankLineRule = re.compile(r'^ *#.*$|^ *$') 9 | entryStartRule = re.compile(r'^\..*$') 10 | 11 | def getLineType(line): 12 | lineType = SmaliLine.TYPE_NORMAL_LINE 13 | if blankLineRule.match(line) is not None: 14 | lineType = SmaliLine.TYPE_BLANK_LINE 15 | elif entryStartRule.match(line) is not None: 16 | lineType = SmaliLine.TYPE_DOT_LINE 17 | 18 | return lineType 19 | 20 | class SmaliLine(object): 21 | ''' 22 | classdocs 23 | ''' 24 | 25 | TYPE_NORMAL_LINE = 0 26 | TYPE_BLANK_LINE = 1 27 | TYPE_DOT_LINE = 2 28 | 29 | def __init__(self, line): 30 | ''' 31 | Constructor 32 | ''' 33 | self.setLine(line) 34 | 35 | def setLine(self, line): 36 | self.mLineType = getLineType(line) 37 | self.mLine = line 38 | 39 | def getLine(self): 40 | return self.mLine 41 | 42 | def getType(self): 43 | return self.mLineType 44 | 45 | def isBlank(self): 46 | return self.mLineType is SmaliLine.TYPE_BLANK_LINE 47 | 48 | def getDotType(self): 49 | if self.mLine is None and self.mLineType is not SmaliLine.TYPE_DOT_LINE: 50 | return None 51 | lstr = re.sub(r'^\.end *', '', self.mLine) 52 | lstr = re.sub(r'^\.', '', lstr) 53 | arr = lstr.split() 54 | return arr[0] 55 | 56 | def isDotEnd(self): 57 | if self.mLine is None and self.mLineType is not SmaliLine.TYPE_DOT_LINE: 58 | return False 59 | if re.compile(r'^\.end.*$').match(self.mLine) is None: 60 | return False 61 | else: 62 | return True 63 | -------------------------------------------------------------------------------- /smaliparser/SmaliMethod.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | ''' 4 | Created on 2012-12-11 5 | 6 | @author: tangliuxiang 7 | ''' 8 | 9 | import re 10 | import sys 11 | import os 12 | import utils 13 | 14 | from SmaliEntry import SmaliEntry 15 | 16 | INVOKE_DIRECT = "invoke-direct" 17 | INVOKE_INTERFACE = "invoke-interface" 18 | INVOKE_STATIC = "invoke-static" 19 | INVOKE_SUPER = "invoke-super" 20 | INVOKE_VIRTUAL = "invoke-virtual" 21 | 22 | INVOKE_RE = re.compile("^ *invoke-.*$", re.M) 23 | USE_FIELD_RE = re.compile("^ *iget.*$|^ *iput.*$|^ *sget.*$|^ *sput.*$", re.M) 24 | PUT_FIELD_RE = re.compile("iput.*|sput.*") 25 | 26 | class Invoke(object): pass 27 | class UsedField(object): pass 28 | 29 | def isPutUseField(usedField): 30 | if PUT_FIELD_RE.match(usedField.type) is not None: 31 | return True 32 | return False 33 | 34 | class SmaliMethod(SmaliEntry): 35 | ''' 36 | classdocs 37 | ''' 38 | def __init__(self, type, content, clsName, preContent=None): 39 | super(SmaliMethod, self).__init__(type, content, clsName, preContent) 40 | self.mInvokeMethods = None 41 | self.mUsedFields = None 42 | 43 | def __getInvokeMethods__(self): 44 | invokeMethodsList = [] 45 | for line in self.getContentStr().split('\n'): 46 | if INVOKE_RE.match(line) is not None: 47 | splitArray = line.split() 48 | invokeItem = Invoke() 49 | assert len(splitArray) >= 2, "Wrong invoke: %s" %line 50 | invokeItem.type = splitArray[0].split(r'/')[0] 51 | 52 | splitArrayNew = splitArray[len(splitArray) - 1].split('->') 53 | assert len(splitArrayNew) == 2, "Wrong invoke: %s" %line 54 | 55 | if splitArrayNew[0][0] == r'[': 56 | #print ">>> ignore cls: %s" % splitArrayNew[0] 57 | continue 58 | 59 | invokeItem.cls = splitArrayNew[0] 60 | invokeItem.method = splitArrayNew[1] 61 | invokeItem.belongMethod = self.getName() 62 | invokeItem.belongCls = self.mClsName 63 | 64 | invokeMethodsList.append(invokeItem) 65 | return list(set(invokeMethodsList)) 66 | 67 | def getInvokeMethods(self): 68 | if self.mInvokeMethods is None: 69 | self.mInvokeMethods = self.__getInvokeMethods__() 70 | 71 | return self.mInvokeMethods 72 | 73 | def __getUsedFields__(self): 74 | usedFieldsList = [] 75 | for line in self.getContentStr().split('\n'): 76 | if USE_FIELD_RE.match(line) is not None: 77 | splitArray = line.split() 78 | usedField = UsedField() 79 | assert len(splitArray) >= 2, "Wrong field get or put: %s" %line 80 | usedField.type = splitArray[0].split(r'/')[0] 81 | 82 | splitArrayNew = splitArray[len(splitArray) - 1].split('->') 83 | assert len(splitArrayNew) == 2, "Wrong field get or put: %s" %line 84 | usedField.cls = splitArrayNew[0] 85 | usedField.field = splitArrayNew[1] 86 | 87 | usedFieldsList.append(usedField) 88 | return list(set(usedFieldsList)) 89 | 90 | def getUsedFields(self): 91 | if self.mUsedFields is None: 92 | self.mUsedFields = self.__getUsedFields__() 93 | 94 | return self.mUsedFields 95 | 96 | def formatUsingField(self, formatMap): 97 | entryStr = self.getContentStr() 98 | modifed = False 99 | for usedFieldItem in self.getUsedFields(): 100 | key = r'%s->%s' % (usedFieldItem.cls, usedFieldItem.field) 101 | if formatMap.has_key(key): 102 | modifed = True 103 | entryStr = entryStr.replace(key, formatMap[key]) 104 | if modifed: 105 | self.setContentStr(entryStr) 106 | return modifed 107 | 108 | def getReturnType(self): 109 | return getReturnType(self.getName()) 110 | 111 | def isConstructor(self): 112 | return self.hasKey(utils.KEY_CONSTRUCTOR) 113 | 114 | def getSimpleName(self): 115 | return self.getName().split('(')[0] 116 | 117 | def getReturnType(methodName): 118 | splitArray = methodName.split(r')') 119 | if len(splitArray) < 2: 120 | utils.SLog.w("method %s return nothing!" %methodName) 121 | return "" 122 | else: 123 | return splitArray[-1] 124 | -------------------------------------------------------------------------------- /smaliparser/SmaliSubClass.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on 2012-12-11 3 | 4 | @author: jock 5 | ''' 6 | 7 | class SmaliSubClass(object): 8 | ''' 9 | classdocs 10 | ''' 11 | 12 | 13 | def __init__(self): 14 | ''' 15 | Constructor 16 | ''' 17 | -------------------------------------------------------------------------------- /smaliparser/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/smaliparser/__init__.py -------------------------------------------------------------------------------- /smaliparser/classtobosp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #**************************************************# 4 | #This shell used to call SCheck to replace smali 5 | #**************************************************# 6 | 7 | CUR_DIR=$(dirname $0) 8 | SCHECK=$CUR_DIR/SCheck 9 | PRE_DIR=$PWD 10 | PRJ_ROOT=$PWD 11 | 12 | function usage() 13 | { 14 | echo "################ USAGE ################" 15 | echo "#" 16 | echo "# smalitobosp smali" 17 | echo "# smali: the target smali, which will be replace to bosp" 18 | echo "#" 19 | echo "# ex:" 20 | echo "# smalitobosp services.jar.out/smali/com/android/server/pm/ShutdownThread.smali" 21 | echo "# it will replace the smali mservices.jar.out/smali/com/android/server/pm/ShutdownThread.smali and the memberclass to bosp!" 22 | echo "#" 23 | echo "# Attention:" 24 | echo "# This is not just simple replace, it will check the methods, fields, class which was used can be found!" 25 | echo "#" 26 | } 27 | 28 | if [ $# -lt 1 ]; then 29 | usage 30 | exit 1 31 | fi 32 | 33 | function getPrjRoot() 34 | { 35 | while [ ! -f $PRJ_ROOT/Makefile ] && [ ! -f $PRJ_ROOT/makefile ] 36 | do 37 | PRJ_ROOT=`dirname $PRJ_ROOT` 38 | if [ $PRJ_ROOT == '/' ]; then 39 | echo "Error: can not get the project's root directory!" 40 | echo " make sure you run this command in your device directory" 41 | exit 1 42 | fi 43 | done 44 | 45 | if [ ${PRJ_ROOT#$PORT_ROOT*} == $PRJ_ROOT ]; then 46 | echo "Error: you should run 'source ./build/envsetup.sh' in coron first!" 47 | exit 1 48 | fi 49 | } 50 | 51 | function main() 52 | { 53 | if [ $# -lt 1 ]; then 54 | usage 55 | exit 1 56 | fi 57 | getPrjRoot 58 | 59 | cd $PRJ_ROOT > /dev/null 60 | tmpFile=`mktemp -t methodtobosp.XXXXX` 61 | echo "$@" > $tmpFile 62 | make smalitobosp SMALI_FILE=$tmpFile 63 | rm $tmpFile 64 | cd $PRE_DIR > /dev/null 65 | } 66 | 67 | main $@ 68 | -------------------------------------------------------------------------------- /smaliparser/help/reject_advice: -------------------------------------------------------------------------------- 1 | | 2 | | >> Advice: 3 | | The reason that these methods can not be replace to bosp 4 | | probaly because they are constructor methods, 5 | | where the fields which was added by vendor will be initiated! 6 | | 7 | | You better fix the remain rejects by yourself! 8 | | 9 | | How to fix the reject: 10 | | you can find it in "manifests/Coron-Developer-Guide.pdf" 11 | | 12 | -------------------------------------------------------------------------------- /smaliparser/help/reject_success: -------------------------------------------------------------------------------- 1 | | 2 | | >> ^_^. All reject has been fixed. Congratulations! 3 | | 4 | | Advice: 5 | | You could go on to `make` out a ROM, flash it into 6 | | your device, and then fix bugs depends on real-time logs. 7 | | 8 | -------------------------------------------------------------------------------- /smaliparser/help/smalitobosp_advice: -------------------------------------------------------------------------------- 1 | | 2 | | >> Advice: 3 | | The reason that these smali's method can not be replace to bosp 4 | | probaly because they are constructor methods, 5 | | where the fields which was added by vendor will be initiated! 6 | | 7 | | You better fix the reject by yourself! There are errors when replace to bosp! 8 | | 9 | -------------------------------------------------------------------------------- /smaliparser/help/smalitobosp_success: -------------------------------------------------------------------------------- 1 | | 2 | | >> ^_^. All of the smali has been successfully replaced to bosp . Congratulations! 3 | | 4 | | Advice: 5 | | You could go on to `make` out a ROM, flash it into 6 | | your device, and then fix bugs depends on real-time logs. 7 | | 8 | -------------------------------------------------------------------------------- /smaliparser/methodtobosp: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | #**************************************************# 4 | #This shell used to call SCheck to replace smali 5 | #**************************************************# 6 | 7 | CUR_DIR=$(dirname $0) 8 | SCHECK=$CUR_DIR/SCheck 9 | PRE_DIR=$PWD 10 | PRJ_ROOT=$PWD 11 | 12 | function usage() 13 | { 14 | echo "################ USAGE ################" 15 | echo "#" 16 | echo "# methodtobosp smali methodName" 17 | echo "# smali: the target smali, which will be replace to bosp" 18 | echo "# methodName: the method's name" 19 | echo "#" 20 | echo "# ex:" 21 | echo "# methodtobosp services.jar.out/smali/com/android/server/am/ActivityManagerService.smali 'moveTaskToFront(IILandroid/os/Bundle;)V'" 22 | echo "# it will replace the method moveTaskToFront(IILandroid/os/Bundle;)V in services.jar.out/smali/com/android/server/am/ActivityManagerService.smali by autopatch/bosp/services.jar.out/smali/com/android/server/am/ActivityManagerService.smali" 23 | echo "#" 24 | echo "# Attention:" 25 | echo "# The method name should enclose in the quotes." 26 | echo "#" 27 | } 28 | 29 | if [ $# -lt 1 ]; then 30 | usage 31 | exit 1 32 | fi 33 | 34 | function getPrjRoot() 35 | { 36 | while [ ! -f $PRJ_ROOT/Makefile ] && [ ! -f $PRJ_ROOT/makefile ] 37 | do 38 | PRJ_ROOT=`dirname $PRJ_ROOT` 39 | if [ $PRJ_ROOT == '/' ]; then 40 | echo "Error: can not get the project's root directory!" 41 | echo " make sure you run this command in your device directory" 42 | exit 1 43 | fi 44 | done 45 | 46 | if [ ${PRJ_ROOT#$PORT_ROOT*} == $PRJ_ROOT ]; then 47 | echo "Error: you should run 'source ./build/envsetup.sh' in coron first!" 48 | exit 1 49 | fi 50 | } 51 | 52 | function main() 53 | { 54 | if [ $# -lt 2 ]; then 55 | usage 56 | exit 1 57 | fi 58 | 59 | getPrjRoot 60 | 61 | cd $PRJ_ROOT > /dev/null 62 | tmpFile=`mktemp -t methodtobosp.XXXXX` 63 | echo "$2" > $tmpFile 64 | make methodtobosp SMALI_FILE=$1 METHOD=$tmpFile 65 | rm -rf $tmpFile 66 | cd $PRE_DIR > /dev/null 67 | } 68 | 69 | main 70 | 71 | -------------------------------------------------------------------------------- /smaliparser/tobosp.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Created on Jun 3, 2014 3 | 4 | @author: tangliuxiang 5 | ''' 6 | 7 | import SCheck 8 | import SmaliEntry 9 | import SmaliFileReplace 10 | import os 11 | import utils 12 | import Replace 13 | 14 | def usage(): 15 | print "" 16 | 17 | def tobosp(args): 18 | if len(args) <= 0: 19 | usage() 20 | elif len(args) == 2: 21 | Replace.replace(utils.getMatchFile(args[0], utils.BOSP), args[0], SmaliEntry.METHOD, SmaliEntry, args[1]) 22 | else: 23 | for smaliFile in args: 24 | SmaliFileReplace.replace(utils.getMatchFile(smaliFile, utils.BOSP), smaliFile) 25 | -------------------------------------------------------------------------------- /su-chmod: -------------------------------------------------------------------------------- 1 | su-tools/su-chmod -------------------------------------------------------------------------------- /su-pull: -------------------------------------------------------------------------------- 1 | su-tools/su-pull -------------------------------------------------------------------------------- /su-push: -------------------------------------------------------------------------------- 1 | su-tools/su-push -------------------------------------------------------------------------------- /su-tools/check-su: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | prog="$0" 4 | while [ -h "${prog}" ]; do 5 | newProg=`/bin/ls -ld "${prog}"` 6 | #echo ${newProg} 7 | 8 | 9 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 10 | if expr "x${newProg}" : 'x/' >/dev/null; then 11 | prog="${newProg}" 12 | else 13 | progdir=`dirname "${prog}"` 14 | prog="${progdir}/${newProg}" 15 | fi 16 | done 17 | oldwd=`pwd` 18 | progdir=`dirname "${prog}"` 19 | cd "${progdir}" 20 | progdir=`pwd` 21 | prog="${progdir}"/`basename "${prog}"` 22 | cd "${oldwd}" 23 | 24 | CHECK_SU=$progdir/phone-check-su 25 | PHONE_TMP_DIR=/data/local/tmp 26 | PHONE_CHECK_SU=$PHONE_TMP_DIR/phone-check-su 27 | 28 | function getRet() 29 | { 30 | adb wait-for-device 31 | adb push $CHECK_SU $PHONE_CHECK_SU 32 | adb shell chmod 777 $PHONE_CHECK_SU 33 | 34 | ret=$(adb shell sh $PHONE_CHECK_SU 2>&1 | grep OK) 35 | if [ "x$ret" != "x" ]; then 36 | echo "su is ok" 37 | return 0 38 | else 39 | echo "Error: su is wrong" 40 | return 1 41 | fi 42 | } 43 | 44 | getRet 45 | exit $? 46 | -------------------------------------------------------------------------------- /su-tools/phone-check-su: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | 3 | su -c "mount -o remount,rw /system" 4 | 5 | if [ $? == 0 ]; then 6 | echo "OK" 7 | exit 0 8 | fi; 9 | 10 | echo "ERROR" 11 | 12 | 13 | -------------------------------------------------------------------------------- /su-tools/phone-chmod: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | self=$0 3 | 4 | pushed_file="" 5 | if [ "x$1" == "x--after-push" ] || [ "x$1" == "x-a" ]; then 6 | pushed_file=$2 7 | shift 8 | shift 9 | fi 10 | 11 | RECURSIVE=false 12 | if [ "x$1" == "x--recursive" ] || [ "x$1" == "x-R" ]; then 13 | RECURSIVE=true 14 | shift 15 | fi 16 | 17 | permission=$1 18 | target=$2 19 | CHMOD_CMD="chmod" 20 | 21 | if [ -d "$target" ]; then 22 | pushed_base_name=${pushed_file##*/} 23 | if [ "x$pushed_file" != "x" ] && [ -f "$target/$pushed_base_name" ]; then 24 | target="$target/$pushed_base_name" 25 | fi 26 | 27 | if [ -d "$target" ]; then 28 | if [ "$RECURSIVE" == true ]; then 29 | CHMOD_CMD="$CHMOD_CMD -R" 30 | fi 31 | fi 32 | fi 33 | 34 | $CHMOD_CMD $permission $target 35 | chmod 777 $self 36 | -------------------------------------------------------------------------------- /su-tools/phone-cp: -------------------------------------------------------------------------------- 1 | #!/system/bin/sh 2 | # author: tangliuxiang 3 | 4 | self=$0 5 | src=$1 6 | dst=$2 7 | 8 | if [ ${dst:${#dst}-1} == '/' ]; then 9 | dst=${dst::${#dst}-1} 10 | fi 11 | 12 | if [ -d $src ]; then 13 | ls $src | while read f; do 14 | $self $src/$f $dst/$f 15 | done 16 | else [ -f $src ] 17 | if [ -d $dst ]; then 18 | srcBN=${src##*/} 19 | echo "cat $src > $dst/$srcBN" 20 | cat $src > $dst/$srcBN 21 | else 22 | dstBN=${dst%/*} 23 | mkdir -p $dstBN 24 | echo "cat $src > $dst" 25 | cat $src > $dst 26 | fi 27 | fi 28 | -------------------------------------------------------------------------------- /su-tools/su-chmod: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: tangliuxiang 3 | 4 | function usage() 5 | { 6 | echo "USAGE: su-chmod [OPTION] MODE FILE" 7 | echo " -R, --recursive" 8 | echo " change files and directories recursively" 9 | } 10 | 11 | prog="$0" 12 | while [ -h "${prog}" ]; do 13 | newProg=`/bin/ls -ld "${prog}"` 14 | #echo ${newProg} 15 | 16 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 17 | if expr "x${newProg}" : 'x/' >/dev/null; then 18 | prog="${newProg}" 19 | else 20 | progdir=`dirname "${prog}"` 21 | prog="${progdir}/${newProg}" 22 | fi 23 | done 24 | oldwd=`pwd` 25 | progdir=`dirname "${prog}"` 26 | cd "${progdir}" 27 | progdir=`pwd` 28 | prog="${progdir}"/`basename "${prog}"` 29 | cd "${oldwd}" 30 | 31 | if [ $# -lt 2 ]; then 32 | usage 33 | exit 1 34 | fi 35 | 36 | pushed_file="" 37 | if [ "x$1" == "x--after-push" ] || [ "x$1" == "x-a" ]; then 38 | pushed_file="--after-push $2" 39 | shift 40 | shift 41 | fi 42 | 43 | RECURSIVE="" 44 | if [ "x$1" == "x--recursive" ] || [ "x$1" == "x-R" ]; then 45 | RECURSIVE="-R" 46 | shift 47 | fi 48 | 49 | permission=$1 50 | target=$2 51 | p_chmod="$progdir/phone-chmod" 52 | phone_chmod=/data/local/tmp/phone-chmod 53 | 54 | adb push $p_chmod $phone_chmod 55 | adb shell chmod 777 $phone_chmod 56 | 57 | chmod_cmd="$phone_chmod $pushed_file $RECURSIVE $permission $target" 58 | 59 | if [[ $target == "/system/"* ]] || [[ $target == "system/"* ]];then 60 | #echo "su -c \"mount -o remount,rw /system; $chmod_cmd ;mount -o remount,ro /system\"; exit $?" | adb shell 61 | adb shell su -c mount -o remount,rw /system; 62 | adb shell su -c $chmod_cmd 63 | # adb shell su -c mount -o remount,ro /system 64 | else 65 | #echo "su -c \"$chmod_cmd; \"; exit $?" | adb shell 66 | adb shell su -c $chmod_cmd; 67 | fi 68 | -------------------------------------------------------------------------------- /su-tools/su-pull: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: tangliuxiang 3 | 4 | function usage() 5 | { 6 | echo "USAGE: su-pull " 7 | echo " - copy file/dir from device to pc" 8 | echo "Just like the usage of adb pull" 9 | } 10 | 11 | prog="$0" 12 | while [ -h "${prog}" ]; do 13 | newProg=`/bin/ls -ld "${prog}"` 14 | #echo ${newProg} 15 | 16 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 17 | if expr "x${newProg}" : 'x/' >/dev/null; then 18 | prog="${newProg}" 19 | else 20 | progdir=`dirname "${prog}"` 21 | prog="${progdir}/${newProg}" 22 | fi 23 | done 24 | oldwd=`pwd` 25 | progdir=`dirname "${prog}"` 26 | cd "${progdir}" 27 | progdir=`pwd` 28 | prog="${progdir}"/`basename "${prog}"` 29 | cd "${oldwd}" 30 | 31 | if [ $# -lt 2 ]; then 32 | usage 33 | exit 1 34 | fi 35 | 36 | src=$1 37 | target=$2 38 | 39 | src_basename=`basename $src` 40 | CHECK_SU=$progdir/check-su 41 | pcp=$progdir/phone-cp 42 | ptmp_su_pull=/data/local/tmp/su_pull_tmp 43 | phone_cp=/data/local/tmp/phone-cp 44 | 45 | if [ x"$target" == x ];then 46 | target=$PWD/$src_basename 47 | fi 48 | 49 | adb wait-for-device 50 | 51 | $CHECK_SU 52 | if [ $? != 0 ]; then 53 | echo "Error: failed to pull $src to $target" 54 | echo " You better make sure you have an correct su, you can run check-su to test if su is ok" 55 | exit 1 56 | fi 57 | 58 | adb push $pcp $phone_cp 59 | adb shell chmod 777 $phone_cp 60 | 61 | echo "begin copy $src to $ptmp_su_pull/$src_basename" 62 | #echo "su -c \"rm -rf $ptmp_su_pull; mkdir -p $ptmp_su_pull; chmod 777 $ptmp_su_pull; $phone_cp $src $ptmp_su_pull/$src_basename; chmod -R 777 $ptmp_su_pull/$src_basename\"; exit" | adb shell 63 | adb shell su -c "rm -rf $ptmp_su_pull"; 64 | adb shell su -c "mkdir -p $ptmp_su_pull"; 65 | adb shell su -c "chmod 777 $ptmp_su_pull"; 66 | adb shell su -c "$phone_cp $src $ptmp_su_pull/$src_basename"; 67 | adb shell su -c "chmod -R 777 $ptmp_su_pull/$src_basename"; 68 | 69 | adb pull $ptmp_su_pull/$src_basename $target 70 | #echo "su -c \"rm -rf $ptmp_su_pull\"; exit" | adb shell 71 | adb shell su -c "rm -rf $ptmp_su_pull"; 72 | -------------------------------------------------------------------------------- /su-tools/su-push: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # author: tangliuxiang 3 | 4 | function usage() 5 | { 6 | echo "USAGE: su-push " 7 | echo " - copy file/dir to device" 8 | echo "Just like the usage of adb push" 9 | } 10 | 11 | prog="$0" 12 | while [ -h "${prog}" ]; do 13 | newProg=`/bin/ls -ld "${prog}"` 14 | #echo ${newProg} 15 | 16 | newProg=`expr "${newProg}" : ".* -> \(.*\)$"` 17 | if expr "x${newProg}" : 'x/' >/dev/null; then 18 | prog="${newProg}" 19 | else 20 | progdir=`dirname "${prog}"` 21 | prog="${progdir}/${newProg}" 22 | fi 23 | done 24 | oldwd=`pwd` 25 | progdir=`dirname "${prog}"` 26 | cd "${progdir}" 27 | progdir=`pwd` 28 | prog="${progdir}"/`basename "${prog}"` 29 | cd "${oldwd}" 30 | 31 | PERMISSION="" 32 | if [ "x$1" == "x-p" ]; then 33 | PERMISSION="$2" 34 | shift 35 | shift 36 | fi 37 | 38 | if [ $# -lt 2 ]; then 39 | usage 40 | exit 1 41 | fi 42 | 43 | src=$1 44 | target=$2 45 | CHECK_SU=$progdir/check-su 46 | SU_CHMOD=$progdir/su-chmod 47 | pcp=$progdir/phone-cp 48 | ptmp_su_push=/data/local/tmp/su_push 49 | phone_cp=/data/local/tmp/phone-cp 50 | 51 | src_basename=`basename $src` 52 | 53 | if [ -f $src ] || [ -d $src ]; then 54 | adb wait-for-device 55 | $CHECK_SU 56 | if [ $? != 0 ]; then 57 | echo "Error: failed to push $src to $target" 58 | echo " You better make sure you have an correct su, you can run check-su to test if su is ok" 59 | exit 1 60 | fi 61 | 62 | adb shell rm -rf $ptmp_su_push 63 | adb shell mkdir -p $ptmp_su_push 64 | adb push $src $ptmp_su_push 65 | adb push $pcp $phone_cp 66 | adb shell chmod 777 $phone_cp 67 | 68 | if [ -d $src ]; then 69 | ptmp_src=$ptmp_su_push 70 | else 71 | ptmp_src=$ptmp_su_push/$src_basename 72 | fi 73 | 74 | if [[ $target == "/system/"* ]] || [[ $target == "system/"* ]];then 75 | #echo "su -c \"mount -o remount,rw /system; $phone_cp $ptmp_src $target;mount -o remount,ro /system\"; exit $?" | adb shell 76 | adb shell su -c mount -o remount,rw /system; 77 | adb shell su -c $phone_cp $ptmp_src $target; 78 | # adb shell su -c mount -o remount,ro /system; 79 | else 80 | #echo "su -c \"$phone_cp $PERMISSION $ptmp_src $target; \"; exit $?" | adb shell 81 | adb shell su -c $phone_cp $PERMISSION $ptmp_src $target; 82 | fi 83 | 84 | adb shell rm -rf $ptmp_su_push 85 | 86 | if [ $? == 0 ]; then 87 | if [ "x$PERMISSION" != "x" ]; then 88 | $SU_CHMOD --after-push $src $PERMISSION $target 89 | if [ $? != 0 ]; then 90 | echo "Error: Failed to push $src to $target" 91 | exit 1 92 | fi 93 | fi 94 | echo "Success push $src to $target" 95 | else 96 | echo "Error: Failed to push $src to $target" 97 | exit 1 98 | fi 99 | else 100 | echo "Error: $src doesn't exist!" 101 | exit 1 102 | fi 103 | -------------------------------------------------------------------------------- /unpack_bootimg: -------------------------------------------------------------------------------- 1 | bootimgpack/unpack_bootimg.py -------------------------------------------------------------------------------- /workflow/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/workflow/__init__.py -------------------------------------------------------------------------------- /workflow/coron.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | 3 | # Copyright 2015 Coron 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | """ 19 | Coron 20 | """ 21 | 22 | __author__ = "duanqz@gmail.com" 23 | 24 | 25 | import sys 26 | from workflow import CoronStateMachine 27 | from helpdoc import help 28 | 29 | 30 | if __name__ == "__main__": 31 | if len(sys.argv) == 1: 32 | help.usage() 33 | sys.exit(0) 34 | 35 | arg = sys.argv[1] 36 | if arg == "fire": 37 | CoronStateMachine().start() 38 | elif arg == "help": 39 | help.main(sys.argv[1:]) 40 | else: 41 | CoronStateMachine().doAction(sys.argv[1:]) 42 | 43 | -------------------------------------------------------------------------------- /workflow/workflow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | inactive 4 | 5 | 6 | 7 | 8 | inactive 9 | 10 | 11 | 12 | makeconfig 13 | 14 | 15 | 16 | 17 | inactive 18 | 19 | 20 | 21 | 22 | make newproject 23 | git init 24 | git add --all 25 | git commit -am "newproject" 26 | 27 | 28 | 29 | 30 | inactive 31 | 32 | 33 | 34 | 35 | make patchall 36 | 37 | 38 | 39 | 40 | inactive 41 | 42 | 43 | 44 | 45 | make autofix 46 | 47 | 48 | 49 | 50 | inactive 51 | 52 | 53 | 54 | make 55 | 56 | 57 | 58 | 59 | inactive 60 | 61 | 62 | 63 | 64 | make clean 65 | 66 | 67 | 68 | 69 | 70 | make clean-all 71 | 72 | 73 | 74 | 75 | 76 | make upgrade 77 | 78 | 79 | 80 | 81 | 82 | make porting 83 | 84 | 85 | -------------------------------------------------------------------------------- /zipalign: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FlymeOS/tools/1df75df832b607128b7e80e2e1a256f973315446/zipalign --------------------------------------------------------------------------------