//Callback from process creation. VOID ProcessCreationCB( _In_ HANDLE ParentId, _In_ HANDLE ProcessId, _In_ BOOLEAN Create) { PRECORD_LIST recordList = SpyNewRecord(); if (!recordList) return; if (Create) { recordList->LogRecord.Data.RecordType = CREATE_OP; recordList->LogRecord.Data.ProcessId = (FILE_ID)ProcessId; recordList->LogRecord.Data.ThreadId = (FILE_ID)ParentId; } else { recordList->LogRecord.Data.RecordType = EXIT_OP; recordList->LogRecord.Data.ProcessId = (FILE_ID)ProcessId; } //Set the time for the originating and completion itme. KeQuerySystemTime(&recordList->LogRecord.Data.OriginatingTime); recordList->LogRecord.Data.CompletionTime = recordList->LogRecord.Data.OriginatingTime; //Set the name to "" UNICODE_STRING emptySTR; RtlInitUnicodeString(&emptySTR, L""); SpySetRecordNameAndEcpData(&recordList->LogRecord, &emptySTR, &emptySTR); //Send to the userland! SpyLog(recordList); }
void SendRegistryOperationToUserland (ULONG _opType, PUNICODE_STRING _pTarget ) { PRECORD_LIST recordList = SpyNewRecord(); if (!recordList) return; //Set the operation type. recordList->LogRecord.Data.RecordType = _opType; //Fill the basic stuff (PID-TID). recordList->LogRecord.Data.ProcessId = (FILE_ID)PsGetCurrentProcessId(); recordList->LogRecord.Data.ThreadId = (FILE_ID)PsGetCurrentThreadId(); //Fill the SystemTypeStuff. KeQuerySystemTime(&recordList->LogRecord.Data.OriginatingTime); KeQuerySystemTime(&recordList->LogRecord.Data.CompletionTime); ////Set the name to "" UNICODE_STRING emptySTR; RtlInitUnicodeString(&emptySTR, L""); DbgPrint("SendRegistryOperationToUserland : %wZ", _pTarget); SpySetRecordNameAndEcpData(&recordList->LogRecord, _pTarget, NULL); ////Send to the userland! SpyLog(recordList); }
VOID SpyLogIrpCompletion ( __in PIRP Irp, __inout PRECORD_LIST RecordList ) /*++ Routine Description: Records the Irp necessary information according to LoggingFlags in RecordList. For any activity on the Irp path of a device being logged, this function should get called twice: once on the IRPs originating path and once on the IRPs completion path. Arguments: Irp - The Irp that contains the information we want to record. LoggingFlags - The flags that say what to log. RecordList - The PRECORD_LIST in which the Irp information is stored. Return Value: None. --*/ { PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_OBJECT deviceObject = pIrpStack->DeviceObject; PRECORD_IRP pRecordIrp; // // Process the log record // if (SHOULD_LOG( deviceObject )) { pRecordIrp = &RecordList->LogRecord.Record.RecordIrp; // // Record the information we use for a completion Irp. // pRecordIrp->ReturnStatus = Irp->IoStatus.Status; pRecordIrp->ReturnInformation = Irp->IoStatus.Information; KeQuerySystemTime(&pRecordIrp->CompletionTime); // // Add RecordList to our gOutputBufferList so that it gets up to // the user // SpyLog( RecordList ); } else { if (RecordList) { // // Context is set with a RECORD_LIST, but we are no longer // logging so free this record. // SpyFreeRecord( RecordList ); } } switch (pIrpStack->MajorFunction) { case IRP_MJ_CREATE: // // If the operation failed remove the name from the cache because // it is stale // if (!NT_SUCCESS(Irp->IoStatus.Status) && (pIrpStack->FileObject != NULL)) { SpyNameDelete(pIrpStack->FileObject); } break; case IRP_MJ_CLOSE: // // Always remove the name on close // SpyNameDelete(pIrpStack->FileObject); break; case IRP_MJ_SET_INFORMATION: // // If the operation was successful and it was a rename, always // remove the name. They can re-get it next time. // if (NT_SUCCESS(Irp->IoStatus.Status) && (FileRenameInformation == pIrpStack->Parameters.SetFile.FileInformationClass)) { SpyNameDelete(pIrpStack->FileObject); } break; } }