Question

I downloaded a program yesterday, it is for encryption and security. I won't name it here unless someone asks me to but it has a feature to make files inside a specified folder completely invisible.

I have Hidden Files and Folders - Selected and also Hide protected operating system files - Unselected yet the files are gone completely from view and don't show up in a search either. I copied the folder over from VMware Workstation to my main machine and still the files are super hidden! There are zero files in the folder according to Windows.

How is this voodoo magick possible? I want to emulate this using Delphi in my own encryption program. I have not found any way on here and via Google that suggests how it is possible but the actual programs help file says they are still in the folder but do not register with most normal Windows software that process files.

This is one of those questions where I can not give any code to show what I have tried, but rather open to suggestions of what I can try or maybe someone here knows exactly how it is done?

Was it helpful?

Solution

Since less informa One possebility would be using alternative filestreams on NTFS, which can be added to files and folders. You can just try this by typing "notepad C:\temp:hidden1.txt" at the comandline, new filestream will be created if you aswer with yes. After saving you can reopen it exact the same way. This can also be done from delphi (loading/saving). Will only work if NTFS is used. I don't know if this method is used in described case, finding ADS can be done with following code:

unit u_ListADS;

// 20120928 by Thomas Wassermann
// www.devworx.de
interface

uses
  Windows, Messages, SysUtils, Variants, Classes, StrUtils;

 Procedure GetADS(List: TStrings; const Path, WildCard: String; Recursiv: Boolean = false);

function NtQueryInformationFile(FileHandle: Cardinal; IoStatusBlock: Pointer; FileInformation: Pointer; FileInformationLength: Cardinal;
  FileInformationClass: Cardinal): Cardinal; stdcall; external 'ntdll.dll';

implementation

type
  _FILE_STREAM_INFORMATION = record
    NextEntryOffset: Cardinal;
    StreamNameLength: Cardinal;
    StreamSize: int64;
    StreamAllocationSize: int64;
    StreamName: array [0 .. MAX_PATH] of WideChar;
  end;

  PFILE_STREAM_INFORMATION = ^_FILE_STREAM_INFORMATION;

function GetStreams(aFilename: String): TStringList;
var
  FileHandle: Integer;
  FileName: array [0 .. MAX_PATH] of WideChar;
  StreamName: String;
  InfoBlock: _FILE_STREAM_INFORMATION;
  StatusBlock: record Status: Cardinal;
                      Information: PDWORD;
               end;

  Procedure Analyze;
    begin
      CopyMemory(@FileName, @InfoBlock.StreamName, InfoBlock.StreamNameLength);
      StreamName := Copy(Filename, 1, PosEx(':', Filename, 2) - 1);
      if StreamName <> ':' then Result.Add(StreamName);
    end;
begin
  Result := TStringList.Create;
  FileHandle := FileOpen(aFilename, GENERIC_READ);
  NtQueryInformationFile(FileHandle, @StatusBlock, @InfoBlock, SizeOf(InfoBlock), 22);
  FileClose(FileHandle);
  if InfoBlock.StreamNameLength <> 0 then
    Repeat

      if (InfoBlock.NextEntryOffset <> 0) then
        begin
        InfoBlock := PFILE_STREAM_INFORMATION(PByte(@InfoBlock) + InfoBlock.NextEntryOffset)^;
        Analyze;
        end;
    until InfoBlock.NextEntryOffset = 0
end;

Procedure GetADS(List: TStrings; const Path, WildCard: String; Recursiv: Boolean = false);
  Var
    SR: SysUtils.TSearchRec;
    RES: Integer;
    SP: String;
    StreamList: TStringList;
    i: Integer;
  begin
    if length(Path) = 0 then
      exit;
    if length(WildCard) = 0 then
      exit;
    SP := IncludeTrailingBackSlash(Path) + WildCard;
    RES := FindFirst(IncludeTrailingBackSlash(Path) + '*.*', faDirectory, SR);
    While RES = 0 Do
    Begin
      If (SR.attr And faDirectory) <> 0 Then
        If SR.Name[1] <> '.' Then
          if Recursiv then
            GetADS(List, IncludeTrailingBackSlash(Path) + SR.Name, WildCard, Recursiv);
      RES := FindNext(SR);
    End;
    SysUtils.FindClose(SR);
    RES := FindFirst(SP, $27, SR);
    While RES = 0 Do
    Begin
      StreamList := GetStreams(IncludeTrailingBackSlash(Path) + SR.Name);
      for i := 0 to StreamList.Count - 1 do
        List.Add(IncludeTrailingBackSlash(Path) + SR.Name + StreamList[i]);
      StreamList.Free;
      RES := FindNext(SR);
    End;
    SysUtils.FindClose(SR);
  end;

end.

Call could be e.g.

  GetADS(Listbox1.Items,Directory.Text, WildCards.Text,rekursiv.checked);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top