?? specialiofunction.cpp
字號:
ntStatus=ZwClose(TargetFileHandle);
if (!NT_SUCCESS(ntStatus))
{
FsTPM_DbgPrint(("Close Target File Failed!"));
ErrorString(ntStatus);
return ntStatus;
}
return STATUS_SUCCESS;
}
NTSTATUS
FsTPMCopyFile(
PFILE_OBJECT TargetFileObject,
PFILE_OBJECT SourceFileObject,
PDEVICE_OBJECT pSourceDeviceObject,
PDEVICE_OBJECT pTargetDeviceObject
)
//++
// Function: FsTPMCopyFile
//
// Description:
// Copy file
//
// Arguments:
// TargetFileObject - Target file object
// SourceFileObject - Source file object
//
// Return value:
// STATUS_SUCCESS if successful,
// STATUS_UNSUCCESSFUL otherwise
//
// Notice :
// This function is provided by OSR
//--
{
PVOID buffer;
PMDL mdl;
IO_STATUS_BLOCK iosb;
FILE_STANDARD_INFORMATION standardInformation;
LARGE_INTEGER currentOffset;
LONGLONG bytesToTransfer;
//
// The algorithm used by this routine is straight-forward: read 64k chunks from the
// source file and write it to the target file, until the entire file itself has been copied.
//
buffer = ExAllocatePoolWithTag(NonPagedPool,
MAX_TRANSFER_SIZE,
'BcfK');
if (!buffer) {
//
// Allocation must have failed.
//
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// Build an MDL describing the buffer. We'll use THAT to do the
// I/O (rather than a direct buffer address.)
//
mdl = IoAllocateMdl(buffer, MAX_TRANSFER_SIZE, FALSE, TRUE, 0);
MmBuildMdlForNonPagedPool(mdl);
//
// Set up the current offset information
//
currentOffset.QuadPart = 0;
//
// Get the size of the input file.
//
FsTPMGetFileStandardInformation(SourceFileObject, &standardInformation, &iosb,pSourceDeviceObject);
if (!NT_SUCCESS(iosb.Status)) {
//
// This is a failure condition.
//
return (iosb.Status);
}
//
// Set the allocation size of the output file.
//
FsTPMSetFileAllocation(TargetFileObject,
&standardInformation.AllocationSize,
&iosb,pTargetDeviceObject);
if (!NT_SUCCESS(iosb.Status)) {
//
// Failure...
//
return (iosb.Status);
}
//
// Save away the information about the # of bytes to transfer.
//
bytesToTransfer = standardInformation.EndOfFile.QuadPart;
//
// Now copy the source to the target until we run out...
//
while (bytesToTransfer) {
ULONG nextTransferSize;
//
// The # of bytes to copy in the next operation is based upon the maximum of
// the balance IN the file, or KFC_MAX_TRANSFER_SIZE
//
nextTransferSize = (bytesToTransfer < MAX_TRANSFER_SIZE) ?
(ULONG) bytesToTransfer : MAX_TRANSFER_SIZE;
FsTPMRead(SourceFileObject, ¤tOffset, nextTransferSize, mdl, &iosb,pSourceDeviceObject);
if (!NT_SUCCESS(iosb.Status)) {
//
// An error condition occurred.
//
return (iosb.Status);
}
FsTPMWrite(TargetFileObject, ¤tOffset, nextTransferSize, mdl, &iosb,pTargetDeviceObject);
if (!NT_SUCCESS(iosb.Status)) {
//
// An error condition occurred.
//
return (iosb.Status);
}
//
// Now, update the offset/bytes to transfer information
//
currentOffset.QuadPart += nextTransferSize;
bytesToTransfer -= nextTransferSize;
}
//
// At this point, we're done with the copy operation. Return success
//
return (STATUS_SUCCESS);
}
// Notice you should be sure that the file is shared.
NTSTATUS
FsTPMCreateFileObject(
IN PWCHAR TargetFileName,
OUT PFILE_OBJECT* ppFileObject
)
{
//WCHAR *UTarget=NULL;
//UTarget=(WCHAR*)ExAllocatePool(NonPagedPool,512);
WCHAR UTarget[256];
UNICODE_STRING CUTarget;
PFILE_OBJECT pTargetFileObject=NULL;
HANDLE TargetFileHandle;
FILE_OBJECT TargetFileObject;
VCB TargetVCB;
OBJECT_ATTRIBUTES TargetAttributes;
ULONG ThrowInf; // We don't want to see the value of the returned informatiom
// So throw it.
NTSTATUS ntStatus;
_snwprintf(UTarget,256,L"\\??\\%s",TargetFileName);
RtlInitUnicodeString(&CUTarget,UTarget);
CUTarget.MaximumLength=512;
// We should make sure the path's name is like this : "C:\*\*.*"
ASSERT( (TargetFileName[0]>=L'A' && TargetFileName[0]<=L'Z'));
ntStatus=FsTPMCreateDirectory(TargetFileName);
if (!NT_SUCCESS(ntStatus))
{
FsTPM_DbgPrint(("Create Directory Fail!\n"));
ErrorString(ntStatus);
return ntStatus;
}
FsTPM_DbgPrint(("Enter Create File Object now!!!\n"));
// Build VCB. here , the next lower device and real device are the same
TargetVCB=((PHOOK_EXTENSION)(DriveHookDevices[TargetFileName[0]-'A']->DeviceExtension))->Vcb;
// Then we should initialize the file object's attributes
InitializeObjectAttributes(
&TargetAttributes,
&CUTarget,
OBJ_CASE_INSENSITIVE,
NULL, NULL
);
// ntStatus=ZwCreateFile(&TargetFileHandle,
// FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA|DELETE,
// &TargetAttributes,
// &temp,
// 0,
// FILE_ATTRIBUTE_NORMAL,
// FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
// FILE_OPEN_IF ,
// FILE_SYNCHRONOUS_IO_ALERT,
// NULL,
// 0
// );
//
ntStatus=FsTPMCreateFile(&TargetVCB,
FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA|DELETE,
&TargetAttributes,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
FILE_OPEN_IF ,
FILE_SYNCHRONOUS_IO_ALERT,
NULL,
0,
FILE_SYNCHRONOUS_IO_ALERT,
&ThrowInf,
&TargetFileObject,
&TargetFileHandle
);
if (!NT_SUCCESS(ntStatus))
{
FsTPM_DbgPrint(("Create Target File Failed!"));
ErrorString(ntStatus);
return ntStatus;
}
ntStatus = ObReferenceObjectByHandle( TargetFileHandle, FILE_READ_DATA|FILE_WRITE_DATA,
NULL, KernelMode, (void**)&pTargetFileObject, NULL );
if (!NT_SUCCESS(ntStatus))
{
FsTPM_DbgPrint((("Get Target File Object Fail\n")));
ErrorString(ntStatus);
return ntStatus;
}
ASSERT(pTargetFileObject!=NULL);
*ppFileObject=pTargetFileObject;
return STATUS_SUCCESS;
}
VOID
FsTPMWriteIRP(
PFILE_OBJECT FileObject,
PDEVICE_OBJECT pDevice,
PIRP pOrgIrp,
PIO_STACK_LOCATION pOrgIoStk,
PIO_STATUS_BLOCK IoStatusBlock,
PMDL mdl
)
//++
// Function: FsTPMWriteIRP
//
// Description:
// This routine is used to write to the file object from memory discribed by MDL
//
// Arguments:
//PFILE_OBJECT FileObject,
//PDEVICE_OBJECT pDevice,
//PIRP pOrgIrp,
//PIO_STACK_LOCATION pOrgIoStk
//PIO_STATUS_BLOCK IoStatusBlock,
//
// Return value:
// None
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PDEVICE_OBJECT fsdDevice =pDevice;
//
// Set up the event we'll use.
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate and build the IRP we'll be sending to the FSD.
//
irp = IoAllocateIrp(fsdDevice->StackSize, FALSE);
if (!irp) {
//
// Allocation failed, presumably due to memory allocation failure.
//
IoStatusBlock->Status = STATUS_INSUFFICIENT_RESOURCES;
IoStatusBlock->Information = 0;
return ;
}
irp->AssociatedIrp.SystemBuffer = pOrgIrp->AssociatedIrp.SystemBuffer;
irp->MdlAddress = pOrgIrp->MdlAddress;
irp->UserBuffer=pOrgIrp->UserBuffer;
irp->UserEvent = &event;
irp->UserIosb = IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject= FileObject;
irp->RequestorMode = KernelMode;
//
// Indicate that this is a WRITE operation.
//
irp->Flags = IRP_WRITE_OPERATION;
//
// Set up the next I/O stack location. These are the parameters
// that will be passed to the underlying driver.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = pOrgIoStk->MajorFunction;
ioStackLocation->MinorFunction = pOrgIoStk->MinorFunction;
ioStackLocation->DeviceObject = fsdDevice;
ioStackLocation->FileObject = FileObject;
//
// We use a completion routine to keep the I/O Manager from doing
// "cleanup" on our IRP - like freeing our MDL.
//
IoSetCompletionRoutine(irp, KfcIoCompletion, 0, TRUE, TRUE, TRUE);
ioStackLocation->Parameters.Write.Length = pOrgIoStk->Parameters.Write.Length;
ioStackLocation->Parameters.Write.ByteOffset = pOrgIoStk->Parameters.Write.ByteOffset;
ioStackLocation->Parameters.Write.Key = pOrgIoStk->Parameters.Write.Key;
//
// Send it on. Ignore the return code.
//
(void) IoCallDriver(fsdDevice, irp);
//
// Wait for the I/O to complete.
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done. Return results are in the io status block.
//
return;
}
NTSTATUS
GetFileFullNameByQuery(
OUT PUNICODE_STRING SourceFileName,
IN PHOOK_EXTENSION pHookExt ,
IN PFILE_OBJECT FileObject
)
{
VCB Vcb;
ULONG ResultLen;
NTSTATUS ntStatus;
WCHAR USName[256];
_snwprintf(USName,256,L"A:");
UNICODE_STRING CUSourceName;
RtlInitUnicodeString(&CUSourceName,USName);
CUSourceName.MaximumLength=512;
Vcb=pHookExt->Vcb;
PFILE_NAME_INFORMATION fileNameInfo;
if (0==FileObject->FileName.Length) // 我不知道為什么會有這樣的情況
return STATUS_UNSUCCESSFUL;
//調查"家底",確認其真實文件名
fileNameInfo = (PFILE_NAME_INFORMATION)ExAllocatePool( NonPagedPool, MAXPATHLEN*sizeof(WCHAR));
if (NULL==fileNameInfo)
{
FsTPM_DbgPrint((("Memory Allocate Fail!\n")));
if (fileNameInfo!=NULL)
ExFreePool(fileNameInfo);
return STATUS_UNSUCCESSFUL;
}
ntStatus=FsTPMQueryInformationFile(&Vcb,FileObject,FileNameInformation,fileNameInfo,(MAXPATHLEN-5)*sizeof(WCHAR),&ResultLen);
if (!NT_SUCCESS(ntStatus))
{
FsTPM_DbgPrint(((" Query Name Information of file Fail\n")));
ErrorString(ntStatus);
if (fileNameInfo!=NULL)
ExFreePool(fileNameInfo);
return ntStatus;
}
fileNameInfo->FileName[fileNameInfo->FileNameLength/2]=0;
_snwprintf(CUSourceName.Buffer+wcslen(CUSourceName.Buffer),256-wcslen(CUSourceName.Buffer),L"%s",fileNameInfo->FileName);
CUSourceName.Buffer[0]=(WCHAR)(pHookExt->LogicalDrive);
CUSourceName.Length=wcslen(CUSourceName.Buffer)*sizeof(WCHAR);
RtlCopyUnicodeString( SourceFileName, &(UNICODE_STRING)CUSourceName );
if (fileNameInfo!=NULL)
ExFreePool(fileNameInfo);
return STATUS_SUCCESS;
}
VOID CreateFileSizeZero(PUNICODE_STRING pUniFile,BOOL isdir)
{
// Then we should initialize the file object's attributes
UNICODE_STRING uFile;
FILE_OBJECT fileobject;
HANDLE fileHandle;
ULONG ThrowInf;
ULONG op1;
ULONG op2;
NTSTATUS ntStatus;
OBJECT_ATTRIBUTES FileAttrib;
RtlInitUnicodeString(&uFile,&pUniFile->Buffer[2]);
InitializeObjectAttributes(
&FileAttrib,
&uFile,
OBJ_CASE_INSENSITIVE,
NULL, NULL
);
if (isdir)
{
op1=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING|FILE_DIRECTORY_FILE;
op2=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING|FILE_DIRECTORY_FILE;
}
else
{
op1=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING;
op2=FILE_SYNCHRONOUS_IO_NONALERT|FILE_NO_INTERMEDIATE_BUFFERING;
}
ntStatus=FsTPMCreateFile(&(((PHOOK_EXTENSION)(DriveHookDevices[pUniFile->Buffer[0]-L'A']->DeviceExtension))->Vcb),
FILE_READ_DATA|SYNCHRONIZE|FILE_WRITE_DATA,
&FileAttrib,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_CREATE ,
op1,
NULL,
0,
op2,
&ThrowInf,
&fileobject,
&fileHandle
);
ZwClose(fileHandle);
}
//----------------------------------------------------------------------
//
// FsTPMGetProcess
//
// Uses undocumented data structure offsets to obtain the name of the
// currently executing process.
//
//----------------------------------------------------------------------
PCHAR
FsTPMGetProcess(
PCHAR ProcessName
)
{
PEPROCESS curproc;
char *nameptr;
// ULONG i;
//
// We only do this if we determined the process name offset
//
if( ProcessNameOffset ) {
//
// Get a pointer to the current process block
//
curproc = PsGetCurrentProcess();
//
// Dig into it to extract the name. Make sure to leave enough room
// in the buffer for the appended process ID.
//
nameptr = (PCHAR) curproc + ProcessNameOffset;
strncpy( ProcessName, nameptr, NT_PROCNAMELEN-1 );
ProcessName[NT_PROCNAMELEN-1] = 0;
// sprintf( ProcessName + strlen(ProcessName), ":%d", PsGetCurrentProcessId());
} else {
strcpy( ProcessName, "???" );
}
return ProcessName;
}
//----------------------------------------------------------------------
//
// FsTPMGetProcessNameOffset
//
// In an effort to remain version-independent, rather than using a
// hard-coded into the KPEB (Kernel Process Environment Block), we
// scan the KPEB looking for the name, which should match that
// of the system process. This is because we are in the system process'
// context in DriverEntry, where this is called.
//
//----------------------------------------------------------------------
ULONG
FsTPMGetProcessNameOffset(
VOID
)
{
PEPROCESS curproc;
int i;
curproc = PsGetCurrentProcess();
//
// Scan for 12KB, hoping the KPEB never grows that big!
//
for( i = 0; i < 3*PAGE_SIZE; i++ ) {
if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {
return i;
}
}
//
// Name not found - oh, well
//
return 0;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -