📄 flister.cpp
字号:
/*
simple proof-of-concept
uncovers files hidden by various rootkits ;)
joanna at invisiblethings.org
http://invisiblethings.org
*/
#include <windows.h>
#include <stdio.h>
typedef ULONG NTSTATUS;
typedef struct _IO_STATUS_BLOCK {
union {
NTSTATUS Status;
PVOID Pointer;
};
ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
typedef
VOID
(NTAPI *PIO_APC_ROUTINE) (
IN PVOID ApcContext,
IN PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG Reserved
);
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;
#define NTAPI __stdcall
#define IN
#define OUT
#define OPTIONAL
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileNamesInformation = 12
//...
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
typedef struct _FILE_DIRECTORY_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER EndOfFile;
LARGE_INTEGER AllocationSize;
ULONG FileAttributes;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_DIRECTORY_INFORMATION,
*PFILE_DIRECTORY_INFORMATION;
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG Unknown;
ULONG FileNameLength;
WCHAR FileName[1024];
} FILE_NAMES_INFORMATION,
*PFILE_NAMES_INFORMATION;
int ZwQueryDirFileNo = 0;
void usage (char *str) {
printf ("FLISTER 0.1, (c) 2005 by joanna\n");
printf ("http://invisiblethings.org\n");
printf ("%s <dir> [ZwQueryDirFile_Syscall_Index]\n", str);
exit (0);
}
_declspec(naked)
NTSTATUS NTAPI PrivQueryDirectoryFile (
IN HANDLE hFile,
IN HANDLE hEvent OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID AppContext OPTIONAL,
OUT PIO_STATUS_BLOCK pIoStatusBlock,
OUT PVOID FileInfo,
IN ULONG FileInfoLen,
IN FILE_INFORMATION_CLASS FileInfoClass,
IN BOOLEAN ReturnSingleEntry,
IN PUNICODE_STRING FileName OPTIONAL,
IN BOOLEAN RestartScan
) {
_asm {
mov eax, ZwQueryDirFileNo
lea edx, [esp+4]
int 2Eh
ret 2Ch
}
}
typedef NTSTATUS (NTAPI *ZWQUERYDIRFUNC) (
HANDLE,
HANDLE,
PIO_APC_ROUTINE,
PVOID,
PIO_STATUS_BLOCK,
PVOID,
ULONG,
FILE_INFORMATION_CLASS,
BOOLEAN,
PUNICODE_STRING,
BOOLEAN);
ZWQUERYDIRFUNC ZwQueryDirectoryFile;
int main (int argc, char **argv) {
if (argc != 2 && argc != 3) usage(argv[0]);
HANDLE hDir = CreateFile (
argv[1],
FILE_LIST_DIRECTORY,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if (hDir == INVALID_HANDLE_VALUE) {
printf ("Can't open directory\n");
exit (1);
}
if (argc == 2) {
HMODULE hNTDLL = LoadLibrary ("ntdll");
ZwQueryDirectoryFile = (ZWQUERYDIRFUNC)
GetProcAddress (hNTDLL, "ZwQueryDirectoryFile");
printf ("ZwQueryDirFile at addr %#x\n", (DWORD)ZwQueryDirectoryFile);
// ZwQueryDirFileNo = *(DWORD*)((char*)addr + 1);
} else {
ZwQueryDirFileNo = strtoul(argv[2], 0, 0);
printf ("Using funtion from SysCallTable[%d]...\n",
ZwQueryDirFileNo);
ZwQueryDirectoryFile = PrivQueryDirectoryFile;
}
printf ("directory dump:\n---------------------\n");
IO_STATUS_BLOCK stat;
FILE_NAMES_INFORMATION fileInfo;
while (1) {
memset (&fileInfo, 0, sizeof (fileInfo));
memset (&stat, 0, sizeof (stat));
NTSTATUS s = ZwQueryDirectoryFile (
hDir,
0,
0,
0,
&stat,
&fileInfo,
sizeof (fileInfo),
FileNamesInformation,
TRUE,
NULL,
FALSE);
if (s == 0x80000006) break;
if (s != 0) {
printf ("error while scanning directory (err = %#x)\n", s);
exit (2);
}
WCHAR *wfname = new WCHAR [fileInfo.FileNameLength/2 + 1];
memcpy (wfname, fileInfo.FileName, fileInfo.FileNameLength);
wfname [fileInfo.FileNameLength/2] = 0;
printf ("%S\n", wfname);
delete wfname;
}
CloseHandle (hDir);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -