Showing ADS Files only

1

1

Currently, the code I'm using to show Alternate Data Stream (ADS) files in cmd.exe is dir /R.

However, what this does is that it lists all my other files, in addition to the ADS files.

The question is - what command should I use to only display ADS files.


The command dir C:\ /r /s | findstr /r "\$DATA" is the best I can find - although I'm not too convinced with its accuracy. Any others?

user196661

Posted 2013-02-08T12:37:04.917

Reputation: 11

Answers

1

AltStreamDump utility (from Nirsoft) can also do this.

EDIT: There is also GUI application AlternateStreamView (Nirsoft too) that have command line support and allow e.g export list to a file

Greck

Posted 2013-02-08T12:37:04.917

Reputation: 241

Any commands that do not require the installation of third-party programs? – user196661 – 2013-02-08T13:17:43.250

1

Very cool - I had never heard of ADS before, and had to look up what it was.

I can't vouch for how reliable your method is, but I can see three ways to potentially improve it.

1) A normal file could be named "$DATA". You can improve the accuracy of your filter by using:

findstr /el :$DATA


2) You lose the path information when you use DIR /R /S option and keep only the :$DATA lines. Here is a nasty one liner that lists the file size and full path for all ADS. I redirect stderr to nul to hide error messages from inaccessible folders:

for /r %F in (.) do @(pushd "%F"&&(for /f "tokens=1*" %A in ('dir /r^|findstr /el :$DATA') do @echo %A %~fB)&popd)2>nul


3) An ADS can be attached to a folder as well as a file. Suppose the following folder structure exists: C:\root\child\grandchild\. Also suppose that C:\root\child has an ADS named child:ads.txt. The DIR /R /S command will list the ADS at the following three levels:

  • C:\root will list child:ads.txt:$DATA

  • C:\root\child will list .:ads.txt:$DATA

  • C:\root\grandchild will list ..:ads.txt:$DATA

Only the first listing is wanted. Within the FOR /F loop, the size of %B can be gotten by using %~zB, but that only works for the first listing; it expands to an empty string for the other two. That provides a convenient and efficient way to eliminate the unwanted listings.

for /r %F in (.) do @(pushd "%F"&&(for /f "tokens=1*" %A in ('dir /r^|findstr /el :$DATA') do @if .%~zB neq . echo %A %~fB)&popd)2>nul


The final solution looks much better as a multi-line batch script

@echo off
for /r %%F in (.) do (
  pushd "%%F" &&(
    for /f "tokens=1*" %%A in (
      'dir /r^|findstr /el :$DATA'
    ) do if "%%~zB" neq "" echo %%~zB %%~fB
    popd
  )
)2>nul


Simply remove %%A (or %A) from the ECHO command if you only want the ADS file paths without the file sizes.

dbenham

Posted 2013-02-08T12:37:04.917

Reputation: 9 212

The only problem is that alternate streams can have any name, so you need to search for file names containing colons. – afrazier – 2013-02-08T22:57:08.830

@afrazier - I don't understand your logic. The DIR /R command appends :$DATA to the listed name of every ADS, and my solution looks for that exact ending string. The name of the ADS has no bearing on the outcome. For example, an ADS named file.txt:hidden.txt is listed as file.txt:hidden.txt:$DATA. – dbenham – 2013-02-08T23:03:30.450

Windows file names cannot contain a :. – aphoria – 2013-02-09T01:57:53.937

@dbenham: Sorry, I thought that $DATA was the stream name. In that case, your scripts look like just the thing then. – afrazier – 2013-02-09T04:15:26.150