首先,我HOOK了SSDT的ZwReadFile函数,替换为我的_ZwReadFile,实现对系统所有进程读文件操作的过滤目的。当检测当前进程为w3wp.exe或者为ReadFileTest.exe(由于我获取进程名只获取到16个字节,所以少获取了一个'e',判断时,使用了ReadFileTest.ex)进程时,将判断这两个进程读的文件头10个字节,是否为我指定的内容,如果是,则执行相关解密操作。
其次,在进程进入我的_ZwReadFile时,是可以正常读取文件内容的,然后我想判断一下此次读的文件的头10个字节是否为我指定的内容,由于刚刚已经读到了文件结尾,下一次读时需要将文件位置设置为0,以便再次从文件头中读取文件头10个字节的内容。
于是,有如下代码:
boolIsEncrypt(HANDLEFileHandle)
{
IO_STATUS_BLOCKioStatus;
ULONGdwReaded=0;
FILE_POSITION_INFORMATIONcurrent_fpi;
FILE_POSITION_INFORMATIONfpi;
NTSTATUSstatus;
InterlockedIncrement(&g_uCount);
//获取当前文件位置信息,以便读取文件头后,恢复当前文件指针位置
status=ZwQueryInformationFile(FileHandle,&ioStatus,¤t_fpi,sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
DbgPrint("%ld",current_fpi.CurrentByteOffset);
if(NT_SUCCESS(status))
{
DbgPrint("ZwQueryInformationFilesuccessful");
}
else
{
DbgPrint("ZwQueryInformationFilefailed");
}
//移动文件指针位置到文件头部
fpi.CurrentByteOffset.QuadPart=0i64;
DbgPrint("%ld",fpi.CurrentByteOffset);
//设置文件指针位置信息
status=ZwSetInformationFile(FileHandle,&ioStatus,&fpi,sizeof(FILE_POSITION_INFORMATION),FilePositionInformation);
if(NT_SUCCESS(status))
{
DbgPrint("ZwSetInformationFilesuccessful");
}
else
{
DbgPrint("ZwSetInformationFilefailed");
}
char*szFileHeader=(char*)ExAllocatePool(NonPagedPool,10);
ULONGlength=10;
NTSTATUSstatus1=g_pfnZwReadFile(
FileHandle,
NULL,
NULL,
NULL,
&ioStatus,
szFileHeader,
length,
NULL,
NULL);
if(NT_SUCCESS(status1))
{
DbgPrint("ReadFileHeadersuccessful");
}
else
{
//此处将会被执行,读取文件失败。。。
DbgPrint("ReadFileHeaderfailed:%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"))
{
returnTRUE;
}
ExFreePool(szFileHeader);
returnFALSE;
}
NTSTATUSNTAPI_ZwReadFile(
INHANDLEFileHandle,
INHANDLEEventOPTIONAL,
INPIO_APC_ROUTINEApcRoutineOPTIONAL,
INPVOIDApcContextOPTIONAL,
OUTPIO_STATUS_BLOCKIoStatusBlock,
OUTPVOIDBuffer,
INULONGLength,
INPLARGE_INTEGERByteOffsetOPTIONAL,
INPULONGKeyOPTIONAL
)
{
NTSTATUSstatus;
charszProcessName[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("CurrentProcessName:%s",szProcessName);
DbgPrint("%s",Buffer);
if(IsEncrypt(FileHandle))
{
DbgPrint("thefileisencrypt!!!");
Decrypt((char*)Buffer,Length);
}
}
returnstatus;
}
注:g_pfnZwReadFile为HOOK后,原ZwReadFile函数的指针。
经过一周时间windbg调试+DebugView,也没能找出读文件失败原因,还请大神指点,表示感谢!
可用分全部奉上....
分 -->
|