Jump to content
Sign in to follow this  
mikeytown2

NTFS Alternate Data Stream

Recommended Posts

mikeytown2

I've always wanted to keep a programs preferences but i wanted to keep it as a single executable; no external ini files or registry settings. I have found a solution! Alternate Data Streams (ADS) allow you to "hide" a file inside another file, its a feature found on NTFS partitions. Apple's use ADS quite regularly, that is why most files from a mac have no extension, the file type is stored in a ADS.

This is a demo that stores text in an ini file, then retrieves that hidden info from the compiled exe file. It also opens the hiden file in notepad.

$File = "test.ini"  ;name of ini file, or alternate data stream (NTFS) if no errors

;error checking and setting of location
$inifileloc = ActOnChk(ErrorChk())

;write ini file
IniWrite($inifileloc, "section2", "key" & Round(Random(), 3) * 1000, InputBox("", "", "Enter Some Text "))

;Read the ADS
$var = IniReadSection($inifileloc, "section2")

;Display the contents of the INI file
If @error Then
    MsgBox(4096, "", "Error occurred, probably no INI file.")
Else
    For $i = 1 To $var[0][0]
        MsgBox(4096, $inifileloc, "Key: " & $var[$i][0] & @CRLF & "Value: " & $var[$i][1])
    Next
EndIf

;Show it in notepad
Run(@ComSpec & ' /c ' & 'notepad "' & $inifileloc & '"', "", @SW_HIDE)



Func ErrorChk()
    Select
        Case @Compiled == 0 ;program not compiled
            Return(1)
        Case StringInStr(@AutoItExe, "\\") == 1 ;networked path not mapped to drive
            Return(2)
        Case DriveGetFileSystem(StringLeft(@AutoItExe, 3)) <> "NTFS"    ;drive not NTFS
            Return(3)
        Case IsAdmin() == 0 ;user is not admin
            Return(4)
    EndSelect
EndFunc   ;==>ErrorChk

Func ActOnChk($ADS_ERR)
    Switch $ADS_ERR
        Case 0  ;no error
            Return @AutoItExe & ':' & $File
        Case 1  ;program not compiled
            MsgBox(16, "Can Not Use Alternate Data Streams", "Please Complile Program")
            Return $File    ;set it to a normal file
        Case 2  ;networked path not mapped to drive
            MsgBox(16, "Can Not Use Alternate Data Streams", "Please Map Network Folder To Drive")
            Return $File    ;set it to a normal file
        Case 3  ;drive not NTFS
            MsgBox(16, "Can Not Use Alternate Data Streams", "Please Run From A NTFS Partition")
            Return $File    ;set it to a normal file
        Case 4  ;user is not admin
            MsgBox(16, "Can Not Use Alternate Data Streams", "Please Run With Admin Rights")
            Return $File    ;set it to a normal file
    EndSwitch
EndFunc   ;==>ActOnChk
In order for this to work it needs to be run from a NTFS partition and it needs to be compiled into an exe file. If you del the compiled exe or re-compile the program, the ADS is lost. If you copy the exe to a non NTFS partiton, you lose the ADS. If you email/zip/ftp the exe, you lose the ADS. Thus the info that is stored in here is sorta non transferable from computer to computer; windows shares and external NTFS drives are the only way you can safely transfer the ADS to another computer when copying the exe file.

This fact makes ADS very useful for personal preferences and serial numbers; when you copy the exe to another computer you lose the ADS. Let me know how this works, and if there is anything else this should do.

Read more about Alternative Data Streams

EDIT... Let me know if you think hiding support DLL files in the ADS would be useful. I'll dream one up then.

EDIT... Simplified the code, its fairly straightforward now.

EDIT... More Logical, added in an admin check, let me know if it works without admin rights.

EDIT... Better Error Checking (now checks if run from networked folder). Also put code in AutoIt codebox!

Edited by mikeytown2

Share this post


Link to post
Share on other sites
MHz

Interestingly simple. It could open some ideas of use.

Thanks :)

Share this post


Link to post
Share on other sites
SkinnyWhiteGuy

I had always wondered if AutoIt could handle NTFS streams by itself, or if you'd need to rely on Windows command line tools to at least handle the storage and retrieval of files before Autoit could use them. Thanks for at least killing my curiosity (in a good way).

Share this post


Link to post
Share on other sites
Paulchen

@SkinnyWhiteGuy

you can simple test streams with following internals commands.

1. start commandline klick start/run

2. type cmd

3. in the cmd windows type echo "Hallo" >123456.txt

this create a file with the name 123456.txt. you can open this with notepad

4. type dir >123456.txt:blabla

this write the output from dir command to the blabla Stream in the 123456.txt file.

5.type more <123456.txt:blabla

this command display the blabla stream from 123456.txt file

@mikeytown2

I do not like streams in exe, dll, ocx... files. This are bad. I work normaly with a lockdown account und have no right to write on this files.

Share this post


Link to post
Share on other sites
Ghastly_MIB

Very cool :)

Thanks for sharing!

Share this post


Link to post
Share on other sites
mikeytown2

@SkinnyWhiteGuy

Looks like autoit has full support of ADS, i changed the example code accordingly.

@Paulchen

If you are not an admin you can not write ADS?

Can someone verify the needing of admin right to write an ADS. It would be nice to know so i can put an admin flag in for the checks as well.

Share this post


Link to post
Share on other sites
jftuga
flyingboz

Nice idea for implementation; I've looked at the API a few times,

but never had enough need to work my way through the DllCalls.

A question and suggestion..

I'm wondering how the above code can ever return True. :)

In the 'would be nice' category , if you want to fix this up for UDF inclusion,

consider turning your initial $inifileloc var to isolate the possible errors, and

return the specific error code and/or text.

Again, nice idea.

Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites
martin

DriveGetFileSystem(StringLeft(@AutoItExe,3)) == "NTFS"

I'm wondering how the above code can ever return True. :)

It will return true if the drive where the autoitexe is stored has an NTFS file system.

Serial port communications UDF Includes functions for binary transmission and reception.printing UDF Useful for graphs, forms, labels, reports etc.Add User Call Tips to SciTE for functions in UDFs not included with AutoIt and for your own scripts.Functions with parameters in OnEvent mode and for Hot Keys One function replaces GuiSetOnEvent, GuiCtrlSetOnEvent and HotKeySet.UDF IsConnected2 for notification of status of connected state of many urls or IPs, without slowing the script.

Share this post


Link to post
Share on other sites
mikeytown2

Nice idea for implementation; I've looked at the API a few times,

but never had enough need to work my way through the DllCalls.

what dll's??? The idea behind ADS are quite simple, all thats needed is a :

In the 'would be nice' category , if you want to fix this up for UDF inclusion,

consider turning your initial $inifileloc var to isolate the possible errors, and

return the specific error code and/or text.

Again, nice idea.

yep, thats all i intended it to be an idea, no where close to a UDF. It is a working idea though.

Read more about Alternative Data Streams

Share this post


Link to post
Share on other sites
flyingboz

I've been looking for modifying the summary properties of files; perhaps this technique is not going to be

directly applicable. Still, food for thought.

BTW, the NTFS check will not work on executables invoked via UNC paths.

Edited by flyingboz

Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites
mikeytown2

BTW, the NTFS check will not work on executables invoked via UNC paths.

Good point, i fixed it and made a nice looking error check that tells you whats wrong.

Anyone know of a better way to check if the UNC path is NTFS other then mapping the drive?

Share this post


Link to post
Share on other sites
Michel Claveau

Hi!

If I use your script ; then, if I copy files on my USB-key (Corsair Voyager GT), who is formated in ...FAT

Will I lose information(s)?

Share this post


Link to post
Share on other sites
Siao

Will I lose information(s)?

Of course you will lose everything that was in ADS.

"be smart, drink your wine"

Share this post


Link to post
Share on other sites
flyingboz

Anyone know of a better way to check if the UNC path is NTFS other then mapping the drive?

As \\server\share works with DriveGetFileSystem() but \\sherver\share\subdir fails, one method would be to:

While StringLen(DriveGetFileSystem($path)) = 0

Trim the rightmost directory from the path....

This will walk you up the tree until you get to the share.

Another method (probably faster) would be to locate the fourth backslash, and trim it and everyting to its right.

_PathSplit() is supposed to support UNC paths, but it's definition of Drive and DriveGetFileSystem() 's differ.

This might be considered a bug or programmatic inconsistency in _PathSplit().


Reading the help file before you post... Not only will it make you look smarter, it will make you smarter.

Share this post


Link to post
Share on other sites
ptrex

@mrRevoked

Maybe this can help you out.

Reveal ADS

download NTFSext.exe which contains, among others a file strmext.dll. Just put it in the system32 folder and run the command

regsvr32 StrmExt.dll

Now you have a new tab in the file properties of Windows Explorer. It does not help much to search for ADS, but is nice if you already know a file which has an ADS.

To make the tab visible for folders, you need to add the following Registry key:

HKEY_CLASSES_ROOT\Directory\shellex\PropertySheetHandlers\{C3ED1679-814B-4DA9-AB00-1CAC71F5E337}

To make the tab visible for root folders, you need to add the following Registry key:

HKEY_CLASSES_ROOT\Drive\shellex\PropertySheetHandlers\{C3ED1679-814B-4DA9-AB00-1CAC71F5E337}

Regards,

ptrex

Share this post


Link to post
Share on other sites
Reaper HGN

This caught my eye so I decided to take a look. While my response adds no value to the post, I do want to say this topic (ADS) is very interesting and it prompted me to do a bit of research on my own. I am considering using this as a potential mechanism for storing "transient" data quickly and easily. Thanks for the post.

Share this post


Link to post
Share on other sites
YourSpace

ok explain exactly how this works please.... say im working with Messenger.exe

and i want to write hallo into the stream xty

what code woudl i need to write to do this.

Share this post


Link to post
Share on other sites
Skrip

ok explain exactly how this works please.... say im working with Messenger.exe

and i want to write hallo into the stream xty

what code woudl i need to write to do this.

Look at my _ADS() UDF, up in the examples forum.

[left][sub]We're trapped in the belly of this horrible machine.[/sub][sup]And the machine is bleeding to death...[/sup][sup][/sup][/left]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.