
    u%jzS                         d dl Z d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ ddlmZ  e j                  d      Z G d	 d
e      Zy)    N)unpack)bytecode)StringBlock)public   )
ARSCHeaderzpyaxmlparser.axmlparserc                       e Zd ZdZd Zd Zd Zd ZeZd Z	e
d        Ze
d        Ze
d	        Ze
d
        Ze
d        Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zy)
AXMLParseran  
    AXMLParser reads through all chunks in the AXML file
    and implements a state machine to return information about
    the current chunk, which can then be read by :class:`~AXMLPrinter`.

    An AXML file is a file which contains multiple chunks of data, defined
    by the `ResChunk_header`.
    There is no real file magic but as the size of the first header is fixed
    and the `type` of the `ResChunk_header` is set to `RES_XML_TYPE`, a file
    will usually start with `0x03000800`.
    But there are several examples where the `type` is set to something
    else, probably in order to fool parsers.

    Typically the AXMLParser is used in a loop which terminates if `m_event` is set to `END_DOCUMENT`.
    You can use the `next()` function to get the next chunk.
    Note that not all chunk types are yielded from the iterator! Some chunks are processed in
    the AXMLParser only.
    The parser will set `is_valid()` to False if it parses something not valid.
    Messages what is wrong are logged.

    See http://androidxref.com/9.0.0_r3/xref/frameworks/base/libs/androidfw/include/androidfw/ResourceTypes.h#563
    c                    | j                          d| _        d| _        t        j                  |      | _        | j
                  j                         dk  rDt        j                  dj                  | j
                  j                                      d| _        y | j
                  j                         dkD  rDt        j                  dj                  | j
                  j                                      d| _        y 	 t        | j
                        }|j                  | _        |j                  dk(  rt        j                  d	       |j                  dk7  r6t        j                  d
j                  |j                               d| _        y | j                  | j
                  j                         kD  rOt        j                  dj                  | j                  | j
                  j                                      d| _        y | j                  | j
                  j                         k  rNd| _        t        j                  dj                  | j                  | j
                  j                                      |j                  t         j"                  k7  r5d| _        t        j                  dj                  |j                               	 t        | j
                        }|j                  dk7  r6t        j                  dj                  |j                               d| _        y |j                  t         j$                  k7  r6t        j                  dj                  |j                               d| _        y t'        | j
                  |      | _        g | _        g | _        y # t        $ r'}t        j                  d|       d| _        Y d }~y d }~ww xY w# t        $ r'}t        j                  d|       d| _        Y d }~y d }~ww xY w)NTF   z;Filesize is too small to be a valid AXML file! Filesize: {}    z;Filesize is too large to be a valid AXML file! Filesize: {}z'Error parsing first resource header: %sixm  z?Header size is 28024! Are you trying to parse a plain XML file?zTThis does not look like an AXML file. header size does not equal 8! header size = {}zZThis does not look like an AXML file. Declared filesize does not match real size: {} vs {}z|Declared filesize ({}) is smaller than total file size ({}). Was something appended to the file? Trying to parse it anyways.zAXML file has an unusual resource type! Malware likes to to such stuff to anti androguard! But we try to parse it anyways. Resource Type: 0x{:04x}z0Error parsing resource header of string pool: %s   zbThis does not look like an AXML file. String chunk header size does not equal 28! header size = {}z?Expected String Pool header, got resource type 0x{:04x} instead)_reset_validaxml_tamperedr   
BuffHandlebuffsizelogerrorformatr   AssertionErrorfilesizeheader_sizewarningtypeconstRES_XML_TYPERES_STRING_POOL_TYPEr   sbm_resourceIDs
namespaces)selfraw_buffaxml_headereheaders        e/home/ubuntu/.local/share/pipx/venvs/gplaycli/lib/python3.12/site-packages/pyaxmlparser/axmlparser.py__init__zAXMLParser.__init__5   s+   "''1	 99>>aIISZZ[_[d[d[i[i[klmDK 99>>j(IISZZ[_[d[d[i[i[klmDK	$TYY/K $((""e+ KKYZ""a'IIAAG++B  DK==499>>++IIGGMvMM499>>#3H  DK==499>>++!%DKKRRXRXMM499>>#3S u111!%DKK* +1&1A1A*B				*F %II;;A6&&<  DK;;%444II &-  DKdii0   k  	II?CDK	p  	IIH!LDK	s0   <N  	O  	O)OO	PO>>Pc                     | j                   S )z
        Get the state of the AXMLPrinter.
        if an error happend somewhere in the process of parsing the file,
        this flag is set to False.
        )r   r#   s    r(   is_validzAXMLParser.is_valid   s     {{    c                 t    d| _         d| _        d| _        d| _        g | _        d| _        d| _        d| _        y )N)m_eventm_lineNumberm_namem_namespaceUrim_attributesm_idAttributem_classAttributem_styleAttributer+   s    r(   r   zAXMLParser._reset   s@      " "r-   c                 :    | j                          | j                  S )N)_do_nextr0   r+   s    r(   __next__zAXMLParser.__next__   s    ||r-   c           	         | j                   t        j                  k(  ry | j                          | j                  r| j
                  j                         s'| j
                  j                         | j                  k(  rt        j                  | _         y 	 t        | j
                        }|j                  t        j                  k(  rt        j                  d       |j                   dk  s|j                   dz  dk7  rt        j                  d       d| _        y t#        |j                   |j$                  z
  dz        D ]C  }| j&                  j)                  t+        d| j
                  j-                  d            d          E W|j                  t        j.                  k  s|j                  t        j0                  kD  r`t        j                  d	j3                  |j                  |j                                | j
                  j5                  |j                         |j$                  d
k7  rkt        j                  dj3                  |j                  |j$                  |j                                | j
                  j7                  |j                         kt+        d| j
                  j-                  d            \  | _        t+        d| j
                  j-                  d            \  | _        | j:                  dk7  rg|j                  t        j<                  t        j>                  fv r;t        jA                  dj3                  | jB                  | j:                                  |j                  t        j<                  k(  rt+        d| j
                  j-                  d            \  }t+        d| j
                  j-                  d            \  }| jB                  |   }| jB                  |   }t        j                  dj3                  ||||             |dk(  r$t        jA                  dj3                  |             ||f| jD                  v r%t        jG                  dj3                  ||             | jD                  j)                  ||f       g|j                  t        j>                  k(  rt+        d| j
                  j-                  d            \  }t+        d| j
                  j-                  d            \  }||f| jD                  v r| jD                  jI                  ||f       n%t        jA                  dj3                  ||             '|j                  t        jJ                  k(  rt+        d| j
                  j-                  d            \  | _&        t+        d| j
                  j-                  d            \  | _'        | j
                  j-                  d      }t+        d| j
                  j-                  d            \  }	t+        d| j
                  j-                  d            \  | _(        |	d
z	  dz
  | _)        |	dz  | _*        | jP                  d
z	  dz
  | _+        | jP                  dz  dz
  | _(        t#        d| jT                  t        jX                  z        D ]C  }| jZ                  j)                  t+        d| j
                  j-                  d            d          E t#        t        j\                  t_        | jZ                        t        jX                        D ]!  }| jZ                  |   dz	  | jZ                  |<   # t        j`                  | _         y |j                  t        jb                  k(  rnt+        d| j
                  j-                  d            \  | _&        t+        d| j
                  j-                  d            \  | _'        t        jd                  | _         y |j                  t        jf                  k(  rt+        d| j
                  j-                  d            \  | _'        t+        d| j
                  j-                  d            \  }
}}}t        j                  dj3                  | jN                  |
|||             t        jh                  | _         y t        jA                  dj3                  |j                  |j                                | j
                  j5                  |j                         | j                  ry y # t        $ r'}t        j                  d|       d| _        Y d }~y d }~ww xY w)Nz!Error parsing resource header: %sFzAXML contains a RESOURCE MAPr      r   z,Invalid chunk size in chunk XML_RESOURCE_MAPz<Lz:Not a XML resource chunk type: 0x{:04x}. Skipping {} bytes   zuXML Resource Type Chunk header size does not match 16! At chunk type 0x{:04x}, declared header size={}, chunk size={}r   z*Unhandled Comment at namespace chunk: '{}'z<Start of Namespace mapping: prefix {}: '{}' --> uri {}: '{}' zDNamespace prefix '{}' resolves to empty URI. This might be a packer.z{Namespace mapping ({}, {}) already seen! This is usually not a problem but could indicate packers or broken AXML compilers.z]Reached a NAMESPACE_END without having the namespace stored before? Prefix ID: {}, URI ID: {}r   i     z<HBBLzYfound a CDATA Chunk: index={: 6d}, size={: 4d}, res0={: 4d}, dataType={: 4d}, data={: 4d}z/Unknown XML Chunk: 0x{:04x}, skipping {} bytes.)5r0   r   END_DOCUMENTr   r   r   endget_idxr   r   r   r   r   r   RES_XML_RESOURCE_MAP_TYPEdebugr   ranger   r!   appendr   readRES_XML_FIRST_CHUNK_TYPERES_XML_LAST_CHUNK_TYPEr   set_idxseekr1   m_comment_indexRES_XML_START_NAMESPACE_TYPERES_XML_END_NAMESPACE_TYPEr   r    r"   inforemoveRES_XML_START_ELEMENT_TYPEr3   r2   r6   r5   m_attribute_countr7   ATTRIBUTE_LENGHTr4   ATTRIBUTE_IX_VALUE_TYPElen	START_TAGRES_XML_END_ELEMENT_TYPEEND_TAGRES_XML_CDATA_TYPETEXT)r#   hr&   iprefixuris_prefixs_uri_attributeCountr   res0dataTypedatas                 r(   r9   zAXMLParser._do_next   s   <<5---kkyy}}$))"3"3"5"F$11tyy) vv888		89 66A:!&&1*!2IILM"'DK 61<= RA&&--fT499>>!;L.Ma.PQR  vv666!&&5C`C`:` 		V]]^_^d^dfgflflmn		!!!%%( }}$		$$*F1661==!&&$I
 		quu% "(diinnQ.?!@D %+41B$C!D ##z1aff6644A6 76 HOOGGD0013  vv;;; tyy~~a'89dDIINN1$56776?		006#u1 B;KK !::@&:JL C=DOO3HH<<BF63<OQ &&}5 vv999 tyy~~a'89dDIINN1$56 C=DOO3OO**FC=9KK44:F634G  vv999 (.dDIINN14E'F$#%dDIINN1,=>IINN1%"(tyy~~a/@"A)/diinnQ6G)H&%&4&:a%?")7&)@&)-)>)>")D(I%)-)>)>)G1(L% q$"8"85;Q;Q"QR QA %%,,VD$))..:K-LQ-OPQ u<<c$BSBS>TV[VlVlm FA+/+<+<Q+?2+ED%%a(F  %vv777'-dDIINN14E'F$#%dDIINN1,=>$}}vv111  &dDIINN1,=> .4GTYY^^A=N-O*dHd		3396T444  %zz KKIPPQRQWQWYZY_Y_`aIIaee$C kk " 		=qA#s   d 	eeec                     | j                   dk(  s:| j                  t        j                  k7  r| j                  t        j                  k7  ry| j
                  | j                      S )zA
        Return the String assosciated with the tag name
        r/   r>   )r2   r0   r   rV   rX   r    r+   s    r(   namezAXMLParser.name  sG    
 ;;"!@T\\UZUbUbEbwwt{{##r-   c                 T    | j                   dk(  ry| j                  | j                      S )z
        Return the comment at the current position or None if no comment is given

        This works only for Tags, as the comments of Namespaces are silently dropped.
        Currently, there is no way of retrieving comments of namespaces.
        r   N)rL   r    r+   s    r(   commentzAXMLParser.comment  s*     :-wwt++,,r-   c                     | j                   dk(  s:| j                  t        j                  k7  r| j                  t        j                  k7  ry| j
                  dk(  ry| j                  | j
                     S )zS
        Return the Namespace URI (if any) as a String for the current tag
        r/   r>   r   )r2   r0   r   rV   rX   r3   r    r+   s    r(   	namespacezAXMLParser.namespace  s\    
 ;;"!@T\\UZUbUbEb *,wwt**++r-   c                     t               }t        | j                        D ]B  \  }}| j                  |   }| j                  |   }|dk7  s*|dk7  s0|j	                         ||<   D |S )a  
        Returns the current namespace mapping as a dictionary

        there are several problems with the map and we try to guess a few
        things here:

        1) a URI can be mapped by many prefixes, so it is to decide which one to take
        2) a prefix might map to an empty string (some packers)
        3) uri+prefix mappings might be included several times
        4) prefix might be empty
        r>   )dictsetr"   r    strip)r#   NSMAPkvr_   r`   s         r(   nsmapzAXMLParser.nsmap  sd     ( 	0DAqwwqzHGGAJE{x2~"'++-h	0 r-   c                     | j                   dk(  s| j                  t        j                  k7  ry| j                  | j                      S )zE
        Return the String assosicated with the current text
        r/   r>   )r2   r0   r   rZ   r    r+   s    r(   textzAXMLParser.text  s5    
 ;;"

 :wwt{{##r-   c                     | j                   S )zh
        Legacy only!
        use :py:attr:`~androguard.core.bytecodes.AXMLParser.name` instead
        )rg   r+   s    r(   getNamezAXMLParser.getName      
 yyr-   c                     | j                   S )zh
        Legacy only!
        use :py:attr:`~androguard.core.bytecodes.AXMLParser.text` instead
        )ru   r+   s    r(   getTextzAXMLParser.getText  rx   r-   c                     | j                   S )zm
        Legacy only!
        use :py:attr:`~androguard.core.bytecodes.AXMLParser.namespace` instead
        )rk   r+   s    r(   	getPrefixzAXMLParser.getPrefix  s    
 ~~r-   c                     | j                   t        j                  k7  rt        j	                  d       |t        j
                  z  }|t        | j                        k\  rt        j	                  d       |S )zV
        Return the start inside the m_attributes array for a given attribute
        zCurrent event is not START_TAG.zInvalid attribute index)r0   r   rV   r   r   rS   rU   r4   r#   indexoffsets      r(   _get_attribute_offsetz AXMLParser._get_attribute_offset  sV     <<5??*KK9:///S**++KK12r-   c                 V    | j                   t        j                  k7  ry| j                  S )zY
        Return the number of Attributes for a Tag
        or -1 if not in a tag
        r/   )r0   r   rV   rR   r+   s    r(   getAttributeCountzAXMLParser.getAttributeCount  s#    
 <<5??*%%%r-   c                 h    | j                  |      }| j                  |t        j                  z      }|S )zN
        Returns the numeric ID for the namespace URI of an attribute
        )r   r4   r   ATTRIBUTE_IX_NAMESPACE_URI)r#   r   r   r^   s       r(   getAttributeUrizAXMLParser.getAttributeUri  s4     ++E2)I)I IJ
r-   c                 N    | j                  |      }|dk(  ry| j                  |   S )zE
        Return the Namespace URI (if any) for the attribute
        r   r>   )r   r    )r#   r   r^   s      r(   getAttributeNamespacez AXMLParser.getAttributeNamespace   s/     ""5) *wws|r-   c                 6   | j                  |      }| j                  |t        j                  z      }| j                  |   }|sV| j
                  |   }|t        j                  d   d   v rdt        j                  d   d   |   z   }|S dj                  |      }|S )zH
        Returns the String which represents the attribute name
        
attributesinversezandroid:z'android:UNKNOWN_SYSTEM_ATTRIBUTE_{:08x})	r   r4   r   ATTRIBUTE_IX_NAMEr    r!   r   SYSTEM_RESOURCESr   )r#   r   r   rg   resattrs         r(   getAttributeNamezAXMLParser.getAttributeName  s     ++E2  %*A*A!ABggdm%%d+Dv..|<YGG 6#:#:<#H#STX#YY 
 @FFtL
r-   c                 d    | j                  |      }| j                  |t        j                  z      S )zs
        Return the type of the attribute at the given index

        :param index: index of the attribute
        )r   r4   r   rT   r~   s      r(   getAttributeValueTypez AXMLParser.getAttributeValueType   0     ++E2  %*G*G!GHHr-   c                 d    | j                  |      }| j                  |t        j                  z      S )zs
        Return the data of the attribute at the given index

        :param index: index of the attribute
        )r   r4   r   ATTRIBUTE_IX_VALUE_DATAr~   s      r(   getAttributeValueDataz AXMLParser.getAttributeValueData)  r   r-   c                     | j                  |      }| j                  |t        j                  z      }|t        j                  k(  r/| j                  |t        j
                  z      }| j                  |   S y)a	  
        This function is only used to look up strings
        All other work is done by
        :func:`~androguard.core.bytecodes.axml.format_value`
        # FIXME should unite those functions
        :param index: index of the attribute
        :return:
        r>   )r   r4   r   rT   TYPE_STRINGATTRIBUTE_IX_VALUE_STRINGr    )r#   r   r   	valueTypevalueStrings        r(   getAttributeValuezAXMLParser.getAttributeValue2  sj     ++E2%%fu/L/L&LM	)))++FU5T5T,TUK77;''r-   N)__name__
__module____qualname____doc__r)   r,   r   r:   nextr9   propertyrg   ri   rk   rs   ru   rw   rz   r|   r   r   r   r   r   r   r   r    r-   r(   r
   r
      s    ,kZ# DF%P $ $ 
- 
- , ,  2 $ $&
(IIr-   r
   )loggingstructr   pyaxmlparser.constants	constantsr   pyaxmlparserr   pyaxmlparser.stringblockr   pyaxmlparser.resourcesr   arscutilr   	getLoggerr   objectr
   r   r-   r(   <module>r      s=   $   & ! 0 )  g12b br-   