Example #1
0
int main(int argc, char* argv[]) {
    int x = -7640;

    if (argc > 1)
        x = atoi(argv[1]);

    DebuggerEngine* engine = startEngine();

    DWORD clientAppearance = getClientAppearance(engine);

    DWORD clientControllerPointer = getClientController(engine);

    DWORD messageQueueDataTransformPointer = engine->getMessageQueueDataTransformPointer();

    INJECT local;
    local.clientAppearanceAddress = clientAppearance;
    local.clientControllerPointer = clientControllerPointer;
    local.messageQueueDataTransformPointer = messageQueueDataTransformPointer;
    local.x = x;

    cout << "Injecting Code...\n";

    HANDLE hThread = injectCode(engine->getProcessHandle(), local);

    if (hThread != NULL) {
        cout << "Code Injected...\n";
        cout << "Dumping";

        while (WaitForSingleObject(hThread, 1000) == WAIT_TIMEOUT)
            cout << ".";

        //CloseHandle(hThread);

        cout << "\nLook for heights.bin in your swg folder\n";
    } else {
        cout << "Failed to inject code..\n";
    }

    engine->stop();

    cout << "Wating for engine to finish..\n";

    while (engine->isRunning())
        Sleep(500);

    delete engine;

    cout << "Shutting down.";
    return 0;
}
Example #2
0
DebuggerEngine* startEngine() {
    DebuggerEngine* engine = new DebuggerEngine();

    engine->start();

    cout << "Loading Engine...\n";

    while (!engine->isWaitingForEvent())
        Sleep(500);

    cout << "Engine Started!\n";

    return engine;
}
Example #3
0
void SnapshotHandler::createSnapshot(int index)
{
    DebuggerEngine *engine = at(index);
    QTC_ASSERT(engine, return);
    engine->createSnapshot();
}
Example #4
0
void StackTreeView::contextMenuEvent(QContextMenuEvent *ev)
{
    DebuggerEngine *engine = currentEngine();
    StackHandler *handler = engine->stackHandler();
    const QModelIndex index = indexAt(ev->pos());
    const int row = index.row();
    StackFrame frame;
    if (row >= 0 && row < handler->stackSize())
        frame = handler->frameAt(row);
    const quint64 address = frame.address;

    QMenu menu;
    menu.addAction(action(ExpandStack));

    QAction *actCopyContents = menu.addAction(tr("Copy Contents to Clipboard"));
    actCopyContents->setEnabled(model() != 0);

    QAction *actSaveTaskFile = menu.addAction(tr("Save as Task File..."));
    actSaveTaskFile->setEnabled(model() != 0);

    if (engine->hasCapability(CreateFullBacktraceCapability))
        menu.addAction(action(CreateFullBacktrace));

    QAction *additionalQmlStackAction = 0;
    if (engine->hasCapability(AdditionalQmlStackCapability))
        additionalQmlStackAction = menu.addAction(tr("Load QML Stack"));

    QAction *actShowMemory = 0;
    if (engine->hasCapability(ShowMemoryCapability)) {
        actShowMemory = menu.addAction(QString());
        if (address == 0) {
            actShowMemory->setText(tr("Open Memory Editor"));
            actShowMemory->setEnabled(false);
        } else {
            actShowMemory->setText(tr("Open Memory Editor at 0x%1").arg(address, 0, 16));
            actShowMemory->setEnabled(engine->hasCapability(ShowMemoryCapability));
        }
    }

    QAction *actShowDisassemblerAt = 0;
    QAction *actShowDisassemblerAtAddress = 0;
    QAction *actShowDisassemblerAtFunction = 0;

    if (engine->hasCapability(DisassemblerCapability)) {
        actShowDisassemblerAt = menu.addAction(QString());
        actShowDisassemblerAtAddress = menu.addAction(tr("Open Disassembler at Address..."));
        actShowDisassemblerAtFunction = menu.addAction(tr("Disassemble Function..."));
        if (address == 0) {
            actShowDisassemblerAt->setText(tr("Open Disassembler"));
            actShowDisassemblerAt->setEnabled(false);
        } else {
            actShowDisassemblerAt->setText(tr("Open Disassembler at 0x%1").arg(address, 0, 16));
        }
    }


    QAction *actLoadSymbols = 0;
    if (engine->hasCapability(ShowModuleSymbolsCapability))
        actLoadSymbols = menu.addAction(tr("Try to Load Unknown Symbols"));

    if (engine->hasCapability(MemoryAddressCapability))
        menu.addAction(action(UseAddressInStackView));

    menu.addSeparator();
    menu.addAction(action(UseToolTipsInStackView));
    menu.addSeparator();
    menu.addAction(action(SettingsDialog));

    QAction *act = menu.exec(ev->globalPos());
    if (!act)
        return;

    if (act == actCopyContents) {
        copyContentsToClipboard();
    } else if (act == actShowMemory) {
        MemoryViewSetupData data;
        data.startAddress = address;
        data.title = tr("Memory at Frame #%1 (%2) 0x%3").
            arg(row).arg(frame.function).arg(address, 0, 16);
        data.markup.push_back(MemoryMarkup(address, 1, QColor(Qt::blue).lighter(),
                                  tr("Frame #%1 (%2)").arg(row).arg(frame.function)));
        engine->openMemoryView(data);
    } else if (act == actShowDisassemblerAtAddress) {
        AddressDialog dialog;
        if (address)
            dialog.setAddress(address);
        if (dialog.exec() == QDialog::Accepted)
            currentEngine()->openDisassemblerView(Location(dialog.address()));
    } else if (act == actShowDisassemblerAtFunction) {
        const StackFrame frame = inputFunctionForDisassembly();
        if (!frame.function.isEmpty())
            currentEngine()->openDisassemblerView(Location(frame));
    } else if (act == actShowDisassemblerAt)
        engine->openDisassemblerView(frame);
    else if (act == actLoadSymbols)
        engine->loadSymbolsForStack();
    else if (act == actSaveTaskFile)
        saveTaskFile(this, handler);
    else if (act == additionalQmlStackAction)
        engine->loadAdditionalQmlStack();
}
Example #5
0
void RegisterItem::triggerChange()
{
    QString value = "0x" + m_reg.value.toString(m_reg.kind, m_reg.size, HexadecimalFormat);
    m_engine->setRegisterValue(m_reg.name, value);
}
Example #6
0
void QmlCppEngine::slaveEngineStateChanged
    (DebuggerEngine *slaveEngine, const DebuggerState newState)
{
    DebuggerEngine *otherEngine = (slaveEngine == m_cppEngine)
         ? m_qmlEngine : m_cppEngine;

    QTC_CHECK(otherEngine != slaveEngine);

    if (debug) {
        EDEBUG("GOT SLAVE STATE: " << slaveEngine << newState);
        EDEBUG("  OTHER ENGINE: " << otherEngine << otherEngine->state());
        EDEBUG("  COMBINED ENGINE: " << this << state() << isDying());
    }

    // Idea is to follow the state of the cpp engine, except where we are stepping in QML.
    // That is, when the QmlEngine moves between InferiorStopOk, and InferiorRunOk, InferiorStopOk ...
    //
    // Accordingly, the 'active engine' is the cpp engine until the qml engine enters the
    // InferiorStopOk state. The cpp engine becomes the active one again as soon as it itself enters
    // the InferiorStopOk state.

    if (slaveEngine == m_cppEngine) {
        switch (newState) {
        case DebuggerNotReady: {
            // Can this ever happen?
            break;
        }
        case EngineSetupRequested: {
            // set by queueSetupEngine()
            QTC_ASSERT(state() == EngineSetupRequested, qDebug() << state());
            break;
        }
        case EngineSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineSetupFailed();
            break;
        }
        case EngineSetupOk: {
            notifyEngineSetupOk();
            break;
        }
        case InferiorSetupRequested: {
            // set by queueSetupInferior()
            QTC_ASSERT(state() == InferiorSetupRequested, qDebug() << state());
            break;
        }
        case InferiorSetupFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorSetupFailed();
            break;
        }
        case InferiorSetupOk: {
            notifyInferiorSetupOk();
            break;
        }
        case EngineRunRequested: {
            // set by queueRunEngine()
            break;
        }
        case EngineRunFailed: {
            qmlEngine()->quitDebugger();
            notifyEngineRunFailed();
            break;
        }
        case InferiorUnrunnable: {
            qmlEngine()->quitDebugger();
            notifyInferiorUnrunnable();
            break;
        }
        case InferiorRunRequested: {
            // might be set already by notifyInferiorRunRequested()
            QTC_ASSERT(state() == InferiorRunRequested
                       || state() == InferiorStopOk, qDebug() << state());
            if (state() != InferiorRunRequested)
                notifyInferiorRunRequested();
            break;
        }
        case InferiorRunOk: {
            QTC_ASSERT(state() == EngineRunRequested
                       || state() == InferiorRunRequested, qDebug() << state());
            if (state() == EngineRunRequested)
                notifyEngineRunAndInferiorRunOk();
            else if (state() == InferiorRunRequested)
                notifyInferiorRunOk();

            if (qmlEngine()->state() == InferiorStopOk) {
                // track qml engine again
                setState(InferiorStopRequested);
                notifyInferiorStopOk();
                setActiveEngine(m_qmlEngine);
            }
            break;
        }
        case InferiorRunFailed: {
            qmlEngine()->quitDebugger();
            notifyInferiorRunFailed();
            break;
        }
        case InferiorStopRequested: {
            if (m_activeEngine == cppEngine()) {
                // might be set by doInterruptInferior()
                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunOk, qDebug() << state());
                if (state() == InferiorRunOk)
                    setState(InferiorStopRequested);
            } else {
                // we're debugging qml, but got an interrupt, or abort
                QTC_ASSERT(state() == InferiorRunOk
                          || state() == InferiorStopOk
                           || state() == InferiorRunRequested, qDebug() << state());

                if (state() == InferiorRunOk) {
                    setState(InferiorStopRequested);
                } else if (state() == InferiorStopOk) {
                    notifyInferiorRunRequested();
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                } else if (state() == InferiorRunRequested) {
                    notifyInferiorRunOk();
                    setState(InferiorStopRequested);
                }
                // now track cpp engine
                setActiveEngine(m_cppEngine);
            }
            break;
        }
        case InferiorStopOk: {
            if (isDying()) {
                EDEBUG("... CPP ENGINE STOPPED DURING SHUTDOWN ");
                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunOk
                           || state() == InferiorStopOk, qDebug() << state());

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    setState(InferiorStopOk);
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != cppEngine()) {
                    showStatusMessage(tr("C++ debugger activated"));
                    setActiveEngine(m_cppEngine);
                }

                QTC_ASSERT(state() == InferiorStopRequested
                           || state() == InferiorRunRequested
                           || state() == EngineRunRequested
                           || state() == InferiorRunOk
                           || state() == InferiorStopOk, qDebug() << state());
                switch (state()) {
                case InferiorStopRequested:
                    EDEBUG("... CPP ENGINE STOPPED EXPECTEDLY");
                    notifyInferiorStopOk();
                    break;
                case EngineRunRequested:
                    EDEBUG("... CPP ENGINE STOPPED ON STARTUP");
                    notifyEngineRunAndInferiorStopOk();
                    break;
                case InferiorRunOk:
                    EDEBUG("... CPP ENGINE STOPPED SPONTANEOUSLY");
                    notifyInferiorSpontaneousStop();
                    break;
                case InferiorRunRequested:
                    // can happen if qml engine was active
                    notifyInferiorRunFailed();
                default:
                    break;
                }
            }
            break;
        }
        case InferiorStopFailed: {
            QTC_ASSERT(state() == InferiorStopRequested, qDebug() << state());
            notifyInferiorStopFailed();
            break;
        }
        case InferiorExitOk: {
            // InferiorExitOk will be called through notifyInferiorExited
            // when InferiorShutDownOk is reached
            qmlEngine()->quitDebugger();
            break;
        }
        case InferiorShutdownRequested: {
            // might be set by queueShutdownInferior() already
            QTC_ASSERT(state() == InferiorShutdownRequested
                       || state() == InferiorStopOk, qDebug() << state());
            if (state() == InferiorStopOk)
                setState(InferiorShutdownRequested);
            qmlEngine()->quitDebugger();
            break;
        }
        case InferiorShutdownFailed: {
            QTC_ASSERT(state() == InferiorShutdownRequested, qDebug() << state());
            notifyInferiorShutdownFailed();
            break;
        }
        case InferiorShutdownOk: {
            if (state() == InferiorShutdownRequested) {
                notifyInferiorShutdownOk();
            } else {
                // we got InferiorExitOk before, but ignored it ...
                notifyInferiorExited();
            }
            break;
        }
        case EngineShutdownRequested: {
            // set by queueShutdownEngine()
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            break;
        }
        case EngineShutdownFailed: {
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            notifyEngineShutdownFailed();
            break;
        }
        case EngineShutdownOk: {
            QTC_ASSERT(state() == EngineShutdownRequested, qDebug() << state());
            notifyEngineShutdownOk();
            break;
        }
        case DebuggerFinished: {
            // set by queueFinishDebugger()
            QTC_ASSERT(state() == DebuggerFinished, qDebug() << state());
            break;
        }
        }
    } else {
        // QML engine state change
        if (newState == InferiorStopOk) {
            if (isDying()) {
                EDEBUG("... QML ENGINE STOPPED DURING SHUTDOWN ");

                // Just to make sure, we're shutting down anyway ...
                setActiveEngine(m_cppEngine);

                if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
                // otherwise we're probably inside notifyInferiorStopOk already
            } else {
                if (m_activeEngine != qmlEngine()) {
                    showStatusMessage(tr("QML debugger activated"));
                    setActiveEngine(m_qmlEngine);
                }

                QTC_ASSERT(state() == InferiorRunOk
                           || state() == InferiorStopRequested
                           || state() == InferiorShutdownRequested, qDebug() << state());

                if (state() == InferiorRunOk)
                    notifyInferiorSpontaneousStop();
                else if (state() == InferiorStopRequested)
                    notifyInferiorStopOk();
            }

        } else if (newState == InferiorRunOk) {
            if (m_activeEngine == qmlEngine()) {
                QTC_ASSERT(state() == InferiorRunRequested, qDebug() << state());
                notifyInferiorRunOk();
            }
        }
    }
}
Example #7
0
void RegisterItem::triggerChange()
{
    QString value = "0x" + m_reg.value.toString(m_reg.kind, m_reg.size, HexadecimalFormat);
    DebuggerEngine *engine = static_cast<RegisterHandler *>(model())->engine();
    engine->setRegisterValue(m_reg.name, value);
}
Example #8
0
void RegisterItem::triggerChange()
{
    QByteArray ba = "0x" + m_reg.value.toByteArray(m_reg.kind, m_reg.size, HexadecimalFormat);
    DebuggerEngine *engine = static_cast<RegisterHandler *>(model())->engine();
    engine->setRegisterValue(m_reg.name, QString::fromLatin1(ba));
}