通过NtQueryDirectoryFile钩子隐藏文件夹时资源管理器崩溃问题排查
钩子NtQueryDirectoryFile隐藏文件夹时资源管理器崩溃问题排查
我尝试通过钩子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; }
注入后资源管理器再次崩溃,C:\log.txt日志内容为:
1 2 3 fibdi 1 end
崩溃仅在进入目标文件夹所在目录时发生,求排查问题原因。
内容的提问来源于stack exchange,提问作者NBB
相关产品推荐
相关产品推荐

