- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在一个小型的 antirootkit 中工作,我需要添加一个功能:
那么,首先有必要知道所有这些目录和文件,对吧?
为此,我下面的代码已经完成了这项任务的一半。他枚举了特定目录的所有目录和文件,但不“查看”子目录(文件和文件夹)。
例如:
输出:
代码:
#include <ntifs.h>
typedef unsigned int UINT;
NTSTATUS EnumFilesInDir()
{
HANDLE hFile = NULL;
UNICODE_STRING szFileName = { 0 };
OBJECT_ATTRIBUTES Oa = { 0 };
NTSTATUS ntStatus = 0;
IO_STATUS_BLOCK Iosb = { 0 };
UINT uSize = sizeof(FILE_BOTH_DIR_INFORMATION);
FILE_BOTH_DIR_INFORMATION *pfbInfo = NULL;
BOOLEAN bIsStarted = TRUE;
RtlInitUnicodeString(&szFileName, L"\\??\\C:\\MyDirectory");
InitializeObjectAttributes(&Oa, &szFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL);
ntStatus = ZwCreateFile(&hFile, GENERIC_READ | SYNCHRONIZE, &Oa, &Iosb, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if (!NT_SUCCESS(ntStatus)) { return ntStatus; }
pfbInfo = ExAllocatePoolWithTag(PagedPool, uSize, '0000');
if (pfbInfo == NULL)
{
ZwClose(hFile); return STATUS_NO_MEMORY;
}
while (TRUE)
{
lbl_retry:
RtlZeroMemory(pfbInfo, uSize);
ntStatus = ZwQueryDirectoryFile(hFile, 0, NULL, NULL, &Iosb, pfbInfo, uSize, FileBothDirectoryInformation, FALSE, NULL, bIsStarted);
if (STATUS_BUFFER_OVERFLOW == ntStatus) {
ExFreePoolWithTag(pfbInfo, '000');
uSize = uSize * 2;
pfbInfo = ExAllocatePoolWithTag(PagedPool, uSize, '0000');
if (pfbInfo == NULL) { ZwClose(hFile); return STATUS_NO_MEMORY; }
goto lbl_retry;
}
else if (STATUS_NO_MORE_FILES == ntStatus)
{
ExFreePoolWithTag(pfbInfo, '000');
ZwClose(hFile); return STATUS_SUCCESS;
}
else if (STATUS_SUCCESS != ntStatus)
{
ExFreePoolWithTag(pfbInfo, '000');
ZwClose(hFile);
return ntStatus;
}
if (bIsStarted)
{
bIsStarted = FALSE;
}
while (TRUE)
{
WCHAR * szWellFormedFileName = ExAllocatePoolWithTag(PagedPool, (pfbInfo->FileNameLength + sizeof(WCHAR)), '0001');
if (szWellFormedFileName)
{
RtlZeroMemory(szWellFormedFileName, (pfbInfo->FileNameLength + sizeof(WCHAR)));
RtlCopyMemory(szWellFormedFileName, pfbInfo->FileName, pfbInfo->FileNameLength);
//KdPrint(("File name is: %S\n", szWellFormedFileName));
KdPrint((" %S\n", szWellFormedFileName));
ExFreePoolWithTag(szWellFormedFileName, '000');
}
if (pfbInfo->NextEntryOffset == 0) { break; }
pfbInfo += pfbInfo->NextEntryOffset;
}
}
ZwClose(hFile);
ExFreePoolWithTag(pfbInfo, '000');
return ntStatus;
}
那么,怎么做呢?
提前感谢任何帮助或建议。
-------------------------------------------- - - - - - - 编辑: - - - - - - - - - - - - - - - - - - --------------------------------
我找到了一个可能的解决方案,但我在这一行遇到了蓝屏死机:
if ( (*pDir)->NextEntryOffset)
在 KernelFindNextFile
方法中。
一些建议?
这是我找到的代码:
#include <ntifs.h>
#include <stdlib.h>
HANDLE KernelCreateFile(IN PUNICODE_STRING pstrFile,IN BOOLEAN bIsDir)
{
HANDLE hFile = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = {0};
ULONG ulShareAccess = FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE;
ULONG ulCreateOpt = FILE_SYNCHRONOUS_IO_NONALERT;
OBJECT_ATTRIBUTES objAttrib = {0};
ULONG ulAttributes = OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE;
InitializeObjectAttributes(&objAttrib,pstrFile,ulAttributes,NULL,NULL);
ulCreateOpt |= bIsDir?FILE_DIRECTORY_FILE:FILE_NON_DIRECTORY_FILE;
Status = ZwCreateFile(
&hFile,
GENERIC_ALL,
&objAttrib,
&StatusBlock,
0,
FILE_ATTRIBUTE_NORMAL,
ulShareAccess,
FILE_OPEN_IF,
ulCreateOpt,
NULL,
0);
if (!NT_SUCCESS(Status))
{
return (HANDLE)-1;
}
return hFile;
}
PFILE_BOTH_DIR_INFORMATION KernelFindFirstFile(IN HANDLE hFile,IN ULONG ulLen,OUT PFILE_BOTH_DIR_INFORMATION pDir)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK StatusBlock = {0};
PFILE_BOTH_DIR_INFORMATION pFileList = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,ulLen);
Status = ZwQueryDirectoryFile(
hFile,NULL,NULL,NULL,
&StatusBlock,
pDir,
ulLen,
FileBothDirectoryInformation,
TRUE,
NULL,
FALSE);
RtlCopyMemory(pFileList,pDir,ulLen);
Status = ZwQueryDirectoryFile(
hFile,NULL,NULL,NULL,
&StatusBlock,
pFileList,
ulLen,
FileBothDirectoryInformation,
FALSE,
NULL,
FALSE);
return pFileList;
}
NTSTATUS KernelFindNextFile(IN OUT PFILE_BOTH_DIR_INFORMATION* pDir)
{
if ( (*pDir)->NextEntryOffset)
{
(*pDir)=(PFILE_BOTH_DIR_INFORMATION)((UINT32)(*pDir)+(*pDir)->NextEntryOffset);
return STATUS_SUCCESS;
}
return STATUS_UNSUCCESSFUL;
}
void Traversal()
{
UNICODE_STRING ustrFolder = {0};
WCHAR szSymbol[0x512] = L"\\??\\";
UNICODE_STRING ustrPath = RTL_CONSTANT_STRING(L"C:\\MyDirectory");
HANDLE hFile = NULL;
SIZE_T nFileInfoSize = sizeof(FILE_BOTH_DIR_INFORMATION)+270*sizeof(WCHAR);
SIZE_T nSize = nFileInfoSize*0x256;
char strFileName[0x256] = {0};
PFILE_BOTH_DIR_INFORMATION pFileListBuf = NULL;
PFILE_BOTH_DIR_INFORMATION pFileList = NULL;
PFILE_BOTH_DIR_INFORMATION pFileDirInfo = (PFILE_BOTH_DIR_INFORMATION)ExAllocatePool(PagedPool,nSize);
wcscat_s(szSymbol,_countof(szSymbol),ustrPath.Buffer);
RtlInitUnicodeString(&ustrFolder,szSymbol);
hFile = KernelCreateFile(&ustrFolder,TRUE);
pFileList = pFileListBuf;
KernelFindFirstFile(hFile,nSize,pFileDirInfo);
if (pFileList)
{
RtlZeroMemory(strFileName,0x256);
RtlCopyMemory(strFileName,pFileDirInfo->FileName,pFileDirInfo->FileNameLength);
if (strcmp(strFileName,"..")!=0 || strcmp(strFileName,".")!=0)
{
if (pFileDirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DbgPrint("[Directory]%S\n",strFileName);
}
else
{
DbgPrint("[File]%S\n",strFileName);
}
}
}
while (NT_SUCCESS(KernelFindNextFile(&pFileList)))
{
RtlZeroMemory(strFileName,0x256);
RtlCopyMemory(strFileName,pFileList->FileName,pFileList->FileNameLength);
if (strcmp(strFileName,"..")==0 || strcmp(strFileName,".")==0)
{
continue;
}
if (pFileList->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DbgPrint("[Directory]%S\n",strFileName);
}
else
{
DbgPrint("[File]%S\n",strFileName);
}
}
RtlZeroMemory(strFileName,0x256);
RtlCopyMemory(strFileName,pFileListBuf->FileName,pFileListBuf->FileNameLength);
if (strcmp(strFileName,"..")!=0 || strcmp(strFileName,".")!=0)
{
if (pFileDirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DbgPrint("[Directory]%S\n",strFileName);
}
else
{
DbgPrint("[File]%S\n",strFileName);
}
ExFreePool(pFileListBuf);
ExFreePool(pFileDirInfo);
}
}
蓝屏:
FAULTING_SOURCE_LINE_NUMBER: 263
FAULTING_SOURCE_CODE:
259: }
260:
261: NTSTATUS KernelFindNextFile(IN OUT PFILE_BOTH_DIR_INFORMATION* pDir)
262: {
> 263: if ((*pDir)->NextEntryOffset)
264: {
265: (*pDir) = (PFILE_BOTH_DIR_INFORMATION)((UINT32)(*pDir) + (*pDir)->NextEntryOffset);
266: return STATUS_SUCCESS;
267: }
268:
最佳答案
好的,这里是测试过并且有效的代码。如果有人无法使用它或出现 BSOD - 可能问题不在代码中,而是在某些人的技能中
一些注意事项 - 如果您有以前的模式内核 - 使用 Nt*
api(导出时)而不是 Zw*
api。或 Io*
api。如果你不明白为什么,或者你以前的模式是什么 - 最好不要尝试在内核中编程。
强制 使用FILE_OPEN_REPARSE_POINT
选项,如果不明白这是什么以及为什么需要使用,甚至不要尝试运行此代码
用于删除 - 使用 FILE_DELETE_ON_CLOSE
选项打开文件,仅用于转储 - 使用 FILE_DIRECTORY_FILE
选项。
你自己的代码在最深的文件夹中使用了 <= 0x1800 字节的 x64 堆栈,比如 c:\Users
- 所以这对内核来说没问题,但总是用 IoGetRemainingStackSize
检查堆栈空间
如果你自己做不到,我不会纠正你代码中的每一个逗号
#define ALLOCSIZE PAGE_SIZE
#ifdef _REAL_DELETE_
#define USE_DELETE_ON_CLOSE FILE_DELETE_ON_CLOSE
#define FILE_ACCESS FILE_GENERIC_READ|DELETE
#else
#define USE_DELETE_ON_CLOSE FILE_DIRECTORY_FILE
#define FILE_ACCESS FILE_GENERIC_READ
#endif
// int nLevel, PSTR prefix for debug only
void ntTraverse(POBJECT_ATTRIBUTES poa, ULONG FileAttributes, int nLevel, PSTR prefix)
{
if (IoGetRemainingStackSize() < PAGE_SIZE)
{
DbgPrint("no stack!\n");
return ;
}
if (!nLevel)
{
DbgPrint("!nLevel\n");
return ;
}
NTSTATUS status;
IO_STATUS_BLOCK iosb;
UNICODE_STRING ObjectName;
OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName };
DbgPrint("%s[<%wZ>]\n", prefix, poa->ObjectName);
#ifdef _REAL_DELETE_
if (FileAttributes & FILE_ATTRIBUTE_READONLY)
{
if (0 <= NtOpenFile(&oa.RootDirectory, FILE_WRITE_ATTRIBUTES, poa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT|FILE_OPEN_REPARSE_POINT))
{
static FILE_BASIC_INFORMATION fbi = { {}, {}, {}, {}, FILE_ATTRIBUTE_NORMAL };
NtSetInformationFile(oa.RootDirectory, &iosb, &fbi, sizeof(fbi), FileBasicInformation);
NtClose(oa.RootDirectory);
}
}
#endif//_REAL_DELETE_
if (0 <= (status = NtOpenFile(&oa.RootDirectory, FILE_ACCESS, poa, &iosb, FILE_SHARE_VALID_FLAGS,
FILE_SYNCHRONOUS_IO_NONALERT|FILE_OPEN_REPARSE_POINT|FILE_OPEN_FOR_BACKUP_INTENT|USE_DELETE_ON_CLOSE)))
{
if (FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (PVOID buffer = ExAllocatePool(PagedPool, ALLOCSIZE))
{
union {
PVOID pv;
PBYTE pb;
PFILE_DIRECTORY_INFORMATION DirInfo;
};
while (0 <= (status = NtQueryDirectoryFile(oa.RootDirectory, NULL, NULL, NULL, &iosb,
pv = buffer, ALLOCSIZE, FileDirectoryInformation, 0, NULL, FALSE)))
{
ULONG NextEntryOffset = 0;
do
{
pb += NextEntryOffset;
ObjectName.Buffer = DirInfo->FileName;
switch (ObjectName.Length = (USHORT)DirInfo->FileNameLength)
{
case 2*sizeof(WCHAR):
if (ObjectName.Buffer[1] != '.') break;
case sizeof(WCHAR):
if (ObjectName.Buffer[0] == '.') continue;
}
ObjectName.MaximumLength = ObjectName.Length;
#ifndef _REAL_DELETE_
if (DirInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
#endif
{
ntTraverse(&oa, DirInfo->FileAttributes, nLevel - 1, prefix - 1);
}
#ifndef _REAL_DELETE_
else
#endif
{
DbgPrint("%s%8I64u <%wZ>\n", prefix, DirInfo->EndOfFile.QuadPart, &ObjectName);
}
} while (NextEntryOffset = DirInfo->NextEntryOffset);
}
ExFreePool(buffer);
if (status == STATUS_NO_MORE_FILES)
{
status = STATUS_SUCCESS;
}
}
}
NtClose(oa.RootDirectory);
}
if (0 > status)
{
DbgPrint("---- %x %wZ\n", status, poa->ObjectName);
}
}
void ntTraverse()
{
char prefix[MAXUCHAR + 1];
memset(prefix, '\t', MAXUCHAR);
prefix[MAXUCHAR] = 0;
STATIC_OBJECT_ATTRIBUTES(oa, "\\??\\c:\\users");
//STATIC_OBJECT_ATTRIBUTES(oa, "\\systemroot");
ntTraverse(&oa, FILE_ATTRIBUTE_DIRECTORY|FILE_ATTRIBUTE_READONLY, MAXUCHAR, prefix + MAXUCHAR);
}
关于c++ - Windows 驱动内核 : How enumerate all subdirectories and files?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41854736/
如何写入子文件夹中的文件?这里的其他答案说使用路径,但没有运气。在我的代码中,对于whichFileToSaveTo,如果我从中删除“/Subfolder/”,我的代码将正常工作并写入文件。使用“/S
我在 yii2 安装的项目中创建了一个子文件夹,我想将此子文件夹作为普通的 html 网站使用,但它重定向到 yii2 登录页面。如何让它像普通的html网站一样工作? 最佳答案 在我看来,你可以将你
我有一个带有布局的 Python 项目 setup.py foobar/ __init__.py foo.py bar/ __init__.py foobar/
我喜欢使用 IPython(或现在的 Jupyter)notebook 进行我的 Django 项目所需的某些计算。 Shell_plus 为我完成了这项工作。但是随着 IPython noteboo
在子目录或别名中部署 symfony2 应用程序的最佳方法是什么? 假设我的应用程序将在:http://domain/symfonytest 下运行 symfonytest 是我文件系统中某个目录的别
我正在开发一个包含前端和后端的包。我遵循有关为后端和前端部件构建 Controller 和 View 的最佳方法的说明here和 here .但是我找不到如何在我的路由配置文件中指定子目录。我试着把这
我有两个有关 CMake 的问题 假设我们有一个变量${MY_CURRENT_DIR},它包含一个目录的路径,该目录包含多个子目录:mydir1、mydir2 和 mydir3。我想检测这些子目录并将
我想找到给定目录中子目录中最长的路径,因为我遇到了这个错误: The specified path, file name, or both are too long. The fully qualif
我的网站有表单验证,一切正常。现在我想创建一个子目录并为其设置密码保护,但是!我需要该子目录使用与整个网站使用的一组完全不同的登录名/密码。 例如,我将网站的用户存储在数据库的“用户”表中。但是对于子
我有一个包含多个文件的文件夹,我想将它们移动到子文件夹中: mkdir subfolder mv ./* subfolder 但是当我这样做时,我得到: mv: 无法将“子文件夹”移动到其自身的子目录
我在 Mac 上使用 Pycharm。在下面的脚本中,我在名为 dwnld.py 的文件上调用 os.path.isfile 函数。它打印出“文件存在”,因为 dwnld.py 与脚本 (/Users
这是我的目录结构: app/ template/ layout/ base.tmpl index.tmpl template.ParseGlob("*/*.tmpl")
我正在开发一个名为 'vee-type-safe' 的库,用于运行时类型检查。一切都很顺利,直到我添加了一个子目录 /express 和一个文件 /express/index.ts,我在其中导出了一些
这已经困扰我很长时间了。我喜欢使用wildmenu 在命令模式下浏览目录。问题是要进入子目录我需要使用 总是遥不可及的 key 。我试图做一些映射来克服这个问题,但没有成功。例如: cnoremap
如何在 Jenkins Workflow: Multibranch job 中从 SCM 结帐到作业工作区的子目录?是否有任何选择: checkout scm 最佳答案 dir('subdir') {
以下是相关的配置文件,也位于http://dpaste.com/97213/。 apache配置当前正在工作,因为访问“example.com/”会向我显示我放置在文档根目录下的index.html文
我想在我的 blob 中创建一些子目录。但效果并不好 这是我的代码 protected void ButUpload_click(object sender, EventArgs e) {
(我知道这本身不是一个编程问题,但它涉及正则表达式,所以至少它是边界......) 设置: Windows 上带有 mod_rewrite 的 Apache 2.0。两个域,我们称它们为domain1
我有一个文件指向基本目录: File baseDir = new File("c:\\baseDir"); 现在我想“进入子目录”: File subDir = new File("c:\\baseD
我正在为一个硬件编写一个 Linux 设备驱动程序,该硬件提供多个独立的数据“ channel ”。系统中可能存在多个设备,每个设备提供一组 channel ,这些 channel 将被表示为基本独立
我是一名优秀的程序员,十分优秀!