4

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

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

这个巫毒魔法怎么可能?我想在我自己的加密程序中使用 Delphi 来模拟这个。我在这里和通过谷歌没有找到任何方法来暗示它是如何可能的,但实际的程序帮助文件说它们仍在文件夹中,但没有注册大多数处理文件的普通 Windows 软件。

这是我无法提供任何代码来显示我尝试过的内容的问题之一,而是对我可以尝试的建议持开放态度,或者这里的某个人可能确切地知道它是如何完成的?

4

1 回答 1

7

由于信息较少,一种可能性是在 NTFS 上使用替代文件流,可以将其添加到文件和文件夹中。您可以通过在命令行中键入“notepad C:\temp:hidden1.txt”来尝试此操作,如果您选择“是”,则将创建新的文件流。保存后,您可以以完全相同的方式重新打开它。这也可以从 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);
于 2012-11-22T06:48:22.973 回答