我正在尝试使用 NtQueryDirectoryFile 挂钩从资源管理器中隐藏文件夹。我发现了一个隐藏文件的函数代码:
NTSTATUS WINAPI Mine_NtQueryDirectoryFile(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PVOID ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan)
{
NTSTATUS status = originalNtQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, Length, FileInformationClass, ReturnSingleEntry, FileName, RestartScan);
PFILE_FULL_DIR_INFORMATION pFileFullDirInfo;
PFILE_BOTH_DIR_INFORMATION pFileBothDirInfo;
switch (FileInformationClass) {
case fileFullDirectoryInformation:
pFileFullDirInfo = (PFILE_FULL_DIR_INFORMATION)FileInformation;
while (pFileFullDirInfo->NextEntryOffset) {
pFileFullDirInfo = (PFILE_FULL_DIR_INFORMATION)((LPBYTE)pFileFullDirInfo + pFileFullDirInfo->NextEntryOffset);
}
break;
case fileBothDirectoryInformation:
pFileBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
while (pFileBothDirInfo->NextEntryOffset) {
pFileBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)((LPBYTE)pFileBothDirInfo + pFileBothDirInfo->NextEntryOffset);
}
break;
case fileIdBothDirectoryInformation:
PFILE_ID_BOTH_DIR_INFORMATION current = (PFILE_ID_BOTH_DIR_INFORMATION)FileInformation;
while (current->NextEntryOffset) {
PFILE_ID_BOTH_DIR_INFORMATION next = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)current + current->NextEntryOffset);
if (compareToFileName(next, "d.txt") == true) {
if (next->NextEntryOffset != 0) {
next = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)next + next->NextEntryOffset);
current->NextEntryOffset += next->NextEntryOffset;
}
else {
current->NextEntryOffset = 0;
}
}
else {
current = next;
}
}
break;
}
return status;
}
但是当我尝试指定文件夹名称而不是文件名并将 DLL 注入资源管理器时,它会崩溃并显示错误 c0000005,或者冻结。我想了解问题所在,但我在任何地方都找不到答案。与 Microsoft Detours 挂钩。
我在每个程序操作的文件中添加了一个条目。这是修改后的代码:
NTSTATUS WINAPI Mine_NtQueryDirectoryFile(IN HANDLE FileHandle, IN HANDLE Event OPTIONAL, IN PVOID ApcRoutine OPTIONAL, IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass,
IN BOOLEAN ReturnSingleEntry, IN PUNICODE_STRING FileName OPTIONAL, IN BOOLEAN RestartScan)
{
std::ofstream myfile;
myfile.open("C:\\log.txt");
NTSTATUS status = originalNtQueryDirectoryFile(FileHandle, Event, ApcRoutine, ApcContext, IoStatusBlock, FileInformation, Length, FileInformationClass, ReturnSingleEntry, FileName, RestartScan);
myfile << "1\n";
PFILE_FULL_DIR_INFORMATION pFileFullDirInfo;
myfile << "2\n";
PFILE_BOTH_DIR_INFORMATION pFileBothDirInfo;
myfile << "3\n";
switch (FileInformationClass) {
case fileFullDirectoryInformation:
{
pFileFullDirInfo = (PFILE_FULL_DIR_INFORMATION)FileInformation;
myfile << "ffdi 1\n";
int counter1 = 0;
while (pFileFullDirInfo->NextEntryOffset) {
pFileFullDirInfo = (PFILE_FULL_DIR_INFORMATION)((LPBYTE)pFileFullDirInfo + pFileFullDirInfo->NextEntryOffset);
myfile << "ffdi while iteration ", counter1, "\n";
counter1++;
}
myfile << "ffdi end\n";
}
break;
case fileBothDirectoryInformation:
{
pFileBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)FileInformation;
myfile << "fbdi 1\n";
int counter2 = 0;
while (pFileBothDirInfo->NextEntryOffset) {
pFileBothDirInfo = (PFILE_BOTH_DIR_INFORMATION)((LPBYTE)pFileBothDirInfo + pFileBothDirInfo->NextEntryOffset);
myfile << "fbdi while iteration ", counter2, "\n";
counter2++;
}
myfile << "fbdi end\n";
}
break;
case fileIdBothDirectoryInformation:
{
PFILE_ID_BOTH_DIR_INFORMATION current = (PFILE_ID_BOTH_DIR_INFORMATION)FileInformation;
myfile << "fibdi 1\n";
int counter3 = 0;
while (current->NextEntryOffset) {
myfile << "cycle start\n";
PFILE_ID_BOTH_DIR_INFORMATION next = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)current + current->NextEntryOffset);
myfile << "PFILE_ID_BOTH_DIR_INFORMATION ", next, " = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)", current, " + ", current, "->NextEntryOffset)";
if (compareToFileName(next, "detours") == true) {
myfile << "if (compareToFileName(", next, ", detours) == true) == true\n";
if (next->NextEntryOffset != 0) {
myfile << "if (", next, "->NextEntryOffset != 0) == true\n";
next = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)next + next->NextEntryOffset);
myfile << next, " = (PFILE_ID_BOTH_DIR_INFORMATION)((LPBYTE)", next, " + ", next, "->NextEntryOffset);\n";
current->NextEntryOffset += next->NextEntryOffset;
myfile << current, "->NextEntryOffset += ", next, "->NextEntryOffset; \n";
}
else {
myfile << "if (", next, "->NextEntryOffset != 0) == false\n";
current->NextEntryOffset = 0;
myfile << "current->NextEntryOffset = 0 \n";
}
}
else {
myfile << "if (compareToFileName(", next, ", detours) == true) == false\n";
current = next;
}
myfile << "fibdi while iteration ", counter3, "\n";
counter3++;
}
}
break;
}
myfile << "end \n";
myfile.close();
return status;
}
DLL注入后,资源管理器再次崩溃。这是注入后C:\log.txt文件的内容:
1
2
3
fibdi 1
结束
只有当我进入代码中指定的文件夹的目录后,资源管理器才崩溃