o
    jW                     @   s`   d dl mZ d dl mZ d dlmZmZmZ d dlmZm	Z	 G dd dZ
dd Zdd
dZdS )    )division)print_function)packunpackcalcsize)bPY3c                   @   s   e Zd ZdZdZdZdZd3ddZedd Z	d	d
 Z
dd Zd4ddZdd Zdd Zdd Zdd Zdd Zdd Zdd Zd4ddZedfdd Zd4d!d"Zd4d#d$Zd4d%d&Zd'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zd3d1d2ZdS )5	Structurea   sublcasses can define commonHdr and/or structure.
        each of them is an tuple of either two: (fieldName, format) or three: (fieldName, ':', class) fields.
        [it can't be a dictionary, because order is important]
        
        where format specifies how the data in the field will be converted to/from bytes (string)
        class is the class to use when unpacking ':' fields.

        each field can only contain one value (or an array of values for *)
           i.e. struct.pack('Hl',1,2) is valid, but format specifier 'Hl' is not (you must use 2 dfferent fields)

        format specifiers:
          specifiers from module pack can be used with the same format 
          see struct.__doc__ (pack/unpack is finally called)
            x       [padding byte]
            c       [character]
            b       [signed byte]
            B       [unsigned byte]
            h       [signed short]
            H       [unsigned short]
            l       [signed long]
            L       [unsigned long]
            i       [signed integer]
            I       [unsigned integer]
            q       [signed long long (quad)]
            Q       [unsigned long long (quad)]
            s       [string (array of chars), must be preceded with length in format specifier, padded with zeros]
            p       [pascal string (includes byte count), must be preceded with length in format specifier, padded with zeros]
            f       [float]
            d       [double]
            =       [native byte ordering, size and alignment]
            @       [native byte ordering, standard size and alignment]
            !       [network byte ordering]
            <       [little endian]
            >       [big endian]

          usual printf like specifiers can be used (if started with %) 
          [not recommended, there is no way to unpack this]

            %08x    will output an 8 bytes hex
            %s      will output a string
            %s\x00  will output a NUL terminated string
            %d%d    will output 2 decimal digits (against the very same specification of Structure)
            ...

          some additional format specifiers:
            :       just copy the bytes from the field into the output string (input may be string, other structure, or anything responding to __str__()) (for unpacking, all what's left is returned)
            z       same as :, but adds a NUL byte at the end (asciiz) (for unpacking the first NUL byte is used as terminator)  [asciiz string]
            u       same as z, but adds two NUL bytes at the end (after padding to an even size with NULs). (same for unpacking) [unicode string]
            w       DCE-RPC/NDR string (it's a macro for [  '<L=(len(field)+1)/2','"\x00\x00\x00\x00','<L=(len(field)+1)/2',':' ]
            ?-field length of field named 'field', formatted as specified with ? ('?' may be '!H' for example). The input value overrides the real length
            ?1*?2   array of elements. Each formatted as '?2', the number of elements in the array is stored as specified by '?1' (?1 is optional, or can also be a constant (number), for unpacking)
            'xxxx   literal xxxx (field's value doesn't change the output. quotes must not be closed or escaped)
            "xxxx   literal xxxx (field's value doesn't change the output. quotes must not be closed or escaped)
            _       will not pack the field. Accepts a third argument, which is an unpack code. See _Test_UnpackCode for an example
            ?=packcode  will evaluate packcode in the context of the structure, and pack the result as specified by ?. Unpacking is made plain
            ?&fieldname "Address of field fieldname".
                        For packing it will simply pack the id() of fieldname. Or use 0 if fieldname doesn't exists.
                        For unpacking, it's used to know weather fieldname has to be unpacked or not, i.e. by adding a & field you turn another field (fieldname) in an optional field.
            
     r   Nc                 C   s<   t | ds|| _i | _|| _|d ur| | d S d | _d S )N	alignment)hasattrr   fieldsrawData
fromStringdata)selfr   r   r
   r
   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/aiosmb/dcerpc/v5/structure.py__init__M   s   

zStructure.__init__c                 C   s   |  }| |t| |S N)r   readlen)r   fileanswerr
   r
   r   fromFileX   s   zStructure.fromFilec                 C   
   || _ d S r   )r   )r   r   r
   r
   r   setAlignment^      
zStructure.setAlignmentc                 C   r   r   )r   )r   r   r
   r
   r   setDataa   r   zStructure.setDatac                 C   sp   | j rtd||f  |d u r| |}|| jv r%| j|| j| |d}n| j|d |d}| j r6td|  |S )NzpackField( %s | %s ))fieldz
	answer %r)debugprintformatForFieldr   r   )r   	fieldNameformatansr
   r
   r   	packFieldd   s   

zStructure.packFieldc                 C   s   | j d ur| j S t }| j| j D ]j}z|| |d |d 7 }W n> ty_ } z2|d | jv rH| jd|d |d | |d  | jf f7  _ | jd|d |d | jf f7  _ d }~ww | j	r{t
|| j	 r{|d| j	 d t
|| j	   7 }q|S )Nr      z'When packing field '%s | %s | %r' in %sz"When packing field '%s | %s' in %s    )r   bytes	commonHdr	structurer%   	Exceptionr   args	__class__r   r   )r   r   r   er
   r
   r   getDatau   s&   
.$"zStructure.getDatac                 C   s8  || _ | j| j D ]}| jrtd|d |d |f  | |d ||d }| jr/td|  t}t|dkr;|d }z| j|d |d | ||d d| |d < W n t	yq } z| j
d|d |d ||f f7  _
 d }~ww | |d | |d  |d }| jr|| j r|| j|| j  7 }||d  }q	| S )NzfromString( %s | %s | %r )r   r&   z  size = %d   )dataClassOrCoder   z(When unpacking field '%s | %s | %r[:%d]')r   r)   r*   r   r    calcUnpackSizer   r   r   r+   r,   calcPackSizer   )r   r   r   sizer1   r.   r
   r
   r   r      s,   .$zStructure.fromStringc                 C   s   || j |< d | _d S r   )r   r   )r   keyvaluer
   r
   r   __setitem__   s   

zStructure.__setitem__c                 C   s
   | j | S r   r   r   r5   r
   r
   r   __getitem__   r   zStructure.__getitem__c                 C   s   | j |= d S r   r8   r9   r
   r
   r   __delitem__   s   zStructure.__delitem__c                 C   s   |   S r   )r/   r   r
   r
   r   __str__   s   zStructure.__str__c                 C   s   t |  S r   )r   r/   r<   r
   r
   r   __len__   s   zStructure.__len__c           
      C   s  | j rtd|||f  |r| |}|d ur|d u rdS |d d dkr'dS |d d dks7|d d dkr?t|dd  S |d}t|dkrqz	| |d	 |W S    d
| i}|| j | |d	 t	|d i | Y S |d}t|dkrz	| |d	 |W S    |d | jv r| |d  d ur| |d	 t
| |d  dt|d	 d > d @  Y S | |d	 d	 Y S |d}t|dkrz	| |d	 |W S    | |d	 | |d  Y S |d}t|dkr.t }|D ]}|| |d |7 }q|d	 r,|d	  r t|d	 t|krtd|S | |d	 t|| S |S |d d dkr=t|| S |d d dkrPtt|td S |d d dkrot|td t|d@ rktdpld S |d d dkrt|d	krtd}nt|d rt|td }tdt|d }	d|	|	td|gS |d u rtd|d d dkrt|tr| S t|dr| S t|trt|S t|tdurtt|S |S |dd  dkrt|tst|trt||S t|t|S t||S )Nz  pack( %s | %r | %s)    r&   _'"=r0   r   r   &   -*FArray field has a constant size, and it doesn't match the actual value%z u  w<Lz    zTrying to pack None:r/   Ts)r   r    findAddressFieldForr   splitr   r   updater   evalidr   calcPackFieldSizer(   isdigitintr+   join
isinstancer	   r/   r   	bytearray)
r   r#   r   r   addressFieldtwor   r   eachlr
   r
   r   r      s   
 
 
8


,



zStructure.packc                 C   s2  | j rtd||f  |r| |}|d ur| | sd S |d d dkr;|tkr9| |d}|| j t|i |S d S |d d dksK|d d dkra|dd  }t||kr_td||f |S |d}t	|d	krt| 
|d
 |S |d}t	|d	kr| 
|d
 |S |d}t	|d	kr| 
|d
 |S |d}t	|d	krg }d
}	|d
  rt|d
 }
n|d
 r|	| |d
 |7 }	| 
|d
 |d |	 }
nd}
|
r|	t	|k r|	| |d ||	d   }|| 
|d ||	| | |
d8 }
|}	|
r|	t	|k s|S |d d dkr|| S |dkrD|dd  tdkr2td||f tr>|d d dS |d d S |dkrb|dd  tdkr\td||f |d d S |dkr|t
d|d d d
 }|dd|d	   S |dkrt|tr|tu r|S ||S t
||d
 S )Nz  unpack( %s | %r )r&   r@   )r   inputDataLeftrA   rB   z>Unpacked data doesn't match constant value '%r' should be '%r'rD   r0   r   rC   rF   rG   rQ   rI   rJ   rK   z&%s 'z' field is not NUL terminated: %rzlatin-1rL   rM   z*%s 'u' field is not NUL-NUL terminated: %rrN   rO         rP   )r   r    rS   r   rU   r   rV   r+   rT   r   r   rY   rZ   r2   appendr   decoder\   r(   )r   r#   r   r1   r   r^   r   r   r_   sofarnumbernsofarra   r
   r
   r   r     s   

 



 



zStructure.unpackc           	      C   s  |r|  |}|d ur| | sdS |d d dkrdS |d d dks+|d d dkr1t|d S |d}t|dkrD| |d |S |d}t|dkrW| |d |S |d	}t|dkrj| |d |S |d
}t|dkrd}|d  rt|d t|krtdn|d r|| |d t|7 }|D ]}|| |d |7 }q|S |d d dkrt|| S |d d dkrt|d S |d d dkrt|}||d@ rdpd S |d d dkrt|}d| |d  S |d d dkrt|S t|S )Nr   r&   r@   rA   rB   rD   r0   rC   rF   rG   rH   rI   rJ   rL      rN   re   rP   )rS   r   rT   r3   rY   rZ   r+   r   )	r   r#   r   r   r^   r_   r   r`   ra   r
   r
   r   r3   ~  sV   
 



zStructure.calcPackSizec           
      C   s  | j rtd|||f  |d d dkrdS | |}|d ur%| | s%dS z| |}t| | W S  ty:   Y nw |d d dksK|d d dkrQt|d S |d}t|dkrd| |d |S |d	}t|dkrw| |d |S |d
}t|dkr| |d |S |d}t|dkrd}|d r|d 	 rt|d }n|| |d |7 }| 
|d |d | }|r|d8 }|| |d ||d  7 }|s|S |t|k r|| |d ||d  7 }|t|k s|S |d d dkrtd|d d dkr|tdd S |d d dkr,|td}	|	|	d@ r)dp*d S |d d dkrFt
d|d d d }	d|	d  S |d d dkrSt|S t|S )Nz  calcUnpackSize( %s | %s | %r)r&   r@   r   rA   rB   rD   r0   rC   rF   rG   rI   z=Can't guess the size of a printf like specifier for unpackingrJ   rK   rL   rM   rk   rN   rO   rd   re   rP   )r   r    rS   findLengthFieldForrZ   r+   r   rT   r2   rY   r   indexr   r   )
r   r#   r   r   r^   lengthFieldr_   r   ri   ra   r
   r
   r   r2     sn   

 



zStructure.calcUnpackSizec                 C   s"   |d u r	|  |}| || | S r   )r!   r3   )r   r"   r#   r
   r
   r   rX     s   
zStructure.calcPackFieldSizec                 C   s6   | j | j D ]}|d |kr|d   S qtd| )Nr   r&   zField %s not found)r)   r*   r+   )r   r"   r   r
   r
   r   r!     s
   zStructure.formatForFieldc                 C   H   d| }t |}| j| j D ]}|d | d  |kr!|d   S qd S )Nz&%sr&   r   r   r)   r*   r   r"   
descriptorra   r   r
   r
   r   rS   %     zStructure.findAddressFieldForc                 C   ro   )Nz-%sr&   r   rp   rq   r
   r
   r   rl   -  rs   zStructure.findLengthFieldForc                 C   s|   | d}t|dkr|d  r| |d ft|d  S |ddks(dS d|v r.dS |d	v r4dS |d
kr<tdS dS )NrG   r0   r   r&   rQ   r
   rR   r?   )rJ   rP   rL   rN   rM   )rT   r   rY   	zeroValuerZ   findr   )r   r#   r_   r
   r
   r   rt   5  s   
zStructure.zeroValuec                 C   s,   | j | j D ]}| |d | |d < qd S )Nr&   r   )r)   r*   rt   )r   r   r
   r
   r   clearF  s   zStructure.clearc                 C   s  |d u r| j j}d| }td|  g }| j| j D ]8}|d }|| jv rR|| t| | trG| | j	d||f |d d td|  qtd||| | f  qt
t| jt| }|D ]*}t| | tr| | j	d||f |d d td|  q`td||| | f  q`d S )	N z
%sr   z%s%s:{rd   )indentz%s}z
%s%s: {%r})r-   __name__r    r)   r*   r   rf   r\   r	   dumplistset)r   msgrx   indfixedFieldsr   iremainingFieldsr
   r
   r   rz   J  s*   

zStructure.dump)Nr   r   ) ry   
__module____qualname____doc__r)   r*   r   r   classmethodr   r   r   r%   r/   r   r7   r:   r;   r=   r>   r   r   r   r3   r2   rX   r!   rS   rl   rt   rv   rz   r
   r
   r
   r   r	      s:    <



m
_
G
Tr	   c                 C   s   t | dv r
t | S dS )Nz_0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ .)chr)xr
   r
   r   pretty_printc  s   r    c                 C   s   | d u rd S t | trt| d} t| }t|}d}||k rpd||f }tdD ]!}|| |k r=|d|||   7 }n|d7 }|d dkrK|d7 }q*|d	7 }|d
dd |||d  D 7 }t| |d7 }||k s d S d S )Nzutf-8r   z
 %s%04x      z%02X z      rw   z  r   c                 s   s    | ]}t |V  qd S r   )r   ).0r   r
   r
   r   	<genexpr>{  s    zhexdump.<locals>.<genexpr>)	r\   rZ   strencoder]   r   ranger[   r    )r   rx   r   strLenr   linejr
   r
   r   hexdumpi  s*   
$r   N)r   )
__future__r   r   structr   r   r   sixr   r   r	   r   r   r
   r
   r
   r   <module>   s       [