
    d6                         d dl Z d dlmZ ddlmZ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 d	dlmZmZmZ  G d de      Z G d de      Z G d de      Z G d dee      Z G d dee      Zy)    N)defaultdict   )ELFHashTableGNUHashTable)SectionSymbol)
ENUM_D_TAG)Segment)RelocationTable   )ELFError)
elf_assertstruct_parseparse_cstring_from_streamc                       e Zd ZdZd Zd Zy)_DynamicStringTablez Bare string table based on values found via ELF dynamic tags and
        loadable segments only.  Good enough for get_string() only.
    c                      || _         || _        y N)_stream_table_offset)selfstreamtable_offsets      6/usr/lib/python3/dist-packages/elftools/elf/dynamic.py__init__z_DynamicStringTable.__init__   s    )    c                 r    t        | j                  | j                  |z         }|r|j                  d      S dS )zI Get the string stored at the given offset in this string table.
        zutf-8 )r   r   r   decode)r   offsetss      r   
get_stringz_DynamicStringTable.get_string   s5     &dllD4F4F4OP$%qxx -2-r   N)__name__
__module____qualname____doc__r   r"    r   r   r   r      s    *.r   r   c                   <    e Zd ZdZ eg d      Zd Zd Zd Zd Z	y)
DynamicTaga   Dynamic Tag object - representing a single dynamic tag entry from a
        dynamic section.

        Allows dictionary-like access to the dynamic structure. For special
        tags (those listed in the _HANDLED_TAGS set below), creates additional
        attributes for convenience. For example, .soname will contain the actual
        value of DT_SONAME (fetched from the dynamic symbol table).
    )	DT_NEEDEDDT_RPATH
DT_RUNPATH	DT_SONAMEDT_SUNW_FILTERc                     |t        d      || _        |j                  | j                  v rLt	        | |j                  dd  j                         |j                  | j                  j                               y y )Nz(Creating DynamicTag without string table   )r   entryd_tag_HANDLED_TAGSsetattrlowerr"   d_val)r   r1   stringtables      r   r   zDynamicTag.__init__1   si    EFF
;;$,,,D%++ab///1**4::+;+;<> -r   c                      | j                   |   S )z/ Implement dict-like access to entries
        )r1   )r   names     r   __getitem__zDynamicTag.__getitem__9   s     zz$r   c                 P    d| j                   j                  d| j                   dS )N<DynamicTag (z): >)r1   r2   )r   s    r   __repr__zDynamicTag.__repr__>   s    *.***:*:DJJGGr   c                    | j                   j                  | j                  v r5dt        | | j                   j                  dd  j	                               z  }nd| j                   j
                  z  }d| j                   j                  d|dS )Nz"%s"r0   z%#xr<   z) r=   )r1   r2   r3   getattrr5   d_ptr)r   r!   s     r   __str__zDynamicTag.__str__A   so    ::t111tzz'7'7';'A'A'CDDA

(((A)-)9)91==r   N)
r#   r$   r%   r&   	frozensetr3   r   r:   r>   rB   r'   r   r   r)   r)   $   s-     	M> 
H>r   r)   c                   J    e Zd ZdZd Zd Zd ZddZddZd Z	d	 Z
d
 Zd Zy)DynamiczA Shared functionality between dynamic sections and segments.
    c                     || _         |j                  | _        || _        |sdnd| _        || _        | j                  j                  j                         | _        || _	        || _
        y)a  
        stream:
            The file-like object from which to load data

        elffile:
            The parent elffile object

        stringtable:
            A stringtable reference to use for parsing string references in
            entries

        position:
            The file offset of the dynamic segment/section

        empty:
            Whether this is a degenerate case with zero entries. Normally, every
            dynamic table will have at least one entry, the DT_NULL terminator.
        r   N)elffilestructs
elfstructsr   	_num_tags_offsetElf_Dynsizeof_tagsize_empty_stringtable)r   r   rH   r7   positionemptys         r   r   zDynamic.__init__L   sZ    & !//#(a//668 (r   c                     d}| j                  |      D ]  }|d   } n d}|r%t        | j                  j                  |      d      }||fS )zH Return the virtual address and file offset of a dynamic table.
        NtyperA   )
_iter_tagsnextrH   address_offsets)r   tag_nameptrtagr    s        r   get_table_offsetzDynamic.get_table_offsetj   s^     ???1 	Cg,C	 $,,66s;TBFF{r   c                    | j                   r| j                   S | j                  d      \  }}|'t        | j                  |      | _         | j                   S | j                  j                  d      | _         | j                   S )z Return a string table for looking up dynamic tag related strings.

            This won't be a "full" string table object, but will at least
            support the get_string() function.
        	DT_STRTABz.dynstr)rQ   r]   r   r   rH   get_section_by_name)r   _r   s      r   _get_stringtablezDynamic._get_stringtablez   sy     $$$
 //<<# 3DLL, OD$$$ !LL<<YG   r   Nc              #      K   | j                   ryt        j                         D ]+  }| j                  |      }||d   |k(  r| |d   dk(  s+ y yw)z; Yield all raw tags (limit to |type| if specified)
        Nr2   DT_NULL)rP   	itertoolscount_get_tag)r   rV   nr\   s       r   rW   zDynamic._iter_tags   sZ      ;;" 	A--"C|s7|t3	7|y(	s   AAAc              #   r   K   | j                  |      D ]  }t        || j                                  yw)z7 Yield all tags (limit to |type| if specified)
        rU   N)rW   r)   rb   )r   rV   r\   s      r   	iter_tagszDynamic.iter_tags   s8      ???- 	;CS$"7"7"9::	;s   57c                     | j                   dk7  r|| j                   k\  rt        |      | j                  || j                  z  z   }t	        | j
                  j                  | j                  |      S )z3 Get the raw tag at index #n from the file
        rG   
stream_pos)rK   
IndexErrorrL   rO   r   rJ   rM   r   )r   rh   r    s      r   rg   zDynamic._get_tag   s`     >>RA$7Q-DMM 11OO##LL 	r   c                 T    t        | j                  |      | j                               S )zC Get the tag at index #n from the file (DynamicTag object)
        )r)   rg   rb   )r   rh   s     r   get_tagzDynamic.get_tag   s#     $--*D,A,A,CDDr   c                     | j                   dk7  r| j                   S t        j                         D ]D  }| j                  |      }|j                  j
                  dk(  s.|dz   | _         | j                   c S  y)zG Number of dynamic tags in the file, including the DT_NULL tag
        rG   rd   r   N)rK   re   rf   rp   r1   r2   )r   rh   r\   s      r   num_tagszDynamic.num_tags   sb     >>R>>!" 	&A,,q/Cyy)+!"Q~~%		&r   c           
         i }t        | j                  d            rt        | j                  | j	                  d      d   t        | j                  d            d   d      |d<   t        | j                  d            d   }t        |d   j                  |k(  d|z         t        | j                  d	            rt        | j                  | j	                  d	      d   t        | j                  d
            d   d      |d<   t        | j                  d            d   }t        |d   j                  |k(  d|z         t        | j                  d            rmt        | j                  | j	                  d      d   t        | j                  d            d   t        | j                  d            d   t        d	   k(        |d<   |S )z Load all available relocation tables from DYNAMIC tags.

            Returns a dictionary mapping found table types (REL, RELA,
            JMPREL) to RelocationTable objects.
        DT_RELr   DT_RELSZr6   FREL	DT_RELENTzExpected DT_RELENT to be %sDT_RELA	DT_RELASZTRELA
DT_RELAENTzExpected DT_RELAENT to be %s	DT_JMPRELDT_PLTRELSZ	DT_PLTRELJMPREL)	listrj   r   rH   r]   rX   r   
entry_sizer	   )r   resultrelentszs      r   get_relocation_tableszDynamic.get_relocation_tables   s    x()+DLL%%h/2T^^J/095BF5M DNN;78AHve}//8;-8: y)*,T\\%%i03T^^K01':DBF6N DNN<89'BHvf~00H<.9; {+,.t||%%k215T^^M23G<T^^K01':j>SS UF8
 r   r   )r#   r$   r%   r&   r   r]   rb   rW   rj   rg   rp   rr   r   r'   r   r   rE   rE   I   s5    (< !,
;	E

&!r   rE   c                       e Zd ZdZd Zy)DynamicSectionzH ELF dynamic table section.  Knows how to process the list of tags.
    c           	          t        j                  | |||       |j                  |d         }t        j                  | | j                  | j
                  || d   | d   dk(         y )Nsh_link	sh_offsetsh_type
SHT_NOBITS)r   r   get_sectionrE   r   rH   )r   headerr9   rH   r7   s        r   r   zDynamicSection.__init__   s]    vtW5))&*;<t{{DLL+tI,>	@r   N)r#   r$   r%   r&   r   r'   r   r   r   r      s    @r   r   c                   .    e Zd ZdZd Zd Zd Zd Zd Zy)DynamicSegmentzH ELF dynamic table segment.  Knows how to process the list of tags.
    c           	      x   d }|j                         D ]4  }t        |t              s|d   |d   k(  s |j                  |d         } n t	        j
                  | ||       t        j                  | |||| d   | d   dk(         | j                  j                  j                         | _
        d | _        d | _        y )Nr   p_offsetr   p_fileszr   )iter_sections
isinstancer   r   r
   r   rE   rJ   Elf_SymrN   _symbol_size_num_symbols_symbol_name_map)r   r   r   rH   r7   sections         r   r   zDynamicSegment.__init__   s     ,,. 	G7N3K(F:,>>%11')2DE		
 	vv.vwT*=M*"	$ OO33::<  $r   c                 v   | j                   | j                   S | j                  d      \  }}|,t        | j                  ||       }|j	                         | _         | j                   B| j                  d      \  }}|,t        | j                  ||       }|j	                         | _         | j                   | j                  d      \  }}||t        d      d}| j                         D ]N  }|d   }	|d   dk(  r/| j                  |d	   k7  rt        d
|d	   | j                  fz        |	|kD  sE|||	kD  sM|	}P |B| j                  j                         D ]%  }
|
d   |k  s||
d   |
d   z   k  s|
d   |
d   z   }' |}||z
  | j                  z  | _         | j                   t        d      | j                   S )zA Number of symbols in the table recovered from DT_SYMTAB
        NDT_GNU_HASHDT_HASH	DT_SYMTAB#Segment does not contain DT_SYMTAB.rA   r2   	DT_SYMENTr6   zDT_SYMENT (%d) != Elf_Sym (%d).p_vaddrr   z&Cannot determine the end of DT_SYMTAB.)
r   r]   r   rH   get_number_of_symbolsr   r   rj   r   iter_segments)r   ra   gnu_hash_offsethash_sectionhash_offsettab_ptr
tab_offsetnearest_ptrr\   tag_ptrsegmentend_ptrs               r   num_symbolszDynamicSegment.num_symbols  s	    ($$$ "22=A?&'otLL , B B DD $!229=NA{&+DLL+tL$0$F$F$H!$ #'"7"7"DGZ*"4DEEK~~' 
*g,w<;.((CL8 ''H(+Gd6G6G'H(I J Jg%$,g0E")K
* "#||99; OG	*g5#	(:WZ=P(PQ&-i&87:;N&NO
 "G!(7!2t7H7H HD$CDD   r   c                     | j                  d      \  }}||t        d      t        | j                  j                  | j
                  ||| j                  z  z         }| j                         }|j                  |d         }t        ||      S )zG Get the symbol at index #index from the table (Symbol object)
        r   r   rl   st_name)
r]   r   r   rJ   r   r   r   rb   r"   r   )r   indexr   r   symbolstring_tablesymbol_names          r   
get_symbolzDynamicSegment.get_symbol:  s     #33K@?j0@AAOO##LL!ED,=,=$==?
 ,,."--fY.?@fk**r   c                 Z   | j                   ]t        t              | _         t        | j	                               D ]-  \  }}| j                   |j
                     j                  |       / | j                   j                  |      }|r|D cg c]  }| j                  |       c}S dS c c}w )za Get a symbol(s) by name. Return None if no symbol by the given name
            exists.
        N)	r   r   r   	enumerateiter_symbolsr9   appendgetr   )r   r9   isymsymnumss        r   get_symbol_by_namez!DynamicSegment.get_symbol_by_nameK  s       ($/$5D!#D$5$5$78 :3%%chh/66q9:''++D18?G4q"4ITI4s   B(c              #   n   K   t        | j                               D ]  }| j                  |        yw)a0   Yield all symbols in this dynamic segment. The symbols are usually
            the same as returned by SymbolTableSection.iter_symbols. However,
            in stripped binaries, SymbolTableSection might have been removed.
            This method reads from the mandatory dynamic tag DT_SYMTAB.
        N)ranger   r   )r   r   s     r   r   zDynamicSegment.iter_symbolsY  s4      t'')* 	&A//!$%	&s   35N)	r#   r$   r%   r&   r   r   r   r   r   r'   r   r   r   r      s"    %(5!n+"J&r   r   )re   collectionsr   hashr   r   sectionsr   r   enumsr	   segmentsr
   
relocationr   common.exceptionsr   common.utilsr   r   r   objectr   r)   rE   r   r   r'   r   r   <module>r      sm     # , %   ' ( N N.& ."> ">JVf Vr@Wg @t&Wg t&r   