├── .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
--------------------------------------------------------------------------------