a
    kÄ#dqv  ã                   @   sv  d dl Z d dlZd dlZd dlZd dlmZ d dlmZmZm	Z	m
Z
mZmZmZmZmZmZ d dlmZ d dlmZ d dlm  mZ d dlmZ d dlmZ d dlmZ d d	lmZm Z  d d
l!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z- d dl.m/Z/ d dl0m1Z1m2Z2m3Z3m4Z4 d dl5m6Z6m7Z7m8Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z> d dl?m@Z@ d dlAT g d¢ZBe Ce jD¡G dd„ de6ƒƒZEG dd„ deEe8ƒZFG dd„ deEe8ƒZGG dd„ deEe8ƒZHG dd„ deEƒZIG dd„ deEƒZJG d d!„ d!e>ƒZKG d"d#„ d#eEe4ƒZLG d$d%„ d%eEe8ƒZMG d&d'„ d'eEe8ƒZNG d(d)„ d)eEƒZOG d*d+„ d+eEƒZPG d,d-„ d-eEƒZQG d.d/„ d/eEƒZRG d0d1„ d1e@ƒZSdS )2é    N)Údefaultdict)
ÚOptionalÚListÚTypeÚAnyÚTupleÚIterableÚDictÚcastÚCallableÚorb)Úlog_automotive)ÚPacket)Úconf)ÚSuperSocket)ÚScapy_Exception)ÚGMLAN_InitDiagnosticsÚGMLAN_TesterPresentSender)ÚGMLANÚGMLAN_SAÚGMLAN_RDÚGMLAN_TDÚ
GMLAN_RMBAÚ
GMLAN_RDBIÚGMLAN_RDBPIÚ	GMLAN_IDOÚGMLAN_NRÚ
GMLAN_WDBIÚGMLAN_DCÚGMLAN_PM)ÚEcuState)ÚAutomotiveTestCaseABCÚ_SocketUnionÚ_TransitionTupleÚStateGenerator)ÚServiceEnumeratorÚ_AutomotiveTestCaseScanResultÚ StateGeneratingServiceEnumerator)Ú'AutomotiveTestCaseExecutorConfiguration)Ú_Edge)ÚStagedAutomotiveTestCase)ÚAutomotiveTestCaseExecutor)Ú*)ÚGMLAN_ScannerÚGMLAN_ServiceEnumeratorÚGMLAN_RDBIEnumeratorÚGMLAN_RDBPIEnumeratorÚGMLAN_RMBAEnumeratorÚGMLAN_TPEnumeratorÚGMLAN_IDOEnumeratorÚGMLAN_PMEnumeratorÚGMLAN_RDEnumeratorÚGMLAN_TDEnumeratorÚGMLAN_WDBIEnumeratorÚGMLAN_SAEnumeratorÚGMLAN_WDBISelectiveEnumeratorÚGMLAN_DCEnumeratorc                   @   sD   e Zd ZdZedd„ ƒZedd„ ƒZedd„ ƒZdd	„ Zd
d„ Z	dS )ÚGMLAN_Enumeratorzp
    Abstract base class for GMLAN service enumerators. This class
    implements GMLAN specific functions.
    c                 C   s   | j S ©N©Ú
returnCode)Úresp© r@   ú`/var/www/html/gsl.tools/lib/python3.9/site-packages/scapy/contrib/automotive/gm/gmlan_scanner.pyÚ_get_negative_response_code=   s    z,GMLAN_Enumerator._get_negative_response_codec                 C   s   t | d� d¡S )Nr=   z%GMLAN_NR.returnCode%)r   Úsprintf)Znrcr@   r@   rA   Ú_get_negative_response_descB   s    z,GMLAN_Enumerator._get_negative_response_descc                 C   s
   |   d¡S )NzNR: %GMLAN_NR.returnCode%)rC   )Úresponser@   r@   rA   Ú_get_negative_response_labelG   s    z-GMLAN_Enumerator._get_negative_response_labelc                 C   s   |   |d ¡S ©Né   ©Ú
_get_label©ÚselfÚtupr@   r@   rA   Ú_get_table_entry_zL   s    z#GMLAN_Enumerator._get_table_entry_zc                 K   s   t dƒ‚d S )NzOverwrite this method©ÚNotImplementedError©rL   Úkwargsr@   r@   rA   Ú_get_initial_requestsP   s    z&GMLAN_Enumerator._get_initial_requestsN)
Ú__name__Ú
__module__Ú__qualname__Ú__doc__ÚstaticmethodrB   rD   rF   rN   rS   r@   r@   r@   rA   r;   7   s   


r;   c                   @   s$   e Zd ZdZdZdd„ Zdd„ ZdS )r.   zº
    This enumerator scans for all services identifiers of GMLAN. During this
    scan, corrupted packets might be sent to an ECU and mainly negative
    responses will be received.
    z2Available services and negative response per statec                 K   sL   t dd„ tdƒD ƒƒ}| d¡ | d¡ | d¡ | d¡ dd„ |D ƒS )	Nc                 s   s   | ]}|d @ V  qdS )i¿ÿÿÿNr@   ©Ú.0Úxr@   r@   rA   Ú	<genexpr>_   ó    z@GMLAN_ServiceEnumerator._get_initial_requests.<locals>.<genexpr>é   é   é>   é¥   é4   c                 s   s   | ]}t |d �V  qdS )©ÚserviceN©r   rY   r@   r@   rA   r\   d   r]   )ÚsetÚrangeÚremove)rL   rR   Zservicesr@   r@   rA   rS   ]   s    



z-GMLAN_ServiceEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nú
0x%02x: %sé   z%GMLAN.service%)rd   rC   rK   r@   r@   rA   Ú_get_table_entry_yf   s    ÿz*GMLAN_ServiceEnumerator._get_table_entry_yN)rT   rU   rV   rW   Ú_descriptionrS   rk   r@   r@   r@   rA   r.   U   s   	r.   c                   @   sD   e Zd ZdZdZdd„ Zedd„ ƒZedd„ ƒZd	d
„ Z	dd„ Z
dS )r2   z�
    Performs a check if TesterPresent is available. If a positive response is
    received, a new system state is generated and returned.
    zTesterPresent supportedc                 K   s   t dd�gS )Nr`   rc   re   rQ   r@   r@   rA   rS   s   s    z(GMLAN_TPEnumerator._get_initial_requestsc                 C   sV   |j r(d |d< | jtdd�ddd� dS t | |¡ ttt| ƒƒ|d< |d  ¡  dS )NÚtpsr`   rc   gš™™™™™¹?F©ÚtimeoutÚverboseT)	ÚunittestÚsr1r   r2   Úcleanupr   r
   r   Ústart)ÚsocketÚconfigurationrR   r@   r@   rA   Úenterw   s    ÿzGMLAN_TPEnumerator.enterc                 C   s8   z |d r|d   ¡  d |d< W n ty2   Y n0 dS )Nrm   T)ÚstopÚKeyError)Ú_rv   r@   r@   rA   rs   ˆ   s    zGMLAN_TPEnumerator.cleanupc                 C   s   | j ddi| jfS )NÚdescZTP)rw   rs   ©rL   ru   Úedger@   r@   rA   Úget_transition_function“   s    z*GMLAN_TPEnumerator.get_transition_functionc                 C   s   dS )NzTesterPresent:r@   rK   r@   r@   rA   rk   —   s    z%GMLAN_TPEnumerator._get_table_entry_yN)rT   rU   rV   rW   rl   rS   rX   rw   rs   r~   rk   r@   r@   r@   rA   r2   l   s   


r2   c                       sP   e Zd ZdZdd„ Zedd„ ƒZ‡ fdd„Zedd	„ ƒZd
d„ Z	dd„ Z
‡  ZS )r3   z%InitiateDiagnosticOperation supportedc                 K   s   t ƒ tdd� gS )NrH   ©Úsubfunction)r   r   rQ   r@   r@   rA   rS   Ÿ   s    z)GMLAN_IDOEnumerator._get_initial_requestsc                 C   sP   | j tƒ tdd� ddd�}|d ur>|jdkr>t dt|ƒ¡ |d uoN|jdkS )NrH   r   é   Frn   é   z:InitiateDiagnosticOperation received negative response!
%s)rr   r   r   rd   r   ÚdebugÚrepr)ru   Zansr@   r@   rA   Úenter_diagnostic_session£   s    ÿþz,GMLAN_IDOEnumerator.enter_diagnostic_sessionc                    s0   t t| ƒ ||¡}|r,|\}}d|_||fS d S ©Nrj   )Úsuperr3   Úget_new_edgeÚtp©rL   ru   Úconfigr}   ÚstateÚ	new_state©Ú	__class__r@   rA   rˆ   ®   s    z GMLAN_IDOEnumerator.get_new_edgec                 C   s0   t  | ||¡ t | ¡rdS t  | |¡ dS d S )NTF)r2   rw   r3   r…   rs   )Úsockr   rR   r@   r@   rA   Úenter_state_with_tp·   s
    
z'GMLAN_IDOEnumerator.enter_state_with_tpc                 C   s   | j dditjfS )Nr{   ZIDO_TP©r‘   r2   rs   r|   r@   r@   rA   r~   Á   s    z+GMLAN_IDOEnumerator.get_transition_functionc                 C   s   dS )NzInitiateDiagnosticOperation:r@   rK   r@   r@   rA   rk   Å   s    z&GMLAN_IDOEnumerator._get_table_entry_y)rT   rU   rV   rl   rS   rX   r…   rˆ   r‘   r~   rk   Ú__classcell__r@   r@   rŽ   rA   r3   œ   s   

	
	r3   c                   @   s4   e Zd ZdZdd„ Zedd„ ƒZdd„ Zdd	„ Zd
S )r/   z"Readable data identifier per statec                 K   s   |  dtdƒ¡}dd„ |D ƒS )NÚ
scan_ranger^   c                 s   s   | ]}t ƒ t|d � V  qdS ©)ÚdataIdentifierN)r   r   rY   r@   r@   rA   r\   Ð   r]   z=GMLAN_RDBIEnumerator._get_initial_requests.<locals>.<genexpr>©Úpoprg   ©rL   rR   r”   r@   r@   rA   rS   Í   s    z*GMLAN_RDBIEnumerator._get_initial_requestsc                 C   sD   t | ƒdkrt| ƒdd … nd}dt |ƒdkr>|d d… d n| S )Né   rH   s   No data availablezPR: %ré   é   s   ...)ÚlenÚbytes)r?   Úloadr@   r@   rA   Úprint_informationÒ   s     z&GMLAN_RDBIEnumerator.print_informationc                 C   s   d|d j |d  d¡f S )Nú
0x%04x: %srj   z%GMLAN_RDBI.dataIdentifier%©r–   rC   rK   r@   r@   rA   rk   Ø   s    
ÿz'GMLAN_RDBIEnumerator._get_table_entry_yc                 C   s   |   |d | j¡S rG   )rJ   r    rK   r@   r@   rA   rN   Ý   s    z'GMLAN_RDBIEnumerator._get_table_entry_zN)	rT   rU   rV   rl   rS   rX   r    rk   rN   r@   r@   r@   rA   r/   Ê   s   
r/   c                       sf   e Zd ZdZe ej¡Ze dedfi¡ e	j
d Z
‡ fdd„Ze
e_dd„ Zd	d
„ Zdd„ Z‡  ZS )r7   z#Writeable data identifier per stateÚrdbi_enumeratorNzø
        :param rdbi_enumerator: Specifies an instance of a GMLAN_RDBIEnumerator
                                which is used to extract possible data
                                identifiers.
        :type rdbi_enumerator: GMLAN_RDBIEnumeratorc                    s   t t| ƒj||fi |¤Ž d S r<   )r‡   r7   Úexecute©rL   ru   rŒ   rR   rŽ   r@   rA   r¤   ï   s    zGMLAN_WDBIEnumerator.executec                 K   sX   |  dtdƒ¡}|  dd ¡}|d u r2dd„ |D ƒS t|tƒrLdd„ |jD ƒS tdƒ‚d S )Nr”   r^   r£   c                 s   s   | ]}t ƒ t|d � V  qdS r•   )r   r   rY   r@   r@   rA   r\   ú   r]   z=GMLAN_WDBIEnumerator._get_initial_requests.<locals>.<genexpr>c                 s   sP   | ]H}|j jd krtt|j ƒƒdkrtƒ t|j jt|j ƒdd… d� V  qdS )r‚   rH   N)r–   Ú
dataRecord)r?   rd   r�   rž   r   r   r–   ©rZ   Útr@   r@   rA   r\   ü   s
   ýÿz=rdbi_enumerator has to be an instance of GMLAN_RDBIEnumerator)r˜   rg   Ú
isinstancer/   Zfiltered_resultsr   )rL   rR   r”   r£   r@   r@   rA   rS   õ   s    
þz*GMLAN_WDBIEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nri   rj   z%GMLAN_WDBI.dataIdentifier%r¢   rK   r@   r@   rA   rk     s    
ÿz'GMLAN_WDBIEnumerator._get_table_entry_yc                 C   s   |   |d d¡S )NrH   zPR: WriteablerI   rK   r@   r@   rA   rN   	  s    z'GMLAN_WDBIEnumerator._get_table_entry_z)rT   rU   rV   rl   Úcopyr;   Ú_supported_kwargsÚupdater/   r%   Ú_supported_kwargs_docr¤   rW   rS   rk   rN   r“   r@   r@   rŽ   rA   r7   â   s   ÿ
r7   c                       s(   e Zd Zedd„ ƒZ‡ fdd„Z‡  ZS )r9   c                 C   s   d| iS )Nr£   r@   )Zrdbirz   r@   r@   rA   Z__connector_rdbi_to_wdbi  s    z6GMLAN_WDBISelectiveEnumerator.__connector_rdbi_to_wdbic                    s$   t t| ƒ tƒ tƒ gd | jg¡ d S r<   )r‡   r9   Ú__init__r/   r7   Ú6_GMLAN_WDBISelectiveEnumerator__connector_rdbi_to_wdbi©rL   rŽ   r@   rA   r®     s    

þz&GMLAN_WDBISelectiveEnumerator.__init__)rT   rU   rV   rX   r¯   r®   r“   r@   r@   rŽ   rA   r9     s   
r9   c                       sÚ   e Zd ZdZeƒ Ze ej¡Ze 	ddi¡ e
jd Z‡ fdd„Zee_dd„ Zd	d
„ Zdd„ Zdd„ Z‡ fdd„Z‡ fdd„Zed#dd„ƒZedd„ ƒZed$dd„ƒZed%dd„ƒZedd„ ƒZdd „ Zd!d"„ Z‡  ZS )&r8   zSecurityAccess supportedÚkeyfunction)NNz¤
        :param keyfunction: Specifies a function to generate the key from a
                            given seed.
        :type keyfunction: Callable[[int], int]c                    s   t t| ƒj||fi |¤Ž d S r<   )r‡   r8   r¤   r¥   rŽ   r@   rA   r¤   (  s    zGMLAN_SAEnumerator.executec                 K   s"   |  dtdddƒ¡}dd„ |D ƒS )Nr”   rj   é
   rH   c                 s   s   | ]}t ƒ t|d � V  qdS )r   N)r   r   rY   r@   r@   rA   r\   1  r]   z;GMLAN_SAEnumerator._get_initial_requests.<locals>.<genexpr>r—   r™   r@   r@   rA   rS   .  s    z(GMLAN_SAEnumerator._get_initial_requestsc                 C   s   d|d j  S )NzSubfunction %02drj   r   rK   r@   r@   rA   rk   3  s    z%GMLAN_SAEnumerator._get_table_entry_yc                 C   s   |   |d dd„ ¡S )NrH   c                 S   s
   d| j  S ©NzPR: %s)ÚsecuritySeed©Úrr@   r@   rA   Ú<lambda>9  r]   z7GMLAN_SAEnumerator._get_table_entry_z.<locals>.<lambda>rI   rK   r@   r@   rA   rN   7  s    z%GMLAN_SAEnumerator._get_table_entry_zc                 C   s$   t t| ƒj| r |js t d¡ d S )Né   )r
   r%   Z
_retry_pktrq   ÚtimeÚsleep)rL   ru   rŒ   Úglobal_configurationr@   r@   rA   Úpre_execute;  s    ÿzGMLAN_SAEnumerator.pre_executec                    s^   t t| ƒj|||fi |¤Žr dS |jdkrZ|  |¡dv rZt dt|ƒ¡ t t| ƒ ||¡S dS )NTr‚   )é"   é7   zMRetry %s because requiredTimeDelayNotExpired or requestSequenceError receivedF)	r‡   r8   Ú_evaluate_retryrd   rB   r   rƒ   r„   Z_populate_retry©rL   rŒ   ÚrequestrE   rR   rŽ   r@   rA   r¿   D  s"    
ÿÿ
ÿý
ÿz"GMLAN_SAEnumerator._evaluate_retryc                    sR   t t| ƒj|||fi |¤Žr dS |d urN|jdkrN|jd dkrNt d¡ dS dS )NTég   rH   rj   z&Seed received. Leave scan to try a keyF)r‡   r8   Ú_evaluate_responserd   r€   r   rƒ   rÀ   rŽ   r@   rA   rÃ   Y  s    
ÿÿÿÿ
z%GMLAN_SAEnumerator._evaluate_responserj   c                 C   s¦   t ƒ t|d� }tdƒD ]ˆ}| j|ddd�}|d u r: d S |jdkrht |¡dkrht dt	|ƒ¡  d S |jdkr˜t |¡dkr˜t d	¡ t
 d¡ qq|  S qd S )
Nr   r²   r�   Frn   r‚   r¾   zSecurity access no seed! NR: %sz!Security access retry to get seed)r   r   rg   rr   rd   r;   rB   r   Úinfor„   r¹   rº   )r�   ÚlevelÚreqrz   Úseedr@   r@   rA   Úget_seed_pkti  s(    
ÿÿ
ÿ


zGMLAN_SAEnumerator.get_seed_pktc                 C   s\   | d u s| j dkrJt t|ƒ¡ t t|ƒ¡ t t| ƒ¡ t d¡ dS t d¡ dS d S )Nr‚   zSecurity access error!FzSecurity access granted!T)rd   r   rƒ   r„   rÄ   )ÚresrÇ   Úkeyr@   r@   rA   Ú!evaluate_security_access_response€  s    

z4GMLAN_SAEnumerator.evaluate_security_access_responsec                 C   s@   z
| j }W n ty   Y d S 0 tttƒ t|d ||ƒd� ƒS )Nrj   )r€   ZsecurityKey)r´   ÚAttributeErrorr
   r   r   r   )rÇ   r±   rÅ   Úsr@   r@   rA   Úget_key_pkt�  s    
ÿzGMLAN_SAEnumerator.get_key_pktNc                 C   sn   t  d| ¡ |d u r*t | |¡}|s*dS |d u r6dS t |||¡}|d u rPdS | j|ddd�}t |||¡S )Nz+Try bootloader security access for level %dFr�   rn   )r   rÄ   r8   rÈ   rÎ   rr   rË   )r�   rÅ   Úseed_pktr±   Zkey_pktrÉ   r@   r@   rA   Úget_security_access˜  s     ÿÿz&GMLAN_SAEnumerator.get_security_accessc                 C   s   t j| |d |d d�S )NÚ	sec_levelr±   )rÅ   r±   )r8   rÐ   )r�   rz   rR   r@   r@   rA   Útransition_function­  s    ÿz&GMLAN_SAEnumerator.transition_functionc           
      C   sâ   | j d j}| j d j}|d u s*|jdkr.d S zœ|jdksH|jd dkrNW d S |}|j}|| jj  dd ¡}| j||||d�rÈt	 
d¡ t |¡}|jd |_||kr¬W d S ||f}	||f| j|	< |	W S W n tyÜ   Y n0 d S )	Néÿÿÿÿr‚   rÂ   rH   rj   r±   )rÅ   rÏ   r±   zSecurity Access found.)Z_resultsr?   rŒ   rd   r€   r�   rT   ÚgetrÐ   r   rƒ   rª   Zsecurity_levelÚ_transition_function_argsrÌ   )
rL   ru   r‹   Z	last_respZ
last_staterÇ   Zsec_lvlZkfr�   r}   r@   r@   rA   rˆ   ³  s4    
ÿÿ


zGMLAN_SAEnumerator.get_new_edgec                 C   s6   | j | j| d | j| d d| j| d  dœd fS )Nr   rj   zSA=%d)rÑ   r±   r{   )rÒ   rÕ   r|   r@   r@   rA   r~   Ô  s    ýýz*GMLAN_SAEnumerator.get_transition_function)rj   )rj   )rj   NN)rT   rU   rV   rl   ÚdictrÕ   rª   r;   r«   r¬   r%   r­   r¤   rW   rS   rk   rN   r¼   r¿   rÃ   rX   rÈ   rË   rÎ   rÐ   rÒ   rˆ   r~   r“   r@   r@   rŽ   rA   r8     s6   ÿ
	


!r8   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r5   zRequestDownload supportedc                 K   s   t ƒ tdd� gS )Nr_   )Ú
memorySize)r   r   rQ   r@   r@   rA   rS   ß  s    z(GMLAN_RDEnumerator._get_initial_requestsc                 C   s   dS )NzRequestDownload:r@   rK   r@   r@   rA   rk   ã  s    z%GMLAN_RDEnumerator._get_table_entry_yN©rT   rU   rV   rl   rS   rk   r@   r@   r@   rA   r5   Ü  s   r5   c                       sN   e Zd ZdZdd„ Zddd„Z‡ fdd	„Zed
d„ ƒZdd„ Z	dd„ Z
‡  ZS )r4   zProgrammingMode supportedc                 K   s
   t ƒ ‚d S r<   rO   rQ   r@   r@   rA   rS   ë  s    z(GMLAN_PMEnumerator._get_initial_requestsrj   é°  c              	   K   sp   t tt|ƒd| dd¡d�}|r>|  |tƒ tƒ  tdd�¡ n$|  |tƒ tƒ  tƒ tddd	� ¡ d
| j|< d S )Nr›   rq   F©ro   rq   éå   rc   rœ   ra   )r>   ZrequestServiceIdT)	r   r
   r   rÔ   Z_store_resultr   r   r   Ú_state_completed)rL   ru   rŒ   ro   Zexecution_timerR   Ú	supportedr@   r@   rA   r¤   ï  s    

þÿþzGMLAN_PMEnumerator.executec                    s6   t t| ƒ ||¡}|r2|\}}d|_d|_||fS d S r†   )r‡   r4   rˆ   r‰   Zcommunication_controlrŠ   rŽ   r@   rA   rˆ   ÿ  s    zGMLAN_PMEnumerator.get_new_edgec                 C   s@   t  | ||¡ ttt| ƒd|jd�}|s8t  | |¡ dS dS d S )Nr›   rÚ   FT)r2   rw   r   r
   r   rq   rs   )r�   r   rR   rÉ   r@   r@   rA   r‘   	  s    ÿz&GMLAN_PMEnumerator.enter_state_with_tpc                 C   s   | j dditjfS )Nr{   ZPM_TPr’   r|   r@   r@   rA   r~     s    
ÿz*GMLAN_PMEnumerator.get_transition_functionc                 C   s   dS )NzProgrammingMode:r@   rK   r@   r@   rA   rk     s    z%GMLAN_PMEnumerator._get_table_entry_y)rj   rÙ   )rT   rU   rV   rl   rS   r¤   rˆ   rX   r‘   r~   rk   r“   r@   r@   rŽ   rA   r4   è  s   


r4   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r0   z'Readable parameter identifier per statec                 K   s   |  dtdƒ¡}dd„ |D ƒS )Nr”   i   c                 s   s    | ]}t ƒ t|gd � V  qdS ))ÚidentifiersN)r   r   rY   r@   r@   rA   r\   %  r]   z>GMLAN_RDBPIEnumerator._get_initial_requests.<locals>.<genexpr>r—   r™   r@   r@   rA   rS   "  s    z+GMLAN_RDBPIEnumerator._get_initial_requestsc                 C   s(   d|d j d |d  d¡dd… f S )Nr¡   rj   r   z%GMLAN_RDBPI.identifiers%rÓ   )rÞ   rC   rK   r@   r@   rA   rk   '  s    þz(GMLAN_RDBPIEnumerator._get_table_entry_yc                 C   s   |   |d tj¡S rG   )rJ   r/   r    rK   r@   r@   rA   rN   -  s    z(GMLAN_RDBPIEnumerator._get_table_entry_zN)rT   rU   rV   rl   rS   rk   rN   r@   r@   r@   rA   r0     s   r0   c                       s    e Zd ZdZe ej¡Ze edd„ fedd„ fedd„ fdœ¡ ej	d Z	‡ fdd	„Z
e	e
_‡ fd
d„Zdd„ Zdd„ Zd‡ fdd„	Zdd„ Zdd„ Z‡  ZS )r1   z9Readable Memory Addresses and negative response per statec                 C   s   | dkS ©Nr   r@   ©r[   r@   r@   rA   r·   7  r]   zGMLAN_RMBAEnumerator.<lambda>c                 C   s   | dkS rß   r@   rà   r@   r@   rA   r·   8  r]   c                 C   s   | dkS rß   r@   rà   r@   r@   rA   r·   9  r]   )Úprobe_widthÚrandom_probes_lenÚsequential_probes_lenzö
        :param int probe_width: Memory size of a probe.
        :param int random_probes_len: Number of probes.
        :param int sequential_probes_len: Size of a memory block during
                                          sequential probing.c                    s   t t| ƒj||fi |¤Ž d S r<   )r‡   r1   r¤   r¥   rŽ   r@   rA   r¤   B  s    zGMLAN_RMBAEnumerator.executec                    sv   t t| ƒ ¡  ttƒ| _ttƒ| _d| _ddt	j
d d   d | _tdt	j
d d  dƒ| _dt	j
d d  | _d S )	Nr_   rH   é   r   ÚGMLAN_ECU_AddressingSchemerj   r²   i P  )r‡   r1   r®   r   ÚboolÚrandom_probe_finishedÚlistÚpoints_of_interestrá   r   ÚcontribsÚhighest_possible_addrÚminrâ   rã   r°   rŽ   r@   rA   r®   H  s    

ÿÿÿÿzGMLAN_RMBAEnumerator.__init__c                    sh   |  dˆ j¡ˆ _|  dˆ j¡ˆ _|  dˆ j¡ˆ _t tdˆ jˆ jƒˆ j¡}|  d|¡}‡ fdd„|D ƒS )Nrá   râ   rã   r   r”   c                 3   s"   | ]}t ƒ t|ˆ jd � V  qdS )©ÚmemoryAddressr×   N)r   r   rá   rY   r°   r@   rA   r\   a  s   þÿz=GMLAN_RMBAEnumerator._get_initial_requests.<locals>.<genexpr>)r˜   rá   râ   rã   ÚrandomÚsamplerg   rë   )rL   rR   Ú	addressesr”   r@   r°   rA   rS   V  s    ÿÿþ
þz*GMLAN_RMBAEnumerator._get_initial_requestsc                    sÐ  | j ˆ  sd S | jˆ  svt d¡ d| jˆ < ‡ fdd„| jD ƒD ]4}| jˆ   |jjdf¡ | jˆ   |jjdf¡ q@t	| jˆ  ƒsˆd S t dt	| jˆ  ƒ ¡ dd„ | j
D ƒ}‡ fdd„| jD ƒ}tƒ }tƒ }| jˆ  D ]ª\}	}
|	|vrìqÚtƒ }t| j| j| j | jƒD ]T}|
�r&t|	| | jƒ}nt|	| d	ƒ}||v�r
tƒ t|| jd
� }| |¡ �q
t	|ƒrÚ| |d j|
f¡ ||7 }qÚtƒ | jˆ < t	|ƒ�rÌd| j ˆ < || jˆ < || jˆ < t dt	|ƒ ¡ d S )NzRandom memory probing finishedTc                    s   g | ]}|j ˆ kr|‘qS r@   ©rŒ   r§   rò   r@   rA   Ú
<listcomp>m  s   
ÿz5GMLAN_RMBAEnumerator.post_execute.<locals>.<listcomp>Fz.Create %d memory points for sequential probingc                 S   s   g | ]}|j j‘qS r@   )rÆ   rî   ©rZ   rM   r@   r@   rA   ró   {  r]   c                    s   g | ]}|j ˆ kr|jj‘qS r@   )rŒ   rÆ   rî   rô   rò   r@   rA   ró   |  s   
ÿr   rí   rÓ   z&Created %d pkts for sequential probing)rÜ   rç   r   rÄ   Úresults_with_positive_responseré   ÚappendrÆ   rî   r�   Úresultsrè   rg   rá   rã   rì   rë   Úmaxr   r   Z_request_iterators)rL   ru   rŒ   r»   rM   Ztested_addrsZ	pos_addrsZnew_requestsZnew_points_of_interestZpoiZupwardZtemp_new_requestsÚiÚnew_addrZpktr@   rò   rA   Úpost_executee  sr    





ÿ

ÿÿÿ
ÿ
ý
ÿÿ




ÿÿz!GMLAN_RMBAEnumerator.post_executeFTc           
         s°   t t| ƒ |||¡}zZddlm} |ƒ }| jD ].}t|jjƒD ]\}}	t	|	ƒ||j
j| < q>q.|jddd� W n tyŠ   t d¡ Y n0 |r |d ur |d S t|ƒ d S d S )Nr   )ÚIntelHexzRMBA_dump.hexÚhex)Úformatz5Install 'intelhex' to create a hex file of the memoryÚ
)r‡   r1   ÚshowZintelhexrü   rõ   Ú	enumerater?   r¦   r   rÆ   rî   ÚtofileÚImportErrorr   ÚwarningÚprint)
rL   ÚdumpÚfilteredrp   rÍ   rü   ZihrM   rù   ÚbrŽ   r@   rA   r   £  s     
ÿ
zGMLAN_RMBAEnumerator.showc                 C   s   d|d j  S ©Nz0x%04xrj   )rî   rK   r@   r@   rA   rk   ¹  s    z'GMLAN_RMBAEnumerator._get_table_entry_yc                 C   s   |   |d dd„ ¡S )NrH   c                 S   s
   d| j  S r³   )r¦   rµ   r@   r@   rA   r·   ¿  r]   z9GMLAN_RMBAEnumerator._get_table_entry_z.<locals>.<lambda>rI   rK   r@   r@   rA   rN   ½  s    z'GMLAN_RMBAEnumerator._get_table_entry_z)FTF)rT   rU   rV   rl   rª   r;   r«   r¬   Úintr­   r¤   rW   r®   rS   rû   r   rk   rN   r“   r@   r@   rŽ   rA   r1   2  s    


ý
>r1   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r6   z5Transfer Data support and negative response per statec                    sR   |  dtdƒ¡}tjd d }d|d  d d? ‰ ‡ fdd	„|D ƒ}d
d	„ |D ƒS )Nr”   iÿ  r   rå   rH   rä   rj   c                 3   s   | ]}t  d ˆ ¡d> V  qdS )r   rH   N)rï   Úrandint)rZ   rz   ©Zmax_addrr@   rA   r\   Ë  r]   z;GMLAN_TDEnumerator._get_initial_requests.<locals>.<genexpr>c                 s   s    | ]}t ƒ td |d� V  qdS )r   )r€   ÚstartingAddressN)r   r   rY   r@   r@   rA   r\   Ì  s   ÿ)r˜   rg   r   rê   )rL   rR   r”   Útemprñ   r@   r  rA   rS   Å  s    ÿz(GMLAN_TDEnumerator._get_initial_requestsc                 C   s   d|d j  S r	  )r  rK   r@   r@   rA   rk   Ï  s    z%GMLAN_TDEnumerator._get_table_entry_yNrØ   r@   r@   r@   rA   r6   Â  s   
r6   c                   @   s    e Zd ZdZdd„ Zdd„ ZdS )r:   z!DeviceControl supported per statec                 K   s   |  dtdƒ¡}dd„ |D ƒS )Nr”   r^   c                 s   s   | ]}t ƒ t|d � V  qdS ))Ú
CPIDNumberN)r   r   rY   r@   r@   rA   r\   Ú  r]   z;GMLAN_DCEnumerator._get_initial_requests.<locals>.<genexpr>r—   r™   r@   r@   rA   rS   ×  s    z(GMLAN_DCEnumerator._get_initial_requestsc                 C   s   d|d j |d  d¡f S )Nri   rj   z%GMLAN_DC.CPIDNumber%)r  rC   rK   r@   r@   rA   rk   Ü  s    ÿz%GMLAN_DCEnumerator._get_table_entry_yNrØ   r@   r@   r@   rA   r:   Ô  s   r:   c                   @   s   e Zd Zedd„ ƒZdS )r-   c              
   C   s   t ttttttttt	g
S r<   )
r.   r2   r3   r4   r5   r8   r6   r1   r9   r:   r°   r@   r@   rA   Údefault_test_case_clsså  s    üz$GMLAN_Scanner.default_test_case_clssN)rT   rU   rV   Úpropertyr  r@   r@   r@   rA   r-   ä  s   r-   )TÚabcrï   r¹   rª   Úcollectionsr   Zscapy.compatr   r   r   r   r   r   r	   r
   r   r   Zscapy.contrib.automotiver   Zscapy.packetr   Zscapy.libs.sixZlibsÚsixZscapy.configr   Zscapy.supersocketr   Zscapy.errorr   Z&scapy.contrib.automotive.gm.gmlanutilsr   r   Z!scapy.contrib.automotive.gm.gmlanr   r   r   r   r   r   r   r   r   r   r   r   Zscapy.contrib.automotive.ecur    Z*scapy.contrib.automotive.scanner.test_caser!   r"   r#   r$   Z+scapy.contrib.automotive.scanner.enumeratorr%   r&   r'   Z.scapy.contrib.automotive.scanner.configurationr(   Z&scapy.contrib.automotive.scanner.graphr)   Z1scapy.contrib.automotive.scanner.staged_test_caser*   Z)scapy.contrib.automotive.scanner.executorr+   Z,scapy.contrib.automotive.gm.gmlan_ecu_statesÚ__all__Úadd_metaclassÚABCMetar;   r.   r2   r3   r/   r7   r9   r8   r5   r4   r0   r1   r6   r:   r-   r@   r@   r@   rA   Ú<module>	   sP   08
0., B7 