Debugger. Debugger működése. Megszakítás és nyomkövetés. Izsó Tamás október 31. Izsó Tamás Debugger működése/ 1

Hasonló dokumentumok
Interrupt kezelés Debugger. Debugger működése. Megszakítás és nyomkövetés. Izsó Tamás szeptember 19. Izsó Tamás Debugger működése/ 1

Operációs rendszerek. Az Executive és a kernel Policy és mechanizmusok szeparálása Executive: policy - objektum kezelés Kernel: mechanizmusok:

Operációs rendszerek. Az NT folyamatok kezelése

Biztonságos programozás Puffer túlcsordulásos támadások

Konkurens TCP Szerver

Pénzügyi algoritmusok

Stack Vezérlés szerkezet Adat 2.

Mechatronika és mikroszámítógépek 2017/2018 I. félév. Bevezetés a C nyelvbe

Pénzügyi algoritmusok

Bevezetés Kiíratás Beolvasás Formázás Fájlkezelés Gyakorló feladatok C++ I/O. Bevezetés. Izsó Tamás február 20. Izsó Tamás C++ I/O / 1

Programozási nyelvek JAVA EA+GY 1. gyakolat

Informatika terméktervezőknek

Szoftvertechnológia alapjai Java előadások

Fordító részei. Fordító részei. Kód visszafejtés. Izsó Tamás szeptember 29. Izsó Tamás Fordító részei / 1

Tartalomjegyzék. Általános Információ! 2. Felhasználói dokumentáció! 3. Feladat! 3. Környezet! 3. Használat! 3. Bemenet! 3. Példa!

Mintavételes szabályozás mikrovezérlő segítségével

ISA szimulátor objektum-orientált modell (C++)

Programzás I gyakorlat

Haladó DBMS ismeretek 1

Programozás C++ -ban 2007/7

A programozás alapjai

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós február 18. Széchenyi István Egyetem, Gy r

Digitális rendszerek. Utasításarchitektúra szintje

Programozási nyelvek (ADA)

Digitális technika VIMIAA01 9. hét Fehér Béla BME MIT

Digitális technika VIMIAA01 9. hét

PE/COFF fájl formátum

Bevezetés a programozásba I.

3D-s technológiák a játékfejlesztésben UDK bevezetés

Szerző. Varga Péter ETR azonosító: VAPQAAI.ELTE cím: Név: Kurzuskód:

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

Kivételek kezelése (exception handling) Hibakezelés old style. Kivételkezelés

A C# programozási nyelv alapjai

Programozás II. 2. Dr. Iványi Péter

Bevezetés a programozásba I.

Járműfedélzeti rendszerek II. 2. előadás Dr. Bécsi Tamás

Operációs rendszerek. Folyamatok kezelése a UNIX-ban

A TURBO DEBUGGER HASZNÁLATA

Algoritmizálás + kódolás C++ nyelven és Pascalban

Programozás C nyelven (3. ELŐADÁS) Sapientia EMTE

5. Gyakorlat. struct diak {

Máté: Assembly programozás

Az SQL*Plus használata

Programozás Minta programterv a 1. házi feladathoz 1.

Algoritmizálás és adatmodellezés tanítása 1. előadás

Programozás BMEKOKAA146. Dr. Bécsi Tamás 1. Előadás

Felhasználó által definiált adattípus

Operációs rendszerek III.

Operációs rendszerek Folyamatok 1.1

Maximum kiválasztás tömbben

Programozási alapismeretek beadandó feladat: ProgAlap beadandó feladatok téma 99. feladat 1

BASH script programozás II. Vezérlési szerkezetek

Vizuális, eseményvezérelt programozás XI.

.NET (Dot-NET) #1 (Bevezetés)

Biztonságos programozás Puffer túlcsordulásos támadások

A 32 bites x86-os architektúra regiszterei

Programozás II. ATM példa Dr. Iványi Péter

Clang Static Analyzer belülről

Matlab alapok. Baran Ágnes. Baran Ágnes Matlab alapok Elágazások, függvények 1 / 15

OOP #14 (referencia-elv)

Számítógépek felépítése

találhatók. A memória-szervezési modell mondja meg azt, hogy miként

M-Fájlok létrehozása MATLAB-ban

Programozási nyelvek II. JAVA EA+GY 1. gyakolat

Szkriptnyelvek. 1. UNIX shell

Számítástechnika I. BMEKOKAA152 BMEKOKAA119 Infokommunikáció I. BMEKOKAA606. Dr. Bécsi Tamás

Vé V g é r g e r h e a h j a tá t s á i s s z s ál á ak a Runnable, Thread

Programozási nyelv Java

Programozási alapismeretek 2009/2010

Programozás C és C++ -ban

Vezérlési szerkezetek

Szoftvertervezés és -fejlesztés I.

Irvine eljárások. ClrScr - Törli a képernyő tartalmát és a kurzort a képernyő bal felső sarkába helyezi (Clear Screen).

Imperatív programozás

George Shepherd. 1. A webes alkalmazások alapjai 1

16F628A megszakítás kezelése

SQL*Plus. Felhasználók: SYS: rendszergazda SCOTT: demonstrációs adatbázis, táblái: EMP (dolgozó), DEPT (osztály) "közönséges" felhasználók

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Az interrupt Benesóczky Zoltán 2004

Adabáziselérés ODBC-n keresztül utasításokkal C#-ban

LabVIEW példák és bemutatók KÉSZÍTETTE: DR. FÜVESI VIKTOR

Powershell 2. gyakorlat

Programozási technológia I.

A ChipScope logikai analizátor

Programozás BMEKOKAA146. Dr. Bécsi Tamás 3. előadás

C# nyelv alapjai. Krizsán Zoltán 1. Objektumorientált programozás C# alapokon tananyag. Általános Informatikai Tanszék Miskolci Egyetem

Programozás 6. Dr. Iványi Péter

Kivételkezelés a C++ nyelvben Bevezetés

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

A szerzõrõl... xi Bevezetés... xiii

HORVÁTH ZSÓFIA 1. Beadandó feladat (HOZSAAI.ELTE) ápr 7. 8-as csoport

Architektúra, megszakítási rendszerek

A Code::Blocks fejlesztőkörnyezet

Processzusok (Processes), Szálak (Threads), Kommunikáció (IPC, Inter-Process Communication)

C programozási nyelv

Számítástechnika II. BMEKOKAA Előadás. Dr. Bécsi Tamás

Operációs rendszerek gyak.

C++ programozási nyelv Konstruktorok-destruktorok

Programozási alapismeretek :: beadandó feladat. Felhasználói dokumentáció. Molnár Tamás MOTIABT.ELTE

1. feladat. Szabóné Nacsa Rozália

Átírás:

Debugger működése Megszakítás és nyomkövetés. Izsó Tamás 2013. október 31. Izsó Tamás Debugger működése/ 1

Section 1 Debugger Izsó Tamás Debugger működése/ 2

Debugger felépítése Proccess indítás nyomkövetéssel. Nyomkövető ciklus létrehozása. STARTUPINFO s i ; PROCESS_INFORMATION p i ; ZeroMemory ( &si, sizeof ( s i ) ) ; s i. cb = sizeof ( s i ) ; ZeroMemory ( &pi, sizeof ( p i ) ) ; CreateProcess ( ProcessNameToDebug, NULL, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, & p i ) ; Izsó Tamás Debugger működése/ 3

Definíciók és követelmények 1 Debugger az a processz amely egy másik processzt monitoroz. 2 Debuggolt program a nyomkövetett program. 3 Debuggolt program csak egy debugger-hez lehet hozzárendelve. 4 Egy debugger több processzt is nyomkövethet. 5 A processz indítása és a processz debuggolására alkalmas ciklus ugyanabban a processzben kell hogy legyen. Izsó Tamás Debugger működése/ 4

Debug ciklus DEBUG_EVENT debug_event = { 0 } ; for ( ; ; ) { i f (! WaitForDebugEvent (& debug_event, INFINITE ) ) return ; / / User-defined function, not API ProcessDebugEvent (& debug_event ) ; } ContinueDebugEvent ( debug_event. dwprocessid, debug_event. dwthreadid, DBG_CONTINUE ) ; DBG_CONTINUE folytatjuk a nyomkövetést. DBG_EXCEPTION_NOT_HANDLED valami hiba volt és feladjuk. Izsó Tamás Debugger működése/ 5

Nyomkövetési esemény rekordja struct DEBUG_EVENT { DWORD dwdebugeventcode ; DWORD dwprocessid ; DWORD dwthreadid ; union { EXCEPTION_DEBUG_INFO Exception ; CREATE_THREAD_DEBUG_INFO CreateThread ; CREATE_PROCESS_DEBUG_INFO CreateProcessInfo ; EXIT_THREAD_DEBUG_INFO ExitThread ; EXIT_PROCESS_DEBUG_INFO ExitProcess ; LOAD_DLL_DEBUG_INFO Loa ddll ; UNLOAD_DLL_DEBUG_INFO UnloadDll ; OUTPUT_DEBUG_STRING_INFO DebugString ; RIP_INFO R i p I n f o ; } u ; } ; Izsó Tamás Debugger működése/ 6

Debug ciklus kicsit részletesebben bool bcontinuedebugging = t r u e ; while ( bcontinuedebugging ) { i f (! WaitForDebugEvent (& debug_event, INFINITE ) ) return ; switch ( debug_event. dwdebugeventcode ) { case CREATE_PROCESS_DEBUG_EVENT:... break ; case CREATE_THREAD_DEBUG_EVENT:... break ; case EXIT_THREAD_DEBUG_EVENT:... break ; case EXIT_PROCESS_DEBUG_EVENT:... break ; case LOAD_DLL_DEBUG_EVENT:... break ; case UNLOAD_DLL_DEBUG_EVENT:... break ; case OUTPUT_DEBUG_STRING_EVENT:... break ; case EXCEPTION_DEBUG_EVENT: }... } EXCEPTION_DEBUG_INFO& exception = debug_event. u. Exception ;... break ; Izsó Tamás Debugger működése/ 7

CREATE_PROCESS_DEBUG_EVENT esemény Ez az esemény a nyomkövetett program betöltése után a futás előtt következik be. Itt lehet megadni a breakpoint-ot. s t r u c t CREATE_PROCESS_DEBUG_INFO { HANDLE h F i l e ; / / (.EXE) file handle HANDLE hprocess ; / / process handle HANDLE hthread ; / / első thread handle LPVOID lpbaseofimage ; 1 DWORD dwdebuginfofileoffset ; DWORD ndebuginfosize ; LPVOID lpthreadlocalbase ; LPTHREAD_START_ROUTINE lpstartaddress ; 2 LPVOID lpimagename ; 3 WORD funicode ; / / fájlnév kódolása } ; 1 A memóriába betöltött exe fájl kezdőcíme. 2 Első végrehajtandó utasítás címe. 3 Program nevének a címe a debuggolt program címterében. Izsó Tamás Debugger működése/ 8

CREATE_PROCESS_DEBUG_EVENT esemény használata Ez az esemény a nyomkövetett program betöltése után a futás előtt következik be. Itt lehet megadni a breakpoint-ot. case CREATE_PROCESS_DEBUG_EVENT: { char filename = GetFileNameFromHandle ( debug_event. u. CreateProcessInfo. h F i l e ) ; } ; A betöltött végrehajtható fájl nevét nem a lpimagename alapján, hanem a hozzá tartozó fájl handler alapján a GetFileNameFromHandle függvény segítségével állítjuk elő. A függvény leírását az MSDN-en Obtaining a File Name From a File Handle címmel találhatjuk meg. Kb 10 rendszerhívást tartalmaz, ami számunkra most nem izgalmas. Izsó Tamás Debugger működése/ 9

OUTPUT_DEBUG_STRING_EVENT esemény Ez az esemény akkor következik be, ha a nyomkövetett programban diagnosztikai üzeneteket írunk ki a OutputDebugString rendszerhívás segítségével. Ezeket az üzeneteket a debugger kapja meg. struct OUTPUT_DEBUG_STRING_INFO { LPSTR lpdebugstringdata ; / / char* WORD funicode ; WORD ndebugstringlength ; } ; Izsó Tamás Debugger működése/ 10

OUTPUT_DEBUG_STRING_EVENT esemény case OUTPUT_DEBUG_STRING_EVENT: { char msg ; 1 OUTPUT_DEBUG_STRING_INFO & DebugString = debug_event. u. DebugString ; msg=new char [ DebugString. ndebugstringlength + 1 ] ; } ReadProcessMemory ( p i. hprocess, 2 DebugString. lpdebugstringdata, 3 msg, 4 DebugString. ndebugstringlength, NULL ) ; p r i n t f ( " Debug i n f o : %s \ n ", msg ) ; d e l e t e [ ] msg ; 1 Nem Unicode-ot használunk. 2 Debuggolt processz handle-t a processz indításánál kaptuk meg. 3 Üzenet címe a debuggolt program címterében. 4 Üzenet másolata a debugger címterében. Izsó Tamás Debugger működése/ 11

EXIT_PROCESS_DEBUG_INFO esemény Nyomkövetett program befejeződésénél jelentkező esemény. st ru ct EXIT_PROCESS_DEBUG_INFO { DWORD dwexitcode ; } ; Használata: bool bcontinuedebugging= t r u e ;... case EXIT_PROCESS_DEBUG_EVENT: { p r i n t f ( " Process e x i t e d with code : 0x%x ", debug_event. u. ExitProcess. dwexitcode ) ; bcontinuedebugging= f a l s e ; } break ; Izsó Tamás Debugger működése/ 12

(LOAD/ UNLOAD)_DLL_DEBUG_EVENT esemény A DLL betöltéséhez kapcsolódó információk azonosak a processz betöltésénél tanult információkkal. struct LOAD_DLL_DEBUG_INFO { HANDLE h F i l e ; / / (.DLL) file handle LPVOID lpbaseofdll ; 1 DWORD dwdebuginfofileoffset ; DWORD ndebuginfosize ; LPVOID lpimagename ; WORD funicode ; } ; 1 Dll betöltési címe a debuggolt processz szemszögéből. struct UNLOAD_DLL_DEBUG_INFO { LPVOID lpbaseofdll ; } ; Izsó Tamás Debugger működése/ 13

DLL-ek nyomkövetése Debugger std : : map<lpvoid, std : : s t r i n g > DllNameMap ; case LOAD_DLL_DEBUG_EVENT: { s t r i n g name = GetFileNameFromHandle ( debug_event. u. LoadDll. h F i l e ) ; DllNameMap [ debug_event. u. LoadDll. lpbaseofdll ] =name ; cout << " Load DLL " << name << " " << std : : hex << debug_event. u. LoadDll. lpbaseofdll << std : : endl ; } break ; case UNLOAD_DLL_DEBUG_EVENT: cout << " Unload DLL " << DllNameMap [ debug_event. u. UnloadDll. lpbaseofdll ] << std : : endl ; break ; Izsó Tamás Debugger működése/ 14

EXCEPTION_DEBUG_EVENT esemény Azokat az eseményeket kapjuk itt el, amit az előző fejezetben a struktúrált kivétel kezelésnél (SEH) tárgyaltunk. struct EXCEPTION_DEBUG_INFO { EXCEPTION_RECORD ExceptionRecord ; DWORD dwfirstchance ; } ; struct EXCEPTION_RECORD { DWORD ExceptionCode ; DWORD ExceptionFlags ; s t r u c t _EXCEPTION_RECORD ExceptionRecord ; PVOID ExceptionAddress ; DWORD NumberParameters ; ULONG_PTR ExceptionInformation [EXCEPTION_MAXIMUM_PARAMETERS ] ; } ; Izsó Tamás Debugger működése/ 15

EXCEPTION_DEBUG_EVENT esemény case EXCEPTION_DEBUG_EVENT: { EXCEPTION_DEBUG_INFO& exception = debug_event. u. Exception ; switch ( exception. ExceptionRecord. ExceptionCode ) { case STATUS_BREAKPOINT: p r i n t f ( " Break p o i n t " ; ) dwcontinuestatus = DBG_CONTINUE; break ; } default : i f ( exception. dwfirstchance == 1) { p r i n t f ( " Addr : %x code : %d " exception. ExceptionRecord. ExceptionAddress, exception. ExceptionRecord. ExceptionCode ) ; } dwcontinuestatus = DBG_EXCEPTION_NOT_HANDLED; } break ; Izsó Tamás Debugger működése/ 16

Hogyan írjuk meg a debuggert A CREATE_PROCESS_DEBUG_EVENT esemény az a pont, ahol a debugger bele tud szólni a debuggolt program életébe 1 Határozzuk meg azt a memória címet, ahol meg akarjuk nézni a debuggolt processz állapotát. De hol van ez a pont? 2 Módosítsuk az adott helyen lévő utasítást, például tegyünk oda breakpoint-ot ( int 3 vagy 0xCC értékű gépi utasítás). 3 Futtassuk tovább a programot. 4 Kezeljuk le a breakpoint eseményt. 5 Állítsuk vissza az eredeti utasítást, amit a breakpoint-tal felülírtunk. 6 Írjuk ki a memória és regiszterek értékeit, vagy egyéb adatokat, amelyre a felhasználó kiváncsi. 7 Folytassuk a nyomkövetést. Izsó Tamás Debugger működése/ 17

Hogyan módosíthatjuk a debuggolt processzt 1 Mentsük el a felülírandó utasítás első byte-ját. 2 Írjuk felül a breakpoint 0xCC utasítással. 3 Frissítsük az utasítás cache-t (gyorsítótárat). DWORD startaddress = GetStartAddress ( p i. hprocess, p i. hthread ) ; BYTE i n s t r u c t i o n ; DWORD nbyte ; / / Debuggolt processz utasításkódjának olvasása / / Utasítás első byte-jának olvasása ReadProcessMemory ( p i. hprocess, ( void ) startaddress,& i n s t r u c t i o n,1,& nbyte ) ; / / Eredeti érték elmentése o r i g i n a l I n s t r u c t i o n = i n s t r u c t i o n ; / / Utasítás felülírása i n s t r u c t i o n = 0xCC ; WriteProcessMemory ( p i. hprocess, ( void ) startaddress, &i n s t r u c t i o n,1,& nbyte ) ; FlushInstructionCache ( pi, ( void ) startaddress, 1 ) ; Izsó Tamás Debugger működése/ 18

Hogyan folytassuk a programot 1 Állítsuk vissza az eredeti utasítást. 2 Frissítsük az utasítás cache-t (gyorsítótárat). 3 Adjuk rá a visszaállított utasításra a vezérlést. DWORD nbyte ; WriteProcessMemory ( p i. hprocess, startaddress,& o r i g i n a l I n s t r u c t i o n,1,& nbyte ) ; FlushInstructionCache ( p i. hprocess, startaddress, 1 ) ; / / Debuggolt processz állapotának (regisztereinek) olvasása CONTEXT context ; context. ContextFlags = CONTEXT_ALL; GetThreadContext ( p i. hthread, &context ) ; / / Eredeti érték elmentése context. Eip ; / / Visszalépés eggyel SetThreadContext ( p i. hthread, &context ) ; Gondoljuk át mi van, ha a program újból ráfut a startaddress-en lévő utasításra. Észreveszi ezt a debugger? Izsó Tamás Debugger működése/ 19

Lépésenkénti futtatás Debugger Az EXCEPTION_SINGLE_STEP kivétel elkapásával megoldható a probléma..... CONTEXT context ; context. ContextFlags = CONTEXT_ALL; GetThreadContext ( p i. hthread, &context ) ; / / Eredeti érték elmentése context. Eip ; / / Visszalépés eggyel context. EFlags = 0x100 ; / / Trap flag SetThreadContext ( p i. hthread, &context ) ; Az EXCEPTION_SINGLE_STEP bekövetkezése után visszaírhatjuk a breakpoint-ot Izsó Tamás Debugger működése/ 20

Nyomkövetési szolgáltatások biztosítása Hogyan valósítható meg a lépésenkénti nyomkövetés, hívott függvénybe történő visszalépés, adott sorig (kurzorig) tört futtatás, feltételes breakpoint? Izsó Tamás Debugger működése/ 21

Nyomkövetési szolgáltatások biztosítása Hogyan valósítható meg a lépésenkénti nyomkövetés, hívott függvénybe történő visszalépés, adott sorig (kurzorig) tört futtatás, feltételes breakpoint? Segítség: EXCEPTION_SINGLE_STEP felhasználásával Láthatatlan breakpoint-ok (debugger a felhasználó tudta nélkül definiálja) létesítésével és felszedésével. Izsó Tamás Debugger működése/ 21

Demo Debugger cd E:\Reverse.Uj\Debug\example1\Debug\ example1.exe debugger.exe breakpoint.exe Mit tapasztalunk, ha a breakpoint programot debugger alatt futtatjuk? Hol használható fel ez a tapasztalat? Izsó Tamás Debugger működése/ 22

Mi az amit még nem tudunk? 1 Stackframe követését. Mivel a stackframe szervezést később vesszük, ezt itt nem tárgyaljuk. 2 Szimbolikus információk és forrássorok megjelenítését. 3 Disassemblert készíteni. (Nem kell, forrásban elérhető pár megoldás. Pl. PIN-ben). Minden fordító saját formában létrehoz nyomkövetéshez szolgáló információkat. Mik ezek? Szimbolikus változó és függvényneveket, forrásfájlok neve, keresztreferenciát annak eldöntésére, hogy melyik gépi utasítás melyik sor alapján keletkezett, stb. A Visual Studio ezeket az információkat a.pdb fájlban tárolja. Ennek a fájlnak a kezelését szolgáló függvények a DbgHelp.DLL-ben vannak megvalósítva. Izsó Tamás Debugger működése/ 23

Milyen területeket érintett az előadás Számítógép Architektúrák (cache, virtuális memória, interrupt kezelés, gépi utasítások, regiszterek) Operációs rendszerek (Windows rendszerhívások) Fordítók kódgenerálása (kivételkezelés megvalósítása, debugger információk) Izsó Tamás Debugger működése/ 24

Irodalom Debugger Matt Pietrek, A Crash Course on the Depths of Win32 Structured Exception Handling http://www.microsoft. com/msj/0197/exception/exception.aspx Ajay Vijayvargiya, Writing a basic Windows debugger http://www.codeproject.com/articles/43682/ Writing-a-basic-Windows-debugger Vishal Kochhar, How a C++ compiler implements exception handling, http://www.codeproject.com/articles/2126/ How-a-C-compiler-implements-exception-handling Eli Bendersky, How debuggers work, http://eli.thegreenplace.net/2011/01/23/ how-debuggers-work-part-1// Izsó Tamás Debugger működése/ 25