88
99import pkg_resources
1010import rzpipe
11+ import r2pipe
1112
1213# Resource Types Definition
1314# Please reference to
@@ -84,7 +85,7 @@ class AxmlReader(object):
8485 A Class that parses the Android XML file
8586 """
8687
87- def __init__ (self , file_path , structure_path = None ):
88+ def __init__ (self , file_path , core_library = "rizin" , structure_path = None ):
8889 if structure_path is None :
8990 structure_path = pkg_resources .resource_filename (
9091 "quark.core.axmlreader" , "axml_definition"
@@ -96,10 +97,13 @@ def __init__(self, file_path, structure_path=None):
9697 f" of Rizin in { structure_path } "
9798 )
9899
99- self ._rz = rzpipe .open (file_path )
100- self ._rz .cmd (f"pfo { structure_path } " )
100+ if core_library == "rizin" :
101+ self ._core = rzpipe .open (file_path )
102+ else :
103+ self ._core = r2pipe .open (file_path )
104+ self ._core .cmd (f"pfo { structure_path } " )
101105
102- self ._file_size = int (self ._rz .cmd ("i~size[1]" ), 16 )
106+ self ._file_size = int (self ._core .cmd ("i~size[1]" ), 16 )
103107 self ._ptr = 0
104108
105109 self ._cache = {}
@@ -110,7 +114,7 @@ def __init__(self, file_path, structure_path=None):
110114 raise AxmlException ("Filesize exceeds theoretical lower bound." )
111115
112116 # File Header
113- header = self ._rz .cmdj ("pfj axml_ResChunk_header @ 0x0" )
117+ header = self ._core .cmdj ("pfj axml_ResChunk_header @ 0x0" )
114118
115119 self ._data_type = header [0 ]["value" ]
116120 self ._axml_size = header [2 ]["value" ]
@@ -133,7 +137,7 @@ def __init__(self, file_path, structure_path=None):
133137 return
134138
135139 # String Pool
136- string_pool_header = self ._rz .cmdj ("pfj axml_ResStringPool_header @ 8" )
140+ string_pool_header = self ._core .cmdj ("pfj axml_ResStringPool_header @ 8" )
137141
138142 string_pool_size = string_pool_header [0 ]["value" ][2 ]["value" ]
139143
@@ -163,18 +167,18 @@ def __init__(self, file_path, structure_path=None):
163167 self ._stringCount = string_pool_header [1 ]["value" ]
164168 stringStart = string_pool_header [4 ]["value" ]
165169
166- self ._rz .cmd (f"f string_pool_header @ 0x8 " )
170+ self ._core .cmd (f"f string_pool_header @ 0x8 " )
167171 string_pool_index = header_size + self ._ptr
168- self ._rz .cmd (f"f string_pool_index @ { string_pool_index } " )
172+ self ._core .cmd (f"f string_pool_index @ { string_pool_index } " )
169173 string_pool_data = stringStart + self ._ptr
170- self ._rz .cmd (f"f string_pool_data @ { string_pool_data } " )
174+ self ._core .cmd (f"f string_pool_data @ { string_pool_data } " )
171175
172176 self ._ptr += string_pool_size
173177 if self ._ptr >= self ._axml_size :
174178 return
175179
176180 # Resource Map (Optional)
177- header = self ._rz .cmdj (f"pfj axml_ResChunk_header @ { self ._ptr } " )
181+ header = self ._core .cmdj (f"pfj axml_ResChunk_header @ { self ._ptr } " )
178182
179183 header_type = header [0 ]["value" ]
180184 if header_type == RES_XML_RESOURCE_MAP_TYPE :
@@ -201,7 +205,7 @@ def __iter__(self) -> Iterator[ResChunkHeader]:
201205 :yield: header of a resource chunk defined in the binary
202206 """
203207 while self ._axml_size - self ._ptr >= 16 :
204- header = self ._rz .cmdj (f"pfj axml_ResXMLTree_node @ { self ._ptr } " )
208+ header = self ._core .cmdj (f"pfj axml_ResXMLTree_node @ { self ._ptr } " )
205209
206210 node_type = header [0 ]["value" ][0 ]["value" ]
207211 header_size = header [0 ]["value" ][1 ]["value" ]
@@ -224,7 +228,7 @@ def __iter__(self) -> Iterator[ResChunkHeader]:
224228 chunk = {"Address" : self ._ptr , "Type" : node_type }
225229
226230 if node_type == RES_XML_START_ELEMENT_TYPE :
227- ext = self ._rz .cmdj (
231+ ext = self ._core .cmdj (
228232 f"pfj axml_ResXMLTree_attrExt @ { ext_ptr } "
229233 )
230234
@@ -235,7 +239,7 @@ def __iter__(self) -> Iterator[ResChunkHeader]:
235239 # node['AttrCount'] = ext[4]['value']
236240
237241 elif node_type == RES_XML_END_ELEMENT_TYPE :
238- ext = self ._rz .cmdj (
242+ ext = self ._core .cmdj (
239243 f"pfj axml_ResXMLTree_endElementExt @ { ext_ptr } "
240244 )
241245
@@ -246,15 +250,15 @@ def __iter__(self) -> Iterator[ResChunkHeader]:
246250 RES_XML_START_NAMESPACE_TYPE ,
247251 RES_XML_END_NAMESPACE_TYPE ,
248252 ]:
249- ext = self ._rz .cmdj (
253+ ext = self ._core .cmdj (
250254 f"pfj axml_ResXMLTree_namespaceExt @ { ext_ptr } "
251255 )
252256
253257 chunk ["Prefix" ] = ext [0 ]["value" ][0 ]["value" ]
254258 chunk ["Uri" ] = ext [1 ]["value" ][0 ]["value" ]
255259
256260 elif node_type == RES_XML_CDATA_TYPE :
257- ext = self ._rz .cmdj (
261+ ext = self ._core .cmdj (
258262 f"pfj axml_ResXMLTree_cdataExt @ { ext_ptr } "
259263 )
260264
@@ -281,7 +285,7 @@ def get_string(self, index):
281285 if index < 0 or index >= self ._stringCount :
282286 return None
283287
284- return self ._rz .cmdj (
288+ return self ._core .cmdj (
285289 f"pfj Z @ string_pool_data + `pfv n4 "
286290 f"@ string_pool_index+ { index } *4` + 2"
287291 )[0 ]["string" ]
@@ -296,14 +300,14 @@ def get_attributes(self, chunk: ResChunkHeader) -> List[ResValue]:
296300 return None
297301 extAddress = int (chunk ["Address" ]) + 16
298302
299- attrExt = self ._rz .cmdj (f"pfj axml_ResXMLTree_attrExt @ { extAddress } " )
303+ attrExt = self ._core .cmdj (f"pfj axml_ResXMLTree_attrExt @ { extAddress } " )
300304
301305 attrAddress = extAddress + attrExt [2 ]["value" ]
302306 attributeSize = attrExt [3 ]["value" ]
303307 attributeCount = attrExt [4 ]["value" ]
304308 attributes = []
305309 for _ in range (attributeCount ):
306- attr = self ._rz .cmdj (
310+ attr = self ._core .cmdj (
307311 f"pfj axml_ResXMLTree_attribute @ { attrAddress } "
308312 )
309313
@@ -402,6 +406,6 @@ def get_xml_tree(self) -> XMLElementTree:
402406
403407 def __del__ (self ):
404408 try :
405- self ._rz .quit ()
409+ self ._core .quit ()
406410 except BaseException :
407411 pass
0 commit comments