2012-01-05 8 views
12

Attualmente sto implementando l'ultima attività per un piccolo framework di debug, ovvero HW Breakpoints. Ho fatto riferimento a questo articolo finora: http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx e un libro sulla scrittura di un debugger.Hardwarebreakpoint WINAPI

Ho seguito due funzioni finora per l'impostazione di un punto di interruzione HW:

void debuglib::breakpoints::hw_bp() { 
    HANDLE helper = 0; 

    CONTEXT co; 
    CURRENTCONTEXT(co); 

    helper = ::CreateThread(0,0,threadfunc,reinterpret_cast<void*>(co.Eip),0,0); 

    DWORD status = ::WaitForSingleObject(helper,INFINITE); 


    if (status != WAIT_OBJECT_0) { 
      ::MessageBoxA(0, "Helper thread didn't exit cleanly", "HWBreakpoint", MB_OK); 
    } 

    ::CloseHandle(helper); 
} 

static DWORD WINAPI debuglib::breakpoints::threadfunc(void* param) { 

    DWORD suspendcnt = ::SuspendThread(debuglib::process::thread()); 
    if(suspendcnt) { 
     return 0; 
    } 

    CONTEXT co; 
    ::ZeroMemory(&co,sizeof(co)); 
    co.ContextFlags = CONTEXT_DEBUG_REGISTERS; 

    BOOL ok = ::GetThreadContext(debuglib::process::thread(),&co); 

    if(!ok) { 
     return 0; 
    } 

    DWORD freeDr = 0; 
    DWORD condition = debuglib::breakpoints::TRIGGER::CODE; 
    DWORD length = debuglib::breakpoints::SIZE::SIZE_1; 

    co.Dr0 = reinterpret_cast<DWORD>(param); 

    co.Dr7 = co.Dr7 | 1 << (freeDr*2); 
    co.Dr7 = co.Dr7 | condition << ((freeDr*4)+16); 
    co.Dr7 = co.Dr7 | length << ((freeDr*4)+18); 

    co.ContextFlags = CONTEXT_DEBUG_REGISTERS; 
    ok = ::SetThreadContext(debuglib::process::thread(), &co); 

    co.ContextFlags = CONTEXT_DEBUG_REGISTERS; 
    ::GetThreadContext(debuglib::process::thread(),&co); 

    suspendcnt = ::ResumeThread(debuglib::process::thread()); 
    if(suspendcnt == 0xFFFFFFFF) { 
     return 0; 
    } 

    return 1; 
} 

Quindi, prima Sto creando un filo di supporto in quanto sto debug del thread corrente. All'interno della funzione di callback del thread di supporto, sospendo il thread principale. In seguito leggo gli attuali valori di DR del thread principale (al momento questo non è rilevante, dato che io uso sempre DR0, dopo che questo funziona, controllerò quali registri sono liberi e userò fino a 4 BP). Successivamente ho usato l'indirizzo di ritorno della funzione chiamante (EIP) come indirizzo per entrare in DR0 e impostare i flag di appartenenza in DR7.

Alla fine riprendo il filo principale e chiudendo la maniglia del filo di supporto, come è finito.

Con questo codice mi sono seguente problema:

Se eseguo il programma in modalità debug dei programmi interrotto per all'indirizzo giusto, ma non posso fare più niente, dal momento che la bandiera INT1 è impostato Credo e il VS il debugger non può eseguire un singolo passo avanti?

Se eseguo il programma senza eseguire il debug, si verifica un arresto anomalo. Ho provato a usare __try, __eccetto come nel progetto menzionato (http://www.codeproject.com/KB/debug/hardwarebreakpoint.aspx) ma questo non funziona neanche.

Apprezzo e aiuto o informazioni quello che sto facendo male e come risolvere questo problema.

+0

Potresti dirmi qual è il nome del libro che stai utilizzando? Sono anche interessato allo sviluppo di un debugger hw. –

+2

Si chiama "Hacking con Python" ma è scritto in tedesco (http://www.amazon.de/Hacking-mit-Python-Fehlersuche-Programmanalyse/dp/3898646335/ref=sr_1_1?ie=UTF8&qid= 1325766641 & sr = 8-1). – Chris

+0

Grazie, cercherò di trovare qualcosa in inglese dallo stesso autore. –

risposta

1

Non penso che sia una buona idea provare a eseguire un debug di programma. Perché non utilizzare l'API di sviluppo del debugger integrata in Windows?

Dev Center - Desktop> Scopri> Riferimento> Diagnostica> Debug e gestione degli errori> base Debug> Debug Riferimento> Funzioni di debug: http://msdn.microsoft.com/en-us/library/windows/desktop/ms679303%28v=vs.85%29.aspx

su hardware x86, single-stepping è abilitata impostando il flag trappola EFlag. La CPU genererà un'eccezione breakpoint dopo aver completato un'istruzione. Quello che penso stia accadendo è che il debugger di Visual Studio sta cambiando quel bit delle bandiere, interferendo con quello che stai cercando di fare.

Prova a eseguire il programma all'esterno di Visual Studio (senza debugger). Funziona come previsto allora?

Problemi correlati