如何使文件真正隐藏在目录中?

时间:2012-11-22 06:27:53

标签: delphi operating-system delphi-xe2 hidden-files

我昨天下载了一个程序,它用于加密和安全。除非有人问我,否则我不会在这里命名,但它有一个功能,可以使指定文件夹中的文件完全不可见。

我有隐藏文件和文件夹 - 已选择并隐藏受保护的操作系统文件 - 未选中文件已完全从视图中删除,也不会显示在搜索中。我将文件夹从VMware Workstation复制到我的主机,但文件仍然是超级隐藏的!根据Windows,文件夹中没有文件。

这个伏都教魔法怎么可能?我想在我自己的加密程序中使用Delphi来模拟这个。我没有找到任何方式在这里和通过谷歌建议如何可能,但实际程序帮助文件说他们仍然在文件夹中但不注册处理文件的大多数正常的Windows软件。

这是其中一个问题,我无法提供任何代码来展示我尝试过的内容,而是愿意接受我可以尝试的建议,或者这里有人知道它是如何完成的?

1 个答案:

答案 0 :(得分:7)

由于信息较少 一个可拥有性将在NTFS上使用备用文件流,可以将其添加到文件和文件夹中。您可以通过在comandline上键入“notepad C:\ temp:hidden1.txt”来尝试此操作,如果您使用yes,则会创建新的文件流。保存后,您可以以相同的方式重新打开它。这也可以通过delphi(加载/保存)完成。仅在使用NTFS时才有效。 我不知道在描述的情况下是否使用了这种方法,可以使用以下代码来查找ADS:

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.

呼叫可以是例如。

  GetADS(Listbox1.Items,Directory.Text, WildCards.Text,rekursiv.checked);