
    iG                         S r SSKrSSKrSSKrSSKrSSKrSSKrSSKrSr	\R                  r
Sr " S S\5      rS rS rS	 rg)
zpeutils, Portable Executable utilities module


Copyright (c) 2005-2023 Ero Carrera <ero.carrera@gmail.com>

All rights reserved.
    NzEro Carrerazero.carrera@gmail.comc                       \ rS rSrSrSS jrSS jrSS jr SS jrSS jr	SS	 jr
S
 rSS jrSS jrSS jrSS jrSrg)SignatureDatabase   a  This class loads and keeps a parsed PEiD signature database.

Usage:

    sig_db = SignatureDatabase('/path/to/signature/file')

and/or

    sig_db = SignatureDatabase()
    sig_db.load('/path/to/signature/file')

Signature databases can be combined by performing multiple loads.

The filename parameter can be a URL too. In that case the
signature database will be downloaded from that location.
Nc                    [         R                  " S[         R                  5      U l        [	        5       U l        SU l        [	        5       U l        SU l        [	        5       U l	        SU l
        SU l        U R                  XS9  g )Nzh\[(.*?)\]\s+?signature\s*=\s*(.*?)(\s+\?\?)*\s*ep_only\s*=\s*(\w+)(?:\s*section_start_only\s*=\s*(\w+)|)r   filenamedata)recompileS	parse_sigdictsignature_tree_eponly_truesignature_count_eponly_truesignature_tree_eponly_falsesignature_count_eponly_falsesignature_tree_section_startsignature_count_section_start	max_depth_SignatureDatabase__loadselfr   r	   s      4C:\des-py\RoboSAPF\venv\Lib\site-packages\peutils.py__init__SignatureDatabase.__init__&   sm     vDD
" +/&'+,(+/6(,-),0F)-.* X1    c                    [        5       n[        UR                  5       H  u  pVUR                  U:  a  M  UR                  nSUUS-   [        UR                  5      SR                  UR                   Vs/ s H  o[        R                  ;   d  M  UPM     sn5      4-  n	UR                  U R                  UUU	SSUS95        M     SR                  U5      S-   $ s  snf )zGenerates signatures for all the sections in a PE file.

If the section contains any data a signature will be created
for it. The signature name will be a combination of the
parameter 'name' and the section number and its name.
z%s Section(%d/%d,%s)    FT)ep_onlysection_start_only
sig_length
)list	enumeratesectionsSizeOfRawDataPointerToRawDatalenjoinNamestring	printableappend&_SignatureDatabase__generate_signature)
r   penamer"   section_signaturesidxsectionoffsetcsig_names
             r   generate_section_signatures-SignatureDatabase.generate_section_signaturesH   s     "V%bkk2LC$$z1 --F-aBKK GLLJLq9I9I4ILJK	1 H %%))!'+) * 	 34 yy+,t33 Ks   6CCc                 p    UR                  UR                  R                  5      nU R                  XUSUS9$ )zGenerate signatures for the entry point of a PE file.

Creates a signature whose name will be the parameter 'name'
and the section number and its name.
T)r    r"   )get_offset_from_rvaOPTIONAL_HEADERAddressOfEntryPointr/   )r   r0   r1   r"   r5   s        r   generate_ep_signature'SignatureDatabase.generate_ep_signaturen   sA     ''(:(:(N(NO((dz ) 
 	
r   c           	          UR                   X"U-    nSR                  U Vs/ s H  nS[        U5      -  PM     sn5      n	US:X  a  SnOSnUS:X  a  SnOSnSU< SU	< SU< S	U< S
3	n
U
$ s  snf )N z%02xTtruefalse[z]
signature = z
ep_only = z
section_start_only = r#   )__data__r*   ord)r   r0   r5   r1   r    r!   r"   r	   r6   signature_bytes	signatures              r   __generate_signature&SignatureDatabase.__generate_signature{   s     {{6Z$78((T#BTFSVOT#BCd?GG%!'!( 	
	 ' $Cs   A+c                     U R                  XU5      nU(       a+  US:X  a  U Vs/ s H  oUS   US   S   4PM     sn$ US   S   $ gs  snf )zMatches and returns the exact match(es).

If ep_only is True the result will be a string with
the packer name. Otherwise it will be a list of the
form (file_offset, packer_name) specifying where
in the file the signature was found.
Fr   r   N_SignatureDatabase__match)r   r0   r    r!   matchesmatchs         r   rP   SignatureDatabase.match   s`     ,,r,>?
 % ?FFgUq58B<0gFF1:b>!	 Gs   Ac                 P    U R                  XU5      nU(       a  US:X  a  U$ US   $ g)z+Matches and returns all the likely matches.Fr   NrM   )r   r0   r    r!   rO   s        r   	match_allSignatureDatabase.match_all   s4     ,,r,>?% 1:r   c                 b   USL a?   UR                   nU R                  nUR                   Vs/ s H  owR                  PM     nnOhUSL a7   UR                  5       nU R                  nUR                  R                  n	U	/nO,UR                   nU R                  n[        [        U5      5      n/ n
U H>  nU R                  XdXU R                  -    5      nU(       d  M,  U
R                  X45        M@     USL a  U
(       a  U
S   $ U
$ ! [         a  ne S nAff = fs  snf ! [         a  ne S nAff = f)NTr   )rE   	Exceptionr   r&   r(   get_memory_mapped_imager   r<   r=   r   ranger)   (_SignatureDatabase__match_signature_treer   r.   )r   r0   r    r!   r	   excp
signaturesr4   scan_addresseseprO   r3   results                r   __matchSignatureDatabase.__match   sB    %
{{ ::J GIkkRk766kNRN_
113 88J
 ##77B !TN ;;D99J"3t9-N !C00T^^';<F v}- " d?qz!y   S  s4   D DD 
DDD
D.(D))D.c                    UnS/nUSL a  U R                   nOUSL a  U R                  n/ nU H>  nU R                  WXHXR                  -    5      n	U	(       d  M,  UR	                  X45        M@     USL a  U(       a  US   $ U$ )Nr   T)r   r   rY   r   r.   )
r   	code_datar    r!   r	   r\   r[   rO   r3   r^   s
             r   
match_dataSignatureDatabase.match_data
  s     % ::J
 _ 88J !C00Ds^^';<F v}- " d?qz!r   c           	      R   [        5       nUn[        U Vs/ s H%  n[        U[        5      (       a  UO
[	        U5      PM'     sn5       H  u  pxUc    OUR                  US5      n	S[        UR                  5       5      ;   aW  [        5       n
[        UR                  5       5       H  nUS   b  M  U
R                  US   5        M!     UR                  U
5        SU;   aF  UR                  SS5      nX'S-   S nU(       a&  UR                  U R                  XXs-   S-   5      5        U	nM     Ubt  S[        UR                  5       5      ;   aW  [        5       n
[        UR                  5       5       H  nUS   b  M  U
R                  US   5        M!     UR                  U
5        U$ s  snf )zRecursive function to find matches along the signature tree.

signature_tree  is the part of the tree left to walk
data    is the data being checked against the signature tree
depth   keeps track of how far we have gone down the tree
Nr   r   z??)r$   r%   
isinstanceintrF   getvaluesitemsr.   extendrY   )r   signature_treer	   depthmatched_namesrP   br3   byte
match_nextnamesitemmatch_tree_alternatedata_remainings                 r   __match_signature_tree(SignatureDatabase.__match_signature_tree6  s    
 #QU#VQUAAs););AQ$GQU#VWIC } 4.J tELLN++  !/DAwT!W- 0 $$U+
 u}',yyt'<$!%Agi!!((330#+PQ/ EW X` elln)=!=FEU[[]+7?LLa) ,   'q $Ws   ,F$c                 "    U R                  XS9  g)z^Load a PEiD signature file.

Invoking this method on different files combines the signatures.
r   N)r   r   s      r   loadSignatureDatabase.load~  s     	X1r   c                    Ub  [         R                  R                  U5      (       dA   [        R                  R                  U5      nUR                  5       nUR                  5         O0 [        US5      nUR                  5       nUR                  5         OUnU(       d  g S nU R                  R                  U5      nU GH  u  nnn	n
nU
R                  5       R                  5       n
UR                  SS5      R                  5       nUR                  5        Vs/ s H
  o" U5      PM     nnU
S:X  a  Sn
OSn
US:X  a  SnOSnSnUSL a"  U R                   nU =R"                  S	-  sl        OHU
SL a"  U R$                  nU =R&                  S	-  sl        O!U R(                  nU =R*                  S	-  sl        [-        U5       He  u  nnUS	-   [/        U5      :X  a&  UR1                  U[3        5       5      UU'   S UU   U'   OUR1                  U[3        5       5      UU'   UU   nUS	-  nMg     XR4                  :  d  GMz  Xl        GM     g ! [         a    e f = f! [         a    e f = fs  snf )
Nrtc                 *    SU ;   a  U $ [        U S5      $ )N?   )rg   )values    r   to_byte)SignatureDatabase.__load.<locals>.to_byte  s    e|ub>!r   z\nr   rB   TFr   r   )ospathexistsurllibrequesturlopenreadcloseIOErroropenr   findallstriplowerreplacesplitr   r   r   r   r   r   r%   r)   rh   r   r   )r   r   r	   sig_fsig_datar   rO   packer_namerH   superfluous_wildcardsr    r!   ro   rG   rm   treer3   rp   s                     r   __loadSignatureDatabase.__load  sK    77>>(++"NN228<E$zz|HKKM 40E$zz|HKKM
 H
 	" ..((2 
! mmo++-G!))%4::<I3<??3DE3Dawqz3DOE& !V+%)"%*"E!T)8822a72 d?::D4494;;D55:5&7	T7c/22!%$!7DJ.2DJ{+ "&$!7DJDz
 8 ~~%!&a U    L Fs   ?I *,I I%II")r   r   r   r   r   r   r   r   )NN)   )FFr   )TF)r   )__name__
__module____qualname____firstlineno____doc__r   r8   r>   r/   rP   rS   rN   rc   rY   ry   r   __static_attributes__ r   r   r   r      sM    " 2D$4L
 UX62 IV*XFP2d'r   r   c                     g)r   Nr   )r0   s    r   is_validr     s    r   c                    SnSn[        U S5      (       a  U R                   H  nSnUR                   Hp  nUR                  U R                  R
                  s=::  a  UR                  S-   ::  a  O  OSnUb!  XER                  s=::  a	  US-   ::  a  O  OUS-  nUR                  nMr     M     SnU R                  5       nU(       a  U  g)z`
unusual locations of import tables
non recognized section names
presence of long ASCII strings
Fr   DIRECTORY_ENTRY_BASERELOCN   Tr   )hasattrr   entriesrvar<   r=   get_warnings)r0   relocations_overlap_entry_pointsequential_relocs
base_reloclast_reloc_rvarelocwarnings_while_parsingwarningss           r   is_suspiciousr     s     ',# r.//66J!N#++99 2 2 F FW%))VW-W6:3 #.&))I~7II%*%!& , 7& #  H 	r   c                     [        U R                  5       5      nU(       d  gSnSnU R                   H8  nUR                  5       n[        UR	                  5       5      nUS:  d  M4  X6-  nM:     X1-  S:  a  SnU$ )a$  Returns True is there is a high likelihood that a file is packed or contains compressed data.

The sections of the PE file will be analyzed, if enough sections
look like containing compressed data and the data makes
up for more than 20% of the total file size, the function will
return True.
TFr   g@g?)r)   trimr&   get_entropyget_data)r0   total_pe_data_length)has_significant_amount_of_compressed_datatotal_compressed_datar4   	s_entropys_lengths          r   is_probably_packedr   (  s     rwwy>05-
 ;;'')	w'')* s?!-!  	4;48144r   )r   r   r
   r,   urllib.requestr   urllib.parseurllib.errorpefile
__author____version____contact__objectr   r   r   r   r   r   r   <module>r      sR    
 	  1 1 
  %V' V'r	
3	l!5r   