o
    Žõ±jã6  ã                   @   sè   d dl T d dlmZ d dlT d dlT d dlT d dlT ddlmZ ddl	m
Z
 ddlZddlZddlZddlZddlZddlZG dd„ dƒZG d	d
„ d
ƒZG dd„ dƒZG dd„ dƒZedkrre
jd d� eƒ Ze ¡ Ze d¡ dS dS )é   )Ú*)Úenable_debug_privilegeé    )ÚPROCESSOR_ARCHITECTURE)ÚloggerNc                   @   s0   e Zd Zdd„ Zdd„ Zedd„ ƒZdd„ Zd	S )
ÚModulec                 C   s4   d | _ d | _d | _d | _g | _d | _d | _d | _d S ©N)ÚnameÚbaseaddressÚsizeÚ
endaddressÚpagesÚversioninfoÚchecksumÚ	timestamp©Úself© r   ú�/root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/pypykatz/commons/readers/local/live_reader.pyÚ__init__   s   
zModule.__init__c                 C   ó   | j |  ko| jk S   S r   )r
   r   ©r   Úaddrr   r   r   Úinrange#   ó   zModule.inrangec                 C   s4   t ƒ }| |_|j|_|j|_|j|j |_||_|S r   )r   r	   ÚlpBaseOfDllr
   ÚSizeOfImager   r   r   )r	   Úmodule_infor   Úmr   r   r   Úparse&   s   zModule.parsec                 C   s(   d| j t| jƒt| jƒt| jƒ| jf S )Nz%s %s %s %s %s)r	   Úhexr
   r   r   r   r   r   r   r   Ú__str__2   s   (zModule.__str__N)Ú__name__Ú
__module__Ú__qualname__r   r   Ústaticmethodr   r!   r   r   r   r   r      s    
r   c                   @   s@   e Zd Zdd„ Zedd„ ƒZdd„ Zdd„ Zd	d
„ Zdd„ Z	dS )ÚPagec                 C   s(   d | _ d | _d | _d | _d | _d | _d S r   )ÚBaseAddressÚAllocationBaseÚAllocationProtectÚ
RegionSizeÚ
EndAddressÚdatar   r   r   r   r   6   s   
zPage.__init__c                 C   s>   t ƒ }| j|_| j|_| j|_t| jdƒ|_| j| j |_|S )Ni  @)r&   r'   r(   r)   Úminr*   r+   )Ú	page_infoÚpr   r   r   r   ?   s   z
Page.parsec                 C   s   t || j| jƒ| _d S r   )ÚReadProcessMemoryr'   r*   r,   )r   Úprocess_handler   r   r   Ú	read_dataI   s   zPage.read_datac                 C   r   r   )r'   r+   r   r   r   r   r   L   r   zPage.inrangec                 C   s”   t |ƒ| jkr	g S t|| j| jƒ}g }d}t |ƒt |ƒkrH| |¡}|dkr(|S | || | j ¡ ||d d … }||d 7 }t |ƒt |ƒks|S )Nr   éÿÿÿÿr   )Úlenr*   r0   r'   ÚfindÚappend)r   Úpatternr1   r,   ÚflÚoffsetÚmarkerr   r   r   ÚsearchO   s   
úzPage.searchc                 C   s   d| j | j| j| jf S )Nz0x%08x 0x%08x %s 0x%08x)r'   r(   r)   r*   r   r   r   r   r!   _   s   zPage.__str__N)
r"   r#   r$   r   r%   r   r2   r   r;   r!   r   r   r   r   r&   5   s    	
	r&   c                   @   s¦   e Zd Zdd„ Zdd„ Zdd„ Zd*dd	„Zd
d„ Zd+dd„Zdd„ Z	dd„ Z
d,dd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zd-d!d"„Zd#d$„ Zd%d&„ Zd.d(d)„ZdS )/ÚBufferedLiveReaderc                 C   s   || _ g | _d | _d | _d S r   )Úreaderr   Úcurrent_segmentÚcurrent_position)r   r=   r   r   r   r   d   s   
zBufferedLiveReader.__init__c                 C   s‚   | j D ]}| |¡r|| _|| _ dS q| jj D ]"}| |¡r:| | jj¡ t |¡}| j  	|¡ || _|| _ dS qt
d| ƒ‚)z
		
		Nz4Memory address 0x%08x is not in process memory space)r   r   r>   r?   r=   r2   r1   ÚcopyÚdeepcopyr6   Ú	Exception)r   Úrequested_positionÚpageÚ
newsegmentr   r   r   Ú_select_segmentk   s    

ý

úz"BufferedLiveReader._select_segmentc                 C   ó   | j S r   )r=   r   r   r   r   Ú
get_reader‚   ó   zBufferedLiveReader.get_readerr   c                 C   sf   |dkr| j j| }n|dkr| j| }n|dkr | j j| }ntdƒ‚| j  |¡s.tdƒ‚|| _dS )aD  
		Changes the current address to an offset of offset. The whence parameter controls from which position should we count the offsets.
		0: beginning of the current memory segment
		1: from current position
		2: from the end of the current memory segment
		If you wish to move out from the segment, use the 'move' function
		r   r   é   z.Seek function whence value must be between 0-2z5Seek would cross memory segment boundaries (use move)N)r>   r'   r?   r+   rB   r   )r   r9   ÚwhenceÚtr   r   r   Úseek…   s   zBufferedLiveReader.seekc                 C   s   |   |¡ dS )z@
		Moves the buffer to a virtual address specified by address
		N)rF   )r   Úaddressr   r   r   Úmoveœ   s   
zBufferedLiveReader.moveNc                 C   sR   |du r| j jtjkrd}nd}| j| }|dkrdS || | }|  |d¡ dS )zD
		Repositions the current reader to match architecture alignment
		Né   é   r   r   )r=   Úprocessor_architecturer   ÚAMD64r?   rM   )r   Ú	alignmentr9   Úoffset_to_alignedr   r   r   Úalign£   s   
zBufferedLiveReader.alignc                 C   rG   )z)
		Returns the current virtual address
		)r?   r   r   r   r   Útell³   s   zBufferedLiveReader.tellc                 C   s@   | j | }| j |¡stdƒ‚| jj| j | jj || jj … S )z@
		Returns up to length bytes from the current memory segment
		ú#Would read over segment boundaries!)r?   r>   r   rB   r,   r'   )r   ÚlengthrL   r   r   r   Úpeek¹   s   
"zBufferedLiveReader.peekr3   c                 C   s    |dk rt dƒ‚|dkr+| j | j¡}|sdS | j}| jj| _| jj|| jj d… S | j| }| j |¡s:t dƒ‚| j}|| _| jj|| jj || jj … S )z‰
		Returns data bytes of size size from the current segment. If size is -1 it returns all the remaining data bytes from memory segment
		r3   zYou shouldnt be doing thisNrX   )rB   r>   Úremaining_lenr?   r+   r,   r'   r   )r   r   rL   Úold_new_posr   r   r   ÚreadÂ   s   

 zBufferedLiveReader.readc                 C   ó:   | j jtjkrtj|  d¡ddd�S tj|  d¡ddd�S )z¯
		Reads an integer. The size depends on the architecture. 
		Reads a 4 byte small-endian singed int on 32 bit arch
		Reads an 8 byte small-endian singed int on 64 bit arch
		rP   ÚlittleT©Ú	byteorderÚsignedrQ   ©r=   rR   r   rS   ÚintÚ
from_bytesr]   r   r   r   r   Úread_intÙ   ó   zBufferedLiveReader.read_intc                 C   r^   )z³
		Reads an integer. The size depends on the architecture. 
		Reads a 4 byte small-endian unsinged int on 32 bit arch
		Reads an 8 byte small-endian unsinged int on 64 bit arch
		rP   r_   Fr`   rQ   rc   r   r   r   r   Ú	read_uintä   rg   zBufferedLiveReader.read_uintc                 C   s$   | j j |¡}|dkrdS || j S )z:
		Searches for a pattern in the current memory segment
		r3   )r>   r,   r5   r?   )r   r7   Úposr   r   r   r5   ï   s   
zBufferedLiveReader.findc                 C   s@   g }d}	 | j j ||d ¡}|dkr	 |S | || j j ¡ q)zp
		Searches for all occurrences of a pattern in the current memory segment, returns all occurrences as a list
		r3   Tr   )r>   r,   r5   r6   Ústart_address)r   r7   ri   Ú
last_foundr   r   r   Úfind_allø   s   þüzBufferedLiveReader.find_allc                 C   s$   | j  |¡}t|ƒdkrdS |d S )zx
		Searches for the pattern in the whole process memory space and returns the first occurrence.
		This is exhaustive!
		r   r3   )r=   r;   r4   )r   r7   Úpos_sr   r   r   Úfind_global  s   zBufferedLiveReader.find_globalrQ   c                 C   s   | j j||d�S )z�
		Searches for the pattern in the whole process memory space and returns a list of addresses where the pattern begins.
		This is exhaustive!
		)Úallocationprotect)r=   r;   )r   r7   ro   r   r   r   Úfind_all_global  s   z"BufferedLiveReader.find_all_globalc                 C   s   |   |¡ |  ¡ S r   )rO   rh   )r   ri   r   r   r   Úget_ptr  s   
zBufferedLiveReader.get_ptrc                 C   sL   | j jtjkr|  |¡ tj|  d¡ddd�}|d | S |  |¡ |  ¡ S )NrQ   r_   Tr`   )	r=   rR   r   rS   rO   rd   re   r]   rh   )r   ri   Úptrr   r   r   Úget_ptr_with_offset  s   

z&BufferedLiveReader.get_ptr_with_offsetFc                 C   s   | j j||||d�}|S )N)Ú
find_firstÚreverse_order)r=   Úsearch_module)r   Úmodule_namer7   rt   ru   rL   r   r   r   Úfind_in_module'  s   z!BufferedLiveReader.find_in_module)r   r   )r3   ©rQ   ©FF)r"   r#   r$   r   rF   rH   rM   rO   rV   rW   rZ   r]   rf   rh   r5   rl   rn   rp   rq   rs   rx   r   r   r   r   r<   c   s&    


		
	r<   c                   @   s\   e Zd Zddd„Zdd„ Zdd„ Zd	d
„ Zddd„Zdd„ Zdd„ Z	ddd„Z
ddd„ZdS )Ú
LiveReaderNú	lsass.exec                 C   sJ   d | _ || _|| _|| _d | _d | _g | _g | _d | _|  	¡  |  
¡  d S r   )rR   Úprocess_namer1   Úprocess_pidr?   ÚBuildNumberÚmodulesr   Úmsv_dll_timestampÚsanity_checkÚsetup)r   r1   r}   r~   r   r   r   r   -  s   zLiveReader.__init__c                 C   sH   t jdk}t ¡ dk}t ¡  d¡}|dkrtdƒ‚||kr"tdƒ‚dS )zæ
		Check if user is insane
		Windows API functions don't like when a 32 bit process is accessing a 64 bit process's memory space,
		Therefore you must use a 64 bit python on a 64bit Windows and a 32bit python on a 32bit Windows
		l        ÚWindowsÚ64FzThis will only run on WindowszPPython interpreter must be the same architecure of the OS you are running it on.N)ÚsysÚmaxsizeÚplatformÚsystemÚmachineÚendswithrB   )r   Úis_python_64Ú
is_windowsÚis_windows_64r   r   r   r‚   <  s   
ÿzLiveReader.sanity_checkc                 C   sD  t  dd¡ tƒ  t  dd¡ tƒ }t|jjjƒ| _t  dd¡ t	 
t	jd¡}t	 |d¡\}}t|ƒ| _| jd u r„| jd u re| jd u rGtdƒ‚t  dd¡ t| jƒ| _t  dd	| j| jf ¡ t  dd
¡ t  dd| j ¡ ttd| jƒ| _| jd u rƒtdt ¡  ƒ‚nt  d¡ t  dd¡ t| jƒ}|D ]5}t| j|ƒ}t  d|¡ d}t |¡ ¡ dkrºtt |¡j ƒ}|| _!t"| j|ƒ}	| j# $t% &||	|¡¡ q–t  ddt'| j#ƒ ¡ |j(}
|
|j)k røt*| j|
ƒ}| j+ $t, &|¡¡ |
|j-7 }
|
|j)k sßt  ddt'| j+ƒ ¡ | j+D ]}| j#D ]}| .|j/¡dk�r|j+ $|¡ �q�qd S )Nr   zEnabling debug privilegezGetting generic system infozGetting build numberz-SOFTWARE\Microsoft\Windows NT\CurrentVersion\ÚCurrentBuildNumberz5Process name or PID or opened handle must be providedzSearching for lsass.exez%s found at PID %dz$Checking Lsass.exe protection statusz
Opening %sFz#Failed to open lsass.exe Reason: %szUsing pre-defined handlezEnumerating modulesr   z
msv1_0.dllzFound %d moduleszFound %d pagesT)0r   Úlogr   ÚGetSystemInfor   ÚidÚwÚwProcessorArchitecturerR   ÚwinregÚOpenKeyÚHKEY_LOCAL_MACHINEÚQueryValueExrd   r   r1   r~   r}   rB   Úpid_for_nameÚOpenProcessÚPROCESS_ALL_ACCESSÚctypesÚWinErrorÚdebugÚEnumProcessModulesÚGetModuleFileNameExWÚntpathÚbasenameÚlowerÚosÚstatÚst_ctimer�   ÚGetModuleInformationr€   r6   r   r   r4   ÚlpMinimumApplicationAddressÚlpMaximumApplicationAddressÚVirtualQueryExr   r&   r*   r   r'   )r   ÚsysinfoÚkeyÚbuildnumberrL   Úmodule_handlesÚmodule_handleÚmodule_file_pathr   ÚmodinfoÚcurrent_addressr.   rD   Úmodr   r   r   rƒ   K  sb   



	
ÿ




ü

€þÿzLiveReader.setupc                 C   rG   r   )r1   r   r   r   r   Úget_handler�  rI   zLiveReader.get_handlerrQ   c                 C   s(   g }| j D ]}|j|@ r| |¡ q|S r   )r   r)   r6   )r   ro   rL   rD   r   r   r   Ú
get_memory�  s   


€zLiveReader.get_memoryc                 C   s   t | ƒS r   )r<   r   r   r   r   Úget_buffered_reader—  s   zLiveReader.get_buffered_readerc                 C   s0   | j D ]}|j ¡  | ¡ ¡dkr|  S qd S )Nr3   )r€   r	   r£   r5   )r   rw   r³   r   r   r   Úget_module_by_nameš  s
   
ÿzLiveReader.get_module_by_nameFc                 C   s`   |   |¡}|d u rtd| ƒ‚g }|jD ]}|| || j¡7 }t|ƒdkr-|du r-|  S q|S )NzCould not find module! %sr   T)r·   rB   r   r;   r1   r4   )r   rw   r7   rt   ru   r³   ÚneedlesrD   r   r   r   rv      s   

€zLiveReader.search_modulec                 C   s0   g }| j D ]}|j|@ r|| || j¡7 }q|S r   )r   r)   r;   r1   )r   r7   ro   rL   rD   r   r   r   r;   ¬  s   

€zLiveReader.search)Nr|   Nry   rz   )r"   r#   r$   r   r‚   rƒ   r´   rµ   r¶   r·   rv   r;   r   r   r   r   r{   ,  s    
B

r{   Ú__main__)Úleveli   )Úcommon.live_reader_ctypesÚcommon.privilegesr   Úcommon.psapiÚcommon.versionÚcommon.kernel32Úcommon.fileinfoÚ!minidump.streams.SystemInfoStreamr   Úpypykatzr   r†   r@   rˆ   r¤   r¡   r•   r   r&   r<   r{   r"   ÚbasicConfigÚlrr¶   ÚblrrO   r   r   r   r   Ú<module>   s4   . J û