⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpwipedeletent.c

📁 可以实现对邮件的加密解密以及签名
💻 C
📖 第 1 页 / 共 5 页
字号:
                     PKKERNEL_ROUTINE ker_routine,
                     PKRUNDOWN_ROUTINE rd_routine,
                     PKNORMAL_ROUTINE nor_routine,
                     unsigned char mode,
                     void *context);


void KeInsertQueueApc(struct _KAPC *APC,
                      void *SysArg1,
                      void *SysArg2,
                      unsigned char arg4);

/* call this function when you need to send a user-mode APC to
the current thread. addr must be linear address of your user-mode
function to call:

void MyApcRoutine(ULONG arg1, ULONG arg2, ULONG arg3);
...
SendAddrToTheDriverUsingIoctl((ULONG)MyApcRoutine);

you should send it to the driver using your custom IOCTL.
arg1, arg2, arg3 are arbitrary ulong's which are passed to the function
residing at addr; this function should be prototyped as receiving three
parameters and returning void. */

void SendAPC(ULONG addr, PKTHREAD thread, ULONG arg1, ULONG arg2, ULONG arg3)
{
/* this is self-explanatory */

    apc=ExAllocatePool(NonPagedPool, sizeof(struct _KAPC));

/* Initialize the user-mode APC */

    KeInitializeApc(apc, thread, 0,
                    (PKKERNEL_ROUTINE)&MyRoutine, 0,
                    (PKNORMAL_ROUTINE)addr, 1, (PVOID)arg1);

/* Insert it to the queue of the target thread */

    KeInsertQueueApc(apc, (PVOID)arg2, (PVOID)arg3, 0);

/* Mark the current thread as alertable to force it to deliver the APC on
the next return to the user-mode. NOTE: severely undocumented code here!
*/

    *((unsigned char *)thread+0x4a)=1;
}

//----------------------------------------------------------------------
//
// PGPWDNTworkitem
//
// Called by the system, this is initiated in the completion callback.
// We use it to ensure we''re running at passive level when we do
// an PGPWDNT
//
//----------------------------------------------------------------------
#if	(_WIN32_WINNT >= 0x0500)
VOID PGPWDNTWorkItem( IN PDEVICE_OBJECT DeviceObject, PVOID Context )
#else	// _WIN32_WINNT < 0x5000
VOID PGPWDNTWorkItem( PVOID Context )
#endif	// _WIN32_WINNT >= 0x5000
{
	PPGPWDNT_COMPLETE_CONTEXT pwntcc;

	pwntcc=(PPGPWDNT_COMPLETE_CONTEXT)Context;

	num_scheds++;

    // Do the APC call back to the user callback
	SendAPC(tc_callback, tc_thread, (ULONG)pwntcc->FileName, 0, 0);

	KeWaitForSingleObject(&apc_sem,Executive, KernelMode, FALSE, NULL);

	// Free the filename
	ExFreePool(pwntcc->FileName);

	num_scheds--;

    // Complete the IRP
    pwntcc->Irp->IoStatus.Status = STATUS_SUCCESS;
    IoCompleteRequest(pwntcc->Irp,IO_NO_INCREMENT);

#if	(_WIN32_WINNT >= 0x0500)
	// free the work item
	IoFreeWorkItem(pwntcc->WorkItem);
#endif	// _WIN32_WINNT >= 0x5000

	// Free the context memory
	ExFreePool(pwntcc);
}

//----------------------------------------------------------------------
//     D I S P A T C H   A N D   H O O K   E N T R Y   P O I N T S
//----------------------------------------------------------------------


//----------------------------------------------------------------------
//
// PGPWDNTHookDone
//
// Gets control on the way back from a delete operation. At this point
// the file cannot be opened by anything else, so we can send it back
// to the user callback
//
//----------------------------------------------------------------------
NTSTATUS PGPWDNTHookDone( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
                           IN PVOID Context )
{
	PPGPWDNT_COMPLETE_CONTEXT pwntcc;

	pwntcc=(PPGPWDNT_COMPLETE_CONTEXT)Context;

    if( NT_SUCCESS(Irp->IoStatus.Status))
	{
#if	(_WIN32_WINNT >= 0x0500)

		pwntcc->WorkItem = IoAllocateWorkItem(DeviceObject);

		if (pwntcc->WorkItem == NULL)
			return STATUS_SUCCESS;

		IoQueueWorkItem(pwntcc->WorkItem, PGPWDNTWorkItem,
			CriticalWorkQueue, Context);

#else	// _WIN32_WINNT < 0x5000

		ExInitializeWorkItem(&(pwntcc->WorkItem),PGPWDNTWorkItem,Context);
        ExQueueWorkItem(&(pwntcc->WorkItem),CriticalWorkQueue);

#endif	// _WIN32_WINNT >= 0x5000

        // We have to complete the IRP later
        return STATUS_MORE_PROCESSING_REQUIRED;
    }
	else
	{
        // Now we have to mark Irp as pending if necessary
        if( Irp->PendingReturned )
		{
            IoMarkIrpPending( Irp );
        }

        // Free the completion context
        ExFreePool(pwntcc->FileName);
        ExFreePool(pwntcc);
        return Irp->IoStatus.Status;
    }
}


//----------------------------------------------------------------------
//
// pgpWipeDeleteDispatch
//
// This routine is the main hook routine where we figure out what
// calls are being sent to the file system.
//
//----------------------------------------------------------------------
NTSTATUS
pgpWipeDeleteDispatch (
		PDEVICE_OBJECT HookDevice,
		IN PIRP Irp )
{
    PIO_STACK_LOCATION  currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
    PIO_STACK_LOCATION  nextIrpStack    = IoGetNextIrpStackLocation(Irp);
    PDEVEXTENSION		pdeve;
    PPGPWDNT_COMPLETE_CONTEXT completeContext;
	char				*FileName;
	PVOID				Token;

    // Point at the device extension, which contains information on which
    // file system this IRP is headed for
    pdeve = HookDevice->DeviceExtension;

	// Determine what function we're dealing with
    switch( currentIrpStack->MajorFunction )
	{
	    case IRP_MJ_CLEANUP:
		{
			// Do stuff only if WOD is turned on
			if((tc_flags&WDFLAG_WIPEFILES)!=0)
			{
				// If the file will be deleted, see if we have to PGPWDNT it
				if(currentIrpStack->FileObject->DeletePending &&
				  (SystemProcess != PsGetCurrentProcess())&&
				  (tc_flags!=WDFLAG_NOOP)&&
				  (tc_callback!=0))
				{
					Token=PsReferencePrimaryToken(PsGetCurrentProcess());

					if(Token)
					{
						if(PGPWDNTCheckFileForPGPWDNT(HookDevice,Irp,&FileName))
						{					
							// Tell the OS not to delete the file
							PGPWDNTSetDispositionFile( pdeve->pdevoNext,
								currentIrpStack->FileObject, FALSE );

							// Set up the completion context
							completeContext =
								ExAllocatePool( NonPagedPool, sizeof( PGPWDNT_COMPLETE_CONTEXT));

							completeContext->Irp = Irp;
							completeContext->Token = Token;
							completeContext->DeviceObject = HookDevice;
							completeContext->FileName = FileName;

							IoCopyCurrentIrpStackLocationToNext(Irp);
							IoSetCompletionRoutine( Irp, PGPWDNTHookDone,
								(PVOID) completeContext, TRUE, TRUE, TRUE );

							IoMarkIrpPending( Irp );
							IoCallDriver( pdeve->pdevoNext, Irp );

							// Now stall the IRP
							return STATUS_PENDING;
						}
					}
				}
			}

			// default behavior
			IoSkipCurrentIrpStackLocation(Irp);
			return IoCallDriver( pdeve->pdevoNext, Irp );
		}

	#if	(_WIN32_WINNT >= 0x0500)
		case IRP_MJ_POWER:
			// must use special calls to pass down power IRPs
			PoStartNextPowerIrp(Irp);

			IoSkipCurrentIrpStackLocation(Irp);
			return PoCallDriver(pdeve->pdevoNext, Irp);
	#endif	// _WIN32_WINNT >= 0x5000

		default:
			IoSkipCurrentIrpStackLocation(Irp);
		    return IoCallDriver( pdeve->pdevoNext, Irp );
	}
}


//----------------------------------------------------------------------
//   D R I V E R - E N T R Y   A N D   H O O K   R O U T I N E S
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//
// HookDrive
//
// Hook the drive specified by determining which device object to
// attach to. The algorithm used here is similar to the one used
// internally by NT to determine which device object a file system request
// is directed at.
//
//----------------------------------------------------------------------
BOOLEAN
HookDrive(
		IN USHORT Drive,
		IN PDRIVER_OBJECT DriverObject,
		IN PDRVEXTENSION DriverExtension,
		IN HANDLE VolumeHandle )
{
    PDEVICE_OBJECT      fileSysDevice;
    PDEVICE_OBJECT      hookDevice;
    NTSTATUS            ntStatus;
    PFILE_OBJECT        fileObject;
    IO_STATUS_BLOCK  	ioStatus;
    PDEVEXTENSION		pdeve;
    UCHAR               fsAttribInformation[256];

    //
    // Got the file handle, so now look-up the file-object it refers to
    //
    ntStatus = ObReferenceObjectByHandle( VolumeHandle, FILE_READ_DATA,
                                     NULL, KernelMode, &fileObject, NULL );
    if( !NT_SUCCESS( ntStatus ))
	{
        PGPdbgPrint(("PGPutil: Could not get fileobject from handle: %c\n",
					'A'+Drive ));
        return FALSE;
    }

    //
    // Next, find out what device is associated with the file object by
	// getting its related device object
    //
    fileSysDevice = IoGetRelatedDeviceObject( fileObject );

    if ( ! fileSysDevice )
	{
        PGPdbgPrint(("PGPutil: Could not get related device object: %c\n",
					'A'+Drive ));
        ObDereferenceObject( fileObject );
        return FALSE;
    }

    //
    // The file system's device hasn't been hooked already, so make a
	// hooking device object that will be attached to it.
    //
    ntStatus = IoCreateDevice( DriverObject,
                               sizeof(DEVEXTENSION),
                               NULL,
                               fileSysDevice->DeviceType,
                               0,
                               FALSE,
                               &hookDevice );

    if ( !NT_SUCCESS(ntStatus) )
	{
        PGPdbgPrint(("PGPutil: failed to create associated device: %c\n",
					'A'+Drive ));
        ObDereferenceObject( fileObject );
        return FALSE;
    }

    //
    // Clear the device's init flag as per NT DDK KB article on creating device
    // objects from a dispatch routine
    //
    hookDevice->Flags &= ~DO_DEVICE_INITIALIZING;

    //
    // Setup the device extensions. The drive letter and file system object
	// are stored in the extension.
    //
    pdeve = hookDevice->DeviceExtension;
	pdeve->ulDeviceType			= WIPE_DELETE_DEV;
	pdeve->pdrve				= DriverExtension;
	pdeve->ulSkipCount			= 0;			// not used by this device
    pdeve->ucLogicalDrive		= 'A'+Drive;
    pdeve->pdevoNext			= fileSysDevice;
    pdeve->bIsNTFS				= FALSE;
    pdeve->bIsAnsi				= FALSE;

    //
    // Determine which file system this is. If this fails, assume its NOT NTFS
    //
    ntStatus = ZwQueryVolumeInformationFile(
					VolumeHandle, &ioStatus, fsAttribInformation,
					 sizeof(fsAttribInformation), FileFsAttributeInformation );
    if( !NT_SUCCESS( ntStatus ))
	{
        PGPdbgPrint(("PGPutil: Could not get volume attributes: %x\n", ntStatus));
    }
	else if( RtlCompareMemory(
			((PFILE_FS_ATTRIBUTE_INFORMATION)fsAttribInformation)->FileSystemName,
			L"NTFS", 8 ) == 8)
	{
        pdeve->bIsNTFS = TRUE;
        PGPdbgVerbosePrint(("  => Its an NTFS volume\n"));
    }

    //
    // Finally, attach to the device. The second we're successfully attached,
	// we may start receiving IRPs targetted at the device we've hooked.
    //
    if ( IoAttachDeviceToDeviceStack( hookDevice, fileSysDevice ) == NULL )
	{
        //
        // Couldn't attach for some reason
        //
        PGPdbgPrint(("PGPutil: Connect with Filesystem failed: %c (%x) =>%x\n",
                  'A'+Drive, fileSysDevice, ntStatus ));

        //
        // Derefence the object and get out
        //
        ObDereferenceObject( fileObject );
        return FALSE;
    }

    //
    // Note which device this is
    //
    LDriveDevices[Drive] = hookDevice;

    //
    // Dereference the object
    //
    ObDereferenceObject( fileObject );

    return TRUE;
}


//----------------------------------------------------------------------
//
// Installable driver initialization. Here we just set ourselves up.
// This function is called from the drivers DriverEntry routine.
//
//----------------------------------------------------------------------
NTSTATUS
pgpWipeDeleteInit (
		IN PDRIVER_OBJECT	DriverObject,
		IN PDRVEXTENSION	DriverExtension)
{
    NTSTATUS                ntStatus;
    WCHAR                   volumeBuffer[] = L"\\DosDevices\\X:\\";
    UNICODE_STRING          volumeBufferUnicodeString;
    USHORT                  drive;
    HANDLE 		            volumeHandle;
    OBJECT_ATTRIBUTES       objectAttributes;
    IO_STATUS_BLOCK  	    ioStatus;
    BOOLEAN                 errorMode;
    FILE_FS_DEVICE_INFORMATION fsDeviceInformation;

    PGPdbgVerbosePrint (("PGPutil: entering pgpWipeDeleteInit\n"));

	// Some setup work to initialize the driver
	KeInitializeSemaphore(&apc_sem,0,1);
	num_scheds=0;

    //
    // If not NT 4.0 Final Release, shorten the Fast I/O table so that PGPWDNT
    // will work on the Betas and Release Candidates
    //
    if( *NtBuildNumber < NT4FINAL )
	{
        FastIOHook.SizeOfFastIoDispatch =
				(ULONG) &FastIOHook.FastIoQueryNetworkOpenInfo -
				(ULONG) &FastIOHook;
    }

    //
    // Set up the Fast I/O dispatch table
    //
    DriverObject->FastIoDispatch = &FastIOHook;

    //
    // Disable hard errors so that we don't pop-up when touching removable media
    //
    errorMode = IoSetThreadHardErrorMode( FALSE );

    //
    // Need to check each drive to see if its a local hard disk
    //
    RtlInitUnicodeString (&volumeBufferUnicodeString,
                          volumeBuffer );
    for(drive = 2; drive < 26; drive++ )
	{
        LDriveDevices[drive] = NULL;

        volumeBufferUnicodeString.Buffer[12] = drive+'A';

        InitializeObjectAttributes( &objectAttributes,
									&volumeBufferUnicodeString,
                                    OBJ_CASE_INSENSITIVE, NULL, NULL );

        ntStatus = ZwCreateFile( &volumeHandle, FILE_ANY_ACCESS,
                     &objectAttributes, &ioStatus, NULL, 0,
					 FILE_SHARE_READ|FILE_SHARE_WRITE, FILE_OPEN,
                   

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -