├── .gitignore ├── FART_6.0_sourcecode.zip ├── LICENSE ├── README.md ├── fart.py └── frida_fart.zip /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled class file 2 | *.class 3 | 4 | # Log file 5 | *.log 6 | 7 | # BlueJ files 8 | *.ctxt 9 | 10 | # Mobile Tools for Java (J2ME) 11 | .mtj.tmp/ 12 | 13 | # Package Files # 14 | *.jar 15 | *.war 16 | *.nar 17 | *.ear 18 | *.zip 19 | *.tar.gz 20 | *.rar 21 | 22 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 23 | hs_err_pid* 24 | -------------------------------------------------------------------------------- /FART_6.0_sourcecode.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanbinglengyue/FART/50d49f97850e2ff95e9715c6c63699c9566cd6e6/FART_6.0_sourcecode.zip -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FART 2 | ART环境下基于主动调用的自动化脱壳方案,基于Android 6.0实现,理论上可以移植到任何ART系统上。具体原理和实现请移步看雪,系列文章共计3篇,对加固和对抗感兴趣的可以看看: 3 | 4 | 5 | 1、拨云见日:安卓APP脱壳的本质以及如何快速发现ART下的脱壳点 https://bbs.pediy.com/thread-254555.htm 6 | 7 | 8 | 2、FART正餐前甜点:ART下几个通用简单高效的dump内存中dex方法 https://bbs.pediy.com/thread-254028.htm 9 | 10 | 11 | 3、FART:ART环境下基于主动调用的自动化脱壳方案 https://bbs.pediy.com/thread-252630.htm 12 | 13 | 14 | 脱壳流程: 15 | 16 | 1、安装待脱壳apk,并到设置中授予sd卡读写权限(否则dump下的文件无法写入到sdcard) 17 | 18 | 19 | 2、点击app图标,开始进入fart脱壳过程 20 | 21 | 22 | 接下来可以对logcat中的tag为ActivityThread的log进行过滤,等待待脱壳app进程出现"fart run over",此时fart主动调用过程结束。脱壳下来的 23 | 24 | dex文件和函数体bin文件均在/sdcard/fart/app包名的目录下 25 | 26 | 27 | 下面截图为fart的运行流程和脱壳结果 28 | 29 |

30 | 31 |

32 | 33 | 34 |

35 | 36 |

37 | 38 | FART 6.0 8.0镜像地址: 39 | 40 | 41 | 链接:https://pan.baidu.com/s/1c3AyDZ92vVPxt06xwjFO9w 42 | 提取码:1yzb 43 | 44 | FART交流群。 45 | 46 | https://t.me/+BvJFRSInoo05NTA5 47 | 48 | -------------------------------------------------------------------------------------------------- 49 | 添加frida版的fart的两种不同实现,各有特色。可以实现具体到对某一个类下的所有函数甚至是对某一个函数的CodeItem的dump。需要的可以去体验下其强大的脱壳能力。(注意,测试环境为pixel Android8.0,frida-server 12.8.0) 50 |

51 | 52 |

53 | -------------------------------------------------------------------------------- /fart.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/python2.7 2 | # -*- coding: utf8 -*- 3 | 4 | import sys 5 | import struct 6 | import array 7 | filename = "_data_app_com.example.dexcode-1_base.apk0.dex_722044_0" 8 | insfilename ="722044_ins.bin" 9 | DEX_MAGIC = "dex\n" 10 | DEX_OPT_MAGIC = "dey\n" 11 | import base64 12 | import re 13 | methodTable={} 14 | 15 | 16 | FMT10T = 0 17 | FMT10X = 1 18 | FMT11N = 2 19 | FMT11X = 3 20 | FMT12X = 4 21 | FMT20T = 5 22 | FMT21C = 6 23 | FMT21H = 7 24 | FMT21S = 8 25 | FMT21T = 9 26 | FMT22B = 10 27 | FMT22C = 11 28 | FMT22S = 12 29 | FMT22T = 13 30 | FMT22X = 14 31 | FMT23X = 15 32 | FMT30T = 16 33 | FMT31C = 17 34 | FMT31I = 18 35 | FMT31T = 19 36 | FMT32X = 20 37 | FMT35C = 21 38 | FMT3RC = 22 39 | FMT51L = 23 40 | 41 | list1 = ['fmt10t', 'fmt10x', 'fmt11n', 'fmt11x', 'fmt12x', 'fmt20t', 'fmt21c', 'fmt21h', 42 | 'fmt21s', 'fmt21t', 'fmt22b', 'fmt22c', 'fmt22s', 'fmt22t', 'fmt22x', 'fmt23x', 43 | 'fmt30t', 'fmt31c', 'fmt31i', 'fmt31t', 'fmt32x', 'fmt35c', 'fmt3rc', 'fmt51l'] 44 | 45 | 46 | def get_uleb128p1(content): 47 | n, value = get_uleb128(content) 48 | value -= 1 49 | return n, value 50 | 51 | 52 | def get_uleb128(content): 53 | value = 0 54 | if len(content) < 5: 55 | for i in xrange(0, len(content)): 56 | tmp = ord(content[i]) & 0x7f 57 | value = tmp << (i * 7) | value 58 | if (ord(content[i]) & 0x80) != 0x80: 59 | break 60 | elif len(content) == 5: 61 | for i in xrange(0, 5): 62 | tmp = ord(content[i]) & 0x7f 63 | value = tmp << (i * 7) | value 64 | if (ord(content[i]) & 0x80) != 0x80: 65 | break 66 | elif len(content) > 5: 67 | for i in xrange(0, 5): 68 | tmp = ord(content[i]) & 0x7f 69 | value = tmp << (i * 7) | value 70 | if (ord(content[i]) & 0x80) != 0x80: 71 | break 72 | if i == 4 and (tmp & 0xf0) != 0: 73 | print "parse a error uleb128 number" 74 | return -1 75 | return i + 1, value 76 | 77 | def get_leb128(content): 78 | value = 0 79 | 80 | mask = [0xffffff80, 0xffffc000, 0xffe00000, 0xf0000000, 0] 81 | bitmask = [0x40, 0x40, 0x40, 0x40, 0x8] 82 | value = 0 83 | i = 0 84 | if len(content) < 5: 85 | for i in xrange(0, len(content)): 86 | tmp = ord(content[i]) & 0x7f 87 | value = tmp << (i * 7) | value 88 | if (ord(content[i]) & 0x80) != 0x80: 89 | if bitmask[i] & tmp: 90 | value |= mask[i] 91 | break 92 | elif len(content) == 5: 93 | for i in xrange(0, 5): 94 | tmp = ord(content[i]) & 0x7f 95 | value = tmp << (i * 7) | value 96 | if (ord(content[i]) & 0x80) != 0x80: 97 | if bitmask[i] & tmp: 98 | value |= mask[i] 99 | break 100 | elif len(content) > 5: 101 | for i in xrange(0, 5): 102 | tmp = ord(content[i]) & 0x7f 103 | value = tmp << (i * 7) | value 104 | if (ord(content[i]) & 0x80) != 0x80: 105 | if bitmask[i] & tmp: 106 | value |= mask[i] 107 | break 108 | if i == 4 and (tmp & 0xf0) != 0: 109 | print "parse a error uleb128 number" 110 | return -1 111 | buffer = struct.pack("I", value) 112 | value, = struct.unpack("i", buffer) 113 | return i + 1, value 114 | def parse_FMT10X(buffer, dex_object, pc_point, offset): 115 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1]) 116 | 117 | 118 | def parse_FMT10T(buffer, dex_object, pc_point, offset): 119 | val, = struct.unpack_from("b", buffer, 1) 120 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "%04x" % (val + offset)) 121 | 122 | 123 | def parse_FMT11N(buffer, dex_object, pc_point, offset): 124 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % (ord(buffer[1]) & 0xf), 125 | "%d" % ((ord(buffer[1]) >> 4) & 0xf)) 126 | 127 | 128 | def parse_FMT11X(buffer, dex_object, pc_point, offset): 129 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1])) 130 | 131 | 132 | def parse_FMT12X(buffer, dex_object, pc_point, offset): 133 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % (ord(buffer[1]) & 0x0f), 134 | "v%d" % ((ord(buffer[1]) >> 4) & 0xf)) 135 | 136 | 137 | def parse_FMT20T(buffer, dex_object, pc_point, offset): 138 | v, = struct.unpack_from("h", buffer, 2) 139 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "%04x" % (v + offset)) 140 | 141 | 142 | def parse_FMT21C(buffer, dex_object, pc_point, offset): 143 | val = ord(buffer[0]) 144 | 145 | v, = struct.unpack_from("H", buffer, 2) 146 | arg1 = "@%d" % v 147 | if val == 0x1a: 148 | arg1 = "\"%s\"" % dex_object.getstringbyid(v) 149 | elif val in [0x1c, 0x1f, 0x22]: 150 | arg1 = "type@%s" % dex_object.gettypename(v) 151 | else: 152 | arg1 = "field@%s //%s" % (dex_object.getfieldname(v), dex_object.getfieldfullname(v)) 153 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), arg1) 154 | 155 | 156 | def parse_FMT21H(buffer, dex_object, pc_point, offset): 157 | v, = struct.unpack_from("H", buffer, 2) 158 | if ord(buffer[1]) == 0x19: 159 | arg1 = "@%d000000000000" % v 160 | else: 161 | arg1 = "@%d0000" % v 162 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), arg1) 163 | 164 | 165 | def parse_FMT21S(buffer, dex_object, pc_point, offset): 166 | v, = struct.unpack_from("H", buffer, 2) 167 | arg1 = "%d" % v 168 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), arg1) 169 | 170 | 171 | def parse_FMT21T(buffer, dex_object, pc_point, offset): 172 | v, = struct.unpack_from("h", buffer, 2) 173 | arg1 = "%04x" % (v + offset) 174 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), arg1) 175 | 176 | 177 | def parse_FMT22B(buffer, dex_object, pc_point, offset): 178 | cc, bb, = struct.unpack_from("Bb", buffer, 2) 179 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "v%d" % bb, "%d" % cc) 180 | 181 | 182 | def parse_FMT22C(buffer, dex_object, pc_point, offset): 183 | cccc, = struct.unpack_from("H", buffer, 2) 184 | if ord(buffer[0]) == 0x20 or ord(buffer[0]) == 0x23: 185 | prefix = "type@%s" % (dex_object.gettypename(cccc)) 186 | else: 187 | prefix = "field@%s //%s" % (dex_object.getfieldname(cccc), dex_object.getfieldfullname(cccc)) 188 | 189 | bb = ord(buffer[1]) >> 4 190 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % (ord(buffer[1]) & 0xf), 191 | "v%d" % ((ord(buffer[1]) >> 4) & 0xf), "%s" % prefix) 192 | 193 | 194 | def parse_FMT22S(buffer, dex_object, pc_point, offset): 195 | bb = ord(buffer[1]) >> 4 196 | cccc, = struct.unpack_from("h", buffer, 2) 197 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % (ord(buffer[1]) & 0xf), 198 | "v%d" % ((ord(buffer[1]) >> 4) & 0xf), "%d" % cccc) 199 | 200 | 201 | def parse_FMT22T(buffer, dex_object, pc_point, offset): 202 | bb = ord(buffer[1]) >> 4 203 | cccc, = struct.unpack_from("h", buffer, 2) 204 | 205 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % (ord(buffer[1]) & 0xf), 206 | "v%d" % ((ord(buffer[1]) >> 4) & 0xf), "%04x" % (cccc + offset)) 207 | 208 | 209 | def parse_FMT22X(buffer, dex_object, pc_point, offset): 210 | v, = struct.unpack_from("h", buffer, 2) 211 | arg1 = "v%d" % v 212 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), arg1) 213 | 214 | 215 | def parse_FMT23X(buffer, dex_object, pc_point, offset): 216 | cc, bb, = struct.unpack_from("Bb", buffer, 2) 217 | return ( 218 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "v%d" % bb, "v%d" % cc) 219 | 220 | 221 | def parse_FMT30T(buffer, dex_object, pc_point, offset): 222 | aaaaaaaa, = struct.unpack_from("i", buffer, 2) 223 | return dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "+%x" % (aaaaaaaa + offset) 224 | 225 | 226 | def parse_FMT31C(buffer, dex_object, pc_point, offset): 227 | bbbbbbbb, = struct.unpack_from("I", buffer, 2) 228 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "+%d" % bbbbbbbb) 229 | 230 | 231 | def parse_FMT31I(buffer, dex_object, pc_point, offset): 232 | bbbbbbbb, = struct.unpack_from("I", buffer, 2) 233 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "%d" % bbbbbbbb) 234 | 235 | 236 | def parse_FMT31T(buffer, dex_object, pc_point, offset): 237 | bbbbbbbb, = struct.unpack_from("i", buffer, 2) 238 | return ( 239 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "string@%d" % bbbbbbbb) 240 | 241 | 242 | def parse_FMT32X(buffer, dex_object, pc_point, offset): 243 | aaaa, bbbb, = struct.unpack_from("hh", buffer, 2) 244 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % aaaa, "v%d" % bbbb) 245 | 246 | 247 | def parse_FMT35C(buffer, dex_object, pc_point, offset): 248 | A = ord(buffer[1]) >> 4 249 | G = ord(buffer[1]) & 0xf 250 | D = ord(buffer[4]) >> 4 251 | C = ord(buffer[4]) & 0xf 252 | F = ord(buffer[5]) >> 4 253 | E = ord(buffer[5]) & 0xf 254 | bbbb, = struct.unpack_from("H", buffer, 2) 255 | if ord(buffer[0]) == 0x24: 256 | prefix = "type@%s" % (dex_object.getstringbyid(bbbb)) 257 | else: 258 | prefix = "meth@%s //%s" % (dex_object.getmethodname(bbbb), dex_object.getmethodfullname(bbbb, True)) 259 | pass 260 | if A == 5: 261 | return ( 262 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "v%d" % D, "v%d" % E, "v%d" % F, 263 | "v%d" % G, "%s" % (prefix)) 264 | elif A == 4: 265 | return ( 266 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "v%d" % D, "v%d" % E, "v%d" % F, 267 | "%s" % (prefix)) 268 | elif A == 3: 269 | return ( 270 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "v%d" % D, "v%d" % E, "%s" % (prefix)) 271 | elif A == 2: 272 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "v%d" % D, "%s" % (prefix)) 273 | elif A == 1: 274 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "%s" % (prefix)) 275 | elif A == 0: 276 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "%s" % (prefix)) 277 | else: 278 | return (dex_decode[ord(buffer[0])][4], "error .......") 279 | return ( 280 | dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % C, "v%d" % D, "v%d" % E, "v%d" % F, "v%d" % G, 281 | "%s" % (prefix)) 282 | 283 | 284 | def parse_FMT3RC(buffer, dex_object, pc_point, offset): 285 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1]) 286 | 287 | 288 | def parse_FMT51L(buffer, dex_object, pc_point, offset): 289 | if len(buffer) < 10: 290 | return (1, "") 291 | bb = struct.unpack_from("q", buffer, 2) 292 | return (dex_decode[ord(buffer[0])][4], dex_decode[ord(buffer[0])][1], "v%d" % ord(buffer[1]), "%d" % bb) 293 | 294 | 295 | func_point = [parse_FMT10T, parse_FMT10X, parse_FMT11N, parse_FMT11X, parse_FMT12X, parse_FMT20T, parse_FMT21C, 296 | parse_FMT21H, parse_FMT21S, parse_FMT21T, parse_FMT22B, parse_FMT22C, parse_FMT22S, parse_FMT22T, 297 | parse_FMT22X, parse_FMT23X, parse_FMT30T, parse_FMT31C, parse_FMT31I, parse_FMT31T, parse_FMT32X, 298 | parse_FMT35C, parse_FMT3RC, parse_FMT51L] 299 | 300 | 301 | def parse_instruction(buffer, offset, dex_object): 302 | n = len(buffer) 303 | start = 0 304 | 305 | while start < n: 306 | if n == 1736: 307 | print "start = %d" % start 308 | op = ord(buffer[start]) 309 | if op == 0: 310 | type = ord(buffer[start + 1]) 311 | if type == 1: 312 | size, = struct.unpack_from("H", buffer, 2 + start) 313 | start += (size * 2 + 4) * 2 314 | continue 315 | elif type == 2: 316 | size, = struct.unpack_from("H", buffer, 2 + start) 317 | start += (size * 4 + 2) * 2 318 | continue 319 | elif type == 3: 320 | width, = struct.unpack_from("H", buffer, 2 + start) 321 | size, = struct.unpack_from("I", buffer, 4 + start) 322 | # width,size,=struct.unpack_from("HI",buffer,2+start) 323 | start += (8 + ((size * width + 1) / 2) * 2) 324 | continue 325 | 326 | val = func_point[dex_decode[op][3]](buffer[start:], dex_object, offset + start, start / 2) 327 | str = "" 328 | m = 0 329 | for x in buffer[start:start + 2 * val[0]]: 330 | str += "%02x" % ord(x) 331 | m += 1 332 | if m % 2 == 0: 333 | str += " " 334 | 335 | print "%08x: %-36s |%04x:" % (offset + start, str, start / 2), 336 | m = 0 337 | for v in val[1:]: 338 | if m > 1: 339 | print ",", 340 | print v, 341 | m += 1 342 | print "" 343 | start += 2 * val[0] 344 | 345 | 346 | def parseMyinstruction(buffer, offset, dex_object): 347 | n = len(buffer) 348 | start = 0 349 | 350 | while start < n: 351 | if n == 1736: 352 | print "start = %d" % start 353 | op = ord(buffer[start]) 354 | if op == 0: 355 | type = ord(buffer[start + 1]) 356 | if type == 1: 357 | size, = struct.unpack_from("H", buffer, 2 + start) 358 | start += (size * 2 + 4) * 2 359 | continue 360 | elif type == 2: 361 | size, = struct.unpack_from("H", buffer, 2 + start) 362 | start += (size * 4 + 2) * 2 363 | continue 364 | elif type == 3: 365 | width, = struct.unpack_from("H", buffer, 2 + start) 366 | size, = struct.unpack_from("I", buffer, 4 + start) 367 | # width,size,=struct.unpack_from("HI",buffer,2+start) 368 | start += (8 + ((size * width + 1) / 2) * 2) 369 | continue 370 | 371 | val = func_point[dex_decode[op][3]](buffer[start:], dex_object, offset + start, start / 2) 372 | str = "" 373 | m = 0 374 | for x in buffer[start:start + 2 * val[0]]: 375 | str += "%02x" % ord(x) 376 | m += 1 377 | if m % 2 == 0: 378 | str += " " 379 | 380 | print "%08x: %-36s |%04x:" % (offset + start, str, start / 2), 381 | m = 0 382 | for v in val[1:]: 383 | if m > 1: 384 | print ",", 385 | print v, 386 | m += 1 387 | print "" 388 | start += 2 * val[0] 389 | dex_decode = { 390 | 0: (0x00, 'nop', 'fmt10x', FMT10X, 1), 391 | 1: (0x01, 'move', 'fmt12x', FMT12X, 1), 392 | 2: (0x02, 'move/from16', 'fmt22x', FMT22X, 2), 393 | 3: (0x03, 'move/16', 'fmt32x', FMT32X, 3), 394 | 4: (0x04, 'move-wide', 'fmt12x', FMT12X, 1), 395 | 5: (0x05, 'move-wide/from16', 'fmt22x', FMT22X, 2), 396 | 6: (0x06, 'move-wide/16', 'fmt32x', FMT32X, 3), 397 | 7: (0x07, 'move-object', 'fmt12x', FMT12X, 1), 398 | 8: (0x08, 'move-object/from16', 'fmt22x', FMT22X, 2), 399 | 9: (0x09, 'move-object/16', 'fmt32x', FMT32X, 3), 400 | 10: (0x0a, 'move-result', 'fmt11x', FMT11X, 1), 401 | 11: (0x0b, 'move-result-wide', 'fmt11x', FMT11X, 1), 402 | 12: (0x0c, 'move-result-object', 'fmt11x', FMT11X, 1), 403 | 13: (0x0d, 'move-exception', 'fmt11x', FMT11X, 1), 404 | 14: (0x0e, 'return-void', 'fmt10x', FMT10X, 1), 405 | 15: (0x0f, 'return', 'fmt11x', FMT11X, 1), 406 | 16: (0x10, 'return-wide', 'fmt11x', FMT11X, 1), 407 | 17: (0x11, 'return-object', 'fmt11x', FMT11X, 1), 408 | 18: (0x12, 'const/4', 'fmt11n', FMT11N, 1), 409 | 19: (0x13, 'const/16', 'fmt21s', FMT21S, 2), 410 | 20: (0x14, 'const', 'fmt31i', FMT31I, 3), 411 | 21: (0x15, 'const/high16', 'fmt21h', FMT21H, 2), 412 | 22: (0x16, 'const-wide/16', 'fmt21s', FMT21S, 2), 413 | 23: (0x17, 'const-wide/32', 'fmt31i', FMT31I, 3), 414 | 24: (0x18, 'const-wide', 'fmt51l', FMT51L, 5), 415 | 25: (0x19, 'const-wide/high16', 'fmt21h', FMT21H, 2), 416 | 26: (0x1a, 'const-string', 'fmt21c', FMT21C, 2), 417 | 27: (0x1b, 'const-string/jumbo', 'fmt31c', FMT31C, 3), 418 | 28: (0x1c, 'const-class', 'fmt21c', FMT21C, 2), 419 | 29: (0x1d, 'monitor-enter', 'fmt11x', FMT11X, 1), 420 | 30: (0x1e, 'monitor-exit', 'fmt11x', FMT11X, 1), 421 | 31: (0x1f, 'check-cast', 'fmt21c', FMT21C, 2), 422 | 32: (0x20, 'instance-of', 'fmt22c', FMT22C, 2), 423 | 33: (0x21, 'array-length', 'fmt12x', FMT12X, 1), 424 | 34: (0x22, 'new-instance', 'fmt21c', FMT21C, 2), 425 | 35: (0x23, 'new-array', 'fmt22c', FMT22C, 2), 426 | 36: (0x24, 'filled-new-array', 'fmt35c', FMT35C, 3), 427 | 37: (0x25, 'filled-new-array/range', 'fmt3rc', FMT3RC, 3), 428 | 38: (0x26, 'fill-array-data', 'fmt31t', FMT31T, 3), 429 | 39: (0x27, 'throw', 'fmt11x', FMT11X, 1), 430 | 40: (0x28, 'goto', 'fmt10t', FMT10T, 1), 431 | 41: (0x29, 'goto/16', 'fmt20t', FMT20T, 2), 432 | 42: (0x2a, 'goto/32', 'fmt30t', FMT30T, 3), 433 | 43: (0x2b, 'packed-switch', 'fmt31t', FMT31T, 3), 434 | 44: (0x2c, 'sparse-switch', 'fmt31t', FMT31T, 3), 435 | 45: (0x2d, 'cmpl-float', 'fmt23x', FMT23X, 2), 436 | 46: (0x2e, 'cmpg-float', 'fmt23x', FMT23X, 2), 437 | 47: (0x2f, 'cmpl-double', 'fmt23x', FMT23X, 2), 438 | 48: (0x30, 'cmpg-double', 'fmt23x', FMT23X, 2), 439 | 49: (0x31, 'cmp-long', 'fmt23x', FMT23X, 2), 440 | 50: (0x32, 'if-eq', 'fmt22t', FMT22T, 2), 441 | 51: (0x33, 'if-ne', 'fmt22t', FMT22T, 2), 442 | 52: (0x34, 'if-lt', 'fmt22t', FMT22T, 2), 443 | 53: (0x35, 'if-ge', 'fmt22t', FMT22T, 2), 444 | 54: (0x36, 'if-gt', 'fmt22t', FMT22T, 2), 445 | 55: (0x37, 'if-le', 'fmt22t', FMT22T, 2), 446 | 56: (0x38, 'if-eqz', 'fmt21t', FMT21T, 2), 447 | 57: (0x39, 'if-nez', 'fmt21t', FMT21T, 2), 448 | 58: (0x3a, 'if-ltz', 'fmt21t', FMT21T, 2), 449 | 59: (0x3b, 'if-gez', 'fmt21t', FMT21T, 2), 450 | 60: (0x3c, 'if-gtz', 'fmt21t', FMT21T, 2), 451 | 61: (0x3d, 'if-lez', 'fmt21t', FMT21T, 2), 452 | 62: (0x3e, 'unused', 'fmt10x', FMT10X, 1), 453 | 63: (0x3f, 'unused', 'fmt10x', FMT10X, 1), 454 | 64: (0x40, 'unused', 'fmt10x', FMT10X, 1), 455 | 65: (0x41, 'unused', 'fmt10x', FMT10X, 1), 456 | 66: (0x42, 'unused', 'fmt10x', FMT10X, 1), 457 | 67: (0x43, 'unused', 'fmt10x', FMT10X, 1), 458 | 68: (0x44, 'aget', 'fmt23x', FMT23X, 2), 459 | 69: (0x45, 'aget-wide', 'fmt23x', FMT23X, 2), 460 | 70: (0x46, 'aget-object', 'fmt23x', FMT23X, 2), 461 | 71: (0x47, 'aget-boolean', 'fmt23x', FMT23X, 2), 462 | 72: (0x48, 'aget-byte', 'fmt23x', FMT23X, 2), 463 | 73: (0x49, 'aget-char', 'fmt23x', FMT23X, 2), 464 | 74: (0x4a, 'aget-short', 'fmt23x', FMT23X, 2), 465 | 75: (0x4b, 'aput', 'fmt23x', FMT23X, 2), 466 | 76: (0x4c, 'aput-wide', 'fmt23x', FMT23X, 2), 467 | 77: (0x4d, 'aput-object', 'fmt23x', FMT23X, 2), 468 | 78: (0x4e, 'aput-boolean', 'fmt23x', FMT23X, 2), 469 | 79: (0x4f, 'aput-byte', 'fmt23x', FMT23X, 2), 470 | 80: (0x50, 'aput-shar', 'fmt23x', FMT23X, 2), 471 | 81: (0x51, 'aput-short', 'fmt23x', FMT23X, 2), 472 | 82: (0x52, 'iget', 'fmt22c', FMT22C, 2), 473 | 83: (0x53, 'iget-wide', 'fmt22c', FMT22C, 2), 474 | 84: (0x54, 'iget-object', 'fmt22c', FMT22C, 2), 475 | 85: (0x55, 'iget-boolean', 'fmt22c', FMT22C, 2), 476 | 86: (0x56, 'iget-byte', 'fmt22c', FMT22C, 2), 477 | 87: (0x57, 'iget-char', 'fmt22c', FMT22C, 2), 478 | 88: (0x58, 'iget-short', 'fmt22c', FMT22C, 2), 479 | 89: (0x59, 'iput', 'fmt22c', FMT22C, 2), 480 | 90: (0x5a, 'iput-wide', 'fmt22c', FMT22C, 2), 481 | 91: (0x5b, 'iput-object', 'fmt22c', FMT22C, 2), 482 | 92: (0x5c, 'iput-boolean', 'fmt22c', FMT22C, 2), 483 | 93: (0x5d, 'iput-byte', 'fmt22c', FMT22C, 2), 484 | 94: (0x5e, 'iput-char', 'fmt22c', FMT22C, 2), 485 | 95: (0x5f, 'iput-short', 'fmt22c', FMT22C, 2), 486 | 96: (0x60, 'sget', 'fmt21c', FMT21C, 2), 487 | 97: (0x61, 'sget-wide', 'fmt21c', FMT21C, 2), 488 | 98: (0x62, 'sget-object', 'fmt21c', FMT21C, 2), 489 | 99: (0x63, 'sget-boolean', 'fmt21c', FMT21C, 2), 490 | 100: (0x64, 'sget-byte', 'fmt21c', FMT21C, 2), 491 | 101: (0x65, 'sget-char', 'fmt21c', FMT21C, 2), 492 | 102: (0x66, 'sget-short', 'fmt21c', FMT21C, 2), 493 | 103: (0x67, 'sput', 'fmt21c', FMT21C, 2), 494 | 104: (0x68, 'sput-wide', 'fmt21c', FMT21C, 2), 495 | 105: (0x69, 'sput-object', 'fmt21c', FMT21C, 2), 496 | 106: (0x6a, 'sput-boolean', 'fmt21c', FMT21C, 2), 497 | 107: (0x6b, 'sput-byte', 'fmt21c', FMT21C, 2), 498 | 108: (0x6c, 'sput-char', 'fmt21c', FMT21C, 2), 499 | 109: (0x6d, 'sput-short', 'fmt21c', FMT21C, 2), 500 | 110: (0x6e, 'invoke-virtual', 'fmt35c', FMT35C, 3), 501 | 111: (0x6f, 'invoke-super', 'fmt35c', FMT35C, 3), 502 | 112: (0x70, 'invoke-direct', 'fmt35c', FMT35C, 3), 503 | 113: (0x71, 'invoke-static', 'fmt35c', FMT35C, 3), 504 | 114: (0x72, 'invoke-insterface', 'fmt35c', FMT35C, 3), 505 | 115: (0x73, 'unused', 'fmt10x', FMT10X, 1), 506 | 116: (0x74, 'invoke-virtual/range', 'fmt3rc', FMT3RC, 3), 507 | 117: (0x75, 'invoke-super/range', 'fmt3rc', FMT3RC, 3), 508 | 118: (0x76, 'invoke-direct/range', 'fmt3rc', FMT3RC, 3), 509 | 119: (0x77, 'invoke-static/range', 'fmt3rc', FMT3RC, 3), 510 | 120: (0x78, 'invoke-interface/range', 'fmt3rc', FMT3RC, 3), 511 | 121: (0x79, 'unused', 'fmt10x', FMT10X, 1), 512 | 122: (0x7a, 'unused', 'fmt10x', FMT10X, 1), 513 | 123: (0x7b, 'neg-int', 'fmt12x', FMT12X, 1), 514 | 124: (0x7c, 'not-int', 'fmt12x', FMT12X, 1), 515 | 125: (0x7d, 'neg-long', 'fmt12x', FMT12X, 1), 516 | 126: (0x7e, 'not-long', 'fmt12x', FMT12X, 1), 517 | 127: (0x7f, 'neg-float', 'fmt12x', FMT12X, 1), 518 | 128: (0x80, 'neg-double', 'fmt12x', FMT12X, 1), 519 | 129: (0x81, 'int-to-long', 'fmt12x', FMT12X, 1), 520 | 130: (0x82, 'int-to-float', 'fmt12x', FMT12X, 1), 521 | 131: (0x83, 'int-to-double', 'fmt12x', FMT12X, 1), 522 | 132: (0x84, 'long-to-int', 'fmt12x', FMT12X, 1), 523 | 133: (0x85, 'long-to-float', 'fmt12x', FMT12X, 1), 524 | 134: (0x86, 'long-to-double', 'fmt12x', FMT12X, 1), 525 | 135: (0x87, 'float-to-int', 'fmt12x', FMT12X, 1), 526 | 136: (0x88, 'float-to-long', 'fmt12x', FMT12X, 1), 527 | 137: (0x89, 'float-to-double', 'fmt12x', FMT12X, 1), 528 | 138: (0x8a, 'double-to-int', 'fmt12x', FMT12X, 1), 529 | 139: (0x8b, 'double-to-long', 'fmt12x', FMT12X, 1), 530 | 140: (0x8c, 'double-to-float', 'fmt12x', FMT12X, 1), 531 | 141: (0x8d, 'int-to-byte', 'fmt12x', FMT12X, 1), 532 | 142: (0x8e, 'int-to-char', 'fmt12x', FMT12X, 1), 533 | 143: (0x8f, 'int-to-short', 'fmt12x', FMT12X, 1), 534 | 144: (0x90, 'add-int', 'fmt23x', FMT23X, 2), 535 | 145: (0x91, 'sub-int', 'fmt23x', FMT23X, 2), 536 | 146: (0x92, 'mul-int', 'fmt23x', FMT23X, 2), 537 | 147: (0x93, 'div-int', 'fmt23x', FMT23X, 2), 538 | 148: (0x94, 'rem-int', 'fmt23x', FMT23X, 2), 539 | 149: (0x95, 'and-int', 'fmt23x', FMT23X, 2), 540 | 150: (0x96, 'or-int', 'fmt23x', FMT23X, 2), 541 | 151: (0x97, 'xor-int', 'fmt23x', FMT23X, 2), 542 | 152: (0x98, 'shl-int', 'fmt23x', FMT23X, 2), 543 | 153: (0x99, 'shr-int', 'fmt23x', FMT23X, 2), 544 | 154: (0x9a, 'ushr-int', 'fmt23x', FMT23X, 2), 545 | 155: (0x9b, 'add-long', 'fmt23x', FMT23X, 2), 546 | 156: (0x9c, 'sub-long', 'fmt23x', FMT23X, 2), 547 | 157: (0x9d, 'mul-long', 'fmt23x', FMT23X, 2), 548 | 158: (0x9e, 'div-long', 'fmt23x', FMT23X, 2), 549 | 159: (0x9f, 'rem-long', 'fmt23x', FMT23X, 2), 550 | 160: (0xa0, 'and-long', 'fmt23x', FMT23X, 2), 551 | 161: (0xa1, 'or-long', 'fmt23x', FMT23X, 2), 552 | 162: (0xa2, 'xor-long', 'fmt23x', FMT23X, 2), 553 | 163: (0xa3, 'shl-long', 'fmt23x', FMT23X, 2), 554 | 164: (0xa4, 'shr-long', 'fmt23x', FMT23X, 2), 555 | 165: (0xa5, 'ushr-long', 'fmt23x', FMT23X, 2), 556 | 166: (0xa6, 'add-float', 'fmt23x', FMT23X, 2), 557 | 167: (0xa7, 'sub-float', 'fmt23x', FMT23X, 2), 558 | 168: (0xa8, 'mul-float', 'fmt23x', FMT23X, 2), 559 | 169: (0xa9, 'div-float', 'fmt23x', FMT23X, 2), 560 | 170: (0xaa, 'rem-float', 'fmt23x', FMT23X, 2), 561 | 171: (0xab, 'add-double', 'fmt23x', FMT23X, 2), 562 | 172: (0xac, 'sub-double', 'fmt23x', FMT23X, 2), 563 | 173: (0xad, 'mul-double', 'fmt23x', FMT23X, 2), 564 | 174: (0xae, 'div-double', 'fmt23x', FMT23X, 2), 565 | 175: (0xaf, 'rem-double', 'fmt23x', FMT23X, 2), 566 | 176: (0xb0, 'add-int/2addr', 'fmt12x', FMT12X, 1), 567 | 177: (0xb1, 'sub-int/2addr', 'fmt12x', FMT12X, 1), 568 | 178: (0xb2, 'mul-int/2addr', 'fmt12x', FMT12X, 1), 569 | 179: (0xb3, 'div-int/2addr', 'fmt12x', FMT12X, 1), 570 | 180: (0xb4, 'rem-int/2addr', 'fmt12x', FMT12X, 1), 571 | 181: (0xb5, 'and-int/2addr', 'fmt12x', FMT12X, 1), 572 | 182: (0xb6, 'or-int/2addr', 'fmt12x', FMT12X, 1), 573 | 183: (0xb7, 'xor-int/2addr', 'fmt12x', FMT12X, 1), 574 | 184: (0xb8, 'shl-int/2addr', 'fmt12x', FMT12X, 1), 575 | 185: (0xb9, 'shr-int/2addr', 'fmt12x', FMT12X, 1), 576 | 186: (0xba, 'ushr-int/2addr', 'fmt12x', FMT12X, 1), 577 | 187: (0xbb, 'add-long/2addr', 'fmt12x', FMT12X, 1), 578 | 188: (0xbc, 'sub-long/2addr', 'fmt12x', FMT12X, 1), 579 | 189: (0xbd, 'mul-long/2addr', 'fmt12x', FMT12X, 1), 580 | 190: (0xbe, 'div-long/2addr', 'fmt12x', FMT12X, 1), 581 | 191: (0xbf, 'rem-long/2addr', 'fmt12x', FMT12X, 1), 582 | 192: (0xc0, 'and-long/2addr', 'fmt12x', FMT12X, 1), 583 | 193: (0xc1, 'or-long/2addr', 'fmt12x', FMT12X, 1), 584 | 194: (0xc2, 'xor-long/2addr', 'fmt12x', FMT12X, 1), 585 | 195: (0xc3, 'shl-long/2addr', 'fmt12x', FMT12X, 1), 586 | 196: (0xc4, 'shr-long/2addr', 'fmt12x', FMT12X, 1), 587 | 197: (0xc5, 'ushr-long/2addr', 'fmt12x', FMT12X, 1), 588 | 198: (0xc6, 'add-float/2addr', 'fmt12x', FMT12X, 1), 589 | 199: (0xc7, 'sub-float/2addr', 'fmt12x', FMT12X, 1), 590 | 200: (0xc8, 'mul-float/2addr', 'fmt12x', FMT12X, 1), 591 | 201: (0xc9, 'div-float/2addr', 'fmt12x', FMT12X, 1), 592 | 202: (0xca, 'rem-float/2addr', 'fmt12x', FMT12X, 1), 593 | 203: (0xcb, 'add-double/2addr', 'fmt12x', FMT12X, 1), 594 | 204: (0xcc, 'sub-double/2addr', 'fmt12x', FMT12X, 1), 595 | 205: (0xcd, 'mul-double/2addr', 'fmt12x', FMT12X, 1), 596 | 206: (0xce, 'div-double/2addr', 'fmt12x', FMT12X, 1), 597 | 207: (0xcf, 'rem-double/2addr', 'fmt12x', FMT12X, 1), 598 | 208: (0xd0, 'add-int/lit16', 'fmt22s', FMT22S, 2), 599 | 209: (0xd1, 'rsub-int', 'fmt22s', FMT22S, 2), 600 | 210: (0xd2, 'mul-int/lit16', 'fmt22s', FMT22S, 2), 601 | 211: (0xd3, 'div-int/lit16', 'fmt22s', FMT22S, 2), 602 | 212: (0xd4, 'rem-int/lit16', 'fmt22s', FMT22S, 2), 603 | 213: (0xd5, 'and-int/lit16', 'fmt22s', FMT22S, 2), 604 | 214: (0xd6, 'or-int/lit16', 'fmt22s', FMT22S, 2), 605 | 215: (0xd7, 'xor-int/lit16', 'fmt22s', FMT22S, 2), 606 | 216: (0xd8, 'add-int/lit8', 'fmt22b', FMT22B, 2), 607 | 217: (0xd9, 'rsub-int/lit8', 'fmt22b', FMT22B, 2), 608 | 218: (0xda, 'mul-int/lit8', 'fmt22b', FMT22B, 2), 609 | 219: (0xdb, 'div-int/lit8', 'fmt22b', FMT22B, 2), 610 | 220: (0xdc, 'rem-int/lit8', 'fmt22b', FMT22B, 2), 611 | 221: (0xdd, 'and-int/lit8', 'fmt22b', FMT22B, 2), 612 | 222: (0xde, 'or-int/lit8', 'fmt22b', FMT22B, 2), 613 | 223: (0xdf, 'xor-int/lit8', 'fmt22b', FMT22B, 2), 614 | 224: (0xe0, 'shl-int/lit8', 'fmt22b', FMT22B, 2), 615 | 225: (0xe1, 'shr-int/lit8', 'fmt22b', FMT22B, 2), 616 | 226: (0xe2, 'ushr-int/lit8', 'fmt22b', FMT22B, 2), 617 | 227: (0xe3, 'unused', 'fmt10x', FMT10X, 1), 618 | 228: (0xe4, 'unused', 'fmt10x', FMT10X, 1), 619 | 229: (0xe5, 'unused', 'fmt10x', FMT10X, 1), 620 | 230: (0xe6, 'unused', 'fmt10x', FMT10X, 1), 621 | 231: (0xe7, 'unused', 'fmt10x', FMT10X, 1), 622 | 232: (0xe8, 'unused', 'fmt10x', FMT10X, 1), 623 | 233: (0xe9, 'unused', 'fmt10x', FMT10X, 1), 624 | 234: (0xea, 'unused', 'fmt10x', FMT10X, 1), 625 | 235: (0xeb, 'unused', 'fmt10x', FMT10X, 1), 626 | 236: (0xec, 'unused', 'fmt10x', FMT10X, 1), 627 | 237: (0xed, 'unused', 'fmt10x', FMT10X, 1), 628 | 238: (0xee, 'unused', 'fmt10x', FMT10X, 1), 629 | 239: (0xef, 'unused', 'fmt10x', FMT10X, 1), 630 | 240: (0xf0, 'unused', 'fmt10x', FMT10X, 1), 631 | 241: (0xf1, 'unused', 'fmt10x', FMT10X, 1), 632 | 242: (0xf2, 'unused', 'fmt10x', FMT10X, 1), 633 | 243: (0xf3, 'unused', 'fmt10x', FMT10X, 1), 634 | 244: (0xf4, 'unused', 'fmt10x', FMT10X, 1), 635 | 245: (0xf5, 'unused', 'fmt10x', FMT10X, 1), 636 | 246: (0xf6, 'unused', 'fmt10x', FMT10X, 1), 637 | 247: (0xf7, 'unused', 'fmt10x', FMT10X, 1), 638 | 248: (0xf8, 'unused', 'fmt10x', FMT10X, 1), 639 | 249: (0xf9, 'unused', 'fmt10x', FMT10X, 1), 640 | 250: (0xfa, 'unused', 'fmt10x', FMT10X, 1), 641 | 251: (0xfb, 'unused', 'fmt10x', FMT10X, 1), 642 | 252: (0xfc, 'unused', 'fmt10x', FMT10X, 1), 643 | 253: (0xfd, 'unused', 'fmt10x', FMT10X, 1), 644 | 254: (0xfe, 'unused', 'fmt10x', FMT10X, 1), 645 | 255: (0xff, 'unused', 'fmt10x', FMT10X, 1), 646 | } 647 | class CodeItem: 648 | methodname="" 649 | inssize=0 650 | insarray="" 651 | idx=0 652 | def __init__(self,number,methodname, inssize,insarray): 653 | self.idx=number 654 | self.methodname = methodname 655 | self.inssize = inssize 656 | self.insarray=insarray 657 | class DexMethod: 658 | methodname="" 659 | inssize=0 660 | offset=0 661 | idx=0 662 | def __init__(self,number,methodname, inssize,offset): 663 | self.idx=number 664 | self.methodname = methodname 665 | self.inssize = inssize 666 | self.offset=offset 667 | def parseinsfile(): 668 | global insfilename 669 | insfile=open(insfilename) 670 | content=insfile.read() 671 | insfile.close() 672 | #;{name:artMethod::dumpmethod DexFile_dumpDexFile' 673 | # dexfile name:classes.dex-- 674 | # insfilepath:/data/data/com.wlqq/10668484_ins.bin-- 675 | # code_item_len:40, 676 | # code_item_len:40, 677 | # ins:AgABAAIAAABLnY4ADAAAACIAFwNwEPoOAABuIP4OEAAMAR8BFwMRAQ==}; 678 | insarray=re.findall(r"{name:(.*?),method_idx:(.*?),offset:(.*?),code_item_len:(.*?),ins:(.*?)}",content) #(.*?)最短匹配 679 | for eachins in insarray: 680 | methodname=eachins[0].replace(" ","") 681 | number=(int)(eachins[1]) 682 | offset=(int)(eachins[2]) 683 | inssize=int(eachins[3]) 684 | ins=eachins[4] 685 | tempmethod=CodeItem(number,methodname,inssize,ins) 686 | methodTable[number]=tempmethod #添加method 687 | class dex_encode_field: 688 | def __init__(self,idx,flags): 689 | self.m_field_idx_diff = idx 690 | self.m_access_flags = flags 691 | def printf(self,dex_object): 692 | name = dex_object.gettypenamebyid(self.m_field_idx_diff) 693 | #print "%-20s%08x %s"%("field_idx_diff",self.m_field_idx_diff,name) 694 | flags = dex_object.get_access_flags(self.m_access_flags) 695 | #print "%-20s%08x %s"%("access_flags",self.m_access_flags,flags) 696 | print "%s "%flags, 697 | dex_object.FieldId_list[self.m_field_idx_diff].printf_l(dex_object) 698 | class method_code: 699 | def __init__(self,dex_object,offset): 700 | format = "H" 701 | self.registers_size, = struct.unpack_from(format,dex_object.m_content,offset) 702 | offset += struct.calcsize(format) 703 | self.ins_size,=struct.unpack_from(format,dex_object.m_content,offset) 704 | offset += struct.calcsize(format) 705 | self.outs_size,=struct.unpack_from(format,dex_object.m_content,offset) 706 | offset += struct.calcsize(format) 707 | self.tries_size,=struct.unpack_from(format,dex_object.m_content,offset) 708 | offset += struct.calcsize(format) 709 | format = "I" 710 | self.debug_info_off,=struct.unpack_from(format,dex_object.m_content,offset) 711 | offset += struct.calcsize(format) 712 | self.insns_size,=struct.unpack_from(format,dex_object.m_content,offset) 713 | offset += struct.calcsize(format) 714 | self.insns = offset 715 | offset += 2*self.insns_size 716 | if self.insns_size %2 ==1: 717 | offset+=2 718 | if self.tries_size == 0: 719 | self.tries = 0 720 | self.handlers = 0 721 | else: 722 | self.tries = offset 723 | self.handlers = offset + self.tries_size * struct.calcsize("I2H") 724 | def get_param_list(self,dex_object): 725 | if self.debug_info_off != 0: 726 | return parse_debug_info_method_parameter_list(dex_object,self.debug_info_off) 727 | return [] 728 | def printf(self,dex_object,prefix=""): 729 | print "%s%-20s:%08x:%10d"%(prefix,"registers_size",self.registers_size,self.registers_size) 730 | print "%s%-20s:%08x:%10d"%(prefix,"insns_size",self.insns_size,self.insns_size) 731 | print "%s%-20s:%08x:%10d"%(prefix,"debug_info_off",self.debug_info_off,self.debug_info_off) 732 | print "%s%-20s:%08x:%10d"%(prefix,"ins_size",self.ins_size,self.ins_size) 733 | print "%s%-20s:%08x:%10d"%(prefix,"outs_size",self.outs_size,self.outs_size) 734 | print "%s%-20s:%08x:%10d"%(prefix,"tries_size",self.tries_size,self.tries_size) 735 | print "%s%-20s:%08x:%10d"%(prefix,"insns",self.insns,self.insns) 736 | print "%s%-20s:%08x:%10d"%(prefix,"tries",self.tries,self.tries) 737 | print "%s%-20s:%08x:%10d"%(prefix,"handlers",self.handlers,self.handlers) 738 | parse_instruction(dex_object.m_content[self.insns:self.insns+self.insns_size*2],self.insns,dex_object) 739 | class tryitem: 740 | start_addr = 0 741 | ins_count = 0 742 | handlerlist_offset = 0 743 | handler_off = 0 744 | handlercount = 0 745 | handlerlist = [] 746 | def __init__(self, dex_object, content, handlerlist_offset,offset): 747 | format = "H" 748 | tempoffset=0 749 | self.handlerlist=[] 750 | self.handlerlist_offset = handlerlist_offset 751 | self.start_addr, = struct.unpack_from("i", content, offset) 752 | offset += struct.calcsize("i") 753 | self.ins_count, = struct.unpack_from(format, content, offset) 754 | offset += struct.calcsize(format) 755 | self.handler_off, = struct.unpack_from(format, content, offset) 756 | i,self.handlercount = get_leb128(content[self.handler_off+self.handlerlist_offset:]) 757 | if(self.handlercount<=0): 758 | self.handlercount=0-self.handlercount 759 | tempoffset=self.handlerlist_offset+self.handler_off+i 760 | if self.handlercount==0: 761 | #print "this is a finally handler" 762 | i,handler_address=get_uleb128(content[tempoffset:]) 763 | temphandler=handler(0,"finally",handler_address) 764 | self.handlerlist.append(temphandler) 765 | else: 766 | #print "this is not a finally handler" 767 | for j in range(0,self.handlercount): 768 | i,handler_typeidx=get_uleb128(content[tempoffset:]) 769 | tempoffset=tempoffset+i 770 | type_str=dex_object.gettypenamebyid(handler_typeidx) 771 | i,handler_address=get_uleb128(content[tempoffset:]) 772 | tempoffset=tempoffset+i 773 | temphandler = handler(handler_typeidx, type_str, handler_address) 774 | self.handlerlist.append(temphandler) 775 | 776 | class handler: 777 | type_idx = 0 778 | type_str="" 779 | ins_start = 0 780 | 781 | def __init__(self, type_idx, type_str, ins_start): 782 | self.type_idx=type_idx 783 | self.ins_start=ins_start 784 | self.type_str=type_str 785 | class repired_method_code: 786 | dex_obj=None 787 | content = "" 788 | trylist = [] 789 | def __init__(self, dex_obj,content): 790 | offset=0 791 | format = "H" 792 | self.dex_obj=dex_obj 793 | self.content=content 794 | self.registers_size, = struct.unpack_from(format, content, offset) 795 | offset += struct.calcsize(format) 796 | self.ins_size, = struct.unpack_from(format, content, offset) 797 | offset += struct.calcsize(format) 798 | self.outs_size, = struct.unpack_from(format, content, offset) 799 | offset += struct.calcsize(format) 800 | self.tries_size, = struct.unpack_from(format, content, offset) 801 | offset += struct.calcsize(format) 802 | format = "I" 803 | self.debug_info_off, = struct.unpack_from(format, content, offset) 804 | offset += struct.calcsize(format) 805 | self.insns_size, = struct.unpack_from(format, content, offset) 806 | offset += struct.calcsize(format) 807 | self.insns = offset 808 | offset += 2 * self.insns_size 809 | if self.insns_size % 2 == 1: 810 | offset += 2 811 | if self.tries_size == 0: 812 | self.tries = 0 813 | self.handlers = 0 814 | else: 815 | self.handlerlist_offset = offset + 8 * self.tries_size 816 | self.tries = offset 817 | for i in range(0, self.tries_size): 818 | temptryitem = tryitem(self.dex_obj,content, self.handlerlist_offset, offset + 8 * i) 819 | self.trylist.append(temptryitem) 820 | self.handlers = offset + self.tries_size * struct.calcsize("I2H") # 821 | 822 | def printf(self, dex_object, prefix=""): 823 | print "%s%-20s:%08x:%10d" % (prefix, "registers_size", self.registers_size, self.registers_size) 824 | print "%s%-20s:%08x:%10d" % (prefix, "insns_size", self.insns_size, self.insns_size) 825 | print "%s%-20s:%08x:%10d" % (prefix, "debug_info_off", self.debug_info_off, self.debug_info_off) 826 | print "%s%-20s:%08x:%10d" % (prefix, "ins_size", self.ins_size, self.ins_size) 827 | print "%s%-20s:%08x:%10d" % (prefix, "outs_size", self.outs_size, self.outs_size) 828 | print "%s%-20s:%08x:%10d" % (prefix, "tries_size", self.tries_size, self.tries_size) 829 | if self.tries_size > 0: 830 | for i in range(0, self.tries_size): 831 | tryitem = self.trylist[i] 832 | print "%s%-20s:%08x:%10d" % ( 833 | prefix, "try[" + str(i) + "] ins start:", tryitem.start_addr, tryitem.start_addr) 834 | print "%s%-20s:%08x:%10d" % ( 835 | prefix, "try[" + str(i) + "] ins count:", tryitem.ins_count, tryitem.ins_count) 836 | for j in range(len(tryitem.handlerlist)): 837 | temphandler=tryitem.handlerlist[j] 838 | print "%s%-20s:%s" % ( 839 | prefix, "try["+str(i)+"]:handler[" + str(j) + "] exception type:", temphandler.type_str) 840 | print "%s%-20s:%08x:%10d" % ( 841 | prefix, "try["+str(i)+"]:handler[" + str(j) + "] ins start:", temphandler.ins_start, temphandler.ins_start) 842 | # print "%s%-20s:%08x:%10d" % (prefix, "insnsoffset", self.insns, self.insns) 843 | # print "%s%-20s:%08x:%10d" % (prefix, "triesoffset", self.tries, self.tries) 844 | parse_instruction(self.content[self.insns:self.insns + self.insns_size * 2], self.insns, dex_object) 845 | class dex_encode_method: 846 | def __init__(self,idx,flags,code_off,dex_object): 847 | self.m_method_idx_diff = idx 848 | self.m_access_flags = flags 849 | self.m_code_off = code_off 850 | if code_off: 851 | self.m_code_item = method_code(dex_object,code_off)#dex_object.m_content[code_off:]) 852 | def printf(self,dex_object): 853 | name = dex_object.gettypenamebyid(self.m_method_idx_diff) 854 | print "%-20s%08x %s"%("m_method_idx_diff",self.m_method_idx_diff,name) 855 | flags = dex_object.get_access_flags(self.m_access_flags) 856 | print "%-20s%08x %s"%("access_flags",self.m_access_flags,flags) 857 | print "%-20s%08x %d"%("code_off",self.m_code_off,self.m_code_off) 858 | if self.m_code_off !=0: 859 | self.m_code_item.printf(dex_object) 860 | def printf_l(self,dex_object,is_virtual): 861 | flags = dex_object.get_access_flags(self.m_access_flags) 862 | if is_virtual: 863 | flags += " virtual" 864 | print "%48s"%flags, 865 | dex_object.MethodId_list[self.m_method_idx_diff].printf(dex_object) 866 | if self.m_code_off!=0: 867 | self.m_code_item.printf(dex_object) 868 | class dex_class: 869 | def __init__(self,dex_object,classid): 870 | if classid >= dex_object.m_classDefSize: 871 | return "" 872 | offset = dex_object.m_classDefOffset + classid * struct.calcsize("8I") 873 | self.offset = offset 874 | format = "I" 875 | self.thisClass,=struct.unpack_from(format,dex_object.m_content,offset) 876 | offset += struct.calcsize(format) 877 | self.modifiers,=struct.unpack_from(format,dex_object.m_content,offset) 878 | offset += struct.calcsize(format) 879 | self.superClass,=struct.unpack_from(format,dex_object.m_content,offset) 880 | offset += struct.calcsize(format) 881 | self.interfacesOff,=struct.unpack_from(format,dex_object.m_content,offset) 882 | offset += struct.calcsize(format) 883 | self.sourceFileIdx,=struct.unpack_from(format,dex_object.m_content,offset) 884 | offset += struct.calcsize(format) 885 | self.annotationsOff,=struct.unpack_from(format,dex_object.m_content,offset) 886 | offset += struct.calcsize(format) 887 | self.classDataOff,=struct.unpack_from(format,dex_object.m_content,offset) 888 | offset += struct.calcsize(format) 889 | self.staticValuesOff,=struct.unpack_from(format,dex_object.m_content,offset) 890 | offset += struct.calcsize(format) 891 | self.index = classid 892 | self.interfacesSize = 0 893 | if self.interfacesOff != 0: 894 | self.interfacesSize, = struct.unpack_from("I",dex_object.m_content,self.interfacesOff) 895 | if self.classDataOff != 0: 896 | offset = self.classDataOff 897 | count,self.numStaticFields = get_uleb128(dex_object.m_content[offset:]) 898 | offset += count 899 | count,self.numInstanceFields = get_uleb128(dex_object.m_content[offset:]) 900 | offset += count 901 | count,self.numDirectMethods = get_uleb128(dex_object.m_content[offset:]) 902 | offset += count 903 | count,self.numVirtualMethods = get_uleb128(dex_object.m_content[offset:]) 904 | else: 905 | self.numStaticFields = 0 906 | self.numInstanceFields = 0 907 | self.numDirectMethods = 0 908 | self.numVirtualMethods = 0 909 | def format_classname(self,name): 910 | name = name[1:-1].replace("/","_") 911 | name = name.replace("$","_") 912 | return name 913 | def create_header_file_for_cplusplus(self,dex_object): 914 | typelist = [] 915 | name = self.format_classname(dex_object.gettypename(self.thisClass)) 916 | f = open(name+".h","w") 917 | str1 = "class %s"%name 918 | supername = dex_object.gettypename(self.superClass) 919 | 920 | if dex_object.m_class_name_id.has_key(supername) : 921 | str1 += " : " 922 | supername = dex_object.gettypename(self.superClass) 923 | str1 += self.format_classname(supername) 924 | str1 += "\n{\n" 925 | offset = self.classDataOff 926 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 927 | offset += n 928 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 929 | offset += n 930 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 931 | offset += n 932 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 933 | offset += n 934 | field_idx=0 935 | prev_access = -1 936 | for i in xrange(0,self.numStaticFields): 937 | n,field_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 938 | offset += n 939 | field_idx+=field_idx_diff 940 | 941 | n,modifiers = get_uleb128(dex_object.m_content[offset:offset+5]) 942 | 943 | access_str,cur_access = dex_object.get_access_flags1(modifiers) 944 | if cur_access != prev_access: 945 | str1 += access_str 946 | str1 += "\n" 947 | prev_access = cur_access 948 | str1 += "\tconst " 949 | str1 += dex_object.getfieldfullname1(field_idx) 950 | if field_idx not in typelist: 951 | typelist.append(field_idx) 952 | offset += n 953 | if self.staticValuesOff: 954 | str1 += " = " 955 | staticoffset=get_static_offset(dex_object.m_content[self.staticValuesOff:],i) 956 | if staticoffset == -1: 957 | str1 += "0;\n" 958 | continue 959 | size,str2 = parse_encoded_value1(dex_object,dex_object.m_content[self.staticValuesOff+staticoffset:]) 960 | str1 += str2 961 | str1 += ";\n" 962 | field_idx=0 963 | str1+="////////////////////////////////////////////////////////\n" 964 | for i in xrange(0,self.numInstanceFields): 965 | n,field_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 966 | offset += n 967 | field_idx+=field_idx_diff 968 | n,modifiers = get_uleb128(dex_object.m_content[offset:offset+5]) 969 | access_str,cur_access = dex_object.get_access_flags1(modifiers) 970 | if cur_access != prev_access: 971 | str1 += access_str 972 | str1 += "\n" 973 | prev_access = cur_access 974 | str1 += "\t" 975 | str1 += dex_object.getfieldfullname1(field_idx) 976 | if field_idx not in typelist: 977 | typelist.append(field_idx) 978 | str1 += ";\n" 979 | offset += n 980 | #print str1 981 | method_idx = 0 982 | prev_access = -1 983 | for i in xrange(0,self.numDirectMethods): 984 | n,method_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 985 | offset += n 986 | n,access_flags = get_uleb128(dex_object.m_content[offset:offset+5]) 987 | offset += n 988 | n,code_off = get_uleb128(dex_object.m_content[offset:offset+5]) 989 | offset += n 990 | method_idx += method_idx_diff 991 | access_str,cur_access = dex_object.get_access_flags1(access_flags) 992 | if cur_access != prev_access: 993 | str1 += access_str 994 | str1 += "\n" 995 | prev_access = cur_access 996 | str1 += "\t" 997 | parameter_list=[] 998 | if code_off != 0: 999 | parameter_list = method_code(dex_object,code_off).get_param_list(dex_object) 1000 | str1 += dex_object.getmethodfullname1(method_idx,parameter_list,True) 1001 | #print "%s codeoff=%x"%(dex_object.getmethodname(method_idx),code_off) 1002 | str1 += ";\n" 1003 | method_idx = 0 1004 | str1+="//////////////////////virtual method//////////////////////////////////\n" 1005 | for i in xrange(0,self.numVirtualMethods): 1006 | n,method_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 1007 | offset += n 1008 | n,access_flags = get_uleb128(dex_object.m_content[offset:offset+5]) 1009 | offset += n 1010 | n,code_off = get_uleb128(dex_object.m_content[offset:offset+5]) 1011 | offset += n 1012 | method_idx += method_idx_diff 1013 | access_str,cur_access = dex_object.get_access_flags1(access_flags) 1014 | if cur_access != prev_access: 1015 | str1 += access_str 1016 | str1 += "\n" 1017 | prev_access = cur_access 1018 | str1 +="\tvirtual " 1019 | parameter_list=[] 1020 | if code_off != 0: 1021 | parameter_list = method_code(dex_object,code_off).get_param_list(dex_object) 1022 | str1 += dex_object.getmethodfullname1(method_idx,parameter_list,True) 1023 | str1 += ";\n" 1024 | str1 += "}" 1025 | #print str1 1026 | f.write(str1) 1027 | f.close() 1028 | return typelist 1029 | def printf(self,dex_object): 1030 | print "%-20s:%08x:%10d %s"%("thisClass",self.thisClass,self.thisClass,dex_object.gettypename(self.thisClass)) 1031 | print "%-20s:%08x:%10d %s"%("superClass",self.superClass,self.superClass,dex_object.gettypename(self.superClass)) 1032 | print "%-20s:%08x:%10d"%("modifiers",self.modifiers,self.modifiers) 1033 | print "%-20s:%08x:%10d"%("offset",self.offset,self.offset) 1034 | print "%-20s:%08x:%10d"%("annotationsOff",self.annotationsOff,self.annotationsOff) 1035 | print "%-20s:%08x:%10d"%("numStaticFields",self.numStaticFields,self.numStaticFields) 1036 | print "%-20s:%08x:%10d"%("numInstanceFields",self.numInstanceFields,self.numInstanceFields) 1037 | print "%-20s:%08x:%10d"%("numDirectMethods",self.numDirectMethods,self.numDirectMethods) 1038 | print "%-20s:%08x:%10d"%("numVirtualMethods",self.numVirtualMethods,self.numVirtualMethods) 1039 | print "%-20s:%08x:%10d"%("classDataOff",self.classDataOff,self.classDataOff) 1040 | print "%-20s:%08x:%10d"%("interfacesOff",self.interfacesOff,self.interfacesOff) 1041 | print "%-20s:%08x:%10d"%("interfacesSize",self.interfacesSize,self.interfacesSize) 1042 | offset = self.interfacesOff + struct.calcsize("I") 1043 | for n in xrange(0,self.interfacesSize): 1044 | typeid, = struct.unpack_from("H",dex_object.m_content,offset) 1045 | offset += struct.calcsize("H") 1046 | print "\t\t"+ dex_object.gettypename(typeid) 1047 | 1048 | print "%-20s:%08x:%10d"%("staticValuesOff",self.staticValuesOff,self.staticValuesOff) 1049 | print "%-20s:%08x:%10d %s"%("sourceFileIdx",self.sourceFileIdx,self.sourceFileIdx,dex_object.getstringbyid(self.sourceFileIdx)) 1050 | offset = self.classDataOff 1051 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 1052 | offset += n 1053 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 1054 | offset += n 1055 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 1056 | offset += n 1057 | n,tmp = get_uleb128(dex_object.m_content[offset:offset+5]) 1058 | offset += n 1059 | field_idx=0 1060 | for i in xrange(0,self.numStaticFields): 1061 | n,field_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 1062 | offset += n 1063 | field_idx+=field_idx_diff 1064 | print dex_object.getfieldfullname(field_idx), 1065 | n,modifiers = get_uleb128(dex_object.m_content[offset:offset+5]) 1066 | offset += n 1067 | if self.staticValuesOff: 1068 | staticoffset=get_static_offset(dex_object.m_content[self.staticValuesOff:],i) 1069 | if staticoffset == -1: 1070 | print "0;" 1071 | continue 1072 | parse_encoded_value(dex_object,dex_object.m_content[self.staticValuesOff+staticoffset:]) 1073 | print "" 1074 | 1075 | field_idx=0 1076 | for i in xrange(0,self.numInstanceFields): 1077 | n,field_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 1078 | offset += n 1079 | field_idx+=field_idx_diff 1080 | print dex_object.getfieldfullname(field_idx) 1081 | n,modifiers = get_uleb128(dex_object.m_content[offset:offset+5]) 1082 | offset += n 1083 | 1084 | print "=========numDirectMethods[%d]=numVirtualMethods[%d]=numStaticMethods[0]========="%(self.numDirectMethods,self.numVirtualMethods) 1085 | method_idx = 0 1086 | for i in xrange(0,self.numDirectMethods): 1087 | n,method_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 1088 | offset += n 1089 | n,access_flags = get_uleb128(dex_object.m_content[offset:offset+5]) 1090 | offset += n 1091 | n,code_off = get_uleb128(dex_object.m_content[offset:offset+5]) 1092 | offset += n 1093 | method_idx += method_idx_diff 1094 | if code_off != 0: 1095 | methodname=dex_object.getmethodfullname(method_idx,True).replace("::",".").replace(" ","") 1096 | method=None 1097 | try: 1098 | method = methodTable[method_idx] 1099 | except Exception as e: 1100 | pass 1101 | if method != None: 1102 | print "\nDirectMethod:" + dex_object.getmethodfullname(method_idx, True) + "\n" 1103 | try: 1104 | print "before repire method+++++++++++++++++++++++++++++++++++\n" 1105 | method_code(dex_object, code_off).printf(dex_object, "\t\t") 1106 | except Exception as e: 1107 | print e 1108 | try: 1109 | bytearray_str = base64.b64decode(method.insarray) 1110 | print "after repire method++++++++++++++++++++++++++++++++++++\n" 1111 | repired_method_code(dex_object, bytearray_str).printf(dex_object, "\t\t") 1112 | except Exception as e: 1113 | print e 1114 | 1115 | method_idx = 0 1116 | for i in xrange(0,self.numVirtualMethods): 1117 | n,method_idx_diff = get_uleb128(dex_object.m_content[offset:offset+5]) 1118 | offset += n 1119 | n,access_flags = get_uleb128(dex_object.m_content[offset:offset+5]) 1120 | offset += n 1121 | n,code_off = get_uleb128(dex_object.m_content[offset:offset+5]) 1122 | offset += n 1123 | method_idx += method_idx_diff 1124 | if code_off != 0: 1125 | methodname = dex_object.getmethodfullname(method_idx, True).replace("::", ".").replace(" ", "") 1126 | method = None 1127 | try: 1128 | method = methodTable[method_idx] 1129 | except Exception as e: 1130 | pass 1131 | if method != None: 1132 | print "\nVirtualMethod:" + dex_object.getmethodfullname(method_idx, True) + "\n" 1133 | try: 1134 | print "before repire method+++++++++++++++++++++++++++++++++++\n" 1135 | method_code(dex_object, code_off).printf(dex_object, "\t\t") 1136 | except Exception as e: 1137 | print e 1138 | try: 1139 | bytearray_str = base64.b64decode(method.insarray) 1140 | print "after repire method++++++++++++++++++++++++++++++++++++\n" 1141 | repired_method_code(dex_object, bytearray_str).printf(dex_object, "\t\t") 1142 | except Exception as e: 1143 | print e 1144 | print "================================================================================" 1145 | if self.annotationsOff != 0: 1146 | offset = self.annotationsOff 1147 | self.class_annotations_off,self.fields_size,self.annotated_methods_size,self.annotated_parameters_size,=struct.unpack_from("4I",dex_object.m_content,offset) 1148 | #print "%-30s:%08x:%09d"%("class_annotations_off",self.class_annotations_off,self.class_annotations_off) 1149 | #print "%-30s:%08x:%09d"%("fields_size",self.fields_size,self.fields_size) 1150 | #print "%-30s:%08x:%09d"%("annotated_methods_size",self.annotated_methods_size,self.annotated_methods_size) 1151 | #print "%-30s:%08x:%09d"%("annotated_parameters_size",self.annotated_parameters_size,self.annotated_parameters_size) 1152 | offset = self.annotationsOff + struct.calcsize("4I") 1153 | 1154 | if self.fields_size: 1155 | for i in xrange(0,self.fields_size): 1156 | field_idx,annotations_off,=struct.unpack_from("2I",dex_object.m_content,offset) 1157 | offset += struct.calcsize("2I") 1158 | print dex_object.getfieldname(field_idx), 1159 | parse_annotation_set_item(dex_object,annotations_off) 1160 | 1161 | if self.annotated_methods_size: 1162 | print "=====annotated_methods_size===== offset=[%x]===="%offset 1163 | for i in xrange(0,self.annotated_methods_size): 1164 | method_idx,annotations_off,=struct.unpack_from("2I",dex_object.m_content,offset) 1165 | offset += struct.calcsize("2I") 1166 | print dex_object.getmethodname(method_idx), 1167 | parse_annotation_set_item(dex_object,annotations_off) 1168 | if self.annotated_parameters_size: 1169 | for i in xrange(0,self.annotated_parameters_size): 1170 | method_idx,annotations_off,=struct.unpack_from("2I",dex_object.m_content,offset) 1171 | offset+=struct.calcsize("2I") 1172 | print dex_object.getmethodname(method_idx), 1173 | parse_annotation_set_ref_list(dex_object,annotations_off) 1174 | if self.class_annotations_off == 0: 1175 | return 1176 | print "self.class_annotations_off = %x"%self.class_annotations_off 1177 | parse_annotation_set_item(dex_object,self.class_annotations_off) 1178 | 1179 | def repiredex(self, dex_object): 1180 | # if dex_object.gettypename(self.thisClass)!="Landroid/Manifest$permission;": 1181 | # return 1182 | print "%-20s:%08x:%10d %s" % ( 1183 | "thisClass", self.thisClass, self.thisClass, dex_object.gettypename(self.thisClass)) 1184 | print "%-20s:%08x:%10d %s" % ( 1185 | "superClass", self.superClass, self.superClass, dex_object.gettypename(self.superClass)) 1186 | print "%-20s:%08x:%10d" % ("modifiers", self.modifiers, self.modifiers) 1187 | print "%-20s:%08x:%10d" % ("offset", self.offset, self.offset) 1188 | print "%-20s:%08x:%10d" % ("annotationsOff", self.annotationsOff, self.annotationsOff) 1189 | print "%-20s:%08x:%10d" % ("numStaticFields", self.numStaticFields, self.numStaticFields) 1190 | print "%-20s:%08x:%10d" % ("numInstanceFields", self.numInstanceFields, self.numInstanceFields) 1191 | print "%-20s:%08x:%10d" % ("numDirectMethods", self.numDirectMethods, self.numDirectMethods) 1192 | print "%-20s:%08x:%10d" % ("numVirtualMethods", self.numVirtualMethods, self.numVirtualMethods) 1193 | print "%-20s:%08x:%10d" % ("classDataOff", self.classDataOff, self.classDataOff) 1194 | print "%-20s:%08x:%10d" % ("interfacesOff", self.interfacesOff, self.interfacesOff) 1195 | print "%-20s:%08x:%10d" % ("interfacesSize", self.interfacesSize, self.interfacesSize) 1196 | offset = self.interfacesOff + struct.calcsize("I") 1197 | for n in xrange(0, self.interfacesSize): 1198 | typeid, = struct.unpack_from("H", dex_object.m_content, offset) 1199 | offset += struct.calcsize("H") 1200 | print "\t\t" + dex_object.gettypename(typeid) 1201 | 1202 | print "%-20s:%08x:%10d" % ("staticValuesOff", self.staticValuesOff, self.staticValuesOff) 1203 | print "%-20s:%08x:%10d %s" % ( 1204 | "sourceFileIdx", self.sourceFileIdx, self.sourceFileIdx, dex_object.getstringbyid(self.sourceFileIdx)) 1205 | offset = self.classDataOff 1206 | n, tmp = get_uleb128(dex_object.m_content[offset:offset + 5]) 1207 | offset += n 1208 | n, tmp = get_uleb128(dex_object.m_content[offset:offset + 5]) 1209 | offset += n 1210 | n, tmp = get_uleb128(dex_object.m_content[offset:offset + 5]) 1211 | offset += n 1212 | n, tmp = get_uleb128(dex_object.m_content[offset:offset + 5]) 1213 | offset += n 1214 | field_idx = 0 1215 | for i in xrange(0, self.numStaticFields): 1216 | n, field_idx_diff = get_uleb128(dex_object.m_content[offset:offset + 5]) 1217 | offset += n 1218 | field_idx += field_idx_diff 1219 | print dex_object.getfieldfullname(field_idx), 1220 | n, modifiers = get_uleb128(dex_object.m_content[offset:offset + 5]) 1221 | offset += n 1222 | if self.staticValuesOff: 1223 | staticoffset = get_static_offset(dex_object.m_content[self.staticValuesOff:], i) 1224 | if staticoffset == -1: 1225 | print "0;" 1226 | continue 1227 | parse_encoded_value(dex_object, dex_object.m_content[self.staticValuesOff + staticoffset:]) 1228 | print "" 1229 | 1230 | field_idx = 0 1231 | for i in xrange(0, self.numInstanceFields): 1232 | n, field_idx_diff = get_uleb128(dex_object.m_content[offset:offset + 5]) 1233 | offset += n 1234 | field_idx += field_idx_diff 1235 | print dex_object.getfieldfullname(field_idx) 1236 | n, modifiers = get_uleb128(dex_object.m_content[offset:offset + 5]) 1237 | offset += n 1238 | 1239 | print "=========numDirectMethods[%d]=numVirtualMethods[%d]=numStaticMethods[0]=========" % ( 1240 | self.numDirectMethods, self.numVirtualMethods) 1241 | method_idx = 0 1242 | for i in xrange(0, self.numDirectMethods): 1243 | n, method_idx_diff = get_uleb128(dex_object.m_content[offset:offset + 5]) 1244 | offset += n 1245 | n, access_flags = get_uleb128(dex_object.m_content[offset:offset + 5]) 1246 | offset += n 1247 | n, code_off = get_uleb128(dex_object.m_content[offset:offset + 5]) 1248 | offset += n 1249 | method_idx += method_idx_diff 1250 | print dex_object.getmethodfullname(method_idx, True) 1251 | # print "%s codeoff=%x"%(dex_object.getmethodname(method_idx),code_off) 1252 | if code_off != 0: 1253 | method_code(dex_object, code_off).printf(dex_object, "\t\t") 1254 | method_idx = 0 1255 | for i in xrange(0, self.numVirtualMethods): 1256 | n, method_idx_diff = get_uleb128(dex_object.m_content[offset:offset + 5]) 1257 | offset += n 1258 | n, access_flags = get_uleb128(dex_object.m_content[offset:offset + 5]) 1259 | offset += n 1260 | n, code_off = get_uleb128(dex_object.m_content[offset:offset + 5]) 1261 | offset += n 1262 | method_idx += method_idx_diff 1263 | print dex_object.getmethodfullname(method_idx, True) 1264 | # print "%s codeoff=%x"%(dex_object.getmethodname(method_idx),code_off) 1265 | if code_off != 0: 1266 | method_code(dex_object, code_off).printf(dex_object, "\t\t") 1267 | 1268 | print "================================================================================" 1269 | if self.annotationsOff != 0: 1270 | offset = self.annotationsOff 1271 | self.class_annotations_off, self.fields_size, self.annotated_methods_size, self.annotated_parameters_size, = struct.unpack_from( 1272 | "4I", dex_object.m_content, offset) 1273 | # print "%-30s:%08x:%09d"%("class_annotations_off",self.class_annotations_off,self.class_annotations_off) 1274 | # print "%-30s:%08x:%09d"%("fields_size",self.fields_size,self.fields_size) 1275 | # print "%-30s:%08x:%09d"%("annotated_methods_size",self.annotated_methods_size,self.annotated_methods_size) 1276 | # print "%-30s:%08x:%09d"%("annotated_parameters_size",self.annotated_parameters_size,self.annotated_parameters_size) 1277 | offset = self.annotationsOff + struct.calcsize("4I") 1278 | 1279 | if self.fields_size: 1280 | for i in xrange(0, self.fields_size): 1281 | field_idx, annotations_off, = struct.unpack_from("2I", dex_object.m_content, offset) 1282 | offset += struct.calcsize("2I") 1283 | print dex_object.getfieldname(field_idx), 1284 | parse_annotation_set_item(dex_object, annotations_off) 1285 | 1286 | if self.annotated_methods_size: 1287 | print "=====annotated_methods_size===== offset=[%x]====" % offset 1288 | for i in xrange(0, self.annotated_methods_size): 1289 | method_idx, annotations_off, = struct.unpack_from("2I", dex_object.m_content, offset) 1290 | offset += struct.calcsize("2I") 1291 | print dex_object.getmethodname(method_idx), 1292 | parse_annotation_set_item(dex_object, annotations_off) 1293 | if self.annotated_parameters_size: 1294 | for i in xrange(0, self.annotated_parameters_size): 1295 | method_idx, annotations_off, = struct.unpack_from("2I", dex_object.m_content, offset) 1296 | offset += struct.calcsize("2I") 1297 | print dex_object.getmethodname(method_idx), 1298 | parse_annotation_set_ref_list(dex_object, annotations_off) 1299 | if self.class_annotations_off == 0: 1300 | return 1301 | print "self.class_annotations_off = %x" % self.class_annotations_off 1302 | parse_annotation_set_item(dex_object, self.class_annotations_off) 1303 | def get_static_offset(content,index): 1304 | offset = 0 1305 | m,size = get_uleb128(content[offset:offset+5]) 1306 | if index >= size: 1307 | return -1 1308 | offset += m 1309 | for i in xrange(0,index): 1310 | offset += get_encoded_value_size(content[offset:]) 1311 | return offset 1312 | def get_encoded_value_size(content): 1313 | offset = 0 1314 | arg_type, = struct.unpack_from("B",content,offset) 1315 | offset+=struct.calcsize("B") 1316 | value_arg = arg_type>>5 1317 | value_type = arg_type &0x1f 1318 | if value_type in [0x2,3,4,6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b]: 1319 | offset += (value_arg+1) 1320 | elif value_type == 0: 1321 | offset += 1 1322 | elif value_type == 0x1e or value_type == 0x1f: 1323 | offset += 0 1324 | elif value_type == 0x1d: 1325 | offset += get_encoded_annotation_size(content[offset:]) 1326 | elif value_type == 0x1c: 1327 | m,asize = get_uleb128(m_content[offset:offset+5]) 1328 | offset += m 1329 | for q in xrange(0,asize): 1330 | offset += get_encoded_value_size(content[offset:]) 1331 | else: 1332 | print "***************error parse encode_value**************" 1333 | return offset 1334 | class field_annotation: 1335 | def __init__(self,content): 1336 | self.field_idx,self.annotations_off, = struct.unpack_from("2I",content) 1337 | class annotations_directory_item: 1338 | def __init__(self,content,dex_object): 1339 | self.class_annotations_off,self.fields_size,self.annotated_methods_size,self.annotated_parameters_size , =struct.unpack_from("4I",content) 1340 | self.m_fields_list = [] 1341 | self.m_methods_list = [] 1342 | self.m_parameters_list = [] 1343 | offset = struct.calcsize("4I") 1344 | if self.fields_size: 1345 | self.m_fields_list = array.array("L") 1346 | self.m_fields_list.fromstring(content[offset:offset+8*self.fields_size]) 1347 | offset = offset+4*self.fields_size 1348 | if self.annotated_methods_size: 1349 | self.m_methods_list = array.array("L") 1350 | self.m_methods_list.fromstring(content[offset:offset+8*self.annotated_methods_size]) 1351 | offset = offset + 4*self.annotated_methods_size 1352 | for i in xrange(0,annotated_methods_size): 1353 | self.m_parameters_list = array.array("L") 1354 | self.m_parameters_list.fromstring(content[offset:offset+8*self.annotated_parameters_size]) 1355 | content = dex_object.m_content 1356 | for i in xrange(0,self.fields_size): 1357 | size = self.m_fields_list[i*2] 1358 | offset = self.m_fields_list[i*2+1] 1359 | of = array.array("L") 1360 | of.fromstring(content[offset:offset+4*size]) 1361 | for off in of: 1362 | visibility = content[off] 1363 | off += 1 1364 | k,type_idx = get_uleb128(content[off:]) 1365 | off += k 1366 | k,size = get_uleb128(content[off:]) 1367 | for m in xrange(0,size): 1368 | off += k 1369 | k,name_idx=get_uleb128(content[off:]) 1370 | off += k 1371 | get_encoded_value(content[off:]) 1372 | def parse_debug_info_method_parameter_list(dex_object,offset): 1373 | parameter_list = [] 1374 | n ,current_line = get_uleb128(dex_object.m_content[offset:offset+5]) 1375 | offset += n 1376 | n,parameters_size = get_uleb128(dex_object.m_content[offset:offset+5]) 1377 | offset += n 1378 | for i in xrange(0,parameters_size): 1379 | n,string_idx = get_uleb128p1(dex_object.m_content[offset:offset+5]) 1380 | if string_idx!=-1: 1381 | parameter_list.append(dex_object.getstringbyid(string_idx)) 1382 | offset+=n 1383 | return parameter_list 1384 | def parse_debug_info(lex_object,offset): 1385 | print "===parse_debug_info====offset = %08x"%offset 1386 | n ,current_line = get_uleb128(lex_object.m_content[offset:offset+5]) 1387 | offset += n 1388 | n,parameters_size = get_uleb128(lex_object.m_content[offset:offset+5]) 1389 | offset += n 1390 | for i in xrange(0,parameters_size): 1391 | n,string_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1392 | if string_idx!=-1: 1393 | print lex_object.getstringbyid(string_idx) 1394 | offset+=n 1395 | start = offset 1396 | current_pc = 0 1397 | print "===opcode====offset = %08x line=%d pc=%d"%(offset,current_line,current_pc) 1398 | 1399 | 1400 | totalsize = len(lex_object.m_content) 1401 | while offset < totalsize: 1402 | #bytecode = struct.unpack_from("B",lex_object.m_content,offset) 1403 | bytecode = ord(lex_object.m_content[offset]) 1404 | offset += 1 1405 | print "opcode[%02x]"%bytecode, 1406 | if bytecode == 0: 1407 | print "" 1408 | break 1409 | elif bytecode == 1: 1410 | n,val = get_uleb128(lex_object.m_content[offset:offset+5]) 1411 | current_pc += val; 1412 | offset += n 1413 | print "line=%d pc=%x"%(current_line,current_pc) 1414 | elif bytecode == 2: 1415 | n,val = get_leb128(lex_object.m_content[offset:offset+5]) 1416 | 1417 | current_line += val 1418 | offset += n 1419 | print "line=%d pc=%x val=%08x(%d)"%(current_line,current_pc,val,val) 1420 | elif bytecode == 3: 1421 | n,register_num = get_uleb128(lex_object.m_content[offset:offset+5]) 1422 | offset += n 1423 | n,name_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1424 | offset += n 1425 | n,type_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1426 | offset += n 1427 | print "v%d %s %s START_LOCAL"%(register_num,lex_object.gettypenamebyid(type_idx),lex_object.getstringbyid(name_idx)) 1428 | elif bytecode == 4: 1429 | n,register_num = get_uleb128(lex_object.m_content[offset:offset+5]) 1430 | offset += n 1431 | n,name_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1432 | offset += n 1433 | n,type_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1434 | offset += n 1435 | n,sig_idx = get_uleb128p1(lex_object.m_content[offset:offset+5]) 1436 | offset += n 1437 | print "v%d %s %s START_LOCAL_EXTENDED"%(register_num,lex_object.gettypenamebyid(type_idx),lex_object.getstringbyid(name_idx)) 1438 | elif bytecode == 5: 1439 | n,register_num = get_uleb128(lex_object.m_content[offset:offset+5]) 1440 | offset += n 1441 | print "v%d END_LOCAL"%register_num 1442 | elif bytecode == 6: 1443 | n,register_num = get_uleb128(lex_object.m_content[offset:offset+5]) 1444 | offset += n 1445 | print "v%d register to restart"%register_num 1446 | elif bytecode == 7: 1447 | print "SET_PROLOGUE_END" 1448 | pass 1449 | elif bytecode == 8: 1450 | print "SET_EPILOGUE_BEGIN" 1451 | pass 1452 | elif bytecode == 9: 1453 | n,name_idx = get_uleb128(lex_object.m_content[offset:offset+5]) 1454 | print "%s"%lex_object.getstringbyid(name_idx) 1455 | offset += n 1456 | else: 1457 | adjusted_opcode = bytecode - 0xa 1458 | current_line += (adjusted_opcode % 15)-4 1459 | current_pc += (adjusted_opcode / 15) 1460 | #offset += 1 1461 | print "line=%d pc=%x adjusted_opcode=%d pc+ %d line+%d"%(current_line,current_pc,adjusted_opcode,(adjusted_opcode/15),(adjusted_opcode%15)-4) 1462 | print "===parse_debug_info====offset = %08x$"%offset 1463 | def get_encoded_value(content): 1464 | VALUE_SHORT = 0x2 1465 | VALUE_CHAR = 0x3 1466 | VALUE_INT = 0x4 1467 | VALUE_LONG = 0x6 1468 | VALUE_FLOAT = 0x10 1469 | VALUE_DOUBLE = 0x11 1470 | VALUE_STRING = 0x17 1471 | VALUE_TYPE = 0x18 1472 | VALUE_FIELD = 0x19 1473 | VALUE_METHOD = 0x1a 1474 | VALUE_ENUM = 0x1b 1475 | VALUE_ARRAY = 0x1c 1476 | VALUE_ANNOTATION = 0x1d 1477 | VALUE_NULL = 0x1e 1478 | VALUE_BOOLEAN = 0x1f 1479 | type_enum = [0x0,0x2,0x3,0x4,0x6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f] 1480 | size_type = ord(content[0]) 1481 | usebyte = 1 1482 | 1483 | size = size_type >> 5 1484 | type = size_type & 0x1f 1485 | if type not in size_type: 1486 | print "encoded value error!" 1487 | if type == 0 and size == 0: 1488 | value,=struct.unpack_from("b",content,1) 1489 | usebyte += 1 1490 | 1491 | elif type == VALUE_SHORT: 1492 | if size == 0: 1493 | value,=struct.unpack_from("b",content,1) 1494 | elif size == 1: 1495 | value,=struct.unpack_from("h",content,1) 1496 | else: 1497 | print "encoded value error! type=short type=%d size=%d"%(type,size) 1498 | usebyte+=size+1 1499 | elif type == VALUE_CHAR: 1500 | if size == 0: 1501 | value, = struct.unpack_from("B",content,1) 1502 | elif size == 1: 1503 | value, = struct.unpack_from("H",content,1) 1504 | else: 1505 | print "encoded value error! type=char type=%d size=%d"%(type,size) 1506 | usebyte+=size+1 1507 | elif type == VALUE_INT: 1508 | if size == 0: 1509 | value,=struct.unpack_from("b",content,1) 1510 | elif size == 1: 1511 | value,=struct.unpack_from("h",content,1) 1512 | elif size == 2: 1513 | value = 0 1514 | elif size == 3: 1515 | value,=struct.unpack_from("i",content,1) 1516 | else: 1517 | print "encoded value error! type=int type=%d size=%d"%(type,size) 1518 | usebyte+=size+1 1519 | 1520 | elif type == VALUE_LONG: 1521 | if size > 7: 1522 | print "encoded value error! type=long type=%d size=%d"%(type,size) 1523 | value=content[1:1+size+1] 1524 | usebyte+=size+1 1525 | elif type == VALUE_FLOAT: 1526 | if size > 3: 1527 | print "encoded value error! type=float type=%d size=%d"%(type,size) 1528 | value=content[1:1+size+1] 1529 | usebyte+=size+1 1530 | elif type == VALUE_DOUBLE: 1531 | if size > 7: 1532 | print "encoded value error! type=double type=%d size=%d"%(type,size) 1533 | value = content[1:1+size+1] 1534 | usebyte+=size+1 1535 | 1536 | elif type == VALUE_STRING: 1537 | if size > 3: 1538 | print "encoded value error! type=double type=%d size=%d"%(type,size) 1539 | value = content[1:1+size+1] 1540 | usebyte+=size+1 1541 | elif type == VALUE_TYPE: 1542 | if size > 3: 1543 | print "encoded value error! type=type type=%d size=%d"%(type,size) 1544 | value = content[1:1+size+1] 1545 | usebyte+=size+1 1546 | 1547 | elif type == VALUE_FIELD: 1548 | if size > 3: 1549 | print "encoded value error! type=field type=%d size=%d"%(type,size) 1550 | value = content[1:1+size+1] 1551 | usebyte+=size+1 1552 | elif type == VALUE_METHOD: 1553 | if size > 3: 1554 | print "encoded value error! type=medhod type=%d size=%d"%(type,size) 1555 | value = content[1:1+size+1] 1556 | usebyte+=size+1 1557 | elif type == VALUE_ENUM: 1558 | if size > 3: 1559 | print "encoded value error! type=enum type=%d size=%d"%(type,size) 1560 | value = content[1:1+size+1] 1561 | usebyte+=size+1 1562 | elif type == VALUE_ARRAY: 1563 | if size != 0: 1564 | print "encoded value error! type=encoded_array type=%d size=%d"%(type,size) 1565 | k,value=get_encoded_array(content[1:1+size+1]) 1566 | usebyte+=k 1567 | elif type == VALUE_ANNOTATION: 1568 | if size != 0: 1569 | print "encoded value error! type=encoded_annotation type=%d size=%d"%(type,size) 1570 | k,type_idx = get_uleb128(content[1:]) 1571 | k1,s = get_uleb128(content[1+k:]) 1572 | k1 = 1+k+k1 1573 | for n in xrange(0,s): 1574 | k2,name_index = get_uleb128(content[k1:]) 1575 | k1+=k2 1576 | k3,value = get_encoded_value(content[k1:]) 1577 | k1+=k3 1578 | usebyte+=k1 1579 | elif type == VALUE_NULL: 1580 | if size != 0: 1581 | print "encoded value error! type=NULL type=%d size=%d"%(type,size) 1582 | value="NULL" 1583 | elif type == VALUE_BOOLEAN: 1584 | value = size 1585 | return usebyte,value 1586 | def get_encoded_array(content): 1587 | offset,size = get_uleb128(content) 1588 | userbyte = offset 1589 | for i in xrange(0,size): 1590 | off,value = get_encoded_value(content[offset:]) 1591 | offset += off 1592 | userbyte += off 1593 | return userbyte,value 1594 | def get_encoded_array_by_index(content,index): 1595 | offset,size = get_uleb128(content) 1596 | userbyte = offset 1597 | for i in xrange(0,size): 1598 | off,value = get_encoded_value(content[offset:]) 1599 | offset += off 1600 | userbyte+=off 1601 | if index == i: 1602 | return userbyte,value 1603 | return offset 1604 | class annotations_directory_item: 1605 | def __init__(self,content): 1606 | self.m_class_annotations_off,self.m_fields_size,self.m_annotated_methods_size,self.m_annotated_parameters_size,=struct.unpack_from("4I",content) 1607 | pass 1608 | def shorty_decode(name): 1609 | val = {"V":"void", 1610 | "Z":"boolean", 1611 | "B":"byte", 1612 | "S":"short", 1613 | "C":"char", 1614 | "I":"int", 1615 | "J":"long", 1616 | "F":"float", 1617 | "D":"double", 1618 | "L":"L" 1619 | } 1620 | value = "" 1621 | 1622 | if name[-1] == ';': 1623 | if name[0] == 'L': 1624 | return name[1:-1].replace("/",".") 1625 | if name[0]=='[': 1626 | if name[1] == 'L': 1627 | return name[2:-1].replace("/",".")+"[]" 1628 | else: 1629 | return name[1:-1].replace("/",".")+"[]" 1630 | i = 0 1631 | for ch in name: 1632 | if val.has_key(ch): 1633 | if i != 0: 1634 | value += " | " 1635 | value += val[ch] 1636 | i += 1 1637 | if '[' in name: 1638 | value += "[]" 1639 | return value 1640 | def get_encoded_value_size(content): 1641 | offset = 0 1642 | arg_type, = struct.unpack_from("B",content,offset) 1643 | offset+=struct.calcsize("B") 1644 | value_arg = arg_type>>5 1645 | value_type = arg_type &0x1f 1646 | if value_type in [0x2,3,4,6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b]: 1647 | offset += (value_arg+1) 1648 | elif value_type == 0: 1649 | offset += 1 1650 | elif value_type == 0x1e or value_type == 0x1f: 1651 | offset += 0 1652 | elif value_type == 0x1d: 1653 | offset += get_encoded_annotation_size(content[offset:]) 1654 | elif value_type == 0x1c: 1655 | m,asize = get_uleb128(m_content[offset:5+offset]) 1656 | offset += m 1657 | for q in xrange(0,asize): 1658 | offset += get_encoded_value_size(content[offset:]) 1659 | else: 1660 | print "***************error parse encode_value**************" 1661 | return offset 1662 | def get_encoded_annotation_size(content): 1663 | offset = 0 1664 | n ,type_idx = get_uleb128(content[offset:5+offset]) 1665 | offset += n 1666 | n ,size = get_uleb128(content[offset:5+offset]) 1667 | offset += n 1668 | for i in xrange(0,n): 1669 | n ,name_idx = get_uleb128(content[offset:5+offset]) 1670 | offset += n 1671 | offset += get_encoded_value_size(content[offset:]) 1672 | return offset 1673 | def parse_encoded_value(lex_object,content,is_root=False): 1674 | offset = 0 1675 | arg_type, = struct.unpack_from("B",content,offset) 1676 | offset+=struct.calcsize("B") 1677 | value_arg = arg_type>>5 1678 | value_type = arg_type &0x1f 1679 | if value_type in [0x2,3,4,6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b]: 1680 | sum = 0 1681 | for q in xrange(0,value_arg+1): 1682 | mm = ord(content[offset+q]) 1683 | mm <<= 8*q 1684 | sum|=mm 1685 | #sum += ord(content[offset+q]) 1686 | if value_type == 0x17: 1687 | print "string@%d"%sum, 1688 | print lex_object.getstringbyid(sum), 1689 | elif value_type == 0x18: 1690 | print "type@%d"%sum, 1691 | print lex_object.gettypename(sum), 1692 | elif value_type == 0x19: 1693 | print "field@%d"%sum, 1694 | print lex_object.getfieldname(sum), 1695 | elif value_type == 0x1a: 1696 | print "method@%d"%sum, 1697 | print lex_object.getmethodname(sum), 1698 | else: 1699 | str = "" 1700 | for q in xrange(0,value_arg+1): 1701 | str += "%02x "%(ord(content[offset+q])) 1702 | print str, 1703 | offset += (value_arg+1) 1704 | elif value_type == 0: 1705 | print "%02x"%ord(content[offset]), 1706 | offset += 1 1707 | 1708 | elif value_type == 0x1e : 1709 | print "NULL", 1710 | elif value_type == 0x1f: 1711 | if value_arg == 0: 1712 | print "False", 1713 | else: 1714 | print "True", 1715 | offset += 0 1716 | elif value_type == 0x1d: 1717 | offset += parse_encoded_annotation(lex_object,content[offset:]) 1718 | elif value_type == 0x1c: 1719 | m,asize = get_uleb128(content[offset:5]) 1720 | offset += m 1721 | print "[%d]"%asize, 1722 | for q in xrange(0,asize): 1723 | offset += parse_encoded_value(lex_object,content[offset:],False) 1724 | else: 1725 | print "***************error parse encode_value**************" 1726 | return offset 1727 | def parse_encoded_value1(lex_object,content,is_root=False): 1728 | str1 = "" 1729 | offset = 0 1730 | arg_type, = struct.unpack_from("B",content,offset) 1731 | offset+=struct.calcsize("B") 1732 | value_arg = arg_type>>5 1733 | value_type = arg_type &0x1f 1734 | if value_type in [0x2,3,4,6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b]: 1735 | sum = 0 1736 | for q in xrange(0,value_arg+1): 1737 | mm = ord(content[offset+q]) 1738 | mm <<= 8*q 1739 | sum|=mm 1740 | #sum += ord(content[offset+q]) 1741 | if value_type == 0x17: 1742 | str1 += "\"" 1743 | str1 += lex_object.getstringbyid(sum) 1744 | str1 += "\"" 1745 | elif value_type == 0x18: 1746 | print "type@%d"%sum, 1747 | str1 += lex_object.gettypename(sum), 1748 | elif value_type == 0x19: 1749 | print "field@%d"%sum, 1750 | str1 += lex_object.getfieldname(sum), 1751 | elif value_type == 0x1a: 1752 | print "method@%d"%sum, 1753 | str1 += lex_object.getmethodname(sum), 1754 | else: 1755 | str2 = "" 1756 | for q in xrange(0,value_arg+1): 1757 | str2 += "%02x "%(ord(content[offset+q])) 1758 | str1+= str2 1759 | offset += (value_arg+1) 1760 | elif value_type == 0: 1761 | str1 += "%02x"%ord(content[offset]) 1762 | offset += 1 1763 | 1764 | elif value_type == 0x1e : 1765 | str1 += "NULL" 1766 | elif value_type == 0x1f: 1767 | if value_arg == 0: 1768 | str1 += "false" 1769 | else: 1770 | str1 += "true" 1771 | offset += 0 1772 | elif value_type == 0x1d: 1773 | size ,text = parse_encoded_annotation1(lex_object,content[offset:]) 1774 | offset += size 1775 | str1 += text 1776 | elif value_type == 0x1c: 1777 | m,asize = get_uleb128(content[offset:5]) 1778 | offset += m 1779 | str1 += "[%d]"%asize 1780 | for q in xrange(0,asize): 1781 | size,text = parse_encoded_value1(lex_object,content[offset:],False) 1782 | offset += size 1783 | str1 += text 1784 | else: 1785 | str1 += "***************error parse encode_value**************" 1786 | return offset,str1 1787 | def parse_encoded_value4441(lex_object,content,is_root=False): 1788 | offset = 0 1789 | arg_type, = struct.unpack_from("B",content,offset) 1790 | offset+=struct.calcsize("B") 1791 | value_arg = arg_type>>5 1792 | value_type = arg_type &0x1f 1793 | if value_type in [0x2,3,4,6,0x10,0x11,0x17,0x18,0x19,0x1a,0x1b]: 1794 | str = "" 1795 | for q in xrange(0,value_arg+1): 1796 | str += "%02x "%(ord(content[offset+q])) 1797 | print str, 1798 | offset += (value_arg+1) 1799 | elif value_type == 0: 1800 | print "%02x"%ord(content[offset]), 1801 | offset += 1 1802 | 1803 | elif value_type == 0x1e : 1804 | print "NULL", 1805 | elif value_type == 0x1f: 1806 | if value_arg == 0: 1807 | print "False", 1808 | else: 1809 | print "True", 1810 | offset += 0 1811 | elif value_type == 0x1d: 1812 | offset += parse_encoded_annotation(lex_object,content[offset:]) 1813 | elif value_type == 0x1c: 1814 | m,asize = get_uleb128(content[offset:5+offset]) 1815 | offset += m 1816 | print "[%d]"%asize, 1817 | for q in xrange(0,asize): 1818 | offset += parse_encoded_value(lex_object,content[offset:],False) 1819 | else: 1820 | print "***************error parse encode_value**************" 1821 | return offset 1822 | def parse_encoded_annotation1(lex_object,content,is_root=False): 1823 | str1 = "" 1824 | offset = 0 1825 | n ,type_idx = get_uleb128(content[offset:5+offset]) 1826 | offset += n 1827 | n ,size = get_uleb128(content[offset:5+offset]) 1828 | offset += n 1829 | if is_root: 1830 | str1 += lex_object.gettypenamebyid(type_idx) 1831 | for i in xrange(0,size): 1832 | n ,name_idx = get_uleb128(content[offset:5+offset]) 1833 | if i == 0 and is_root: 1834 | str1 += lex_object.getstringbyid(name_idx) 1835 | offset += n 1836 | size,text = parse_encoded_value1(lex_object,content[offset:],is_root) 1837 | offset += size 1838 | str1 += text 1839 | return offset, str1 1840 | def parse_encoded_annotation(lex_object,content,is_root=False): 1841 | offset = 0 1842 | n ,type_idx = get_uleb128(content[offset:5+offset]) 1843 | offset += n 1844 | n ,size = get_uleb128(content[offset:5+offset]) 1845 | offset += n 1846 | if is_root: 1847 | print lex_object.gettypenamebyid(type_idx), 1848 | for i in xrange(0,size): 1849 | n ,name_idx = get_uleb128(content[offset:5+offset]) 1850 | if i == 0 and is_root: 1851 | print lex_object.getstringbyid(name_idx), 1852 | offset += n 1853 | offset += parse_encoded_value(lex_object,content[offset:],is_root) 1854 | return offset 1855 | def parse_annotation_set_item(lex_object,offset,is_root=False): 1856 | try: 1857 | size, = struct.unpack_from("I",lex_object.m_content,offset) 1858 | offset += struct.calcsize("I") 1859 | for i in xrange(0,size): 1860 | off,=struct.unpack_from("I",lex_object.m_content,offset) 1861 | visibility, = struct.unpack_from("B",lex_object.m_content,off) 1862 | if visibility == 0: 1863 | print "VISIBILITY_BUILD", 1864 | elif visibility == 1: 1865 | print "VISIBILITY_RUNTIME", 1866 | elif visibility == 2: 1867 | print "VISIBILITY_SYSTEM", 1868 | else: 1869 | print "visibility is unknow %02x"%visibility 1870 | off += struct.calcsize("B") 1871 | parse_encoded_annotation(lex_object,lex_object.m_content[off:],True) 1872 | offset += struct.calcsize("I") 1873 | print "" 1874 | except Exception as e: 1875 | print e 1876 | def parse_annotation_set_ref_list(lex_object,offset,is_root=False): 1877 | size, = struct.unpack_from("I",lex_object.m_content,offset) 1878 | offset += struct.calcsize("I") 1879 | for i in xrange(0,size): 1880 | off,=struct.unpack_from("I",lex_object.m_content,offset) 1881 | parse_annotation_set_item(lex_object,off,True) 1882 | offset += struct.calcsize("I") 1883 | def get_encoded_field(content): 1884 | n , val1 = get_uleb128(content) 1885 | n1 , val2 = get_uleb128(content[n:]) 1886 | return n + n1, val1, val2 1887 | def get_encoded_method(content): 1888 | n , val1 = get_uleb128(content) 1889 | n1 , val2 = get_uleb128(content[n:]) 1890 | n2 , val3 = get_uleb128(content[n+n1:]) 1891 | return n + n1 + n2, val1, val2, val3 1892 | class dex_parser: 1893 | 1894 | def __init__(self,filename): 1895 | global DEX_MAGIC 1896 | global DEX_OPT_MAGIC 1897 | self.m_javaobject_id = 0 1898 | self.m_filename = filename 1899 | self.m_fd = open(filename,"rb") 1900 | self.m_content = self.m_fd.read() 1901 | self.m_fd.close() 1902 | self.m_dex_optheader = None 1903 | self.m_class_name_id = {} 1904 | self.string_table = [] 1905 | if self.m_content[0:4] == DEX_OPT_MAGIC: 1906 | self.init_optheader(self.m_content) 1907 | self.init_header(self.m_content,0x40) 1908 | elif self.m_content[0:4] == DEX_MAGIC: 1909 | self.init_header(self.m_content,0) 1910 | 1911 | bOffset = self.m_stringIdsOff 1912 | if self.m_stringIdsSize > 0: 1913 | for i in xrange(0,self.m_stringIdsSize): 1914 | offset, = struct.unpack_from("I",self.m_content,bOffset + i * 4) 1915 | if i == 0: 1916 | start = offset 1917 | else: 1918 | skip, length = get_uleb128(self.m_content[start:start+5]) 1919 | self.string_table.append(self.m_content[start+skip:offset-1]) 1920 | start = offset 1921 | for i in xrange(start,len(self.m_content)): 1922 | if self.m_content[i]==chr(0): 1923 | self.string_table.append(self.m_content[start+1:i]) 1924 | break 1925 | for i in xrange(0,self.m_classDefSize): 1926 | str1 = self.getclassname(i) 1927 | self.m_class_name_id[str1] = i 1928 | for i in xrange(0,self.m_classDefSize): 1929 | str1 = self.getclassname(i) 1930 | dex_class(self,i).printf(self) 1931 | pass 1932 | #self.getclass(i) 1933 | def create_all_header(self): 1934 | for i in xrange(0,self.m_classDefSize): 1935 | str1 = self.getclassname(i) 1936 | self.create_cpp_header(str1) 1937 | def create_cpp_header(self,classname="Landroid/app/Activity;"): 1938 | if self.m_class_name_id.has_key(classname): 1939 | classid= self.m_class_name_id[classname] 1940 | field_list = dex_class(self,classid).create_header_file_for_cplusplus(self) 1941 | pass 1942 | def getstringbyid(self,stridx): 1943 | if stridx >= self.m_stringIdsSize: 1944 | return "" 1945 | return self.string_table[stridx] 1946 | 1947 | def getmethodname(self,methodid): 1948 | if methodid >= self.m_methodIdsSize: 1949 | return "" 1950 | offset = self.m_methodIdsOffset + methodid * struct.calcsize("HHI") 1951 | class_idx,proto_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1952 | return self.string_table[name_idx] 1953 | def getmethodfullname(self,methodid,hidden_classname=False): 1954 | if methodid >= self.m_methodIdsSize: 1955 | return "" 1956 | offset = self.m_methodIdsOffset + methodid * struct.calcsize("HHI") 1957 | class_idx,proto_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1958 | classname = self.gettypename(class_idx) 1959 | classname = shorty_decode(classname) 1960 | funcname = self.getstringbyid(name_idx) 1961 | if not hidden_classname: 1962 | classname = "" 1963 | return self.getprotofullname(proto_idx,classname,funcname) 1964 | def getmethodfullname1(self,methodid,parameter_list=[],hidden_classname=False): 1965 | if methodid >= self.m_methodIdsSize: 1966 | return "" 1967 | offset = self.m_methodIdsOffset + methodid * struct.calcsize("HHI") 1968 | class_idx,proto_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1969 | classname = self.gettypename(class_idx) 1970 | classname = shorty_decode(classname) 1971 | funcname = self.getstringbyid(name_idx) 1972 | if not hidden_classname: 1973 | classname = "" 1974 | return self.getprotofullname1(proto_idx,classname,parameter_list,funcname) 1975 | def getfieldname(self,fieldid): 1976 | if fieldid >= self.m_fieldIdsSize: 1977 | return "" 1978 | offset = self.m_fieldIdsOffset + fieldid * struct.calcsize("HHI") 1979 | class_idx,type_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1980 | return self.string_table[name_idx] 1981 | def getfieldfullname1(self,fieldid): 1982 | if fieldid >= self.m_fieldIdsSize: 1983 | return "" 1984 | offset = self.m_fieldIdsOffset + fieldid * struct.calcsize("HHI") 1985 | class_idx,type_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1986 | name = self.gettypename(type_idx) 1987 | name = shorty_decode(name) 1988 | index = name.rfind(".") 1989 | fname = self.getstringbyid(name_idx) 1990 | return "%s %s"%(name[index+1:],fname) 1991 | def getfieldfullname2(self,fieldid): 1992 | if fieldid >= self.m_fieldIdsSize: 1993 | return "" 1994 | offset = self.m_fieldIdsOffset + fieldid * struct.calcsize("HHI") 1995 | class_idx,type_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 1996 | typename = self.gettypename(type_idx) 1997 | typename = shorty_decode(typename) 1998 | fieldname = self.getstringbyid(name_idx) 1999 | return typename,fieldname 2000 | def getfieldfullname(self,fieldid): 2001 | if fieldid >= self.m_fieldIdsSize: 2002 | return "" 2003 | offset = self.m_fieldIdsOffset + fieldid * struct.calcsize("HHI") 2004 | class_idx,type_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 2005 | name = self.gettypename(type_idx) 2006 | name = shorty_decode(name) 2007 | fname = self.getstringbyid(name_idx) 2008 | return "%s %s"%(name,fname) 2009 | def getfieldtypename(self,fieldid): 2010 | if fieldid >= self.m_fieldIdsSize: 2011 | return "" 2012 | offset = self.m_fieldIdsOffset + fieldid * struct.calcsize("HHI") 2013 | class_idx,type_idx,name_idx, = struct.unpack_from("HHI",self.m_content,offset) 2014 | name = self.gettypename(type_idx) 2015 | if name[-1] != ";": 2016 | name = shorty_decode(name) 2017 | return name 2018 | 2019 | def gettypename(self,typeid): 2020 | if typeid >= self.m_typeIdsSize: 2021 | return "" 2022 | offset = self.m_typeIdsOffset + typeid * struct.calcsize("I") 2023 | descriptor_idx, = struct.unpack_from("I",self.m_content,offset) 2024 | return self.string_table[descriptor_idx] 2025 | 2026 | def getprotoname(self,protoid): 2027 | if protoid >= self.m_protoIdsSize: 2028 | return "" 2029 | offset = self.m_protoIdsOffset + protoid * struct.calcsize("3I") 2030 | shorty_idx,return_type_idx,parameters_off, = struct.unpack_from("3I",self.m_content,offset) 2031 | return self.string_table[shorty_idx] 2032 | def getprotofullname(self,protoid,classname,func_name): 2033 | if protoid >= self.m_protoIdsSize: 2034 | return "" 2035 | offset = self.m_protoIdsOffset + protoid * struct.calcsize("3I") 2036 | shorty_idx,return_type_idx,parameters_off, = struct.unpack_from("3I",self.m_content,offset) 2037 | retname = self.gettypename(return_type_idx) 2038 | retname = shorty_decode(retname) 2039 | retstr = retname+" " 2040 | if len(classname)==0: 2041 | retstr += "%s("%func_name 2042 | else: 2043 | retstr += "%s::%s("%(classname,func_name) 2044 | if parameters_off != 0: 2045 | offset = parameters_off 2046 | size, = struct.unpack_from("I",self.m_content,offset) 2047 | offset += struct.calcsize("I") 2048 | n = 0 2049 | for i in xrange(0,size): 2050 | type_idx, = struct.unpack_from("H",self.m_content,offset) 2051 | offset += struct.calcsize("H") 2052 | arg = self.gettypename(type_idx) 2053 | arg = shorty_decode(arg) 2054 | if n != 0: 2055 | retstr += "," 2056 | retstr+=arg 2057 | n += 1 2058 | retstr += ")" 2059 | return retstr 2060 | def getprotofullname1(self,protoid,classname,parameter_list,func_name): 2061 | index = classname.rfind(".") 2062 | classname = classname[index+1:] 2063 | if protoid >= self.m_protoIdsSize: 2064 | return "" 2065 | offset = self.m_protoIdsOffset + protoid * struct.calcsize("3I") 2066 | shorty_idx,return_type_idx,parameters_off, = struct.unpack_from("3I",self.m_content,offset) 2067 | retname = self.gettypename(return_type_idx) 2068 | retname = shorty_decode(retname) 2069 | index = retname.rfind(".") 2070 | retname = retname[index+1:] 2071 | retstr = retname+" " 2072 | #if len(classname)==0: 2073 | retstr += "%s("%func_name 2074 | #else: 2075 | # retstr += "%s::%s("%(classname,func_name) 2076 | param_count = len(parameter_list) 2077 | if parameters_off != 0: 2078 | offset = parameters_off 2079 | size, = struct.unpack_from("I",self.m_content,offset) 2080 | offset += struct.calcsize("I") 2081 | n = 0 2082 | for i in xrange(0,size): 2083 | type_idx, = struct.unpack_from("H",self.m_content,offset) 2084 | offset += struct.calcsize("H") 2085 | arg = self.gettypename(type_idx) 2086 | arg = shorty_decode(arg) 2087 | if n != 0: 2088 | retstr += "," 2089 | index = arg.rfind(".") 2090 | arg = arg[index+1:] 2091 | retstr+=arg 2092 | if i < param_count: 2093 | retstr += " " 2094 | retstr += parameter_list[i] 2095 | n += 1 2096 | retstr += ")" 2097 | return retstr 2098 | def getclassmethod_count(self,classid): 2099 | if classid >= self.m_classDefSize: 2100 | return "" 2101 | offset = self.m_classDefOffset + classid * struct.calcsize("8I") 2102 | class_idx,access_flags,superclass_idx,interfaces_off,source_file_idx,annotations_off,class_data_off,static_values_off,= struct.unpack_from("8I",self.m_content,offset) 2103 | if class_data_off: 2104 | offset = class_data_off 2105 | n,static_fields_size = get_uleb128(self.m_content[offset:]) 2106 | offset += n 2107 | n,instance_fields_size = get_uleb128(self.m_content[offset:]) 2108 | offset += n 2109 | n,direct_methods_size = get_uleb128(self.m_content[offset:]) 2110 | offset += n 2111 | n,virtual_methods_size = get_uleb128(self.m_content[offset:]) 2112 | offset += n 2113 | return static_fields_size + instance_fields_size 2114 | return 0 2115 | def getclassmethod(classid,method_idx): 2116 | count = 0 2117 | if classid >= self.m_classDefSize: 2118 | return "" 2119 | offset = self.m_classDefOffset + classid * struct.calcsize("8I") 2120 | class_idx,access_flags,superclass_idx,interfaces_off,source_file_idx,annotations_off,class_data_off,static_values_off,= struct.unpack_from("8I",self.m_content,offset) 2121 | if class_data_off: 2122 | offset = class_data_off 2123 | n,static_fields_size = get_uleb128(self.m_content[offset:]) 2124 | offset += n 2125 | n,instance_fields_size = get_uleb128(self.m_content[offset:]) 2126 | offset += n 2127 | n,direct_methods_size = get_uleb128(self.m_content[offset:]) 2128 | offset += n 2129 | n,virtual_methods_size = get_uleb128(self.m_content[offset:]) 2130 | offset += n 2131 | count = direct_methods_size + virtual_methods_size 2132 | if method_idx >= count: 2133 | return "" 2134 | ncount = static_fields_size + instance_fields_size 2135 | ncount *= 2 2136 | for i in xrange(0,ncount): 2137 | n,tmp = get_uleb128(self.m_content[offset:]) 2138 | offset += n 2139 | ncount *= 3 2140 | for i in xrange(0,ncount): 2141 | n,tmp = get_uleb128(self.m_content[offset:]) 2142 | offset += n 2143 | n,method_idx_diff= get_uleb128(self.m_content[offset:]) 2144 | offset += n 2145 | n,access_flags = get_uleb128(self.m_content[offset:]) 2146 | offset += n 2147 | n,code_off = get_uleb128(self.m_content[offset:]) 2148 | 2149 | 2150 | def getclassname(self,classid): 2151 | if classid >= self.m_classDefSize: 2152 | return "" 2153 | offset = self.m_classDefOffset + classid * struct.calcsize("8I") 2154 | class_idx,access_flags,superclass_idx,interfaces_off,source_file_idx,annotations_off,class_data_off,static_values_off,= struct.unpack_from("8I",self.m_content,offset) 2155 | return self.gettypename(class_idx) 2156 | 2157 | def init_optheader(self,content): 2158 | offset = 0 2159 | format = "4s" 2160 | self.m_magic, = struct.unpack_from(format,content,offset) 2161 | format = "I" 2162 | offset += struct.calcsize(format) 2163 | self.m_version, = struct.unpack_from(format,content,offset) 2164 | offset += struct.calcsize(format) 2165 | self.m_dexOffset, = struct.unpack_from(format,content,offset) 2166 | offset += struct.calcsize(format) 2167 | self.m_dexLength, = struct.unpack_from(format,content,offset) 2168 | offset += struct.calcsize(format) 2169 | self.m_depsOffset, = struct.unpack_from(format,content,offset) 2170 | offset += struct.calcsize(format) 2171 | self.m_depsLength, = struct.unpack_from(format,content,offset) 2172 | offset += struct.calcsize(format) 2173 | self.m_optOffset, = struct.unpack_from(format,content,offset) 2174 | offset += struct.calcsize(format) 2175 | self.m_optLength, = struct.unpack_from(format,content,offset) 2176 | offset += struct.calcsize(format) 2177 | self.m_flags, = struct.unpack_from(format,content,offset) 2178 | offset += struct.calcsize(format) 2179 | self.m_checksum, = struct.unpack_from(format,content,offset) 2180 | 2181 | def init_header(self,content,offset): 2182 | 2183 | format = "4s" 2184 | self.m_magic, = struct.unpack_from(format,content,offset) 2185 | format = "I" 2186 | offset += struct.calcsize(format) 2187 | self.m_version, = struct.unpack_from(format,content,offset) 2188 | offset += struct.calcsize(format) 2189 | self.m_checksum, = struct.unpack_from(format,content,offset) 2190 | format = "20s" 2191 | offset += struct.calcsize(format) 2192 | self.m_signature, = struct.unpack_from(format,content,offset) 2193 | format = "I" 2194 | offset += struct.calcsize(format) 2195 | self.m_fileSize, = struct.unpack_from(format,content,offset) 2196 | offset += struct.calcsize(format) 2197 | self.m_headerSize, = struct.unpack_from(format,content,offset) 2198 | offset += struct.calcsize(format) 2199 | self.m_endianTag, = struct.unpack_from(format,content,offset) 2200 | offset += struct.calcsize(format) 2201 | self.m_linkSize, = struct.unpack_from(format,content,offset) 2202 | offset += struct.calcsize(format) 2203 | self.m_linkOff, = struct.unpack_from(format,content,offset) 2204 | offset += struct.calcsize(format) 2205 | self.m_mapOffset, = struct.unpack_from(format,content,offset) 2206 | offset += struct.calcsize(format) 2207 | self.m_stringIdsSize, = struct.unpack_from(format,content,offset) 2208 | offset += struct.calcsize(format) 2209 | self.m_stringIdsOff, = struct.unpack_from(format,content,offset) 2210 | offset += struct.calcsize(format) 2211 | self.m_typeIdsSize, = struct.unpack_from(format,content,offset) 2212 | offset += struct.calcsize(format) 2213 | self.m_typeIdsOffset, = struct.unpack_from(format,content,offset) 2214 | offset += struct.calcsize(format) 2215 | self.m_protoIdsSize, = struct.unpack_from(format,content,offset) 2216 | offset += struct.calcsize(format) 2217 | self.m_protoIdsOffset, = struct.unpack_from(format,content,offset) 2218 | offset += struct.calcsize(format) 2219 | self.m_fieldIdsSize, = struct.unpack_from(format,content,offset) 2220 | offset += struct.calcsize(format) 2221 | self.m_fieldIdsOffset, = struct.unpack_from(format,content,offset) 2222 | offset += struct.calcsize(format) 2223 | self.m_methodIdsSize, = struct.unpack_from(format,content,offset) 2224 | offset += struct.calcsize(format) 2225 | self.m_methodIdsOffset, = struct.unpack_from(format,content,offset) 2226 | offset += struct.calcsize(format) 2227 | self.m_classDefSize, = struct.unpack_from(format,content,offset) 2228 | offset += struct.calcsize(format) 2229 | self.m_classDefOffset, = struct.unpack_from(format,content,offset) 2230 | offset += struct.calcsize(format) 2231 | self.m_dataSize, = struct.unpack_from(format,content,offset) 2232 | offset += struct.calcsize(format) 2233 | self.m_dataOff, = struct.unpack_from(format,content,offset) 2234 | def gettypenamebyid(self,typeid): 2235 | if typeid >= self.m_typeIdsSize: 2236 | return "" 2237 | offset = self.m_typeIdsOffset + typeid * struct.calcsize("I") 2238 | descriptor_idx, = struct.unpack_from("I",self.m_content,offset) 2239 | return self.string_table[descriptor_idx] 2240 | def get_access_flags(self,flags): 2241 | val = {1:"public", 2242 | 2:"private", 2243 | 4:"protected", 2244 | 8:"static", 2245 | 0x10:"final", 2246 | 0x20:"synchronized", 2247 | 0x40:"volatile", 2248 | 0x80:"bridge", 2249 | 0x100:"native", 2250 | 0x200:"interface", 2251 | 0x400:"abstract", 2252 | 0x800:"strict", 2253 | 0x1000:"synthetic", 2254 | 0x2000:"annotation", 2255 | 0x4000:"enum", 2256 | 0x8000:"unused", 2257 | 0x10000:"constructor", 2258 | 0x20000:"declared_synchronized" 2259 | } 2260 | value = "" 2261 | i = 0 2262 | for key in val: 2263 | if key & flags: 2264 | if i != 0: 2265 | value += " " 2266 | value += val[key] 2267 | i+=1 2268 | if i == 0: 2269 | value += "public " 2270 | 2271 | return value 2272 | def get_access_flags1(self,flags): 2273 | val = {1:"public", 2274 | 2:"private", 2275 | 4:"protected" 2276 | } 2277 | value = "" 2278 | i = 0 2279 | for key in val: 2280 | if key & flags: 2281 | if i != 0: 2282 | value += " " 2283 | value += val[key] 2284 | i+=1 2285 | if i == 0: 2286 | value += "public" 2287 | flags = 1 2288 | 2289 | return value+":",flags 2290 | import getopt 2291 | def init(): 2292 | global filename 2293 | global insfilename 2294 | try: 2295 | opts, args = getopt.getopt(sys.argv[1:], "h:d:i:", ["dumpdexfile=", "insfile="]) 2296 | except getopt.GetoptError: 2297 | print 'Fart.py -d -i ' 2298 | sys.exit(2) 2299 | if len(opts)<=0: 2300 | print 'Fart.py -d -i ' 2301 | sys.exit() 2302 | for opt, arg in opts: 2303 | if opt in ("-h", "--help"): 2304 | print 'Fart.py -d -i ' 2305 | sys.exit() 2306 | if opt in ("-d", "--dumpdexfile"): 2307 | filename = arg 2308 | elif opt in ("-i", "--insfile"): 2309 | insfilename = arg 2310 | print 'dumpdex file:', filename 2311 | print 'ins file:', insfilename 2312 | def main(): 2313 | dex = dex_parser(filename) 2314 | if __name__ == "__main__": 2315 | init() 2316 | methodTable.clear() 2317 | parseinsfile() 2318 | print "methodTable length:" + str(len(methodTable)) 2319 | main() 2320 | -------------------------------------------------------------------------------- /frida_fart.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanbinglengyue/FART/50d49f97850e2ff95e9715c6c63699c9566cd6e6/frida_fart.zip --------------------------------------------------------------------------------