Ejemplo n.º 1
1
VOID
CBTdPostOperationCallback (
    _In_ PVOID RegistrationContext,
    _In_ POB_POST_OPERATION_INFORMATION PostInfo
    )
{
    PTD_CALLBACK_REGISTRATION CallbackRegistration = (PTD_CALLBACK_REGISTRATION)RegistrationContext;

    TdCheckAndFreeCallContext (PostInfo, CallbackRegistration);

    if (PostInfo->ObjectType == *PsProcessType) {
        //
        // Ignore requests for processes other than our target process.
        //

        if (CallbackRegistration->TargetProcess != NULL &&
            CallbackRegistration->TargetProcess != PostInfo->Object
        )   {
            return;
        }

        //
        // Also ignore requests that are trying to open/duplicate the current
        // process.
        //

        if (PostInfo->Object == PsGetCurrentProcess())  {
            return;
        }
    }
    else if (PostInfo->ObjectType == *PsThreadType) {
        HANDLE ProcessIdOfTargetThread = PsGetThreadProcessId ((PETHREAD)PostInfo->Object);

        //
        // Ignore requests for threads belonging to processes other than our
        // target process.
        //

        if (CallbackRegistration->TargetProcess   != NULL &&
            CallbackRegistration->TargetProcessId != ProcessIdOfTargetThread
        )   {
            return;
        }

        //
        // Also ignore requests for threads belonging to the current processes.
        //

        if (ProcessIdOfTargetThread == PsGetCurrentProcessId()) {
            return;
        }
    }
    else    {
        TD_ASSERT (FALSE);
    }

}
Ejemplo n.º 2
0
static
void
send_kd_state_change(DBGKD_ANY_WAIT_STATE_CHANGE* StateChange)
{
    InException = TRUE;

    switch (StateChange->NewState)
    {
    case DbgKdLoadSymbolsStateChange:
    {
        /* We don't care about symbols loading */
        KdpManipulateStateHandler = ContinueManipulateStateHandler;
        break;
    }
    case DbgKdExceptionStateChange:
    {
        PETHREAD Thread = (PETHREAD)(ULONG_PTR)StateChange->Thread;
        /* Save current state for later GDB queries */
        CurrentStateChange = *StateChange;
        KDDBGPRINT("Exception 0x%08x in thread p%p.%p.\n",
            StateChange->u.Exception.ExceptionRecord.ExceptionCode,
            PsGetThreadProcessId(Thread),
            PsGetThreadId(Thread));
        /* Set the current debugged process/thread accordingly */
        gdb_dbg_tid = handle_to_gdb_tid(PsGetThreadId(Thread));
#if MONOPROCESS
        gdb_dbg_pid = 0;
#else
        gdb_dbg_pid = handle_to_gdb_pid(PsGetThreadProcessId(Thread));
#endif
        gdb_send_exception(FALSE);
        /* Next receive call will ask for the context */
        KdpManipulateStateHandler = GetContextManipulateHandler;
        break;
    }
    default:
        KDDBGPRINT("Unknown StateChange %u.\n", StateChange->NewState);
        while (1);
    }
}
Ejemplo n.º 3
0
static
VOID
FirstSendHandler(
    _In_ ULONG PacketType,
    _In_ PSTRING MessageHeader,
    _In_ PSTRING MessageData)
{
    DBGKD_ANY_WAIT_STATE_CHANGE* StateChange = (DBGKD_ANY_WAIT_STATE_CHANGE*)MessageHeader->Buffer;
    PETHREAD Thread;

    if (PacketType == PACKET_TYPE_KD_DEBUG_IO)
    {
        /* This is not the packet we are waiting for */
        send_kd_debug_io((DBGKD_DEBUG_IO*)MessageHeader->Buffer, MessageData);
        return;
    }

    if (PacketType != PACKET_TYPE_KD_STATE_CHANGE64)
    {
        KDDBGPRINT("First KD packet is not a state change!\n");
        /* FIXME: What should we send back to KD ? */
        while(1);
    }

    KDDBGPRINT("KDGDB: START!\n");

    Thread = (PETHREAD)(ULONG_PTR)StateChange->Thread;

    /* Set up the current state */
    CurrentStateChange = *StateChange;
    gdb_dbg_tid = handle_to_gdb_tid(PsGetThreadId(Thread));
#if MONOPROCESS
    gdb_dbg_pid = 0;
#else
    gdb_dbg_pid = handle_to_gdb_pid(PsGetThreadProcessId(Thread));
#endif
    /* This is the idle process. Save it! */
    TheIdleThread = Thread;
    TheIdleProcess = (PEPROCESS)Thread->Tcb.ApcState.Process;

    KDDBGPRINT("Pid Tid of the first message: %" PRIxPTR", %" PRIxPTR ".\n", gdb_dbg_pid, gdb_dbg_tid);

    /* The next receive call will be asking for the version data */
    KdpSendPacketHandler = NULL;
    KdpManipulateStateHandler = GetVersionManipulateStateHandler;
}
Ejemplo n.º 4
0
//
// CBTdPreOperationCallback
//
OB_PREOP_CALLBACK_STATUS
CBTdPreOperationCallback (
    _In_ PVOID RegistrationContext,
    _Inout_ POB_PRE_OPERATION_INFORMATION PreInfo
)
{
    PTD_CALLBACK_REGISTRATION CallbackRegistration;

    ACCESS_MASK AccessBitsToClear     = 0;
    ACCESS_MASK AccessBitsToSet       = 0;
    ACCESS_MASK InitialDesiredAccess  = 0;
    ACCESS_MASK OriginalDesiredAccess = 0;


    PACCESS_MASK DesiredAccess = NULL;

    LPCWSTR ObjectTypeName = NULL;
    LPCWSTR OperationName = NULL;

    // Not using driver specific values at this time
    CallbackRegistration = (PTD_CALLBACK_REGISTRATION)RegistrationContext;


    TD_ASSERT (PreInfo->CallContext == NULL);

    // Only want to filter attempts to access protected process
    // all other processes are left untouched

    if (PreInfo->ObjectType == *PsProcessType)  {
        //
        // Ignore requests for processes other than our target process.
        //

        // if (TdProtectedTargetProcess != NULL &&
        //    TdProtectedTargetProcess != PreInfo->Object)
        if (TdProtectedTargetProcess != PreInfo->Object)
        {
            goto Exit;
        }

        //
        // Also ignore requests that are trying to open/duplicate the current
        // process.
        //

        if (PreInfo->Object == PsGetCurrentProcess())   {
            DbgPrintEx (
                DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
                "ObCallbackTest: CBTdPreOperationCallback: ignore process open/duplicate from the protected process itself\n");
            goto Exit;
        }

        ObjectTypeName = L"PsProcessType";
        AccessBitsToClear     = CB_PROCESS_TERMINATE;
        AccessBitsToSet       = 0;
    }
    else if (PreInfo->ObjectType == *PsThreadType)  {
        HANDLE ProcessIdOfTargetThread = PsGetThreadProcessId ((PETHREAD)PreInfo->Object);

        //
        // Ignore requests for threads belonging to processes other than our
        // target process.
        //

        // if (CallbackRegistration->TargetProcess   != NULL &&
        //     CallbackRegistration->TargetProcessId != ProcessIdOfTargetThread)
        if (TdProtectedTargetProcessId != ProcessIdOfTargetThread)  {
            goto Exit;
        }

        //
        // Also ignore requests for threads belonging to the current processes.
        //

        if (ProcessIdOfTargetThread == PsGetCurrentProcessId()) {
            DbgPrintEx (
                DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
                "ObCallbackTest: CBTdPreOperationCallback: ignore thread open/duplicate from the protected process itself\n");
            goto Exit;
        }

        ObjectTypeName = L"PsThreadType";
        AccessBitsToClear     = CB_THREAD_TERMINATE;
        AccessBitsToSet       = 0;
    }
    else    {
        DbgPrintEx (
            DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL,
            "ObCallbackTest: CBTdPreOperationCallback: unexpected object type\n");
        goto Exit;
    }

    switch (PreInfo->Operation) {
    case OB_OPERATION_HANDLE_CREATE:
        DesiredAccess = &PreInfo->Parameters->CreateHandleInformation.DesiredAccess;
        OriginalDesiredAccess = PreInfo->Parameters->CreateHandleInformation.OriginalDesiredAccess;

        OperationName = L"OB_OPERATION_HANDLE_CREATE";
        break;

    case OB_OPERATION_HANDLE_DUPLICATE:
        DesiredAccess = &PreInfo->Parameters->DuplicateHandleInformation.DesiredAccess;
        OriginalDesiredAccess = PreInfo->Parameters->DuplicateHandleInformation.OriginalDesiredAccess;

        OperationName = L"OB_OPERATION_HANDLE_DUPLICATE";
        break;

    default:
        TD_ASSERT (FALSE);
        break;
    }

    InitialDesiredAccess = *DesiredAccess;

    // Filter only if request made outside of the kernel
    if (PreInfo->KernelHandle != 1) {
        *DesiredAccess &= ~AccessBitsToClear;
        *DesiredAccess |=  AccessBitsToSet;
    }

    //
    // Set call context.
    //

    TdSetCallContext (PreInfo, CallbackRegistration);


    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "ObCallbackTest: CBTdPreOperationCallback: PROTECTED process %p (ID 0x%p)\n",
        TdProtectedTargetProcess,
        (PVOID)TdProtectedTargetProcessId
    );

    DbgPrintEx (
        DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL,
        "ObCallbackTest: CBTdPreOperationCallback\n"
        "    Client Id:    %p:%p\n"
        "    Object:       %p\n"
        "    Type:         %ls\n"
        "    Operation:    %ls (KernelHandle=%d)\n"
        "    OriginalDesiredAccess: 0x%x\n"
        "    DesiredAccess (in):    0x%x\n"
        "    DesiredAccess (out):   0x%x\n",
        PsGetCurrentProcessId(),
        PsGetCurrentThreadId(),
        PreInfo->Object,
        ObjectTypeName,
        OperationName,
        PreInfo->KernelHandle,
        OriginalDesiredAccess,
        InitialDesiredAccess,
        *DesiredAccess
    );

Exit:

    return OB_PREOP_SUCCESS;
}
Ejemplo n.º 5
0
/* q* packets */
static
void
handle_gdb_query(void)
{
    if (strncmp(gdb_input, "qSupported:", 11) == 0)
    {
#if MONOPROCESS
        send_gdb_packet("PacketSize=1000;");
#else
        send_gdb_packet("PacketSize=1000;multiprocess+;");
#endif
        return;
    }

    if (strncmp(gdb_input, "qAttached", 9) == 0)
    {
#if MONOPROCESS
        send_gdb_packet("1");
#else
        UINT_PTR queried_pid = hex_to_pid(&gdb_input[10]);
        /* Let's say we created system process */
        if (gdb_pid_to_handle(queried_pid) == NULL)
            send_gdb_packet("0");
        else
            send_gdb_packet("1");
#endif
        return;
    }

    if (strncmp(gdb_input, "qRcmd,", 6) == 0)
    {
        send_gdb_packet("OK");
        return;
    }

    if (strcmp(gdb_input, "qC") == 0)
    {
        char gdb_out[64];
#if MONOPROCESS
        sprintf(gdb_out, "QC:%"PRIxPTR";",
            handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)));
#else
        sprintf(gdb_out, "QC:p%"PRIxPTR".%"PRIxPTR";",
            handle_to_gdb_pid(PsGetThreadProcessId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)),
            handle_to_gdb_tid(PsGetThreadId((PETHREAD)(ULONG_PTR)CurrentStateChange.Thread)));
#endif
        send_gdb_packet(gdb_out);
        return;
    }

    if ((strncmp(gdb_input, "qfThreadInfo", 12) == 0)
            || (strncmp(gdb_input, "qsThreadInfo", 12) == 0))
    {
        BOOLEAN FirstThread = TRUE;
        PEPROCESS Process;
        PETHREAD Thread;
        char gdb_out[1024];
        char* ptr = gdb_out;
        BOOLEAN Resuming = strncmp(gdb_input, "qsThreadInfo", 12) == 0;
        /* Keep track of where we are. */
        static LIST_ENTRY* CurrentProcessEntry;
        static LIST_ENTRY* CurrentThreadEntry;

        ptr = gdb_out;

        *ptr++ = 'm';
        /* NULL terminate in case we got nothing more to iterate */
        *ptr  = '\0';

        if (!Resuming)
        {
            /* Initialize the entries */
            CurrentProcessEntry = ProcessListHead->Flink;
            CurrentThreadEntry = NULL;

            /* Start with idle thread */
#if MONOPROCESS
            ptr = gdb_out + sprintf(gdb_out, "m1");
#else
            ptr = gdb_out + sprintf(gdb_out, "mp1.1");
#endif
            FirstThread = FALSE;
        }

        if (CurrentProcessEntry == NULL) /* Ps is not initialized */
        {
            send_gdb_packet(Resuming ? "l" : gdb_out);
            return;
        }

        /* List all the processes */
        for ( ;
            CurrentProcessEntry != ProcessListHead;
            CurrentProcessEntry = CurrentProcessEntry->Flink)
        {

            Process = CONTAINING_RECORD(CurrentProcessEntry, EPROCESS, ActiveProcessLinks);

            if (CurrentThreadEntry != NULL)
                CurrentThreadEntry = CurrentThreadEntry->Flink;
            else
                CurrentThreadEntry = Process->ThreadListHead.Flink;

            /* List threads from this process */
            for ( ;
                 CurrentThreadEntry != &Process->ThreadListHead;
                 CurrentThreadEntry = CurrentThreadEntry->Flink)
            {
                Thread = CONTAINING_RECORD(CurrentThreadEntry, ETHREAD, ThreadListEntry);

                /* See if we should add a comma */
                if (FirstThread)
                {
                    FirstThread = FALSE;
                }
                else
                {
                    *ptr++ = ',';
                }

#if MONOPROCESS
                ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
                    "%p",
                    handle_to_gdb_tid(Thread->Cid.UniqueThread));
#else
                ptr += _snprintf(ptr, 1024 - (ptr - gdb_out),
                    "p%p.%p",
                    handle_to_gdb_pid(Process->UniqueProcessId),
                    handle_to_gdb_tid(Thread->Cid.UniqueThread));
#endif
                if (ptr > (gdb_out + 1024))
                {
                    /* send what we got */
                    send_gdb_packet(gdb_out);
                    /* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */
                    return;
                }
            }
            /* We're done for this process */
            CurrentThreadEntry = NULL;
        }

        if (gdb_out[1] == '\0')
        {
            /* We didn't iterate over anything, meaning we were already done */
            send_gdb_packet("l");
        }
        else
        {
            send_gdb_packet(gdb_out);
        }
        /* GDB can ask anything at this point, it isn't necessarily a qsThreadInfo packet */
        return;
    }

    if (strncmp(gdb_input, "qThreadExtraInfo,", 17) == 0)
    {
        ULONG_PTR Pid, Tid;
        PETHREAD Thread;
        PEPROCESS Process;
        char out_string[64];
        STRING String = {0, 64, out_string};

        KDDBGPRINT("Giving extra info for");

#if MONOPROCESS
        Pid = 0;
        Tid = hex_to_tid(&gdb_input[17]);

        KDDBGPRINT(" %p.\n", Tid);

        Thread = find_thread(Pid, Tid);
        Process = CONTAINING_RECORD(Thread->Tcb.Process, EPROCESS, Pcb);
#else
        Pid = hex_to_pid(&gdb_input[2]);
        Tid = hex_to_tid(strstr(gdb_input, ".") + 1);

        /* We cannot use PsLookupProcessThreadByCid as we could be running at any IRQL.
         * So loop. */
        KDDBGPRINT(" p%p.%p.\n", Pid, Tid);

        Process = find_process(Pid);
        Thread = find_thread(Pid, Tid);
#endif

        if (PsGetThreadProcessId(Thread) == 0)
        {
            String.Length = sprintf(out_string, "SYSTEM");
        }
        else
        {
            String.Length = sprintf(out_string, "%.*s", 16, Process->ImageFileName);
        }

        gdb_send_debug_io(&String, FALSE);
        return;
    }

    if (strncmp(gdb_input, "qOffsets", 8) == 0)
    {
        /* We load ntoskrnl at 0x80800000 while compiling it at 0x00800000 base adress */
        send_gdb_packet("TextSeg=80000000");
        return;
    }

    if (strcmp(gdb_input, "qTStatus") == 0)
    {
        /* No tracepoint support */
        send_gdb_packet("T0");
        return;
    }

    KDDBGPRINT("KDGDB: Unknown query: %s\n", gdb_input);
    send_gdb_packet("");
    return;
}