Alternate Data Stream (ADS)

Partagez votre expérience de PureBasic avec les autres utilisateurs.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Alternate Data Stream (ADS)

Message par nico »

Alternate Data Stream (ADS); en Français (flux de données additionnels)

Si vous souhaitez avoir plus d'informations sur l'ADS, consulter ce lien:
http://www.paperblog.fr/2964348/le-dang ... ta-stream/


Résumé:
Sur les systèmes de fichier NTFS, il est possible d'associer des données (stream) à un fichier ou un répertoire .

Ces données ne seront pas visibles dans l'explorateur, seul la date de modification du fichier principal changera mais pas sa taille. Il faut des outils spécifiques pour scanner et supprimer les streams tout en sauvegardant le fichier ou le répertoire principale.

A partir de Vista il est possible de lister ces fichiers par la commande: Dir /r

Il est très simple de créer des Streams comme nous allons le voir,
Je vous propose ce code qui permet de créer, extraire et supprimer un Stream connu:

Code : Tout sélectionner

;----------------
; PureBasic 4.50
;----------------
;-----------------------------------------------------------------------------------------------------------------------
; Lecture, écriture et extraction d'un Alternate Data Stream (ADS); en Français (flux de données additionnels)
; Info sur les ADS --> http://www.paperblog.fr/2964348/le-danger-des-flux-additionnels-ads-alternate-data-stream/
; Fonctionne sur le système de Fichier NTFS 2000, NT, XP, Vista, Window 7
;-----------------------------------------------------------------------------------------------------------------------
; ----------------------------------------------------------------------------------------------------------------------------------
; Ce code vous permet d'associer un fichier (On dira un Stream) à un autre fichier ou un répertoire
; Le Stream que vous aurez associé au fichier ne sera pas visible dans l'explorateur de Window
; Seul la date de modification du fichier changera mais pas sa taille
; L'utilisateur Lambda ne sera jamais qu'il a certains fichiers cachés dans son système
; C'est un bon moyen de sauvegarder des données sensibles et les cachées, car impossible de les supprimer,
; sans effacer le fichier principal ou le répertoire
; Il faut en effet des outils spécifiques pour scanner et ainsi voir tous ces fichiers cachés
; j'en ai essayer certains comme ADS Spy ou hijackthis qui fonctionne très bien
; ----------------------------------------------------------------------------------------------------------------------------------


; Récupère l'adresse d'un dossier spécifique de Windows
Procedure.s GetSpecialFolderLocation(Valeur.l) 
  Protected SpecialFolderLocation.s, Dossier_ID.l
  If SHGetSpecialFolderLocation_(0, Valeur, @Dossier_ID) = 0
    SpecialFolderLocation = Space(#MAX_PATH)
    SHGetPathFromIDList_(Dossier_ID, @SpecialFolderLocation)
    If SpecialFolderLocation
      If Right(SpecialFolderLocation, 1) <> "\"
        SpecialFolderLocation + "\"
      EndIf
    EndIf
  EndIf
  ProcedureReturn SpecialFolderLocation
EndProcedure


Procedure CreateStream(Chemin_ou_CheminFichier.s, NomdeFichier.s, *Buffer.i, longueur.l)
  Protected Res.l
  
  If CreateFile(0, Chemin_ou_CheminFichier+":"+NomdeFichier)
    WriteData(0, *Buffer,longueur)
    CloseFile(0)
    Res=1
  EndIf 
  
  ProcedureReturn Res
EndProcedure


Procedure ExtractStream(Chemin_ou_CheminFichier.s, NomdeFichier.s, Destination.s)
  Protected Longueur.l, *Buffer.i, Res.l
  
  If ReadFile(0, Chemin_ou_CheminFichier+":"+NomdeFichier)
    Longueur=Lof(0)
    *Buffer=AllocateMemory(Longueur)
    ReadData(0, *Buffer,longueur)
    CloseFile(0)
    
    If CreateFile(0, Destination)
      WriteData(0, *Buffer,longueur)
      CloseFile(0)
      Res=1
    EndIf
    
    FreeMemory(*Buffer)
  EndIf
  
  ProcedureReturn Res
EndProcedure


Procedure.l DeleteStream(Chemin_ou_CheminFichier.s, NomdeFichier.s)
  Protected Res.l
  
  Res=DeleteFile(Chemin_ou_CheminFichier+":"+NomdeFichier)
  
  ProcedureReturn Res
EndProcedure

; --------------------------------------------------------------------
; Création d'un Fichier nommé Test.txt sur le bureau
; On écrira le texte :PureBasic
CheminBureau.s=GetSpecialFolderLocation(#CSIDL_DESKTOPDIRECTORY)
CheminFichier.s=CheminBureau+"Test.txt"
If CreateFile(0,CheminFichier)
  WriteString(0,"PureBasic")
  CloseFile(0)
EndIf
; --------------------------------------------------------------------

; --------------------------------------------------------------------
; Création d'un ADS "Fred.txt" associé au fichier "Test.txt"
Texte.s="Fred, le créateur de PureBasic"
CreateStream(CheminFichier,"Fred.txt",@Texte,Len(Texte))
; --------------------------------------------------------------------

; --------------------------------------------------------------------
; Extraction de l' ADS "Fred.txt" associé au Fichier "Test.txt"
ExtractStream(CheminFichier,"Fred.txt", CheminBureau+"Extract.txt")
; --------------------------------------------------------------------

; --------------------------------------------------------------------
; Supression de l'ADS
DeleteStream(CheminFichier,"Fred.txt")
; --------------------------------------------------------------------
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: Alternate Data Stream (ADS)

Message par Backup »

Merci , je ne connaissais pas l'existence de ce truc!!

peut etre une bonne façon de signer ses créations :)
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Alternate Data Stream (ADS)

Message par Ar-S »

Je faisais de l'ADS pour m'amuser mais via la fenêtres DOS (cmd.exe). ^^
Ton code simplifie la chose merci ;)
Le truc est que je ne suis pas sûr que les stream serviront pour des fichiers uppés sur son site vu que les serveurs ne sont pas tous sous windows ni en ntfs.
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Re: Alternate Data Stream (ADS)

Message par Jacobus »

C'est effectivement un truc intéressant que j'utilise depuis quelques années pour le stockage de données d'identification ou autres vu qu'on peut y mettre ce que l'on veut. Si par hasard, le fichier incluant un flux est déplacé sur une FAT32 pour le casser, il suffit d'implémenter un test avant utilisation du fichier cible. Test qui ira lire les données du flux si présentes et si elles n'y sont plus, interruption de l'exécution ou autre action comme ajout d'autres données par exemple. C'est très utile pour plein de choses. L'idéal étant de crypter les données à cacher pour contrer les outils spécifiques de lecture de ces flux qui, même s'ils les voient, ne peuvent les comprendre.
A voir aussi : http://www.purebasic.fr/english/viewtop ... 12&t=10943
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Alternate Data Stream (ADS)

Message par nico »

Voici un code de blueznl, revu et corrigé par moi qui permet de lister tous les streams d'un fichier ou d'un dossier.

Code : Tout sélectionner

; ---------------------------------------
; PureBasic 4.51
; Compile to Unicode
; Afficher la liste des Streams d'un fichier oou d'un dossier
;----------------------------------------

filename.s = ; <-- Indiquer ici le chemin d'un fichier ou d'un dossier
Debug "start"

file_h = CreateFile_(@filename, #READ_CONTROL, 0, 0, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, 0)

If file_h = 0
  Debug "can't open"
  End
EndIf
;
context.l = 0
bytes_read.l = 0
bytes_read1.l = 0
seek_l = 0
seek_h = 0
result.l=0

*stream.WIN32_STREAM_ID = AllocateMemory(20)
z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)


While (bytes_read <> 0 )
  Debug ""
  n = n+1
  Debug "stream "+Str(n)
  Debug "bytes read "+Str(bytes_read)
  id = *stream\dwStreamID
  Debug "stream id "+Str(id)
  
  Select id
    Case #BACKUP_ALTERNATE_DATA ;0x00000004
      Debug "Alternative Data streams. This corresponds To the NTFS $DATA stream type on a named Data stream."
      
    Case #BACKUP_DATA ;0x00000001
      Debug "Standard Data. This corresponds To the NTFS $DATA stream type on the Default (unnamed) Data stream."
      
    Case #BACKUP_EA_DATA ;0x00000002
      Debug "Extended attribute Data. This corresponds To the NTFS $EA stream type."
      
    Case #BACKUP_LINK ;0x00000005
      Debug "Hard link information. This corresponds To the NTFS $FILE_NAME stream type."
      
    Case 7 ;#BACKUP_OBJECT_ID ;0x00000007
      Debug "Objects identifiers. This corresponds To the NTFS $OBJECT_ID stream type."
      
    Case 6 ;#BACKUP_PROPERTY_DATA ;0x00000006
      Debug "Property Data."
      
    Case 8 ;#BACKUP_REPARSE_DATA ;0x00000008
      Debug "Reparse points. This corresponds To the NTFS $REPARSE_POINT stream type."
      
    Case #BACKUP_SECURITY_DATA ;0x00000003
      Debug "Security descriptor Data."
      
    Case 9 ;#BACKUP_SPARSE_BLOCK ;0x00000009
      Debug "Sparse file. This corresponds To the NTFS $DATA stream type For a sparse file."
      
    Case 10 ;#BACKUP_TXFS_DATA ;0x0000000A
      Debug "Transactional NTFS (TxF) Data stream. This corresponds To the NTFS $TXF_DATA stream type."
  EndSelect
  ;
  namesize.l = *stream\dwStreamNameSize
  Debug "name size "+Str(namesize)
  If namesize > 0
    *buffer = AllocateMemory(namesize)
    BackupRead_(file_h,*buffer,namesize,@bytes_read1,0,1,@context)
    Debug PeekS(*buffer,namesize/2,#PB_Unicode)
    FreeMemory(*buffer)
  EndIf
  ;
  
  streamHight.q=*stream\dwStreamSizeHigh & $FFFFFFFF
  streamLow.q=*stream\dwStreamSizeLow & $FFFFFFFF
  streamsize.q =  streamHight<<32 |  streamLow
  Debug "streamsize="+Str(streamsize)
  ;
  
  result.l= BackupSeek_(file_h, *stream\dwStreamSizeLow, *stream\dwStreamSizeHigh, @seek_l, @seek_h, @context)
  ;
  FreeMemory(*stream)
  *stream.WIN32_STREAM_ID = AllocateMemory(20)
  bytes_read = 0
  z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)
Wend 

FreeMemory(*stream)

BackupRead_(file_h,0,0,@bytes_read,1,0,@context)
CloseHandle_(file_h)
;
Debug ""
Debug "done"
Avatar de l’utilisateur
Jacobus
Messages : 1559
Inscription : mar. 06/avr./2004 10:35
Contact :

Re: Alternate Data Stream (ADS)

Message par Jacobus »

Le même en version graphique et francisé

Code : Tout sélectionner

; ---------------------------------------
; PureBasic 4.51
; Compile to Unicode
; Read Stream for file or directory
; Blueznl & nico
;----------------------------------------
Enumeration
  #Win_Stream
  #Btn_SelectFile
  #Btn_CopyStream
  #Btn_CloseStream
  #EditStream
EndEnumeration
  
Procedure ReadStreamFile(filename.s)

AddGadgetItem(#EditStream,-1, "Start - "+FormatDate("%dd - %mm - %yyyy à %hh:%ii:%ss", Date()))
AddGadgetItem(#EditStream,-1, "Fichier = "+filename)
AddGadgetItem(#EditStream,-1, "")
;
; i can read all alternative streams from an open and locked file, using
; Je peux lire tous les flux alternatifs à partir d'un fichier ouvert et verrouillé, à l'aide de
file_h = CreateFile_(@filename, #READ_CONTROL, 0, 0, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, 0)


If file_h = 0
  AddGadgetItem(#EditStream,-1, "Ouverture de "+ filename +" impossible! ")
Else 
  
;
context.l = 0
bytes_read.l = 0
bytes_read1.l = 0
seek_l = 0
seek_h = 0
result.l=0

*stream.WIN32_STREAM_ID = AllocateMemory(20)
z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)


While (bytes_read <> 0 )
  AddGadgetItem(#EditStream,-1, " ")
  ;Debug ""
  n = n+1
  AddGadgetItem(#EditStream,-1, "stream "+Str(n))
  ;Debug "stream "+Str(n)
  AddGadgetItem(#EditStream,-1, "bytes read "+Str(bytes_read))
  ;Debug "bytes read "+Str(bytes_read)
  id = *stream\dwStreamID
  ;Debug "stream id "+Str(id)
  AddGadgetItem(#EditStream,-1, "stream id "+Str(id))
  
  Select id ;{
    Case #BACKUP_ALTERNATE_DATA ;0x00000004
      ;Debug "Alternative Data streams. This corresponds To the NTFS $DATA stream type on a named Data stream."
      AddGadgetItem(#EditStream,-1, "Flux de données alternatifs. Cela correspond au type de flux [ NTFS $Data ] sur un flux de données nommé.")
      
    Case #BACKUP_DATA ;0x00000001
      ;Debug "Standard Data. This corresponds To the NTFS $DATA stream type on the Default (unnamed) Data stream."
      AddGadgetItem(#EditStream,-1, "Données standard. Cela correspond au type de flux [ NTFS $DATA ] sur le flux de données par défaut (sans nom).")
      
    Case #BACKUP_EA_DATA ;0x00000002
      ;Debug "Extended attribute Data. This corresponds To the NTFS $EA stream type."
      AddGadgetItem(#EditStream,-1, "Attribut étendu de données. Cela correspond au type de flux [ NTFS $EA ]")
      
    Case #BACKUP_LINK ;0x00000005
      ;Debug "Hard link information. This corresponds To the NTFS $FILE_NAME stream type."
      AddGadgetItem(#EditStream,-1, "Informations de lien dur. Cela correspond au type de flux [ NTFS $FILE_NAME ]")
      
    Case 7 ;#BACKUP_OBJECT_ID ;0x00000007
      ;Debug "Objects identifiers. This corresponds To the NTFS $OBJECT_ID stream type."
      AddGadgetItem(#EditStream,-1, "Identificateurs d'objets. Cela correspond au type de flux [ NTFS $OBJECT_ID ]")
      
    Case 6 ;#BACKUP_PROPERTY_DATA ;0x00000006
      ;Debug "Property Data."
      AddGadgetItem(#EditStream,-1, "Données de propriété.")
      
    Case 8 ;#BACKUP_REPARSE_DATA ;0x00000008
      ;Debug "Reparse points. This corresponds To the NTFS $REPARSE_POINT stream type."
      AddGadgetItem(#EditStream,-1, "Points d'analyse. Cela correspond au type de flux [ NTFS $REPARSE_POINT ]")
      
    Case #BACKUP_SECURITY_DATA ;0x00000003
      ;Debug "Security descriptor Data."
      AddGadgetItem(#EditStream,-1, "Descripteur de sécurité de données.")
      
    Case 9 ;#BACKUP_SPARSE_BLOCK ;0x00000009
      ;Debug "Sparse file. This corresponds To the NTFS $DATA stream type For a sparse file."
      AddGadgetItem(#EditStream,-1, "Fichier fragmenté. Cela correspond au type de flux [ NTFS $DATA ] pour un fichier fragmenté.")
      
    Case 10 ;#BACKUP_TXFS_DATA ;0x0000000A
      ;Debug "Transactional NTFS (TxF) Data stream. This corresponds To the NTFS $TXF_DATA stream type."
      AddGadgetItem(#EditStream,-1, "Transactionnel des flux de données NTFS (TxF). Cela correspond au type de flux [ NTFS $TXF_DATA ]")
      ;}
  EndSelect
  ;
  namesize.l = *stream\dwStreamNameSize
  ;Debug "name size "+Str(namesize)
  AddGadgetItem(#EditStream,-1, "name size = "+Str(namesize))
  If namesize > 0
    *buffer = AllocateMemory(namesize)
    BackupRead_(file_h,*buffer,namesize,@bytes_read1,0,1,@context)
    ;Debug PeekS(*buffer,namesize/2,#PB_Unicode)
    AddGadgetItem(#EditStream,-1, PeekS(*buffer,namesize/2,#PB_Unicode))
    FreeMemory(*buffer)
  EndIf
  ;
  
  streamHight.q=*stream\dwStreamSizeHigh & $FFFFFFFF
  streamLow.q=*stream\dwStreamSizeLow & $FFFFFFFF
  streamsize.q =  streamHight<<32 |  streamLow
  ;Debug "streamsize="+Str(streamsize)
  AddGadgetItem(#EditStream,-1, "streamsize = "+Str(streamsize))
  ;
  
  result.l= BackupSeek_(file_h, *stream\dwStreamSizeLow, *stream\dwStreamSizeHigh, @seek_l, @seek_h, @context)
  ;Debug "Result="+Str(Result)
  AddGadgetItem(#EditStream,-1, "Resultat = "+Str(Result))
  ;
  FreeMemory(*stream)
  *stream.WIN32_STREAM_ID = AllocateMemory(20)
  bytes_read = 0
  z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)
Wend 

FreeMemory(*stream)

BackupRead_(file_h,0,0,@bytes_read,1,0,@context)
CloseHandle_(file_h)

EndIf

AddGadgetItem(#EditStream,-1, "")
AddGadgetItem(#EditStream,-1, "Terminé.")
;
; Debug ""
; Debug "done" 
EndProcedure 

If OpenWindow(#Win_Stream,0,0,700,400,"Read Stream for file or directory", #PB_Window_SystemMenu |#PB_Window_ScreenCentered |#PB_Window_TitleBar)=0  
  End 
Else 

  If CreatePopupMenu(0)
    MenuItem(1, "Fichier")
    MenuItem(2, "Dossier")
  EndIf

  
  ButtonGadget(#Btn_SelectFile,10,5,80,25,"Select") : GadgetToolTip(#Btn_SelectFile,"Sélectionnez un fichier ou un dossier")
  ButtonGadget(#Btn_CopyStream,100,5,80,25,"Copier") : GadgetToolTip(#Btn_CopyStream,"Copier tout le contenu de l'éditeur")
  ButtonGadget(#Btn_CloseStream,610,5,80,25,"Fermer") : GadgetToolTip(#Btn_CloseStream,"Fermer la fenêtre")

  EditorGadget(#EditStream, 5,35,690,350,#PB_Editor_ReadOnly)
  SetGadgetColor(#EditStream,#PB_Gadget_BackColor,RGB(23, 33, 41))
  SetGadgetColor(#EditStream,#PB_Gadget_FrontColor,RGB(189, 193, 200))
  If LoadFont(3,"Courier new",10,#PB_Font_HighQuality)
    SetGadgetFont(#EditStream,FontID(3))
  EndIf 
  SendMessage_(GadgetID(#EditStream), #EM_SETTARGETDEVICE, #Null, 0) 

 Repeat
   Event = WaitWindowEvent() 
   
    If Event = #PB_Event_Menu
      Select EventMenu()
          
        Case 1
          File$ = OpenFileRequester("Sélection d'un fichier","","*.*",0)
          If File$
            ClearGadgetItems(#EditStream)
            ReadStreamFile(File$)
          EndIf
          
        Case 2
          File$ = PathRequester("Sélectionnez un dossier","c:\")
          If File$
            ClearGadgetItems(#EditStream)
            ReadStreamFile(File$)
          EndIf
          
      EndSelect
    EndIf 
   
    If Event = #PB_Event_Gadget
      Select EventGadget() 
          
        Case #Btn_SelectFile : DisplayPopupMenu(0,WindowID(#Win_Stream))         
          
        Case #Btn_CopyStream 
          RangeAll.CHARRANGE\cpMin = 0 : RangeAll\cpMax = -1 
           SendMessage_(GadgetID(#EditStream),#EM_EXSETSEL,0,@RangeAll)
            SendMessage_(GadgetID(#EditStream), #WM_COPY,0,0)
                    
        Case #Btn_CloseStream : Event = #PB_Event_CloseWindow
          
      EndSelect
    EndIf 
    
  Until Event = #PB_Event_CloseWindow
End 
EndIf 
@+
Quand tous les glands seront tombés, les feuilles dispersées, la vigueur retombée... Dans la morne solitude, ancré au coeur de ses racines, c'est de sa force maturité qu'il renaîtra en pleine magnificence...Jacobus.
nico
Messages : 3702
Inscription : ven. 13/févr./2004 0:57

Re: Alternate Data Stream (ADS)

Message par nico »

Oui , c'est mieux :)

Voici un autre code qui permet de scanner seulement les streams Alternate Data (Ceux qu'on peut créer et modifier), les autres sont réservés à l'OS je crois.

Code : Tout sélectionner

; ---------------------------------------------------------------
; PureBasic 4.51
;----------------------------------------------------------------
; Version 1.0
; Fonctionne à partir de Window 2000 (Système de Fichier NTFS)
;----------------------------------------------------------------
; --> Compiler en Unicode et Activer la gestion des Threads ! <--
;----------------------------------------------------------------
; Ce code permet seulement de lister les streams "Alternate Data"
; contenus dans les fichiers ou les dossiers
;----------------------------------------------------------------

;{- Enumerations / DataSections
;{ Windows
Enumeration
  #Window_Main
EndEnumeration
;}
;{ Gadgets
Enumeration
  #String_Dossier_Fichier
  #Button_Dossier
  #Button_Fichier
  #ListIcon_Stream
  #Button_Scan
  #Button_StopperScan
  #Button_SupprimerleStream
  #Button_EditeravecNotepad
  #Button_Extrairevers
  #Button_Quitter
  #Text_Info
  #Button_OuvrirExplorateur
  #BarreEtat
EndEnumeration
;}
;}

Global Chemin$
Global NomStream.s,StreamSize.q
Global FinRecherche.l

Procedure ReadStream(CheminDossier_CheminFichier.s)
  Protected file_h.i, z.i,*stream.WIN32_STREAM_ID
  Protected context.l=0, bytes_read.l=0, bytes_read1.l=0, seek_l = 0, seek_h = 0, Result.l=0
  Protected namesize.l,streamHight.q,streamLow.q
  
  file_h = CreateFile_(@CheminDossier_CheminFichier, #READ_CONTROL, 0, 0, #OPEN_EXISTING, #FILE_FLAG_BACKUP_SEMANTICS, 0)
  
  If file_h <> 0
    
    *stream.WIN32_STREAM_ID = AllocateMemory(20)
    z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)
    
    While (bytes_read <> 0 ) And Result=0
      
      namesize = *stream\dwStreamNameSize
      If namesize > 0
        *buffer = AllocateMemory(namesize)
        BackupRead_(file_h,*buffer,namesize,@bytes_read1,0,1,@context)
        NomStream= PeekS(*buffer,namesize/2,#PB_Unicode)
        FreeMemory(*buffer)
      EndIf
      
      If *stream\dwStreamID=#BACKUP_ALTERNATE_DATA
        streamHight.q=*stream\dwStreamSizeHigh & $FFFFFFFF
        streamLow.q=*stream\dwStreamSizeLow & $FFFFFFFF
        StreamSize.q =  streamHight<<32 |  streamLow
        Result=1
      EndIf 
      
      BackupSeek_(file_h, *stream\dwStreamSizeLow, *stream\dwStreamSizeHigh, @seek_l, @seek_h, @context)
      
      FreeMemory(*stream)
      *stream.WIN32_STREAM_ID = AllocateMemory(20)
      bytes_read = 0
      z = BackupRead_(file_h, *stream, 20, @bytes_read, 0, 1, @context)
    Wend 
    
    FreeMemory(*stream)
    
    BackupRead_(file_h,0,0,@bytes_read,1,0,@context)
    CloseHandle_(file_h)
    
  EndIf 
  ProcedureReturn Result
EndProcedure 


Procedure.s ParseDirectory(folder.s, id.l = 0)
  Protected Type.s
  
  If Right(folder, 1) <> "\" 
    folder + "\" 
  EndIf  
  If ExamineDirectory(id, folder, "*.*") 
    If FinRecherche<2
      While NextDirectoryEntry(id)  
        If DirectoryEntryName(id) <> "." And DirectoryEntryName(id) <> ".."  
          ;########################################## 
          StatusBarText(#BarreEtat, 0, folder + DirectoryEntryName(id))
          If ReadStream(folder + DirectoryEntryName(id))
            If DirectoryEntryType(id)= #PB_DirectoryEntry_Directory 
              Type.s="Dossier"
            Else
              Type.s="Fichier"
            EndIf
            
            AddGadgetItem(#ListIcon_Stream, -1, NomStream+Chr(10)+Str(StreamSize)+Chr(10)+Type+Chr(10)+folder + DirectoryEntryName(id))
          EndIf
          ;##########################################  
          If DirectoryEntryType(id) = #PB_DirectoryEntry_Directory 
            ParseDirectory(folder + DirectoryEntryName(id), id + 1) 
          EndIf  
        EndIf  
      Wend
    EndIf 
    FinishDirectory(id) 
  EndIf  
EndProcedure   

Procedure ParseCheminFichierouDossier(folder.s)
  Protected Type.s
  
  If FileSize(folder)=-2
      Type.s="Dossier"
  Else
      Type.s="Fichier"
  EndIf
  If ReadStream(folder)
    AddGadgetItem(#ListIcon_Stream, -1, NomStream+Chr(10)+Str(StreamSize)+Chr(10)+Type+Chr(10)+folder)
  EndIf
  If Type="Dossier"
    ParseDirectory(folder)
  EndIf 
EndProcedure

Procedure DisableGadgetGroup1(Etat.l)
  DisableGadget(#Button_Dossier,Etat)
  DisableGadget(#Button_Fichier,Etat)
  DisableGadget(#Button_Scan,Etat)
  DisableGadget(#Button_Quitter,Etat)
EndProcedure

Procedure DisableGadgetGroup2(Etat.l)
  DisableGadget(#Button_SupprimerleStream,Etat)
  DisableGadget(#Button_EditeravecNotepad,Etat)
  DisableGadget(#Button_Extrairevers,Etat)
  DisableGadget(#Button_OuvrirExplorateur,Etat)
EndProcedure

Procedure Thread(lParam.i)
  ParseCheminFichierouDossier(Chemin$)
  StatusBarText(#BarreEtat, 0, "")
  FinRecherche=0
  DisableGadget(#Button_StopperScan,1)
  DisableGadgetGroup1(0)
EndProcedure

Procedure OpenWindow_Window_Main()
  If OpenWindow(#Window_Main, 200, 200, 610, 460, "Alternate Data Stream SPY", #PB_Window_SystemMenu|#PB_Window_TitleBar)
    StringGadget(#String_Dossier_Fichier, 10, 25, 520, 25, "", #PB_String_ReadOnly)
    ButtonGadget(#Button_Dossier, 540, 10, 60, 25, "Dossier")
    ButtonGadget(#Button_Fichier, 540, 40, 60, 25, "Fichier")
    ListIconGadget(#ListIcon_Stream, 10, 110, 590, 250, "Nom du Stream", 100, #PB_ListIcon_AlwaysShowSelection|#PB_ListIcon_FullRowSelect|#PB_ListIcon_GridLines)
    AddGadgetColumn(#ListIcon_Stream, 1, "Taille", 60)
    AddGadgetColumn(#ListIcon_Stream, 2, "Type", 60)
    AddGadgetColumn(#ListIcon_Stream, 3, "Chemin", 360)
    ButtonGadget(#Button_Scan, 110, 70, 155, 25, "Scan Alternate Data Stream")
    ButtonGadget(#Button_StopperScan, 340, 70, 155, 25, "Stopper le Scan")
    ButtonGadget(#Button_SupprimerleStream, 315, 370, 135, 25, "Supprimer le Stream")
    ButtonGadget(#Button_EditeravecNotepad, 10, 370, 135, 25, "Editer avec Notepad")
    ButtonGadget(#Button_Extrairevers, 160, 370, 135, 25, "Extraire le Stream vers...")
    ButtonGadget(#Button_Quitter, 240, 405, 130, 25, "Quitter")
    TextGadget(#Text_Info, 10, 5, 520, 20, "Vous pouvez glisser-déposer un Fichier ou un Dossier dans la zone de texte ci-dessous")
    ButtonGadget(#Button_OuvrirExplorateur, 465, 370, 135, 25, "Ouvrir dans l'explorateur")
    
    CreateStatusBar(#BarreEtat, WindowID(#Window_Main))
    AddStatusBarField(#PB_Ignore)
    
    EnableGadgetDrop(#String_Dossier_Fichier, #PB_Drop_Files, #PB_Drag_Copy)
    
    DisableGadget(#Button_StopperScan,1)
    DisableGadgetGroup2(1)
  EndIf
EndProcedure

OpenWindow_Window_Main()

;{- Event loop
Repeat
  Select WaitWindowEvent()
      ; ///////////////////
    Case #PB_Event_GadgetDrop
      Select EventGadget()
        Case #String_Dossier_Fichier
          Files$ = EventDropFiles()
          Count  = CountString(Files$, Chr(10)) + 1
          SetGadgetText(#String_Dossier_Fichier,StringField(Files$, 1, Chr(10)))
      EndSelect
      
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_Dossier
          Chemin$ = PathRequester("Choisissez un répertoire:", "C:\")
          SetGadgetText(#String_Dossier_Fichier,Chemin$)
          
        Case #Button_Fichier
          Chemin$ = OpenFileRequester("Choisissez un fichier:", "C:\", "*.*",0)
          SetGadgetText(#String_Dossier_Fichier,Chemin$)
          
        Case #ListIcon_Stream
          Index.l=GetGadgetState(#ListIcon_Stream)
          If Index>-1
            DisableGadgetGroup2(0)
          Else
            DisableGadgetGroup2(1)
          EndIf 
          
        Case #Button_Scan
          ClearGadgetItems(#ListIcon_Stream)
          Chemin$=GetGadgetText(#String_Dossier_Fichier)
          If FileSize(Chemin$) <>-1
            DisableGadgetGroup1(1)
            DisableGadgetGroup2(1)
            DisableGadget(#Button_StopperScan,0)
            FinRecherche=1
            CreateThread(@Thread(),0)
          Else
            MessageRequester("Info","Choisissez un chemin de Dossier ou de Fichier valide !")
          EndIf 
          
        Case #Button_StopperScan
          FinRecherche=2
          DisableGadget(#Button_StopperScan,1)
          DisableGadgetGroup1(0)
          
        Case #Button_EditeravecNotepad
          Index.l=GetGadgetState(#ListIcon_Stream)
          If Index>-1
            NameStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 0)
            NameStream=StringField(NameStream,2,":")
            CheminStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 3)
            MessageRequester("Info","Dans certain cas, Notepad ne sera pas en mesure d'ouvrir le Stream !"+Chr(13)+"mais vous pouvez toujours faire une Extraction puis ensuite éditer le Fichier ainsi obtenu.")
            RunProgram("Notepad.exe",CheminStream+":"+NameStream,"")
          EndIf 
          
        Case #Button_Extrairevers
          Index.l=GetGadgetState(#ListIcon_Stream)
          If Index>-1
            NameStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 0)
            NameStream=StringField(NameStream,2,":")
            Taille.s=GetGadgetItemText(#ListIcon_Stream, Index , 1)
            If Taille<>"0"
              NomFichier$ = SaveFileRequester("Choisissez un emplacement:", NameStream, "*.*", 0)
              If NomFichier$<>""
                CheminStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 3)
                If ReadFile(0,CheminStream+":"+NameStream)
                  Longueur.q=Lof(0)
                  *Buffer.i=AllocateMemory(Longueur)
                  ReadData(0,*Buffer,Longueur)
                  CloseFile(0)
                  If CreateFile(0,NomFichier$)
                    WriteData(0,*Buffer,Longueur)
                    CloseFile(0)
                  EndIf
                  FreeMemory(*Buffer)
                Else
                  MessageRequester("Erreur","Le Stream n'a pas pu être sauvegardé !")
                EndIf
              EndIf
            Else
              MessageRequester("Info","La Taille de ce Stream est de 0 octet, il est inutile de vouloir le sauvegarder !")
            EndIf
          EndIf
          
        Case #Button_SupprimerleStream
          Index.l=GetGadgetState(#ListIcon_Stream)
          If Index>-1
            NameStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 0)
            NameStream=StringField(NameStream,2,":")
            CheminStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 3)
            Type.s=GetGadgetItemText(#ListIcon_Stream, Index , 2)
            Message$="Êtes-vous sûr de vouloir supprimer le Stream : "+NameStream+" ?"+Chr(13)+"du "+Type+" "+CheminStream
            Resultat =MessageRequester("Attention",Message$, #PB_MessageRequester_YesNo)
            If Resultat = #PB_MessageRequester_Yes
              If DeleteFile(CheminStream+":"+NameStream)<>0
                RemoveGadgetItem(#ListIcon_Stream, Index)
              Else
                MessageRequester("Erreur","Le Stream n'a pas pu être effacé !")
              EndIf 
            EndIf 
          EndIf 
          
        Case #Button_OuvrirExplorateur
          Index.l=GetGadgetState(#ListIcon_Stream)
          If Index>-1
            CheminStream.s=GetGadgetItemText(#ListIcon_Stream, Index , 3)
            RunProgram("Explorer.exe","/e, /Select,"+CheminStream,"")
          EndIf  
          
        Case #Button_Quitter 
          CloseWindow(#Window_Main)
          Break
      EndSelect
      ; ////////////////////////
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #Window_Main
          If FinRecherche=0
            CloseWindow(#Window_Main)
            Break
          Else
            MessageRequester("Info","Cliquez sur le Bouton Stopper le Scan avant de quitter !")
          EndIf 
      EndSelect
  EndSelect
ForEver
;
;}

jassing
Messages : 2
Inscription : ven. 20/juil./2012 5:06

Re: Alternate Data Stream (ADS)

Message par jassing »

Pardonnez mon français, bien que, techniquement, Google est le français.
Lorsque je tente de compiler le code ici, PB se plaint des éléments de structure manquantes. Plus précisément, les éléments de taille haute et basse:

\ dwStreamSizeHigh & \ dwStreamSizeLow C'est peut-être non unicode? Tout ce que j'ai est "\ Taille"

Toutes les idées?

merci

-josh
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Alternate Data Stream (ADS)

Message par PAPIPP »

La structure suivante a été modifiée entre PB451 et PB461
;***********************************************************************************************
;; structure pour PB451
; Structure WIN32_STREAM_ID
; dwStreamID.l
; dwStreamAttributes.l
; dwStreamSizeLow.l
; dwStreamSizeHigh.l
; dwStreamNameSize.l
; cStreamName.w[1]
; PB_Alignment.b[2]
; EndStructure
par
;;structurepour PB461
; Structure WIN32_STREAM_ID
; dwStreamID.l
; dwStreamAttributes.l
; Size.LARGE_INTEGER
; dwStreamNameSize.l
; cStreamName.w[1]
; PB_Alignment.b[2]
; EndStructure
;**********************************************************************************************
; Structure LARGE_INTEGER
; lowpart.l
; highpart.l
; EndStructure

ce qui donne pour l'un des PRG

Code : Tout sélectionner

; ---------------------------------------
; PureBasic 4.61 -> par PAPIPP
; Compile to Unicode
; Read Stream for file or directory
; Blueznl & nico
;----------------------------------------
Enumeration
	#Win_Stream
	#Btn_SelectFile
	#Btn_CopyStream
	#Btn_CloseStream
	#EditStream
EndEnumeration

Procedure ReadStreamFile(filename.s)
  
  AddGadgetItem(#EditStream,-1,"Start - "+FormatDate("%dd - %mm - %yyyy à %hh:%ii:%ss",Date()))
  AddGadgetItem(#EditStream,-1,"Fichier = "+filename)
  AddGadgetItem(#EditStream,-1,"")
  ;
  ; i can read all alternative streams from an open and locked file, using
  ; Je peux lire tous les flux alternatifs à partir d'un fichier ouvert et verrouillé, à l'aide de
  file_h=CreateFile_(@filename,#READ_CONTROL,0,0,#OPEN_EXISTING,#FILE_FLAG_BACKUP_SEMANTICS,0)
  
  
  If file_h=0
    AddGadgetItem(#EditStream,-1,"Ouverture de "+filename+" impossible! ")
  Else
    
    ;
    context.l=0
    bytes_read.l=0
    bytes_read1.l=0
    seek_l=0
    seek_h=0
    result.l=0
    
    *stream.WIN32_STREAM_ID=AllocateMemory(20)
    z=BackupRead_(file_h,*stream,20,@bytes_read,0,1,@context)
    
    
    While (bytes_read<>0)
      AddGadgetItem(#EditStream,-1," ")
      ;Debug ""
      n=n+1
      AddGadgetItem(#EditStream,-1,"stream "+Str(n))
      ;Debug "stream "+Str(n)
      AddGadgetItem(#EditStream,-1,"bytes read "+Str(bytes_read))
      ;Debug "bytes read "+Str(bytes_read)
      id=*stream\dwStreamID
      ;Debug "stream id "+Str(id)
      AddGadgetItem(#EditStream,-1,"stream id "+Str(id))
      
      Select id ;{
        Case #BACKUP_ALTERNATE_DATA ;0x00000004
          ;Debug "Alternative Data streams. This corresponds To the NTFS $DATA stream type on a named Data stream."
          AddGadgetItem(#EditStream,-1,"Flux de données alternatifs. Cela correspond au type de flux [ NTFS $Data ] sur un flux de données nommé.")
          
        Case #BACKUP_DATA ;0x00000001
          ;Debug "Standard Data. This corresponds To the NTFS $DATA stream type on the Default (unnamed) Data stream."
          AddGadgetItem(#EditStream,-1,"Données standard. Cela correspond au type de flux [ NTFS $DATA ] sur le flux de données par défaut (sans nom).")
          
        Case #BACKUP_EA_DATA ;0x00000002
          ;Debug "Extended attribute Data. This corresponds To the NTFS $EA stream type."
          AddGadgetItem(#EditStream,-1,"Attribut étendu de données. Cela correspond au type de flux [ NTFS $EA ]")
          
        Case #BACKUP_LINK ;0x00000005
          ;Debug "Hard link information. This corresponds To the NTFS $FILE_NAME stream type."
          AddGadgetItem(#EditStream,-1,"Informations de lien dur. Cela correspond au type de flux [ NTFS $FILE_NAME ]")
          
        Case 7 ;#BACKUP_OBJECT_ID ;0x00000007
          ;Debug "Objects identifiers. This corresponds To the NTFS $OBJECT_ID stream type."
          AddGadgetItem(#EditStream,-1,"Identificateurs d'objets. Cela correspond au type de flux [ NTFS $OBJECT_ID ]")
          
        Case 6 ;#BACKUP_PROPERTY_DATA ;0x00000006
          ;Debug "Property Data."
          AddGadgetItem(#EditStream,-1,"Données de propriété.")
          
        Case 8 ;#BACKUP_REPARSE_DATA ;0x00000008
          ;Debug "Reparse points. This corresponds To the NTFS $REPARSE_POINT stream type."
          AddGadgetItem(#EditStream,-1,"Points d'analyse. Cela correspond au type de flux [ NTFS $REPARSE_POINT ]")
          
        Case #BACKUP_SECURITY_DATA ;0x00000003
          ;Debug "Security descriptor Data."
          AddGadgetItem(#EditStream,-1,"Descripteur de sécurité de données.")
          
        Case 9 ;#BACKUP_SPARSE_BLOCK ;0x00000009
          ;Debug "Sparse file. This corresponds To the NTFS $DATA stream type For a sparse file."
          AddGadgetItem(#EditStream,-1,"Fichier fragmenté. Cela correspond au type de flux [ NTFS $DATA ] pour un fichier fragmenté.")
          
        Case 10 ;#BACKUP_TXFS_DATA ;0x0000000A
          ;Debug "Transactional NTFS (TxF) Data stream. This corresponds To the NTFS $TXF_DATA stream type."
          AddGadgetItem(#EditStream,-1,"Transactionnel des flux de données NTFS (TxF). Cela correspond au type de flux [ NTFS $TXF_DATA ]")
          ;}
      EndSelect
      ;
      namesize.l=*stream\dwStreamNameSize
      ;Debug "name size "+Str(namesize)
      AddGadgetItem(#EditStream,-1,"name size = "+Str(namesize))
      If namesize>0
        *buffer=AllocateMemory(namesize)
        BackupRead_(file_h,*buffer,namesize,@bytes_read1,0,1,@context)
        ;Debug PeekS(*buffer,namesize/2,#PB_Unicode)
        AddGadgetItem(#EditStream,-1,PeekS(*buffer,namesize/2,#PB_Unicode))
        FreeMemory(*buffer)
      EndIf
      ;
      
;       streamHight.q=*stream\dwStreamSizeHigh & $FFFFFFFF
      streamHight.q=*stream\Size\highpart & $FFFFFFFF
   
;       streamLow.q=*stream\dwStreamSizeLow & $FFFFFFFF
      streamLow.q=*stream\Size\lowpart & $FFFFFFFF
      streamsize.q=streamHight<<32 | streamLow
      ;Debug "streamsize="+Str(streamsize)
      AddGadgetItem(#EditStream,-1,"streamsize = "+Str(streamsize))
      ;
      
;       result.l=BackupSeek_(file_h,*stream\dwStreamSizeLow,*stream\dwStreamSizeHigh,@seek_l,@seek_h,@context)
      result.l=BackupSeek_(file_h,*stream\Size\lowpart,*stream\Size\highpart,@seek_l,@seek_h,@context)
      ;Debug "Result="+Str(Result)
      AddGadgetItem(#EditStream,-1,"Resultat = "+Str(Result))
      ;
      ;;structurepour PB461
;       Structure WIN32_STREAM_ID
;         dwStreamID.l
;         dwStreamAttributes.l
;         Size.LARGE_INTEGER
;         dwStreamNameSize.l
;         cStreamName.w[1]
;         PB_Alignment.b[2]
;       EndStructure
;**********************************************************************************************
; Structure LARGE_INTEGER
;   lowpart.l
;   highpart.l
; EndStructure

;***********************************************************************************************
 ;; structure pour PB451
;  Structure WIN32_STREAM_ID
;   dwStreamID.l
;   dwStreamAttributes.l
;   dwStreamSizeLow.l
;   dwStreamSizeHigh.l
;   dwStreamNameSize.l
;   cStreamName.w[1]
;   PB_Alignment.b[2]
; EndStructure
     
      
      ;
      FreeMemory(*stream)
      *stream.WIN32_STREAM_ID=AllocateMemory(20)
      bytes_read=0
      z=BackupRead_(file_h,*stream,20,@bytes_read,0,1,@context)
    Wend
    
    FreeMemory(*stream)
    
    BackupRead_(file_h,0,0,@bytes_read,1,0,@context)
    CloseHandle_(file_h)
    
  EndIf
  
  AddGadgetItem(#EditStream,-1,"")
  AddGadgetItem(#EditStream,-1,"Terminé.")
  ;
  ; Debug ""
  ; Debug "done"
EndProcedure

If OpenWindow(#Win_Stream,0,0,700,400,"Read Stream for file or directory",#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_TitleBar)=0
	End
Else
  
	If CreatePopupMenu(0)
		MenuItem(1,"Fichier")
		MenuItem(2,"Dossier")
	EndIf
  
	
	ButtonGadget(#Btn_SelectFile,10,5,80,25,"Select") :GadgetToolTip(#Btn_SelectFile,"Sélectionnez un fichier ou un dossier")
	ButtonGadget(#Btn_CopyStream,100,5,80,25,"Copier") :GadgetToolTip(#Btn_CopyStream,"Copier tout le contenu de l'éditeur")
	ButtonGadget(#Btn_CloseStream,610,5,80,25,"Fermer") :GadgetToolTip(#Btn_CloseStream,"Fermer la fenêtre")
  
	EditorGadget(#EditStream,5,35,690,350,#PB_Editor_ReadOnly)
	SetGadgetColor(#EditStream,#PB_Gadget_BackColor,RGB(23,33,41))
	SetGadgetColor(#EditStream,#PB_Gadget_FrontColor,RGB(189,193,200))
	If LoadFont(3,"Courier new",10,#PB_Font_HighQuality)
		SetGadgetFont(#EditStream,FontID(3))
	EndIf
	SendMessage_(GadgetID(#EditStream),#EM_SETTARGETDEVICE,#Null,0)
  
  Repeat
		Event=WaitWindowEvent()
		
		If Event=#PB_Event_Menu
			Select EventMenu()
					
				Case 1
					File$=OpenFileRequester("Sélection d'un fichier","","*.*",0)
					If File$
						ClearGadgetItems(#EditStream)
						ReadStreamFile(File$)
					EndIf
					
				Case 2
					File$=PathRequester("Sélectionnez un dossier","c:\")
					If File$
						ClearGadgetItems(#EditStream)
						ReadStreamFile(File$)
					EndIf
					
			EndSelect
		EndIf
		
		If Event=#PB_Event_Gadget
			Select EventGadget()
					
				Case #Btn_SelectFile:DisplayPopupMenu(0,WindowID(#Win_Stream))
					
				Case #Btn_CopyStream
					RangeAll.CHARRANGE\cpMin=0:RangeAll\cpMax=-1
          SendMessage_(GadgetID(#EditStream),#EM_EXSETSEL,0,@RangeAll)
          SendMessage_(GadgetID(#EditStream),#WM_COPY,0,0)
          
				Case #Btn_CloseStream:Event=#PB_Event_CloseWindow
					
			EndSelect
		EndIf
		
	Until Event=#PB_Event_CloseWindow
  End
EndIf
Pour fonctionner avec PB461 modifiez la structure des autres PRG comme ci-dessus
A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
PAPIPP
Messages : 534
Inscription : sam. 23/févr./2008 17:58

Re: Alternate Data Stream (ADS)

Message par PAPIPP »

Dernier Prg de nico modifié pour fonctionner sous PB4.61

Code : Tout sélectionner

; De Nico Voici un autre code qui permet de scanner seulement les streams Alternate Data 
;(Ceux qu'on peut créer et modifier), les autres sont réservés à l'OS JE crois.
; ---------------------------------------------------------------
; PureBasic 4.61 ->PAPIPP
;----------------------------------------------------------------
; Version 1.0
; Fonctionne à partir de Window 2000 (Système de Fichier NTFS)
;----------------------------------------------------------------
; --> Compiler en Unicode et Activer la gestion des Threads ! <--
;----------------------------------------------------------------
; Ce code permet seulement de lister les streams "Alternate Data"
; contenus dans les fichiers ou les dossiers
;----------------------------------------------------------------

;{- Enumerations / DataSections
;{ Windows
Enumeration
	#Window_Main
EndEnumeration
;}
;{ Gadgets
Enumeration
	#String_Dossier_Fichier
	#Button_Dossier
	#Button_Fichier
	#ListIcon_Stream
	#Button_Scan
	#Button_StopperScan
	#Button_SupprimerleStream
	#Button_EditeravecNotepad
	#Button_Extrairevers
	#Button_Quitter
	#Text_Info
	#Button_OuvrirExplorateur
	#BarreEtat
EndEnumeration
;}
;}

Global Chemin$
Global NomStream.s,StreamSize.q
Global FinRecherche.l

Procedure ReadStream(CheminDossier_CheminFichier.s)
	Protected file_h.i,z.i,*stream.WIN32_STREAM_ID
	Protected context.l=0,bytes_read.l=0,bytes_read1.l=0,seek_l=0,seek_h=0,Result.l=0
	Protected namesize.l,streamHight.q,streamLow.q
	
	file_h=CreateFile_(@CheminDossier_CheminFichier,#READ_CONTROL,0,0,#OPEN_EXISTING,#FILE_FLAG_BACKUP_SEMANTICS,0)
	
	If file_h<>0
		
		*stream.WIN32_STREAM_ID=AllocateMemory(20)
		z=BackupRead_(file_h,*stream,20,@bytes_read,0,1,@context)
		
		While (bytes_read<>0) And Result=0
			
			namesize=*stream\dwStreamNameSize
			If namesize>0
				*buffer=AllocateMemory(namesize)
				BackupRead_(file_h,*buffer,namesize,@bytes_read1,0,1,@context)
				NomStream=PeekS(*buffer,namesize/2,#PB_Unicode)
				FreeMemory(*buffer)
			EndIf
			
			If *stream\dwStreamID=#BACKUP_ALTERNATE_DATA
; 				streamHight.q=*stream\dwStreamSizeHigh & $FFFFFFFF
; 				streamLow.q=*stream\dwStreamSizeLow & $FFFFFFFF
        streamHight.q=*stream\Size\highpart & $FFFFFFFF
				streamLow.q=*stream\Size\lowpart & $FFFFFFFF
        
				StreamSize.q=streamHight<<32 | streamLow
				Result=1
			EndIf
			
; 			BackupSeek_(file_h,*stream\dwStreamSizeLow,*stream\dwStreamSizeHigh,@seek_l,@seek_h,@context)
			BackupSeek_(file_h,*stream\Size\lowpart,*stream\Size\lowpart,@seek_l,@seek_h,@context)
			
			FreeMemory(*stream)
			*stream.WIN32_STREAM_ID=AllocateMemory(20)
			bytes_read=0
			z=BackupRead_(file_h,*stream,20,@bytes_read,0,1,@context)
		Wend
		
		FreeMemory(*stream)
		
		BackupRead_(file_h,0,0,@bytes_read,1,0,@context)
		CloseHandle_(file_h)
		
	EndIf
	ProcedureReturn Result
EndProcedure


Procedure.s ParseDirectory(folder.s,id.l=0)
	Protected Type.s
	
	If Right(folder,1)<>"\"
		folder+"\"
	EndIf
	If ExamineDirectory(id,folder,"*.*")
		If FinRecherche<2
			While NextDirectoryEntry(id)
				If DirectoryEntryName(id)<>"." And DirectoryEntryName(id)<>".."
					;##########################################
					StatusBarText(#BarreEtat,0,folder+DirectoryEntryName(id))
					If ReadStream(folder+DirectoryEntryName(id))
						If DirectoryEntryType(id)=#PB_DirectoryEntry_Directory
							Type.s="Dossier"
						Else
							Type.s="Fichier"
						EndIf
						
						AddGadgetItem(#ListIcon_Stream,-1,NomStream+Chr(10)+Str(StreamSize)+Chr(10)+Type+Chr(10)+folder+DirectoryEntryName(id))
					EndIf
					;##########################################
					If DirectoryEntryType(id)=#PB_DirectoryEntry_Directory
						ParseDirectory(folder+DirectoryEntryName(id),id+1)
					EndIf
				EndIf
			Wend
		EndIf
		FinishDirectory(id)
	EndIf
EndProcedure

Procedure ParseCheminFichierouDossier(folder.s)
	Protected Type.s
	
	If FileSize(folder)=-2
    Type.s="Dossier"
	Else
    Type.s="Fichier"
	EndIf
	If ReadStream(folder)
		AddGadgetItem(#ListIcon_Stream,-1,NomStream+Chr(10)+Str(StreamSize)+Chr(10)+Type+Chr(10)+folder)
	EndIf
	If Type="Dossier"
		ParseDirectory(folder)
	EndIf
EndProcedure

Procedure DisableGadgetGroup1(Etat.l)
	DisableGadget(#Button_Dossier,Etat)
	DisableGadget(#Button_Fichier,Etat)
	DisableGadget(#Button_Scan,Etat)
	DisableGadget(#Button_Quitter,Etat)
EndProcedure

Procedure DisableGadgetGroup2(Etat.l)
	DisableGadget(#Button_SupprimerleStream,Etat)
	DisableGadget(#Button_EditeravecNotepad,Etat)
	DisableGadget(#Button_Extrairevers,Etat)
	DisableGadget(#Button_OuvrirExplorateur,Etat)
EndProcedure

Procedure Thread(lParam.i)
	ParseCheminFichierouDossier(Chemin$)
	StatusBarText(#BarreEtat,0,"")
	FinRecherche=0
	DisableGadget(#Button_StopperScan,1)
	DisableGadgetGroup1(0)
EndProcedure

Procedure OpenWindow_Window_Main()
	If OpenWindow(#Window_Main,200,200,610,460,"Alternate Data Stream SPY",#PB_Window_SystemMenu | #PB_Window_TitleBar)
		StringGadget(#String_Dossier_Fichier,10,25,520,25,"",#PB_String_ReadOnly)
		ButtonGadget(#Button_Dossier,540,10,60,25,"Dossier")
		ButtonGadget(#Button_Fichier,540,40,60,25,"Fichier")
		ListIconGadget(#ListIcon_Stream,10,110,590,250,"Nom du Stream",100,#PB_ListIcon_AlwaysShowSelection | #PB_ListIcon_FullRowSelect | #PB_ListIcon_GridLines)
		AddGadgetColumn(#ListIcon_Stream,1,"Taille",60)
		AddGadgetColumn(#ListIcon_Stream,2,"Type",60)
		AddGadgetColumn(#ListIcon_Stream,3,"Chemin",360)
		ButtonGadget(#Button_Scan,110,70,155,25,"Scan Alternate Data Stream")
		ButtonGadget(#Button_StopperScan,340,70,155,25,"Stopper le Scan")
		ButtonGadget(#Button_SupprimerleStream,315,370,135,25,"Supprimer le Stream")
		ButtonGadget(#Button_EditeravecNotepad,10,370,135,25,"Editer avec Notepad")
		ButtonGadget(#Button_Extrairevers,160,370,135,25,"Extraire le Stream vers...")
		ButtonGadget(#Button_Quitter,240,405,130,25,"Quitter")
		TextGadget(#Text_Info,10,5,520,20,"Vous pouvez glisser-déposer un Fichier ou un Dossier dans la zone de texte ci-dessous")
		ButtonGadget(#Button_OuvrirExplorateur,465,370,135,25,"Ouvrir dans l'explorateur")
		
		CreateStatusBar(#BarreEtat,WindowID(#Window_Main))
		AddStatusBarField(#PB_Ignore)
		
		EnableGadgetDrop(#String_Dossier_Fichier,#PB_Drop_Files,#PB_Drag_Copy)
		
		DisableGadget(#Button_StopperScan,1)
		DisableGadgetGroup2(1)
	EndIf
EndProcedure

OpenWindow_Window_Main()

;{- Event loop
Repeat
	Select WaitWindowEvent()
			; ///////////////////
		Case #PB_Event_GadgetDrop
			Select EventGadget()
				Case #String_Dossier_Fichier
					Files$=EventDropFiles()
					Count=CountString(Files$,Chr(10))+1
					SetGadgetText(#String_Dossier_Fichier,StringField(Files$,1,Chr(10)))
			EndSelect
			
		Case #PB_Event_Gadget
			Select EventGadget()
				Case #Button_Dossier
					Chemin$=PathRequester("Choisissez un répertoire:","C:\")
					SetGadgetText(#String_Dossier_Fichier,Chemin$)
					
				Case #Button_Fichier
					Chemin$=OpenFileRequester("Choisissez un fichier:","C:\","*.*",0)
					SetGadgetText(#String_Dossier_Fichier,Chemin$)
					
				Case #ListIcon_Stream
					Index.l=GetGadgetState(#ListIcon_Stream)
					If Index>-1
						DisableGadgetGroup2(0)
					Else
						DisableGadgetGroup2(1)
					EndIf
					
				Case #Button_Scan
					ClearGadgetItems(#ListIcon_Stream)
					Chemin$=GetGadgetText(#String_Dossier_Fichier)
					If FileSize(Chemin$)<>-1
						DisableGadgetGroup1(1)
						DisableGadgetGroup2(1)
						DisableGadget(#Button_StopperScan,0)
						FinRecherche=1
						CreateThread(@Thread(),0)
					Else
						MessageRequester("Info","Choisissez un chemin de Dossier ou de Fichier valide !")
					EndIf
					
				Case #Button_StopperScan
					FinRecherche=2
					DisableGadget(#Button_StopperScan,1)
					DisableGadgetGroup1(0)
					
				Case #Button_EditeravecNotepad
					Index.l=GetGadgetState(#ListIcon_Stream)
					If Index>-1
						NameStream.s=GetGadgetItemText(#ListIcon_Stream,Index,0)
						NameStream=StringField(NameStream,2,":")
						CheminStream.s=GetGadgetItemText(#ListIcon_Stream,Index,3)
						MessageRequester("Info","Dans certain cas, Notepad ne sera pas en mesure d'ouvrir le Stream !"+Chr(13)+"mais vous pouvez toujours faire une Extraction puis ensuite éditer le Fichier ainsi obtenu.")
						RunProgram("Notepad.exe",CheminStream+":"+NameStream,"")
					EndIf
					
				Case #Button_Extrairevers
					Index.l=GetGadgetState(#ListIcon_Stream)
					If Index>-1
						NameStream.s=GetGadgetItemText(#ListIcon_Stream,Index,0)
						NameStream=StringField(NameStream,2,":")
						Taille.s=GetGadgetItemText(#ListIcon_Stream,Index,1)
						If Taille<>"0"
							NomFichier$=SaveFileRequester("Choisissez un emplacement:",NameStream,"*.*",0)
							If NomFichier$<>""
								CheminStream.s=GetGadgetItemText(#ListIcon_Stream,Index,3)
								If ReadFile(0,CheminStream+":"+NameStream)
									Longueur.q=Lof(0)
									*Buffer.i=AllocateMemory(Longueur)
									ReadData(0,*Buffer,Longueur)
									CloseFile(0)
									If CreateFile(0,NomFichier$)
										WriteData(0,*Buffer,Longueur)
										CloseFile(0)
									EndIf
									FreeMemory(*Buffer)
								Else
									MessageRequester("Erreur","Le Stream n'a pas pu être sauvegardé !")
								EndIf
							EndIf
						Else
							MessageRequester("Info","La Taille de ce Stream est de 0 octet, il est inutile de vouloir le sauvegarder !")
						EndIf
					EndIf
					
				Case #Button_SupprimerleStream
					Index.l=GetGadgetState(#ListIcon_Stream)
					If Index>-1
						NameStream.s=GetGadgetItemText(#ListIcon_Stream,Index,0)
						NameStream=StringField(NameStream,2,":")
						CheminStream.s=GetGadgetItemText(#ListIcon_Stream,Index,3)
						Type.s=GetGadgetItemText(#ListIcon_Stream,Index,2)
						Message$="Êtes-vous sûr de vouloir supprimer le Stream : "+NameStream+" ?"+Chr(13)+"du "+Type+" "+CheminStream
						Resultat=MessageRequester("Attention",Message$,#PB_MessageRequester_YesNo)
						If Resultat=#PB_MessageRequester_Yes
							If DeleteFile(CheminStream+":"+NameStream)<>0
								RemoveGadgetItem(#ListIcon_Stream,Index)
							Else
								MessageRequester("Erreur","Le Stream n'a pas pu être effacé !")
							EndIf
						EndIf
					EndIf
					
				Case #Button_OuvrirExplorateur
					Index.l=GetGadgetState(#ListIcon_Stream)
					If Index>-1
						CheminStream.s=GetGadgetItemText(#ListIcon_Stream,Index,3)
						RunProgram("Explorer.exe","/e, /Select,"+CheminStream,"")
					EndIf
					
				Case #Button_Quitter
					CloseWindow(#Window_Main)
					Break
			EndSelect
			; ////////////////////////
		Case #PB_Event_CloseWindow
			Select EventWindow()
				Case #Window_Main
					If FinRecherche=0
						CloseWindow(#Window_Main)
						Break
					Else
						MessageRequester("Info","Cliquez sur le Bouton Stopper le Scan avant de quitter !")
					EndIf
			EndSelect
	EndSelect
ForEver
;
;}
A+
Il est fort peu probable que les mêmes causes ne produisent pas les mêmes effets.(Einstein)
Et en logique positive cela donne.
Il est très fortement probable que les mêmes causes produisent les mêmes effets.
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: Alternate Data Stream (ADS)

Message par Ar-S »

Merci pour la maj PAPIPP
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
jassing
Messages : 2
Inscription : ven. 20/juil./2012 5:06

Re: Alternate Data Stream (ADS)

Message par jassing »

Merci beaucoup!
Répondre