Beispiel #1
0
// This function throws an exception that can be caught by the debugger,
// instead of allowing the default CRT behavior of invoking Watson to failfast.
void __cdecl _SOS_invalid_parameter(
   const WCHAR * expression,
   const WCHAR * function, 
   const WCHAR * file, 
   unsigned int line,
   uintptr_t pReserved
)
{
    ExtErr("\nSOS failure!\n");
    throw "SOS failure";
}
Beispiel #2
0
extern "C" HRESULT
ArchQuery(void)
{
    ULONG targetArchitecture;
    IMachine* targetMachine = NULL;

    g_ExtControl->GetExecutingProcessorType(&targetArchitecture);

#ifdef SOS_TARGET_AMD64
    if(targetArchitecture == IMAGE_FILE_MACHINE_AMD64)
    {
        targetMachine = AMD64Machine::GetInstance();
    }
#endif // SOS_TARGET_AMD64
#ifdef SOS_TARGET_X86
    if (targetArchitecture == IMAGE_FILE_MACHINE_I386)
    {
        targetMachine = X86Machine::GetInstance();
    }
#endif // SOS_TARGET_X86
#ifdef SOS_TARGET_ARM
    if (targetArchitecture == IMAGE_FILE_MACHINE_ARMNT)
    {
        targetMachine = ARMMachine::GetInstance();
    }
#endif // SOS_TARGET_ARM
#ifdef SOS_TARGET_ARM64
    if (targetArchitecture == IMAGE_FILE_MACHINE_ARM64)
    {
        targetMachine = ARM64Machine::GetInstance();
    }
#endif // SOS_TARGET_ARM64

    if (targetMachine == NULL)
    {
        g_targetMachine = NULL;
        ExtErr("SOS does not support the current target architecture.\n");
        return E_FAIL;
    }

    g_targetMachine = targetMachine;
    return S_OK;
}
Beispiel #3
0
STDMETHODIMP
EventCallbacks::Exception(
    THIS_
    IN PEXCEPTION_RECORD64 Exception,
    IN ULONG FirstChance)
{    
    g_ResumeState = FALSE;

    if (Exception->ExceptionCode == STATUS_BREAKPOINT)
    {
        if (FirstChance)
        {
            DEBUG_VALUE Reg, Ecx, Edx;            

            // Query EIP, EAX and ECX value.
            if (g_Registers->GetValue(g_EipIndex, &Reg) == S_OK &&
                g_Registers->GetValue(g_EdxIndex, &Edx) == S_OK &&
                g_Registers->GetValue(g_EcxIndex, &Ecx) == S_OK)
            {
                char szParam[MAX_PATH];
                ULONG ReadedBytes = 0;

                // Read current instruction opcode value.
                ZeroMemory(szParam, sizeof(szParam));
                HRESULT Hr = g_DataSpaces->ReadVirtual(RegPtrGet(&Reg), &szParam, 1, &ReadedBytes);                
                if (Hr != S_OK)
                {
                    ExtErr(__FUNCTION__"() ERROR: IDebugDataSpaces::ReadVirtual() fails: %lx\n", Hr);
                    return DEBUG_STATUS_NO_CHANGE;
                }

                // Check for int 3 at EIP.
                if (szParam[0] != '\xCC')
                {
                    return DEBUG_STATUS_NO_CHANGE;
                }

                // Check for the magic engine constnat in EDX.
                if (Edx.I32 != DBGCB_GET_SYMBOL &&
                    Edx.I32 != DBGCB_EXECUTE &&
                    Edx.I32 != DBGCB_FIELD_OFFSET)
                {
                    return DEBUG_STATUS_NO_CHANGE;
                }
                
                g_ResumeState = TRUE;                

                // Read ASCII string with command arguments.
                ZeroMemory(szParam, sizeof(szParam));
                Hr = g_DataSpaces->ReadVirtual(RegPtrGet(&Ecx), &szParam, sizeof(szParam), &ReadedBytes);
                if (Hr != S_OK)
                {
                    ExtErr(__FUNCTION__"() ERROR: IDebugDataSpaces::ReadVirtual() fails: %lx\n", Hr);
                    return DEBUG_STATUS_NO_CHANGE;
                }

                switch (Edx.I32)
                {
                case DBGCB_GET_SYMBOL:
                    {
                        ExtOut("<col fg=\"srccmnt\">" __FUNCTION__"(): DBGCB_GET_SYMBOL \"%s\"</col>\n", szParam);

                        RegPtrSet(&Reg, 0);
                        g_Registers->SetValue(g_EaxIndex, &Reg);

                        Hr = g_Control->Evaluate(szParam, g_RegPtrType, &Reg, NULL);
                        if (Hr == S_OK)
                        {
                            // Return symbol address in EAX.
                            g_Registers->SetValue(g_EaxIndex, &Reg);
                        }
                        else
                        {
                            ExtErr(__FUNCTION__"() WARNING: IDebugControl::Evaluate() fails: %lx\n", Hr);
                        }

                        break;
                    }                                 

                case DBGCB_EXECUTE:
                    {
                        ExtOut("<col fg=\"srccmnt\">" __FUNCTION__ "(): DBGCB_EXECUTE</col>\n");

                        // execute debugger command
                        Hr = g_Control->Execute(
                            DEBUG_OUTCTL_ALL_CLIENTS | DEBUG_OUTCTL_AMBIENT_DML, 
                            szParam, 
                            DEBUG_EXECUTE_DEFAULT
                        );
                        if (Hr == S_OK)
                        {
                            // Return TRUE in EAX
                            RegPtrSet(&Reg, 1);
                            g_Registers->SetValue(g_EaxIndex, &Reg);
                        }
                        else
                        {
                            ExtErr(__FUNCTION__"() WARNING: IDebugControl::Execute() fails: %lx\n", Hr);
                        }

                        break;
                    }                    

                case DBGCB_FIELD_OFFSET:
                    {
                        RegPtrSet(&Reg, (ULONG64)-1);

                        char *lpszModule = szParam, *lpszStruct = NULL, *lpszField = NULL;

                        ExtOut("<col fg=\"srccmnt\">" __FUNCTION__"(): DBGCB_FIELD_OFFSET \"%s\"</col>\n", szParam);

                        // parse structure and field description string
                        if (lpszStruct = strstr(lpszModule, "!"))
                        {
                            *lpszStruct = '\x00';
                            lpszStruct += 1;

                            if (lpszField = strstr(lpszStruct, "::"))
                            {
                                *lpszField = '\x00';
                                lpszField += 2;
                            }
                        }                        

                        if (lpszStruct && lpszField)
                        {
                            // enumerate fields
                            for (ULONG i = 0; ;i++) 
                            {   
                                ULONG64 Module = 0;
                                ULONG TypeId = 0;    

                                // get ID of this symbol
                                Hr = g_Symbols->GetSymbolTypeId(lpszStruct, &TypeId, &Module);
                                if (Hr == S_OK) 
                                {
                                    char szFieldName[MAX_PATH];

                                    // query name of the filed
                                    HRESULT Hr = g_Symbols->GetFieldName(Module, TypeId, i, szFieldName, MAX_PATH, NULL);
                                    if (Hr == S_OK) 
                                    {
                                        ULONG Offset = 0, FieldTypeId = 0;

                                        // query filed type and offset
                                        Hr = g_Symbols->GetFieldTypeAndOffset(Module, TypeId, szFieldName, &FieldTypeId, &Offset);                                   
                                        if (Hr == S_OK)
                                        {
                                            if (!strcmp(szFieldName, lpszField))
                                            {
                                                // Return symbol offset in EAX
                                                RegPtrSet(&Reg, (ULONG64)Offset);                                                
                                                break;
                                            }
                                        }            
                                        else 
                                        {
                                            ExtErr(__FUNCTION__"() WARNING: IDebugSymbols3::GetFieldTypeAndOffset() fails: %lx\n", Hr);
                                        }
                                    } 
                                    else if (Hr == E_INVALIDARG) 
                                    {
                                        // All Fields done
                                        break;
                                    } 
                                    else 
                                    {
                                        ExtErr(__FUNCTION__"() WARNING: IDebugSymbols3::GetFieldName() fails: %lx\n", Hr);
                                    }
                                }
                                else
                                {
                                    ExtErr(__FUNCTION__"() WARNING: IDebugSymbols3::GetSymbolTypeId() fails: %lx\n", Hr);
                                }                                
                            }
                        }
                        else
                        {
                            ExtErr(__FUNCTION__"() WARNING: Bad name format (must be <module>!<struct_name>::<field_name>)\n");
                        }

                        g_Registers->SetValue(g_EaxIndex, &Reg);

                        break;
                    }                    

                default:

                    return DEBUG_STATUS_NO_CHANGE;
                }

                // Skip current int 3 instruction and continue execution
                if (g_Registers->GetValue(g_EipIndex, &Reg) == S_OK && Reg.Type == DEBUG_VALUE_INT32)
                {
                    if (g_bIs64)
                    {
                        Reg.I64 += 1;
                    }
                    else
                    {
                        Reg.I32 += 1;
                    }

                    g_Registers->SetValue(g_EipIndex, &Reg);                    
                }                 

                return DEBUG_STATUS_GO_HANDLED;
            }                      
        }
    }    

    return DEBUG_STATUS_NO_CHANGE;
}