o
    j                     @   s  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d dl	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mZ d	Zd Zd	Zd
ZdZdZdZdZdZdZdZdZ dZ!dZ"dZ#dZ$dZ%dZ&dZ'dZ(dZ)dZ*dZ+dZ,d Z-dZ.dZ/d Z0dZ1dZ2d!Z3d"Z4d#Z5dZ6dZ7d!Z8d	Z9d
Z:dZ;dZ<dZ=d$Z>d%Z?d&Z@dZAd'ZBdZCd(ZDd)ZEd*ZFd+ZGd ZHdZIdZJd ZKd!ZLd,ZMd-ZNd.ZOd"ZPd/ZQd0ZRd1ZSd ZTdZUd ZVdZWd ZXdZYdZZd2Z[G d3d4 d4eZ\G d5d6 d6eZ]G d7d8 d8eZ^G d9d: d:eZ_G d;d< d<eZ`G d=d> d>eZaG d?d@ d@eZbG dAdB dBeZcG dCdD dDeZdG dEdF dFeZeG dGdH dHeZfG dIdJ dJeZgG dKdL dLeZhG dMdN dNeZiG dOdP dPeZjG dQdR dReZkdSdT ZlG dUdV dVZmG dWdX dXemZnG dYdZ dZemZoG d[d\ d\eoZpG d]d^ d^ZqG d_d` d`ZrG dadb dbZsG dcdd ddZtG dedf dfZuG dgdh dhZvG didj djZwG dkdl dlZxG dmdn dnZyG dodp dpejzZ{dqdr Z|e}dskre|  e~d dS dS )t    )division)print_functionN)PY2	text_type)datetime)logger)version)	Structurehexdump       0   @   P   `   p                              i   l          i @  i               i    i   i   i    i  i1  i   i             	   
        c                   @      e Zd ZdZdS )NTFS_BPB))BytesPerSector<H=0)SectorsPerClusterB=0)ReservedSectorsr,   Reserved3s=b"")	Reserved22s=b"")MediaDescriptionr.   )	Reserved3r4   )	Reserved4r,   )	Reserved5r,   )	Reserved6<L=0)	Reserved74s=b""N__name__
__module____qualname__	structure rB   rB   /root/aizidognhua/tmp/workspace/projects/ec89d86c-575f-41c9-af57-ac45cbdbf775/venv/lib/python3.10/site-packages/../../../bin/ntfs-read.pyr*          r*   c                   @   r)   )NTFS_EXTENDED_BPB)
)r1   r<   )TotalSectors<Q=0)MFTClusterNumberrG   )MFTMirrClusterNumberrG   )ClusterPerFileRecordzb=0)r3   r2   )ClusterPerIndexBufferz<b=0)r6   r2   )VolumeSerialNumber8s=b"")CheckSumr<   Nr=   rB   rB   rB   rC   rE      rD   rE   c                   @   r)   )NTFS_BOOT_SECTOR))JmpInstrr2   )OEM_IDrM   )BPBz25s=b"")ExtendedBPBz48s=b"")	Bootstrapz426s=b"")EOSr,   Nr=   rB   rB   rB   rC   rO      rD   rO   c                   @   r)   )NTFS_MFT_RECORD))
MagicLabelr<   	USROffsetr,   USRSizer,   )	LogSeqNumrG   )SeqNumr,   )	LinkCountr,   )AttributesOffsetr,   Flagsr,   )
BytesInUser:   )BytesAllocatedr:   )BaseMftRecordrG   )NextAttrInstancer,   r1   r,   )RecordNumberr:   Nr=   rB   rB   rB   rC   rV      rD   rV   c                   @   s   e Zd ZdZdZdS )NTFS_ATTRIBUTE_RECORD)Typer:   )Lengthr:   )NonResidentr.   )
NameLengthr.   )
NameOffsetr,   r`   )Instancer,   rB   N)r>   r?   r@   	commonHdrrA   rB   rB   rB   rC   rh      s    	rh   c                   @   r)   )"NTFS_ATTRIBUTE_RECORD_NON_RESIDENT))	LowestVCNrG   )
HighestVCNrG   )DataRunsOffsetr,   )CompressionUnitr,   )	Reserved1z4s=""AllocatedSizerG   DataSizerG   )InitializedSizerG   Nr=   rB   rB   rB   rC   rq      rD   rq   c                   @   r)   )NTFS_ATTRIBUTE_RECORD_RESIDENT))ValueLenr:   )ValueOffsetr,   ra   r.   )r1   r.   Nr=   rB   rB   rB   rC   r|      rD   r|   c                   @   r)   )NTFS_FILE_NAME_ATTR))ParentDirectoryrG   CreationTimerG   LastDataChangeTimerG   LastMftChangeTimerG   LastAccessTimerG   rw   ry   FileAttributesr:   )EaSizer:   )FileNameLenr.   )FileNameTyper.   )	_FileNamez
_-FileNamezself["FileNameLen"]*2)FileName:Nr=   rB   rB   rB   rC   r      rD   r   c                   @   r)   )NTFS_STANDARD_INFORMATION)r   r   r   r   r   Nr=   rB   rB   rB   rC   r      rD   r   c                   @   r)   )NTFS_INDEX_HEADER))EntriesOffsetr:   )IndexLengthr:   )rx   r:   r   r0   Nr=   rB   rB   rB   rC   r      rD   r   c                   @   "   e Zd ZdddddddeffZdS )	NTFS_INDEX_ROOTri   )CollationRuler:   )IndexBlockSizer:   )ClustersPerIndexBlockr.   r0   Indexr   Nr>   r?   r@   r   rA   rB   rB   rB   rC   r         r   c                   @   r   )	NTFS_INDEX_ALLOCATION)Magicr<   rX   rZ   )LsnrG   )IndexVcnrG   r   r   Nr   rB   rB   rB   rC   r     r   r   c                   @   r)   )NTFS_INDEX_ENTRY_HEADER))IndexedFilerG   )rk   r,   )	KeyLengthr,   r`   rf   Nr=   rB   rB   rB   rC   r     rD   r   c                   @   s$   e Zd ZdZddefddddfZdS )	NTFS_INDEX_ENTRYr    EntryHeaderr   )_Keyz_-Keyz self["EntryHeader"]["KeyLength"])Keyr   )_Vcnz_-Vcnz$(self["EntryHeader"]["Flags"] & 1)*8)Vcnr   N)r>   r?   r@   	alignmentr   rA   rB   rB   rB   rC   r      s    r   c                   @   r)   )NTFS_DATA_RUN))LCNz<q=0)ClustersrG   )StartVCNrG   )LastVCNrG   Nr=   rB   rB   rB   rC   r   *  rD   r   c                   @   r)   )NTFS_ATTRIBUTE_LIST_ENTRY))AttributeTyper:   )EntryLengthr,   )AttributeNameLengthr.   )AttributeNameOffsetr.   )StartingVCNrG   )BaseFileRecordrG   )AttributeIDr,   Nr=   rB   rB   rB   rC   r   2  rD   r   c                 C   s   | d8 } | d } | S )Nl     }*{Gi rB   )trB   rB   rC   getUnixTime=  s   r   c                   @   D   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dS )	Attributec                 C   sl   d | _ |j| _t|| _| jd dkr2| jd tkr4|| jd d  d | jd d  d| _ d S d S d S )Nrm   r   rj   rn   r   utf-16le)AttributeName
NTFSVolumerh   AttributeHeaderENDdecodeselfiNodedatarB   rB   rC   __init__D  s   
0zAttribute.__init__c                 C   
   | j d S Nra   r   r   rB   rB   rC   getFlagsK     
zAttribute.getFlagsc                 C      | j S N)r   r   rB   rB   rC   getNameN     zAttribute.getNamec                 C   r   )Nrl   r   r   rB   rB   rC   isNonResidentQ  r   zAttribute.isNonResidentc                 C   
   | j  S r   )r   dumpr   rB   rB   rC   r   T  r   zAttribute.dumpc                 C   r   )Nrk   r   r   rB   rB   rC   getTotalSizeW  r   zAttribute.getTotalSizec                 C   r   Nrj   r   r   rB   rB   rC   getTypeZ  r   zAttribute.getTypeN)
r>   r?   r@   r   r   r   r   r   r   r   rB   rB   rB   rC   r   C  s    r   c                   @   s<   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd ZdS )AttributeResidentc                 C   s\   t d|j  t| || t|t| jd  | _|| jd d  d | jd  | _	d S )Nz#Inside AttributeResident: iNode: %sr~   r}   )
loggingdebugINodeNumberr   r   r|   lenr   ResidentHeader	AttrValuer   rB   rB   rC   r   ^  s   &zAttributeResident.__init__c                 C   r   r   )r   r   r   rB   rB   rC   r   d  r   zAttributeResident.dumpc                 C   r   r   )r   r   rB   rB   rC   r   g  r   zAttributeResident.getFlagsc                 C   r   r   )r   r   rB   rB   rC   getValuej  r   zAttributeResident.getValuec                 C   s(   t d||f  | j|d  d | S )N#Inside Read: offset: %d, length: %d)r   r   r   r   offsetlengthrB   rB   rC   readm  s   zAttributeResident.readc                 C   
   t | jS r   )r   r   r   rB   rB   rC   getDataSizeq  r   zAttributeResident.getDataSizeN)	r>   r?   r@   r   r   r   r   r   r   rB   rB   rB   rC   r   ]  s    r   c                   @   L   e Zd Zdd Zdd Zdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dS )AttributeNonResidentc                 C   s   t d|j  t| || || _t|t| jd  | _	|| j	d d  d | j	d  | _
g | _d| _| j	d | _| j	d | _|   d S )Nz&Inside AttributeNonResident: iNode: %srt   rx   r   rz   r{   )r   r   r   r   r   _raw_attr_datarq   r   r   NonResidentHeaderr   DataRunsClusterSize	data_sizeinitialized_sizeparseDataRunsr   rB   rB   rC   r   u  s   "zAttributeNonResident.__init__c                 C   r   r   )r   r   r   rB   rB   rC   r     r   zAttributeNonResident.dumpc                 C   r   r   )r   r   rB   rB   rC   r     r   z AttributeNonResident.getDataSizec                 C      d S r   rB   r   rB   rB   rC   r        zAttributeNonResident.getValuec                 C   s  | j }|du r	dS d}d}|r|dd dkrt|dk rdS |d }|dd }|d@ }|d? }t||k r9dS td|d| ddd }||d }t }||d	< ||d
< || d |d< |dkrwd|d< td|d
 |d | n7t||k rdS |d| }	|	d d@ r|	dd}	n|	dd}	td|	d }
||d }||
7 }||d< | j	| ||7 }|r|dd dksdS dS dS dS )z4Parse data run descriptors from the attribute value.Nr   r          r   <Qr    r   r   r   r   z"Sparse run: VCN %d-%d, clusters %dr      z<q)
r   r   structunpackljustr   r   r   r   append)r   r   vcnprevLcnheaderlengthBytesoffsetBytesclusterCountdr
offsetDatalcnDeltarB   rB   rC   r     sH    $z"AttributeNonResident.parseDataRunsc                 C   s   t d||f  |dkrd| | j S | jj|| j d | jj|| j }t||| j k rK|| jj|| j t| 7 }t||| j k s2t|dkrSd S |S )Nz(Inside ReadClusters: clusters:%d, lcn:%dr   r   r   )r   r   r   r   volumeFDseekr   r   )r   clusterslcnbufrB   rB   rC   readClusters  s    z!AttributeNonResident.readClustersc           
      C   s   t d||f  d}|}| jD ]R}|dkr |S ||d kr q||d k r) |S |d | d }t||}|d dkr?d}n
|d ||d   }| ||}	|	d	u rV |S ||	7 }||8 }||7 }q|S )
zERead clusters starting at VCN, spanning multiple data runs if needed.z*Inside ReadVCN: vcn: %d, numOfClusters: %d    r   r   r   r   r   r   N)r   r   r   minr	  )
r   r   numOfClustersr  clustersLeftr  clustersInRunclustersToReadr  tmpBufrB   rB   rC   readVCN  s2   


zAttributeNonResident.readVCNc                 C   sH  t d||f  || jkrdS t|| j| }| jjd | jjd  | _d}|}|}|dkr|| j }|| j }| j| }||krEd}	nd|| | j d | j  }	| ||	}
|
s\n#|
|||  }||7 }|t|7 }|t|8 }t|dkr{n|dks/|sdS | j	|t| k rt
d| j	| }|d| dt||   }|S )	zRRead bytes from non-resident attribute, respecting data_size and initialized_size.r   r
  r+   r-   r   r   Nr   )r   r   r   r  r   rR   r   r  r   r   max)r   r   r   r  	curOffset	bytesLeftr   	vcnOffsetbytesInFirstClusterr  clusterDatachunk
validBytesrB   rB   rC   r     s>   



zAttributeNonResident.readN)r>   r?   r@   r   r   r   r   r   r	  r  r   rB   rB   rB   rC   r   t  s    5#r   c                       sV   e Zd Zedd Zedd Zedd Zedd Zd fd
d	Zdd Z	  Z
S )NonResidentDataAttributec                 C   s<   |dkrd S |j D ]}|d  |7  < |d  |7  < q	d S )Nr   r   r   )r   )clsattr	start_vcnr  rB   rB   rC   _shift_runs#  s   
z$NonResidentDataAttribute._shift_runsc                 C   s   |j d |j d fS )Nrz   r{   )r   )r  r  rB   rB   rC   _base_sizes+  s   z$NonResidentDataAttribute._base_sizesc                 C   s6   |d ur	|||fS |d \}}|  |\}}|||fS Nr   )r  )r  	collected	base_attrbase_data_sizebase_initialized_size_rB   rB   rC   _ensure_base/  s
   

z%NonResidentDataAttribute._ensure_basec                 C   s~   g }d}d}d}|D ].}|j |j}	|	t|}
|
du rq
|||
f |jdkr8|
}t|
tr8| 	|
\}}q
||||fS )zJCollect $DATA attributes from extent records, identifying the base extent.Nr   )
r   getINodeMftRecordNumbersearchAttributeDATAr   r   
isinstancer   r  )r  r   matchesattribute_namer!  r"  r#  r$  entryextension_inoder  rB   rB   rC   _collect_extents7  s    

z)NonResidentDataAttribute._collect_extentsNc                    s   t |}|s
td|jdd d | |||\}}}}|s#td| ||||\}}}tt| ||j t	|dkrM|d \}	}
| 
| |	j dS | ||| dS )	a   
        Build a unified $DATA stream from multiple attribute list entries.

        Args:
            iNode: Owning inode for volume access
            entries: AttributeListEntry items for the target $DATA stream
            attribute_name: Stream name (None for default $DATA)
        zNo $DATA extents foundc                 S   r   r   )r   )erB   rB   rC   <lambda>[  s    z3NonResidentDataAttribute.__init__.<locals>.<lambda>keyzNo usable $DATA extents foundr   r   N)list
ValueErrorsortr0  r&  superr  r   r   r   r  r   _merge_extents_from_collected)r   r   entriesr-  r,  r!  r"  r#  r$  r.  r%  	__class__rB   rC   r   M  s"   	
z!NonResidentDataAttribute.__init__c           	      C   s   g }|D ]6\}}t |tsq|jD ](}t }|d |d< |d |d< |d |j |d< |d |j |d< || qq|jdd d || _|| _|| _dS )	z:Merge data runs from multiple extents into unified stream.r   r   r   r   c                 S   s   | d S )Nr   rB   )r  rB   rB   rC   r2    s    zHNonResidentDataAttribute._merge_extents_from_collected.<locals>.<lambda>r3  N)	r+  r   r   r   r   r   r7  r   r   )	r   r!  r   	init_sizemerged_runsr.  r  r  new_drrB   rB   rC   r9  u  s    

	
z6NonResidentDataAttribute._merge_extents_from_collectedr   )r>   r?   r@   classmethodr  r  r&  r0  r   r9  __classcell__rB   rB   r;  rC   r  "  s    



(r  c                   @   ,   e Zd Zdd Zdd Zdd Zdd Zd	S )
AttributeStandardInfoc                 C   "   t d || _t| jj| _d S )NzInside AttributeStandardInfo)r   r   r   r   r   StandardInfor   	attributerB   rB   rC   r        
zAttributeStandardInfo.__init__c                 C   r   Nr   )rE  r   rB   rB   rC   getFileAttributes  r   z'AttributeStandardInfo.getFileAttributesc                 C   s&   | j d dkrtt| j d S dS )Nr   r   )rE  r   fromtimestampr   r   rB   rB   rC   getFileTime  s   z!AttributeStandardInfo.getFileTimec                 C   r   r   )rE  r   r   rB   rB   rC   r     r   zAttributeStandardInfo.dumpN)r>   r?   r@   r   rJ  rL  r   rB   rB   rB   rC   rC    s
    rC  c                   @   r   )AttributeFileNamec                 C   rD  )NzInside AttributeFileName)r   r   r   r   r   FileNameRecordrF  rB   rB   rC   r     rH  zAttributeFileName.__init__c                 C   r   )Nr   rN  r   rB   rB   rC   getFileNameType  r   z!AttributeFileName.getFileNameTypec                 C   r   rI  rO  r   rB   rB   rC   rJ    r   z#AttributeFileName.getFileAttributesc                 C   s   | j d dS )Nr   r   )rN  r   r   rB   rB   rC   getFileName     zAttributeFileName.getFileNamec                 C   r   )Nrz   rO  r   rB   rB   rC   getFileSize  r   zAttributeFileName.getFileSizec                 C   r   rI  rO  r   rB   rB   rC   r     r   zAttributeFileName.getFlagsc                 C   r   r   )rN  r   r   rB   rB   rC   r     r   zAttributeFileName.dumpN)
r>   r?   r@   r   rP  rJ  rQ  rS  r   r   rB   rB   rB   rC   rM    s    rM  c                   @   s$   e Zd Zdd Zdd Zdd ZdS )AttributeIndexAllocationc                 C   s   t d || _d S )NzInside AttributeIndexAllocation)r   r   r   rF  rB   rB   rC   r     s   

z!AttributeIndexAllocation.__init__c                 C   s,   t | j  | jjD ]}t |  qd S r   )printr   r   r   r   irB   rB   rC   r     s   zAttributeIndexAllocation.dumpc                 C   s   | j ||S r   )r   r   r   rB   rB   rC   r        zAttributeIndexAllocation.readN)r>   r?   r@   r   r   r   rB   rB   rB   rC   rT    s    rT  c                   @   rB  )
AttributeIndexRootc                 C   s.   t d || _t|j| _g | _|   d S )NzInside AttributeIndexRoot)r   r   r   r   r   IndexRootRecordIndexEntriesparseIndexEntriesrF  rB   rB   rC   r     s
   
zAttributeIndexRoot.__init__c                 C   sJ   | j jt| jd  }	 t|}| j| | rd S || d  }qr   )	r   r   r   rZ  
IndexEntryr[  r   
isLastNodegetSize)r   r   ierB   rB   rC   r\    s   z$AttributeIndexRoot.parseIndexEntriesc                 C   s"   | j   | jD ]}|  qd S r   )rZ  r   r[  rV  rB   rB   rC   r     s   


zAttributeIndexRoot.dumpc                 C   r   r   )rZ  r   rB   rB   rC   r     r   zAttributeIndexRoot.getTypeN)r>   r?   r@   r   r\  r   r   rB   rB   rB   rC   rY    s
    	rY  c                   @   r   )r]  c                 C   s   t || _d S r   )r   r.  )r   r.  rB   rB   rC   r     rX  zIndexEntry.__init__c                 C      | j d d t@ S Nr   ra   )r.  INDEX_ENTRY_NODEr   rB   rB   rC   	isSubNode     zIndexEntry.isSubNodec                 C   ra  rb  )r.  INDEX_ENTRY_ENDr   rB   rB   rC   r^    re  zIndexEntry.isLastNodec                 C   s   t d| jd d S )Nr   r   r   )r   r   r.  r   rB   rB   rC   getVCN  s   zIndexEntry.getVCNc                 C   r   r   )r   r.  r   rB   rB   rC   r_    r   zIndexEntry.getSizec                 C   r   )Nr   r.  r   rB   rB   rC   getKey  r   zIndexEntry.getKeyc                 C   s   | j d d d@ S )Nr   r       rh  r   rB   rB   rC   getINodeNumber  re  zIndexEntry.getINodeNumberc                 C   s   | j   d S r   )r.  r   r   rB   rB   rC   r     rX  zIndexEntry.dumpN)r>   r?   r@   r   rd  r^  rg  r_  ri  rk  r   rB   rB   rB   rC   r]    s    r]  c                   @   s   e Zd Zdd ZdS )AttributeListEntryc                 C   s   t || _| jd | _| jd | _| jd | _| jd | _| jd }|d@ | _|d? d@ | _d | _| jd	 }|d
krQ| jd }||||d   }|	d| _d S d S )Nr   r   r   r   r   rj  r   r(   r   r   r   r   r   )
r   r   r   r   r   r   r(  MftSequenceNumberr   r   )r   
entry_data
raw_recordname_lenname_offset
name_bytesrB   rB   rC   r     s   




zAttributeListEntry.__init__N)r>   r?   r@   r   rB   rB   rB   rC   rl    s    rl  c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	AttributeListzBParses ATTRIBUTE_LIST attribute (can be resident or non-resident).c                 C   s   || _ g | _|   d S r   )rG  Entries_parseEntriesrF  rB   rB   rC   r     s   zAttributeList.__init__c                 C   s   t | jdr| j dur| j }n
| jd| j }|s!dS d}|t|k rU||d }t|dk r7dS t|}|jdkrBdS | j	| ||j7 }|t|k s)dS dS )z+Parse attribute list entries from raw data.r   Nr      )
hasattrrG  r   r   r   r   rl  r   rt  r   )r   r   r   rn  
list_entryrB   rB   rC   ru    s    

zAttributeList._parseEntriesc                 C   r   r   )rt  r   rB   rB   rC   
getEntries#  r   zAttributeList.getEntriesN)r>   r?   r@   __doc__r   ru  ry  rB   rB   rB   rC   rs    s
    rs  c                   @   s   e Zd Zdd Zdd Z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 Zdd Zdd Zdd Zd d! Zd"S )$INODEc                 C   sF   || _ d | _i | _d | _d | _d| _d | _d | _d| _d| _	d| _
d S r   )r   r   
AttributesAttributesRawAttributesLastPosr   r   r   FileSize_walk_root_count_walk_subnode_count)r   r   rB   rB   rC   r   '  s   
zINODE.__init__c                 C   
   | j t@ S r   )r   FILE_ATTR_I30_INDEX_PRESENTr   rB   rB   rC   isDirectory7  r   zINODE.isDirectoryc                 C   r  r   )r   FILE_ATTR_COMPRESSEDr   rB   rB   rC   isCompressed:  r   zINODE.isCompressedc                 C   r  r   )r   FILE_ATTR_ENCRYPTEDr   rB   rB   rC   isEncrypted=  r   zINODE.isEncryptedc                 C   r  r   )r   FILE_ATTR_SPARSE_FILEr   rB   rB   rC   isSparse@  r   zINODE.isSparsec              
   C   s   | j d ur?| jd urAztd|  | j d| j| jf  W d S  ty> } ztd| j	t
|f  W Y d }~d S d }~ww d S d S )Nz%s %s %15d %s  z-Exception when trying to display inode %d: %s)r   r   rU  getPrintableAttributes	isoformatr  	Exceptionr   errorr   str)r   r1  rB   rB   rC   displayNameC  s   *&zINODE.displayNamec                 C   s   d}| j t@ r|d7 }n|d7 }| j t@ r|d7 }n|d7 }| j t@ r(|d7 }n|d7 }|  r5|d7 }n|d7 }|  rB|d7 }n|d7 }|  rP|d7 }|S |d7 }|S )	N d-hSCEs)r   r  FILE_ATTR_HIDDENFILE_ATTR_SYSTEMr  r  r  )r   maskrB   rB   rC   r  K  s*   







zINODE.getPrintableAttributesc                 C   s6  |  td }|d ur&t|}|| jt< |  j| O  _| | _|| jt< |  td }|d ur^t	|}|
 tkrS| | _| | _|  j| O  _|| jt< n|  td d}|d us0|  td }|d urqt|}|| jt< |  td}|d urt|}|| jt< |  td}|d urt|}|| jt< d S d S )NTz$I30)r)  STANDARD_INFORMATIONrC  r|  r   rJ  rL  r   	FILE_NAMErM  rP  FILE_NAME_DOSrQ  r   rS  r  ATTRIBUTE_LISTrs  INDEX_ALLOCATIONrT  
INDEX_ROOTrY  )r   r  sifnaliairrB   rB   rC   parseAttributesg  s>   







zINODE.parseAttributesFc           
         sp  t d| f  d }|du r| j}n| j}	 t|dkr d }nGt| |}| tkr.d }n9| dkr7d }n0| |kr^|	  kr^|
 dkrOt| |}nt| |}|| d  | _n	|| d  }q|d u rt| jv r| jt }|tkr fdd| D }zt| | W S  ty   Y d S w | D ]}|j|kr|j kr| j|j}	|	|   S q|S )Nz,Inside searchAttribute: type: 0x%x, name: %sTr    r   r   c                    s$   g | ]}|j tkr|j kr|qS rB   )r   r*  r   ).0r.  attributeNamerB   rC   
<listcomp>  s
    z)INODE.searchAttribute.<locals>.<listcomp>)r   r   r~  r}  r   r   r   r   r   r   r   r   r   r  r|  r*  ry  r  r6  r   r   r   r'  r(  r)  )
r   attributeTyper  findNextrecordr   	attr_listr:  r.  r/  rB   r  rC   r)    sR   



zINODE.searchAttributec           
      C   s  t d td||d d  d d d }||d d d  d |d d  }t|}d}td|d dD ]>}|| jjd 7 }td||d  d d d }	|	|krat d||	f   d S || ||< ||d  ||d < |d7 }q7t	r}d	
|S t|S )
NzInside PerformFixUp...z<HrY   r   r   r[   z)Magic number 0x%x doesn't match with 0x%xr   r  )r   r   r   r   r5  ranger   
SectorSizer  r   joinbytes)
r   r  r  
numSectorsmagicNumsequenceArraydataListindexrW  	lastBytesrB   rB   rC   PerformFixUp  s"   
$$ 

zINODE.PerformFixUpc                 C   s   g }t | jv r`| jt  }||| jj | jj}|r`t|}| jj| jj }| |||}|d u r3g S |t|tt	  |d d  d  }	 t
|}|| | rW	 |S || d  }qG|S )Nr   r   )r  r|  r   r   r   r   r  r  r   r   r]  r   r^  r_  )r   r   r[  r  r   iaRecsectorsPerIBr`  rB   rB   rC   parseIndexBlocks  s(   

&
zINODE.parseIndexBlocksc                 C   s   t d|  | |}g }|D ]/}| r || | 7 }qt| dkr?| dkr?t	| }|d t
kr?|| q|S )NzInside walkSubNodes: vcn %sr   r   r   )r   r   r  rd  walkSubNodesrg  r   ri  rk  r   r  r   )r   r   r:  filesr.  r  rB   rB   rC   r    s   

zINODE.walkSubNodesc                 C   s   t d g }d| _d| _t| jv ry| jt }| t@ rw|jD ]T}|	 rCt d|
  | |
 }|  jt|7  _||7 }q t| dkrt| dkrtt| }|d tkrtt d|d d |  jd	7  _|| q |S d S d S )
NzInside Walk... r   z/walk: INDEX_ROOT entry points to subnode VCN %dr   r   z walk: INDEX_ROOT inline entry %sr   r   r   )r   r   r  r  r  r|  r   r  r[  rd  rg  r  r   ri  rk  r   r  r   r   )r   r  r  r`  	sub_filesr  rB   rB   rC   walk  s.   





z
INODE.walkc                 C   s   dd }|  |}|D ]C}||}|d ur:||kr|  S ||k r9| r6| | |}|d ur5|  S q d S q| rN| | |}|d urN|  S qd S )Nc                 S   J   t |  dkr#|  dkr#t|  }|d tkr#|d d S d S Nr   r   r   r   r   r   ri  rk  r   r  r   upperr.  r  rB   rB   rC   rQ  0  
   z+INODE.findFirstSubNode.<locals>.getFileName)r  rd  findFirstSubNoderg  )r   r   toSearchrQ  r:  r`  nameresrB   rB   rC   r  /  s*   
	zINODE.findFirstSubNodec                 C   s   dd }t | }t| jv re| jt }| t@ sddkrg|jD ]G}||}|d urP||kr3|  S ||k rO| rL| |	 |}|d urK|  S q! d S q!| rd| |	 |}|d urd|  S q!d S d S d S )Nc                 S   r  r  r  r  rB   rB   rC   rQ  P  r  z$INODE.findFirst.<locals>.getFileNamer   )
r   r  r  r|  r   r  r[  rd  r  rg  )r   fileNamerQ  r  r  r`  r  r  rB   rB   rC   	findFirstM  s4   


	zINODE.findFirstc                 C   s   | j t|ddS )NF)r  )r)  r*  )r   r  rB   rB   rC   	getStreamp  rR  zINODE.getStreamN)F)r>   r?   r@   r   r  r  r  r  r  r  r  r)  r  r  r  r  r  r  r  rB   rB   rB   rC   r{  &  s"    
': #r{  c                   @   rB  )
NTFSc                 C   sH   || _ d | _d | _d | _d | _d | _d | _d | _d | _d | _	| 
  d S r   )_NTFS__volumeName_NTFS__bootSector_NTFS__MFTStartr  rR   rS   
RecordSizer   r  MFTINodemountVolume)r   
volumeNamerB   rB   rC   r   u  s   zNTFS.__init__c                 C   sT   t d t| jd| _|   | t| _| j	t
d }|d u r(| `d | _d S d S )NzMounting volume...rb)r   r   openr  r  readBootSectorr'  FILE_MFTr  r)  r*  )r   r  rB   rB   rC   r    s   

zNTFS.mountVolumec                 C   s@  t d| j  | jdd | jd}t|dk r)|| jd7 }t|dk st|| _t	| jd | _
t| jd | _| j
d | _| j
d | j
d  | jd  | _| jd	 dkrl| j
d | j
d  | jd	  | _n	d
| jd	  > | _| jd dkr| j
d | j
d  | jd  | _n	d
| jd  > | _t d| j  d S )NzReading Boot Sector for %sr   r!   rR   rS   r+   r-   rH   rJ   r   rK   zMFT should start at position %d)r   r   r  r  r  r   r   rO   r  r*   rR   rE   rS   r  r  r  r   )r   r   rB   rB   rC   r    s$   
 ""zNTFS.readBootSectorc                 C   sD  t d|  t| }| j}| jr4|tkr4| jtd }|d u r)t d|  |S |	|| j | j}n-| j
|| j  }| j|d | j	|}t||k ra|| j	|t| 7 }t||k sO|rit||k rrt d|  |S t|}|||| j| j }|d u rt d|  |S ||_||d | d  |_|  |S )NzTrying to fetch inode %dz,Cannot find MFT $DATA attribute for inode %dr   z&Failed to read MFT record for inode %dzFixUp failed for inode %dr_   )r   r   r{  r  r  
FIXED_MFTSr)  r*  r  r   r  r  r  r   rV   r  r  r   r}  r  )r   iNodeNumnewINode	recordLenr  r  diskPosition	mftRecordrB   rB   rC   r'    s6   zNTFS.getINodeN)r>   r?   r@   r   r  r  r'  rB   rB   rB   rC   r  t  s
    r  c                   @   s   e Zd Zdd Zdd Zdd Zdd Z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 Zd)dd Zd!d" Zd*d$d%Zd&d' Zd#S )+	MiniShellc                 C   s`   t j|  || _t|| _| jt| _d| _	d| _
| j| _g | _d| _| dd d| _d S )Nz\>zType help for list of commands\r  F)cmdCmdr   
volumePathr  volumer'  	FILE_Root	rootINodepromptintrocurrentINode
completionpwddo_lslast_output)r   r  rB   rB   rC   r     s   

zMiniShell.__init__c                 C   r   r   rB   r   rB   rB   rC   	emptyline  r   zMiniShell.emptylinec              
   C   s\   d}z
t j| |}W |S  ty- } ztjddd tt| W Y d }~|S d }~ww )NFz
Exception:T)exc_info)r  r  onecmdr  r   r   r  r  )r   r  retValr1  rB   rB   rC   r    s   zMiniShell.onecmdc                 C   s   dS )NTrB   r   linerB   rB   rC   do_exit  r   zMiniShell.do_exitc                 C   s    t | }t| || _d S r   )ospopenr   rU  r  )r   r  outputrB   rB   rC   do_shell  s   
zMiniShell.do_shellc                 C   s   t d d S )Na  
 cd {path} - changes the current directory to {path}
 pwd - shows current remote directory
 ls  - lists all the files in the current directory
 lcd - change local directory
 get {filename} - downloads the filename from the current path
 cat {filename} - prints the contents of filename
 hexdump {filename} - hexdumps the contents of filename
 exit - terminates the server process (and this session)

)rU  r  rB   rB   rC   do_help  s   zMiniShell.do_helpc                 C   s2   |dkrt t  d S t| t t  d S )Nr  )rU  r  getcwdchdirr  rB   rB   rC   do_lcd  s   
zMiniShell.do_lcdc                 C   s   | dd}| j}tt| j|}|| jkrd S t||g}||kr.| t|}n| |}|d u rAtd || _d S |	 dkrQtd || _d S || _
| dd t| j|| _t| j| _| jd | _d S )	N/r  zDirectory not foundr   zNot a directory!r  F>)replacer  ntpathnormpathr  commonprefixfindPathNamer   r  r  r  r  r  )r   r  poldpwdnewPathcommonr  rB   rB   rC   do_cd  s,   



zMiniShell.do_cdc                 C   sf   |dkr| j S | j}|d}|D ]}|dkr| j }q||}|d u r(|  S | j| }q|S )Nr  r  )r  r  splitr  r  r'  rk  )r   pathNametmpINodepartspartr  rB   rB   rC   r     s   

zMiniShell.findPathNamec                 C   s   t | j d S r   )rU  r  r  rB   rB   rC   do_pwd1  rX  zMiniShell.do_pwdTc                 C   s   | j  }|d u rg }td| jt|| j j| j j g | _|D ]6}t	| j
}|d |_|d |_tt|d |_|d d|_|du rK|  | j|j| f q d S )Nz=ls summary for %s: total=%d index_root=%d index_allocation=%dr   rz   r   r   r   T)r  r  r   r   r  r   r  r  r  r{  r  r   r  r   rK  r   r   r   r   r  r   r  )r   r  displayr:  r.  inoderB   rB   rC   r  4  s*   



zMiniShell.do_lsc                 C   s   | j ||||ddS )Nr   )includecomplete_getr   textr  begidxendidxrB   rB   rC   complete_cdJ  s   zMiniShell.complete_cdc                 C      |  ||||S r   r  r  rB   rB   rC   complete_catM  rR  zMiniShell.complete_catc                 C   r  r   r  r  rB   rB   rC   complete_hexdumpP  rR  zMiniShell.complete_hexdumpr   c           	         sV   g }|dkr	d}nt }| jD ]}|d |kr||d  q r) fdd|D S |S )Nr   r   c                    s"   g | ]}|     r|qS rB   )r  
startswith)r  itemr  rB   rC   r  `  s    z*MiniShell.complete_get.<locals>.<listcomp>)r  r  r   )	r   r  r  r  r  r  itemsr  rW  rB   r!  rC   r  S  s   

zMiniShell.complete_getc                 C   s   | j |tdS )Ncommand)do_catr
   r  rB   rB   rC   
do_hexdumpg  rX  zMiniShell.do_hexdumpNc              	   C   sL  |d u rt tjdtjj}|dd}tt| j|}| 	|}|d u r-t
d d S | dkr:t
d d S | sB| rIt
d d S |d }|d u rYt
d d S | }|dkrht
d	 d S d
}d}||k rt||| }	|||	}
|
snz||
 W n ttfy   Y d S w |t|
7 }||k spt
d|  d S )Nbufferr   r  z
Not found!r   zIt's a directory!z,Cannot handle compressed/encrypted files! :(zCannot read file stream!z0 bytes read (empty file)i   z%d bytes read)getattrsysstdoutwriter  r  r  r  r  r  r   r  r  r  r  r  r   infor  r   BrokenPipeErrorOSErrorr   )r   r  r$  r  r  streamdataSize	chunkSizer   toReadr  rB   rB   rC   r%  j  sJ   






zMiniShell.do_catc                 C   sL   | dd}tt| j|}tt|d}| j||jd |	  d S )Nr   r  wbr#  )
r  r  r  r  r  r  basenamer%  r+  close)r   r  r  fhrB   rB   rC   do_get  s
   zMiniShell.do_get)T)r   r   )r>   r?   r@   r   r  r  r  r  r  r  r  r  r  r  r  r  r  r  r&  r%  r7  rB   rB   rB   rC   r    s&    



)r  c                  C   s   t tj tjddd} | jdddd | jddd	d | jd
ddd | jdddd ttjdkr<| 	  t
d |  }t|j|j t|j}|jd ur\|d|j  d S |  d S )NTzNTFS explorer (read-only))add_helpdescriptionr  storez1NTFS volume to open (e.g. \\.\C: or /dev/disk1s1))actionhelpz-extractz5extracts pathname (e.g. \windows\system32\config\sam)z-debug
store_truezTurn DEBUG output ONz-tsz&Adds timestamp to every logging outputr   zget %s)rU  r   BANNERargparseArgumentParseradd_argumentr   r)  argv
print_helpexit
parse_argsr   inittsr   r  r  extractr  cmdloop)parseroptionsshellrB   rB   rC   main  s   



rM  __main__)
__future__r   r   r  r)  r   r   r?  r  r  sixr   r   r   impacket.examplesr   impacketr   impacket.structurer	   r
   r  UNUSEDr  r  r  	OBJECT_IDSECURITY_DESCRIPTORVOLUME_NAMEVOLUME_INFORMATIONr*  r  r  BITMAPREPARSE_POINTEA_INFORMATIONEAPROPERTY_SETLOGGED_UTILITY_STREAMFIRST_USER_DEFINED_ATTRIBUTEr   ATTR_IS_COMPRESSEDATTR_COMPRESSION_MASKATTR_IS_ENCRYPTEDATTR_IS_SPARSEFILE_NAME_POSIXFILE_NAME_WIN32r  FILE_NAME_WIN32_AND_DOSMFT_RECORD_IN_USEMFT_RECORD_IS_DIRECTORYMFT_RECORD_IS_4MFT_RECORD_IS_VIEW_INDEXMFT_REC_SPACE_FILLERFILE_ATTR_READONLYr  r  FILE_ATTR_DIRECTORYFILE_ATTR_ARCHIVEFILE_ATTR_DEVICEFILE_ATTR_NORMALFILE_ATTR_TEMPORARYr  FILE_ATTR_REPARSE_POINTr  FILE_ATTR_OFFLINEFILE_ATTR_NOT_CONTENT_INDEXEDr  FILE_ATTR_VALID_FLAGSFILE_ATTR_VALID_SET_FLAGSr  FILE_ATTR_VIEW_INDEX_PRESENTr  FILE_MFTMirrFILE_LogFileFILE_VolumeFILE_AttrDefr  FILE_Bitmap	FILE_BootFILE_BadClusFILE_SecureFILE_UpCaseFILE_ExtendSMALL_INDEXLARGE_INDEX	LEAF_NODE
INDEX_NODE	NODE_MASKrc  rf  INDEX_ENTRY_SPACE_FILLERr*   rE   rO   rV   rh   rq   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r  rC  rM  rT  rY  r]  rl  rs  r{  r  r  r  rM  r>   rD  rB   rB   rB   rC   <module>   s   
		
	
 /h!  PX O
