ZwReadFile失败,异常代码0xC0000005,求指点
首先,我HOOK了SSDT的ZwReadFile函数,替换为我的_ZwReadFile,实现对系统所有进程读文件操作的过滤目的。当检测当前进程为w3wp.exe或者为ReadFileTest.exe(由于我获取进程名只获取到16个字节,所以少获取了一个'e',判断时,使用了ReadFileTest.ex)进程时,将判断这两个进程读的文件头10个字节,是否为我指定的内容,如果是,则执行相关解密操作。
其次,在进程进入我的_ZwReadFile时,是可以正常读取文件内容的,然后我想判断一下此次读的文件的头10个字节是否为我指定的内容,由于刚刚已经读到了文件结尾,下一次读时需要将文件位置设置为0,以便再次从文件头中读取文件头10个字节的内容。
于是,有如下代码:
bool IsEncrypt(HANDLE FileHandle)
{
IO_STATUS_BLOCK ioStatus;
ULONG dwReaded = 0;
FILE_POSITION_INFORMATION current_fpi;
FILE_POSITION_INFORMATION fpi;
NTSTATUS status;
InterlockedIncrement(&g_uCount);
//获取当前文件位置信息,以便读取文件头后,恢复当前文件指针位置
status = ZwQueryInformationFile(FileHandle, &ioStatus, ¤t_fpi, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
DbgPrint("%ld", current_fpi.CurrentByteOffset);
if (NT_SUCCESS(status))
{
DbgPrint("ZwQueryInformationFile successful");
}
else
{
DbgPrint("ZwQueryInformationFile failed");
}
//移动文件指针位置到文件头部
fpi.CurrentByteOffset.QuadPart = 0i64;
DbgPrint("%ld", fpi.CurrentByteOffset);
//设置文件指针位置信息
status = ZwSetInformationFile(FileHandle, &ioStatus, &fpi, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
if (NT_SUCCESS(status))
{
DbgPrint("ZwSetInformationFile successful");
}
else
{
DbgPrint("ZwSetInformationFile failed");
}
char *szFileHeader = (char*)ExAllocatePool(NonPagedPool, 10);
ULONG length = 10;
NTSTATUS status1 = g_pfnZwReadFile(
FileHandle,
NULL,
NULL,
NULL,
&ioStatus,
szFileHeader,
length,
NULL,
NULL);
if (NT_SUCCESS(status1))
{
DbgPrint("Read File Header successful");
}
else
{
//此处将会被执行,读取文件失败。。。
DbgPrint("Read File Header failed : %d, %d, %d", status1, ioStatus.Status, ioStatus.Information);
}
//恢复文件指针位置
ZwSetInformationFile(FileHandle, &ioStatus, ¤t_fpi, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
InterlockedDecrement(&g_uCount);
DbgPrint("FileHeader : %s", szFileHeader);
if (!strcmp(szFileHeader, "QQ:7278449"))
{
return TRUE;
}
ExFreePool(szFileHeader);
return FALSE;
}
NTSTATUS NTAPI _ZwReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS status;
char szProcessName[256] = {0};
GetProcessName((ULONG)PsGetCurrentProcessId(), szProcessName);
InterlockedIncrement(&g_uCount);
status = g_pfnZwReadFile(
FileHandle,
Event,
ApcRoutine,
ApcContext,
IoStatusBlock,
Buffer,
Length,
ByteOffset,
Key);
InterlockedDecrement(&g_uCount);
if (!strcmp(szProcessName, "w3wp.exe") || !strcmp(szProcessName, "ReadFileTest.ex"))
{
DbgPrint("Current Process Name : %s", szProcessName);
DbgPrint("%s", Buffer);
if (IsEncrypt(FileHandle))
{
DbgPrint("the file is encrypt!!!");
Decrypt((char*)Buffer, Length);
}
}
return status;
}
注:g_pfnZwReadFile为HOOK后,原ZwReadFile函数的指针。
经过一周时间windbg调试+DebugView,也没能找出读文件失败原因,还请大神指点,表示感谢!
可用分全部奉上....