
    jyW                       d dl mZ d dlmZ erd dlmZmZ d dlmZ d dl	Z	d dl
Z
d dlmZ d dlmZ d dlmc mZ d dlmc mZ d dlmZmZ d d	lmZ d d
lmZ d dlmZ d dlmZm Z m!Z!m"Z"m#Z# d dl$m%Z%m&Z&m'Z' d dl(m)Z)m*Z* d dl+m,Z, d dl-m.Z.  ej/        e
j0        ddd           d dZ1 G d d          Z2 G d d          Z3 G d d          Z4dS )!    )annotations)TYPE_CHECKING)AnalysisMethodAnalysis)EncodedFieldN)defaultdict)logger)apkdex)analysis)identify_structures)
JSONWriter)build_def_usedead_code_eliminationplace_declarationsregister_propagationsplit_variables)	constructsimplifysplit_if_nodes)Param	ThisParam)Writer)readFilez{time} {level} {message}dadINFO)formatfilterlevelfieldr   returndictc           	        |                                  dd         |                                 |                                 f}d }| j        r| j        j        }t          j        t          |                    }|x|                                 dk    rt          j        |          }nK| j	        dk    r@t          j
        t          j        dt          j        d|                    d                   }|t          j        |                                           t          j        |                                           |dS )N   zLjava/lang/String;Bz<br   )tripletypeflagsexpr)get_class_nameget_nameget_descriptor
init_valuevaluer   dummystrliteral_stringprotoliteral_hex_intstructunpackpackparse_descriptorutilget_access_fieldget_access_flags)r    r'   r*   vals       f/home/ubuntu/.hermes/hermes-agent/venv/lib/python3.11/site-packages/androguard/decompiler/decompile.pyget_field_astr>   ;   s)   qt$F D 
$C))?##%%)===!055##!1M$C(=(=>>qA 
 +E,@,@,B,BCC&u'='='?'?@@	      c                  J    e Zd ZdZddZddd
ZddZddZddZddZ	d Z
dS )DvMethodz
    This is a wrapper around :class:`~androguard.core.analysis.analysis.MethodAnalysis` and
    :class:`~androguard.core.dex.EncodedMethod` inside the decompiler.

    :param androguard.core.analysis.analysis.MethodAnalysis methanalysis:
    methanalysisr   r!   Nonec                ~   |                                 }|| _        t          |                                                                d           | _        |                                | _        |                                | _	        g | _
        t                      | _        d | _        d | _        d | _        t!          j        |                                          | _        |                                }|                    d          d         | _        t!          j        |          | _        |                                | _        |j        j        | _        |                                }|!t;          j        d| j	        | j                   n|j        |j         z
  }d| j        vr<tC          || j                  | j        |<   | j
        "                    |           |dz  }d}| j        D ]P}||z   }| j
        "                    |           tG          ||          | j        |<   |t!          j$        |          z  }Qd S )N)r%   zNo code : %s %sstaticr$   r   ))
get_methodmethodnextget_basic_blocksgetstart_blockr+   cls_namer,   namelparamsr   var_to_namewritergraphastr9   get_access_methodr;   accessr-   splitr(   get_params_typeparams_type
get_tripler'   
exceptionsget_coder	   debugregisters_sizeins_sizer   appendr   get_type_sizeandroguard.corebytecode
method2pngr   )
selfrB   rH   desccodestart	num_paramptypeparamrb   s
             r=   __init__zDvMethod.__init___   s   ((** = = ? ? C C E EtLL--//OO%%	&==
,V-D-D-F-FGG$$&&JJsOOB'	/55''))&1<  <L*DIt}EEEE'$-7Et{***3E4=*I*I '##E***
I) 7 7	)##E****/u*=*= 'T/666				 		r?   FdoASTboolc                   t          j        d| j                   | j        nt          j        d           |r(t	          d|                                           | _        n.t          d|           | _        | j        	                                 dS t          | j        | j        | j                  }|| _        	 t#          || j                  \  }}t'          || j        ||           t)          |||           t+          |||           |D ]6\  }}t-          |t.                    s|                                | j        |<   7t3          || j        ||           ~~t5          |           t7          |           |                                 	 t;          ||                                           	 |r)t	          ||                                           | _        dS t          ||           | _        | j        	                                 dS )a  
        Processes the method and decompile the code.

        There are two modes of operation:

        1) Normal Decompilation to Java Code
        2) Decompilation into an abstract syntax tree (AST)

        The Decompilation is done twice. First, a rough decompilation is created,
        which is then optimized. Second, the optimized version is used to create the final version.

        :param doAST: generate AST instead of Java Code
        zMETHOD : %sNzNative Method.)r	   r\   rN   rL   r   get_astrS   r   rQ   write_methodr   rP   rZ   rR   r9   
create_pngrM   r   rO   r   r   r   
isinstanceintupperr   r   r   compute_rpor   immediate_dominators)rd   rl   rR   use_defsdef_usesvaris          r=   processzDvMethod.process   s    	]DI... #L)*** +%dD1199;;$T400((***F $*D,<doNN
	P +5$,??(t/8DDDeXx888UHh777  	4 	4FCc3'' 4(+		 %5$"2HhGGGh
 	u 		 	E5#=#=#?#?@@@	  	'!%..6688DHHH --DKK$$&&&&&r?   r"   c                    | j         S )aq  
        Returns the AST, if previously was generated by calling :meth:`process` with argument :code:`doAST=True`.

        The AST is a :class:`dict` with the following keys:

        * triple
        * flags
        * ret
        * params
        * comments
        * body

        The actual AST for the method is in the :code:`body`.

        :return: dict
        )rS   rd   s    r=   ro   zDvMethod.get_ast   s    " xr?   c                H    t          |                                            d S Nprint
get_sourcer}   s    r=   show_sourcezDvMethod.show_source        doo     r?   r1   c                <    | j         rt          | j                   S dS )N )rQ   r1   r}   s    r=   r   zDvMethod.get_source   s!    ; 	$t{###rr?   list[tuple]c                F    | j         r| j                                         S g S r   )rQ   str_extr}   s    r=   get_source_extzDvMethod.get_source_ext   s%    ; 	);&&(((	r?   c                    d| j         z  S )Nz<class DvMethod(object): %s>rN   r}   s    r=   __repr__zDvMethod.__repr__   s    -	99r?   N)rB   r   r!   rC   Frl   rm   r!   rC   r!   r"   r!   rC   r!   r1   )r!   r   )__name__
__module____qualname____doc__rk   r{   ro   r   r   r   r    r?   r=   rA   rA   W   s         . . . .`L' L' L' L' L'\   &! ! ! !   
   
: : : : :r?   rA   c                  \    e Zd ZdZddZdd
ZdddZdddZd dZd!dZ	d"dZ
d#dZd ZdS )$DvClassa  
    This is a wrapper for :class:`~androguard.core.bytecodes.dvm.ClassDefItem` inside the decompiler.

    At first, :py:attr:`methods` contains a list of :class:`~androguard.core.dex.EncodedMethod`,
    which are successively replaced by :class:`DvMethod` in the process of decompilation.

    :param androguard.core.dex.ClassDefItem dvclass: the class item
    :param androguard.core.analysis.analysis.Analysis vma: an Analysis object
    dvclassdex.ClassDefItemvmaanalysis.Analysisr!   rC   c                   |                                 }|                    d          dk    r|                    dd          \  }}nd|}}|dd                              dd          | _        |d d         | _        || _        |                                | _        |	                                | _
        g | _        d| _        |                                }d|z  rd	}|d
z  r|d
z  }nd}t          j        |          | _        |d                    | j                  | j        fz  | _        |                                | _        |                                | _        |                                 | _        t1          j        d| j                   t1          j        d           | j        D ]5}t1          j        d|                                | j        |j                   6t1          j        d           d S )N/r   r$   r   .r%   Fi   z%s %si   z%s class %s z
Class : %szMethods added :z%s (%s, %s))r,   findrsplitreplacepackagerN   r   get_methodsmethods
get_fieldsfieldsrf   innerr;   r9   get_access_classrU   join	prototypeget_interfaces
interfacesget_superclassname
superclass	thisclassr	   r\   get_method_idx)rd   r   r   rN   pckgrU   r   meths           r=   rk   zDvClass.__init__  s    !!99S>>AS!,,JD$$T$DABBx''S11"I	**,,((**	
))++6> 	&I~  %%I+F33"chht{&;&;TY%GG!0022!4466 ))++\49---&'''L 	 	DLt2244di    	Rr?   list[dex.EncodedMethod]c                    | j         S r   )r   r}   s    r=   r   zDvClass.get_methods6  s
    |r?   Fnumrs   rl   rm   c                   | j         |         }t          |t                    sRt          | j                            |                    | j         |<   | j         |                             |           d S |                    |           d S )Nrl   )r   rr   rA   r   rG   r{   )rd   r   rl   rH   s       r=   process_methodzDvClass.process_method9  s    c"&(++ 	( ()<)<V)D)D E EDLL%%E%22222NNN'''''r?   c                    t          t          | j                            D ]R}	 |                     ||           # t          $ r+}t          j        d| j        |         |           Y d }~Kd }~ww xY wd S )Nr   zError decompiling method %s: %s)rangelenr   r   	Exceptionr	   warning)rd   rl   rz   es       r=   r{   zDvClass.processA  s    s4<(()) 	 	A##AU#3333   5t|A       	 	s   =
A2!A--A2r"   c                   d | j         D             }g }| j        D ]E}t          |t                    r.|j        r'|                    |                                           Fd| j        v }| j        dd         t          j
        | j                  t          j
        | j                  | j        |t          t          t          j
        | j                            ||dS )Nc                ,    g | ]}t          |          S r   )r>   ).0fs     r=   
<listcomp>z#DvClass.get_ast.<locals>.<listcomp>L  s     888q-""888r?   	interfacer$   r%   )rawnamerN   superr)   isInterfacer   r   r   )r   r   rr   rA   rS   r_   ro   rU   r   r   r8   r   listmapr   )rd   r   r   mr   s        r=   ro   zDvClass.get_astK  s    88DK888 	, 	,A!X&& ,15 ,qyy{{+++!T[0~ad+/??0AA[&J/AA  
 
 	
r?   r1   c           
        g }| j         s$| j        r|                    d| j        z             | j        | j        }}|,|dk    r&|dd                             dd          }|d|z  z  }t          | j                  dk    r*|d	d
                    d | j        D                       z  z  }|                    d|z             | j	        D ]}|
                                }t          j        |                                          }t          j        |                                          }|                    d           |r=|                    d                    |                     |                    d           |                                }|r|j        }	|dk    r>|	r9dt%          |	                              d                              d          z  }	nId}	nF|j        dk    r;t-          t/          j        dt/          j        d|	                    d                   }	|                    d                    |||	                     |                    d                    ||                     | j        D ]>}
t9          |
t:                    r'|                    |
                                           ?|                    d           d                    |          S )Nzpackage %s;
Ljava/lang/Object;r$   r%   r   r   z extends %sr   z implements %s, c                d    g | ]-}t          |d d                             dd                    .S )r$   r%   r   r   )r1   r   )r   ns     r=   r   z&DvClass.get_source.<locals>.<listcomp>k  s6    IIIAQqtW__S#..//IIIr?   z%s {
    r   Stringz"%s"unicode-escapeasciiz""r&   bz{} {} = {};
z{} {};
}
r   )r   r   r_   r   r   r   r   r   r   r   r,   r9   r:   r;   get_typer-   get_init_valuer/   r1   encodedecoder3   hexr5   r6   r7   r   r   rr   rA   r   )rd   sourcer   r   r    rN   rU   f_typer.   r/   rH   s              r=   r   zDvClass.get_source_  s   z 	:dl 	:MM/DL8999 $I
!j4H&H&H#AbD)11#s;;J33It!##)DIIIIIII- -  I 	h*+++[ 	? 	?E>>##D*5+A+A+C+CDDF]5#7#7#9#9::FMM&!!! #chhv..///c"""--//J ?"(X%% % &U):):,* * &//!* !%[C''  c6;sE3J3J K KA NOOEo44VT5IIJJJJj//==>>>>l 	3 	3F&(++ 3f//11222ewwvr?   list[tuple[str, list]]c                   g }| j         s+| j        r$|                    dddd| j        z  fdgf           ddd                    | j                  z  fd	d| j        z  | j        fg}| j        }|S|d
k    rM|dd                             dd          }|                    d           |                    dd|z  f           t          | j	                  dk    r}|                    d           t          | j	                  D ]S\  }}|dk    r|                    d           |                    d|dd                             dd          f           T|                    d           |                    d|f           | j        D ]}|                                fdt          j        D             }t          j        |                                          }|                                }	|rdd                    |          z  }
nd}
d }|                                }|r|j        }|dk    r1|r,d|                    d                              d          z  }n_d}n\|j        dk    r?d t/          t1          j        d!t1          j        d|                    d                   z  }nd t7          |          z  }|r/|                    d"d#|
fd$d|z  fd%d&d|	z  ||fd'|fd(gf           i|                    d"d#|
fd$d|z  fd%d&d|	z  ||fd(gf           | j        D ]@}t;          |t<                    r)|                    d)|                                f           A|                    d*d+gf           |S ),NPACKAGE)PACKAGE_STARTzpackage NAME_PACKAGEz%s)PACKAGE_END;
PROTOTYPE_ACCESSz	%s class r   NAME_PROTOTYPEr   r$   r%   r   r   )EXTENDz	 extends NAME_SUPERCLASSr   )
IMPLEMENTSz implements )COMMAr   NAME_INTERFACE)PROTOTYPE_ENDz {
	PROTOTYPEc                >    g | ]}|z  t           j        |         S r   )r9   ACCESS_FLAGS_FIELDS)r   flagfield_access_flagss     r=   r   z*DvClass.get_source_ext.<locals>.<listcomp>  s=       ,,(.  r?   z    %s r   r   z = "%s"r   r   z = ""r&   z = %sr   FIELDFIELD_ACCESS
FIELD_TYPE)SPACEr   
NAME_FIELDFIELD_VALUE)	FIELD_ENDr   METHOD	CLASS_END)r   r   ) r   r   r_   r   rU   rN   r   r   r   r   	enumerater   r;   r9   r   r   r-   r,   r   r/   r   r   r3   r   r5   r6   r7   r1   r   rr   rA   r   )rd   r   
list_protor   rz   r   r    rU   r   rN   
access_strr/   r.   rH   r   s                 @r=   r   zDvClass.get_source_ext  sI   z 
	dl 
	MM5')<=.	 	 	  sxx/D/D!DEtdi/>

 _
!j4H&H&H#AbD)11#s;;J56660$2CDEEEt!##<=== )$/ : :  966%%o666!!%y2'>'>sC'H'HI    	3444{J/000[ <	 <	E!&!7!7!9!9    4  F
 ]5#7#7#9#9::F>>##D $&&)9)99

#
E--//J 1"(X%% ( )ELL,- - &//!* !([C''#cc6;sE+B+BCCAF' ' EE $c%jj0E +Z8)4&=9*)4$;F*E20
    +Z8)4&=9*)4$;F0	    l 	C 	CF&(++ Cx)>)>)@)@ABBB{%9$:;<<<r?   c                H    t          |                                            d S r   r   r}   s    r=   r   zDvClass.show_source  r   r?   c                    d| j         z  S )Nz<Class(%s)>r   r}   s    r=   r   zDvClass.__repr__  s    ty((r?   N)r   r   r   r   r!   rC   )r!   r   r   )r   rs   rl   rm   r!   rC   r   r   r   )r!   r   r   )r   r   r   r   rk   r   r   r{   ro   r   r   r   r   r   r?   r=   r   r     s         ' ' ' 'R   ( ( ( ( (    
 
 
 
(1 1 1 1fd d d dL! ! ! !) ) ) ) )r?   r   c                  J    e Zd ZdZddZddZddZddZddZddZ	ddZ
dS )	DvMachinea  
    Wrapper class for a Dalvik Object, like a DEX or ODEX file.

    The wrapper allows to take a Dalvik file and get a list of Classes out of it.
    The :class:`~androguard.decompiler.decompile.DvMachine` can take either an APK file directly,
    where all DEX files from the multidex are used, or a single DEX or ODEX file as an argument.

    At first, :py:attr:`classes` contains only :class:`~androguard.core.dex.ClassDefItem` as values.
    Then these objects are replaced by :class:`DvClass` items successively.
    rN   r1   r!   rC   c                   t          j                    | _        t          j        |          }|dk    rVt          j        |                                          D ].}| j                            t          j
        |                     /n|dk    r:| j                            t          j
        t          |                               nR|dk    r:| j                            t          j        t          |                               nt          d|z            d | j                                        D             | _        dS )z0

        :param name: filename to load
        APKDEXDEYz'Format not recognised for filename '%s'c                L    i | ]!}|j                                         |j         "S r   )
orig_classr,   )r   r   s     r=   
<dictcomp>z&DvMachine.__init__.<locals>.<dictcomp>  s<     
 
 
 ''))7+=
 
 
r?   N)r   r   r   	androconf
is_androidr
   r  get_all_dexaddr   r  r   ODEX
ValueErrorget_classesclasses)rd   rN   ftypeds       r=   rk   zDvMachine.__init__  s   
 $&& $T**E>>WT]]..00 ) )SWQZZ(((()e^^HLL$001111e^^HLL(4..112222FMNNN
 
8//11
 
 
r?   	list[str]c                N    t          | j                                                  S )z
        Return a list of classnames contained in this machine.
        The format of each name is Lxxx;

        :return: list of class names
        )r   r  keysr}   s    r=   r  zDvMachine.get_classes%  s      DL%%''(((r?   
class_namer   c                    | j                                         D ]E\  }}||v r<t          |t                    r|c S t          || j                  x}| j         |<   |c S FdS )a`  
        Return the :class:`DvClass` with the given name

        The name is partially matched against the known class names and the first result is returned.
        For example, the input `foobar` will match on Lfoobar/bla/foo;

        :param str class_name:
        :return: the class matching on the name
        :rtype: :class:`DvClass`
        N)r  itemsrr   r   r   )rd   r  rN   klassr   s        r=   	get_classzDvMachine.get_class.  s      <--// 	 	KD%T!!eW-- ! LLL/6udh/G/GG$,t,	 "	 	r?   c                (   | j                                         D ]w\  }}t          j        d|           t	          |t
                    r|                                 Dt          || j                  x}| j         |<   |                                 xdS )z
        Process all classes inside the machine.

        This calls :meth:`~androgaurd.decompiler.decompile.DvClass.process` on each :class:`DvClass`.
        Processing class: %sN)r  r  r	   r\   rr   r   r{   r   )rd   rN   r  r   s       r=   r{   zDvMachine.processA  s      <--// 	" 	"KD%L/666%)) "/6udh/G/GG$,t,!!!!	" 	"r?   c                f    | j                                         D ]}|                                 dS )z
        Calls `show_source` on all classes inside the machine.
        This prints the source to stdout.

        This calls :meth:`~androgaurd.decompiler.decompile.DvClass.show_source` on each :class:`DvClass`.
        N)r  valuesr   )rd   r  s     r=   r   zDvMachine.show_sourceO  s@     \((** 	  	 E	  	 r?   c                ,   t          | j                                                  D ]l\  }}t          j        d|           t          |t                    st          || j                  }|                                 |	                                 mdS )zO
        Run :meth:`process` and :meth:`show_source` after each other.
        r  N)
sortedr  r  r	   r\   rr   r   r   r{   r   )rd   rN   r  s      r=   process_and_showzDvMachine.process_and_showY  s     "$,"4"4"6"677 	  	 KD%L/666eW-- 1tx00MMOOO	  	 r?   r"   c                R   t                      }t          | j                                                  D ]q\  }}t	          j        d|           t          |t                    st          || j                  }|	                    d           |
                                ||<   r|S )z
        Processes each class with AST enabled and returns a dictionary with all single ASTs
        Classnames as keys.

        :return: an dictionary for all classes
        :rtype: dict
        r  Tr   )r"   r"  r  r  r	   r\   rr   r   r   r{   ro   )rd   retrN   clss       r=   ro   zDvMachine.get_astd  s     ff 2 2 4 455 	& 	&ID#L/666c7++ -c48,,KKdK###CII
r?   N)rN   r1   r!   rC   )r!   r  )r  r1   r!   r   r   r   )r   r   r   r   rk   r  r  r{   r   r#  ro   r   r?   r=   r  r    s        	 	
 
 
 
4) ) ) )   &" " " "       	  	  	  	      r?   r  )r    r   r!   r"   )5
__future__r   typingr   !androguard.core.analysis.analysisr   r   androguard.core.dexr   r5   syscollectionsr   logurur	   androguard.core.androconfcorer  androguard.decompiler.util
decompilerr9   ra   r
   r   androguard.core.analysisr   "androguard.decompiler.control_flowr   androguard.decompiler.dastr   androguard.decompiler.dataflowr   r   r   r   r   androguard.decompiler.graphr   r   r   !androguard.decompiler.instructionr   r   androguard.decompiler.writerr   androguard.utilr   r  stderrr>   rA   r   r  r   r?   r=   <module>r;     s  * # " " " " "             1JJJJJJJJ000000  



 # # # # # #       - - - - - - - - - ) ) ) ) ) ) ) ) ) $ $ $ $ $ $ $ $ - - - - - - B B B B B B 1 1 1 1 1 1              L K K K K K K K K K > > > > > > > > / / / / / / $ $ $ $ $ $ 

J1%v      8h: h: h: h: h: h: h: h:Vz) z) z) z) z) z) z) z)zt t t t t t t t t tr?   