Example #1
0
NTSTATUS
PerfInfoLogBytes(
    USHORT HookId,
    PVOID Data,
    ULONG BytesToLog
    )
/*++

Routine Description:

    Reserves memory for the hook, copies the data, and unref's the hook entry.

Arguments:

    HookId - Id for the hook
    Data - pointer to the data to be logged
    BytesToLog - size of data in bytes

Return Value:

    STATUS_SUCCESS on success
--*/
{
    PERFINFO_HOOK_HANDLE Hook;
    NTSTATUS Status;

    Status = PerfInfoReserveBytes(&Hook, HookId, BytesToLog);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    RtlCopyMemory(PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PPERF_BYTE), Data, BytesToLog);
    PERF_FINISH_HOOK(Hook);

    return STATUS_SUCCESS;
}
Example #2
0
NTSTATUS
PerfInfoProcessRunDown (
    )
/*++

Routine Description:

    This routine does the Process and thread rundown in the kernel mode.
    Since this routine is called only by global logger (i.e., trace from boot),
    no Sid info is collected.

Arguments:

    None.

Return Value:

    Status

--*/
{
    NTSTATUS Status;
    PSYSTEM_PROCESS_INFORMATION ProcessInfo;
    PSYSTEM_EXTENDED_THREAD_INFORMATION ThreadInfo;
    PCHAR Buffer;
    ULONG BufferSize = 4096;
    ULONG ReturnLength;

retry:
    Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, PERFPOOLTAG);

    if (!Buffer) {
        return STATUS_NO_MEMORY;
    }
    Status = ZwQuerySystemInformation( SystemExtendedProcessInformation,
                                       Buffer,
                                       BufferSize,
                                       &ReturnLength
                                       );

    if (Status == STATUS_INFO_LENGTH_MISMATCH) {
        ExFreePool(Buffer);
        BufferSize = ReturnLength;
        goto retry;
    }

    if (NT_SUCCESS(Status)) {
        ULONG TotalOffset = 0;
        ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) Buffer;
        while (TRUE) {
            PWMI_PROCESS_INFORMATION WmiProcessInfo;
            PWMI_EXTENDED_THREAD_INFORMATION WmiThreadInfo;
            PERFINFO_HOOK_HANDLE Hook;
            ANSI_STRING ProcessName;
            PCHAR AuxPtr;
            ULONG NameLength;
            ULONG ByteCount;
            ULONG SidLength = sizeof(ULONG);
            ULONG TmpSid = 0;
            ULONG i;

            //
            // Process Information
            //
            if ( ProcessInfo->ImageName.Buffer  && ProcessInfo->ImageName.Length > 0 ) {
                NameLength = ProcessInfo->ImageName.Length / sizeof(WCHAR) + 1;
            }
            else {
                NameLength = 1;
            }
            ByteCount = FIELD_OFFSET(WMI_PROCESS_INFORMATION, Sid) + SidLength + NameLength;

            Status = PerfInfoReserveBytes(&Hook, 
                                          WMI_LOG_TYPE_PROCESS_DC_START, 
                                          ByteCount);

            if (NT_SUCCESS(Status)){
                WmiProcessInfo = PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PWMI_PROCESS_INFORMATION);

                WmiProcessInfo->ProcessId = HandleToUlong(ProcessInfo->UniqueProcessId);
                WmiProcessInfo->ParentId = HandleToUlong(ProcessInfo->InheritedFromUniqueProcessId);
                WmiProcessInfo->SessionId = ProcessInfo->SessionId;
                WmiProcessInfo->PageDirectoryBase = ProcessInfo->PageDirectoryBase;

                AuxPtr = (PCHAR) &WmiProcessInfo->Sid;
                RtlCopyMemory(AuxPtr, &TmpSid, SidLength);

                AuxPtr += SidLength;
                if (NameLength > 1) {
    
                    ProcessName.Buffer = AuxPtr;
                    ProcessName.MaximumLength = (USHORT) NameLength;
    
                    RtlUnicodeStringToAnsiString( &ProcessName,
                                                (PUNICODE_STRING) &ProcessInfo->ImageName,
                                                FALSE);
                    AuxPtr += NameLength - 1; //point to the place for the '\0'
                }
                *AuxPtr = '\0';

                PERF_FINISH_HOOK(Hook);
            }

            //
            // Thread Information
            //
            ThreadInfo = (PSYSTEM_EXTENDED_THREAD_INFORMATION) (ProcessInfo + 1);

            for (i=0; i < ProcessInfo->NumberOfThreads; i++) {
                Status = PerfInfoReserveBytes(&Hook, 
                                              WMI_LOG_TYPE_THREAD_DC_START, 
                                              sizeof(WMI_EXTENDED_THREAD_INFORMATION));
                if (NT_SUCCESS(Status)){
                    WmiThreadInfo = PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PWMI_EXTENDED_THREAD_INFORMATION);
                    WmiThreadInfo->ProcessId =  HandleToUlong(ThreadInfo->ThreadInfo.ClientId.UniqueProcess);
                    WmiThreadInfo->ThreadId =  HandleToUlong(ThreadInfo->ThreadInfo.ClientId.UniqueThread);
                    WmiThreadInfo->StackBase = ThreadInfo->StackBase;
                    WmiThreadInfo->StackLimit = ThreadInfo->StackLimit;

                    WmiThreadInfo->UserStackBase = NULL;
                    WmiThreadInfo->UserStackLimit = NULL;
                    WmiThreadInfo->StartAddr = ThreadInfo->ThreadInfo.StartAddress;
                    WmiThreadInfo->Win32StartAddr = ThreadInfo->Win32StartAddress;
                    WmiThreadInfo->WaitMode = -1;
                    PERF_FINISH_HOOK(Hook);
                }

                ThreadInfo  += 1;
            }

            if (ProcessInfo->NextEntryOffset == 0) {
                break;
            } else {
                TotalOffset += ProcessInfo->NextEntryOffset;
                ProcessInfo = (PSYSTEM_PROCESS_INFORMATION) &Buffer[TotalOffset];
            }
        }
    } 

    ExFreePool(Buffer);
    return Status;

}
Example #3
0
NTSTATUS
PerfInfoSysModuleRunDown (
    )
/*++

Routine Description:

    This routine does the rundown for loaded drivers in the kernel mode.

Arguments:

    None.

Return Value:

    Status

--*/
{
    NTSTATUS Status;
    PRTL_PROCESS_MODULES            Modules;
    PRTL_PROCESS_MODULE_INFORMATION ModuleInfo;
    PVOID Buffer;
    ULONG BufferSize = 4096;
    ULONG ReturnLength;
    ULONG i;

retry:
    Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, PERFPOOLTAG);

    if (!Buffer) {
        return STATUS_NO_MEMORY;
    }
    Status = ZwQuerySystemInformation( SystemModuleInformation,
                                       Buffer,
                                       BufferSize,
                                       &ReturnLength
                                       );

    if (Status == STATUS_INFO_LENGTH_MISMATCH) {
        ExFreePool(Buffer);
        BufferSize = ReturnLength;
        goto retry;
    }

    if (NT_SUCCESS(Status)) {
        Modules = (PRTL_PROCESS_MODULES) Buffer;
        for (i = 0, ModuleInfo = & (Modules->Modules[0]);
             i < Modules->NumberOfModules;
             i ++, ModuleInfo ++) {

            PWMI_IMAGELOAD_INFORMATION ImageLoadInfo;
            UNICODE_STRING WstrModuleName;
            ANSI_STRING    AstrModuleName;
            ULONG          SizeModuleName;
            PERFINFO_HOOK_HANDLE Hook;
            ULONG ByteCount;

            RtlInitAnsiString( &AstrModuleName, (PCSZ) ModuleInfo->FullPathName);
            SizeModuleName = sizeof(WCHAR) * (AstrModuleName.Length) + sizeof(WCHAR);
            ByteCount = FIELD_OFFSET(WMI_IMAGELOAD_INFORMATION, FileName) 
                        + SizeModuleName;

            Status = PerfInfoReserveBytes(&Hook, WMI_LOG_TYPE_PROCESS_LOAD_IMAGE, ByteCount);

            if (NT_SUCCESS(Status)){
                ImageLoadInfo = PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PWMI_IMAGELOAD_INFORMATION);
                ImageLoadInfo->ImageBase = ModuleInfo->ImageBase;
                ImageLoadInfo->ImageSize = ModuleInfo->ImageSize;
                ImageLoadInfo->ProcessId = HandleToUlong(NULL);
                WstrModuleName.Buffer    = (LPWSTR) &ImageLoadInfo->FileName[0];
                WstrModuleName.MaximumLength = (USHORT) SizeModuleName; 
                Status = RtlAnsiStringToUnicodeString(&WstrModuleName, & AstrModuleName, FALSE);
                if (!NT_SUCCESS(Status)){
                    ImageLoadInfo->FileName[0] = UNICODE_NULL;
                }

                PERF_FINISH_HOOK(Hook);
            }
        }

    } 

    ExFreePool(Buffer);
    return Status;
}
Example #4
0
NTSTATUS
PerfInfoLogBytesAndUnicodeString(
    USHORT HookId,
    PVOID SourceData,
    ULONG SourceByteCount,
    PUNICODE_STRING String
    )
/*++

Routine description:

    This routine logs data with UniCode string at the end of the hook.

Arguments:
    
    HookId - Hook Id.

    SourceData - Pointer to the data to be copied

    SourceByteCount - Number of bytes to be copied.
    
    String - The string to be logged.

Return Value:
    Status

--*/
{
    NTSTATUS Status;
    PERFINFO_HOOK_HANDLE Hook;
    ULONG ByteCount;
    ULONG StringBytes;

    if (String == NULL) {
        StringBytes = 0;
    } else {
        StringBytes = String->Length;
        if (StringBytes > MAX_FILENAME_TO_LOG) {
            StringBytes = MAX_FILENAME_TO_LOG;
        }
    }

    ByteCount = (SourceByteCount + StringBytes + sizeof(WCHAR));

    Status = PerfInfoReserveBytes(&Hook, HookId, ByteCount);
    if (NT_SUCCESS(Status))
    {
        const PVOID pvTemp = PERFINFO_HOOK_HANDLE_TO_DATA(Hook, PVOID);
        RtlCopyMemory(pvTemp, SourceData, SourceByteCount);
        if (StringBytes != 0) {
            RtlCopyMemory(PERFINFO_APPLY_OFFSET_GIVING_TYPE(pvTemp, SourceByteCount, PVOID),
                          String->Buffer,
                          StringBytes
                          );
        }
        (PERFINFO_APPLY_OFFSET_GIVING_TYPE(pvTemp, SourceByteCount, PWCHAR))[StringBytes / sizeof(WCHAR)] = UNICODE_NULL;
        PERF_FINISH_HOOK(Hook);

        Status = STATUS_SUCCESS;
    }
    return Status;
}