- Messaggi
- 2,332
- Reazioni
- 1,928
- Punteggio
- 134
Windows kernel debugging: debuggare Windows
In un precedente articolo sulla traduzione degli indirizzi virtuali in indirizzi fisici, ho riportato alcun output dove si vedevano informazioni su registri (come CR3), strutture interne, e altro ancora. Ho pensato di fare un passo indietro e riportare anche i passaggi per avere un ambiente sul quale è possibile effettuare il debugging.
1 - Introduzione
Debuggare il kernel (o un driver) non è come debuggare un'applicazione utente. Quando si debugga un'applicazione utente utilizzando un debugger (GCC, OllyDbg, ImmunityDebugger, Windbg,...) il sistema continua ad eseguire le sue operazioni, solo l'applicazione in questione verrà interrotta; la stessa cosa non avviene quando si attacca un debugger a Windows. Collegando un debugger il sistema viene immediatamente freezato, non sarà più possibile eseguire alcuna operazione fintanto che non si comunichi tramite il debugger di riprendere l'esecuzione.
Per questo motivo il kernel debugging non si esegue sul medesimo OS. Ci sono tre alternative:
- utilizzare un altro computer fisico
- utilizzare una VM
- utilizzare LiveKD
Deciso questo, ora ci si trova di fronte a un'altra scelta:
- debuggare tramite porta COM
- debuggare usando la rete
2 - Strumenti
~ Virtual Machine ~
La prima cosa che dovrete decidere è quale VM utilizzare. Io ho scelto VMWare Player in quanto è gratuito e fa bene il suo lavoro (inoltre mi trovo comodo); allo scopo penso che un'alternativa valga l'altra. Tuttavia non so quali configurazioni saranno necessarie sulle altre VM, quindi dovrete cercare in rete.~ Windows 10 ISO ~
La seconda cosa importante a questo punto è procurarsi Windows 10. Sino a qualche mese fa era disponibile un'immagine da importare per ciascuna VM più utilizzata (VMWare, VirtualBox, Hyper-V), ma sfortunatamente... trovrete solo Windows 11. Quindi vi consiglio di scaricare la ISO direttamente dal Media Creation Tool. Prestate attenzione all'architettura: io darò per scontato che host e target saranno Windows 10 x64.~ Windows Debugging ~
A questo punto scaricate l'SDK dal sito Microsoft, Windows 10 SDK, e avviate l'applicazione. Vi troverete di fronte ad una schermata analoga:dovrete deselezionare tutto, lasciando la spunta solo sulla voce Debugging Tools for Windows.
~ Debugger ~
Io ho scelto WinDbg Preview, lo trovere sullo store Microsoft. E' in sostanza una GUI su Windbg.3 - Avviamo il target (VM)
A questo punto avrete scaricato la VM con Win 10 x64. Riservatele quante risorse volete. Nella tab dedicata alla rete (Network), va benissimo quello che dovreste avere di default, ovvero:
Una volta avviata la VM è necessario abilitare il debug. Avviate il prompt dei comandi come amministratore e digitate:
Codice:
bcdedit /debug on
fatto questo dovrete riavviare la VM. Se non lo avete fatto, installate anche i Tools di VMWare, vi saranno utili (per il copy & paste, specialmente).
Per essere sicuri che host e target comunichino, aprite il terminale sull'host e digitate
ipconfig
. Nel mio caso ho questo output:
Codice:
Configurazione IP di Windows
Scheda Ethernet vEthernet (Default Switch):
Suffisso DNS specifico per connessione:
Indirizzo IPv6 locale rispetto al collegamento . : fe80::d9fe:ed04:a53d:3c42%32
Indirizzo IPv4. . . . . . . . . . . . : 172.24.128.1
Subnet mask . . . . . . . . . . . . . : 255.255.240.0
Gateway predefinito . . . . . . . . . :
Scheda Ethernet Ethernet 2:
Stato supporto. . . . . . . . . . . . : Supporto disconnesso
Suffisso DNS specifico per connessione: fritz.box
Scheda LAN wireless Connessione alla rete locale (LAN)* 1:
Stato supporto. . . . . . . . . . . . : Supporto disconnesso
Suffisso DNS specifico per connessione:
Scheda LAN wireless Connessione alla rete locale (LAN)* 10:
Stato supporto. . . . . . . . . . . . : Supporto disconnesso
Suffisso DNS specifico per connessione:
Scheda Ethernet VMware Network Adapter VMnet1:
Suffisso DNS specifico per connessione:
Indirizzo IPv6 locale rispetto al collegamento . : fe80::59c4:d251:c7e8:e2f4%8
Indirizzo IPv4. . . . . . . . . . . . : 192.168.74.1
Subnet mask . . . . . . . . . . . . . : 255.255.255.0
Gateway predefinito . . . . . . . . . :
Scheda Ethernet VMware Network Adapter VMnet8:
Suffisso DNS specifico per connessione:
Indirizzo IPv6 locale rispetto al collegamento . : fe80::9a3:7317:1038:dc61%6
Indirizzo IPv4. . . . . . . . . . . . : 192.168.21.1
Subnet mask . . . . . . . . . . . . . : 255.255.255.0
Gateway predefinito . . . . . . . . . :
Scheda LAN wireless Wi-Fi:
Suffisso DNS specifico per connessione:
Indirizzo IPv6 . . . . . . . . . . . . . . . . . : fde7:ea6f:4237:0:700c:da42:4003:3b70
Indirizzo IPv6 temporaneo. . . . . . . . . . . . : fde7:ea6f:4237:0:acb6:fa49:4afe:2bf2
Indirizzo IPv6 locale rispetto al collegamento . : fe80::700c:da42:4003:3b70%19
Indirizzo IPv4. . . . . . . . . . . . : 192.168.1.129
Subnet mask . . . . . . . . . . . . . : 255.255.255.0
Gateway predefinito . . . . . . . . . : 192.168.1.1
Scheda Ethernet vEthernet (WSL):
Suffisso DNS specifico per connessione:
Indirizzo IPv6 locale rispetto al collegamento . : fe80::249f:31f4:b1fe:13f6%50
Indirizzo IPv4. . . . . . . . . . . . : 172.26.32.1
Subnet mask . . . . . . . . . . . . . : 255.255.240.0
Voi avrete probabilmente meno interfacce, ma dipende ad esempio se avete abilitato WSL oppure no etc etc.
L'IP che dovrete annotare è quello alla voce Ethernet VMWare Network Adapter, nel mio caso:
192.168.74.1
.Andate sulla VM, aprite un prompt come amministratori e digitate:
Codice:
ping -4 <vostro-ip>
se i pacchetti raggiungeranno il destinatario, allora la comunicazione tra host e target è stabilita.
Ora tornate sull'host e recatevi nella cartella in cui avete installato i tools per il debugging. Il percorso dovrebbe essere questo:
Codice:
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
dovrete copiare 2 files, chiamati VerifiedNICList.xml e kdnet.exe, e incollarli sul desktop della VM (o dove preferite).
Se non avete più una finestra del prompt aperta da amministratore (sulla VM), è il momento di aprirla. Andate nella cartella in cui avete incollato kdnet e lanciatelo passandogli l'IP visto in precedenza, e una porta [50000, 50039].
Di seguito vedrete il mio input, e l'output di kdnet:
Codice:
C:\Users\DispatchCode\Desktop>kdnet 192.168.74.1 50010
Enabling network debugging on Intel(R) 82574L Gigabit Network Connection.
To debug this machine, run the following command on your debugger host machine.
windbg -k net:port=50010,key=27vh8lqc6awhx.303bt4zycitsc.1duw3o5kopk8o.21cwx8lsfqdi2
Then reboot this machine by running shutdown -r -t 0 from this command prompt.
Qui l'output dà per scontato che utilizziamo windbg, mai in realtà nel nostro caso - nel mio almeno - abbiamo Windbg Preview. Annotatevi il suo output per intero (incollatelo ad esempio su notepad, sull'host).
4 - Connessione tramite debugger
A questo punto ci siamo. Aprite il debugger e riportate le informazioni; sotto il mio screen:
Premete OK. Nella finestra di output sul debugger dovreste vedere qualcosa di analogo:
Codice:
Microsoft (R) Windows Debugger Version 10.0.22549.1000 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Using NET for debugging
Opened WinSock 2.0
Waiting to reconnect...
Connected to target 192.168.1.129 on port 50005 on local IP 192.168.1.129.
You can get the target MAC address by running .kdtargetmac command.
Connected to Windows 10 19041 x64 target at (Sat Apr 30 18:10:16.792 2022 (UTC + 2:00)), ptr64 TRUE
Kernel Debugger connection established.
************* Path validation summary **************
Response Time (ms) Location
Deferred SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 10 Kernel Version 19041 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Kernel base = 0xfffff807`4ec00000 PsLoadedModuleList = 0xfffff807`4f82a270
Debug session time: Sat Apr 30 18:10:16.866 2022 (UTC + 2:00)
System Uptime: 0 days 0:01:18.402
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
* *
* You are seeing this message because you pressed either *
* CTRL+C (if you run console kernel debugger) or, *
* CTRL+BREAK (if you run GUI kernel debugger), *
* on your debugger machine's keyboard. *
* *
* THIS IS NOT A BUG OR A SYSTEM CRASH *
* *
* If you did not intend to break into the debugger, press the "g" key, then *
* press the "Enter" key now. This message might immediately reappear. If it *
* does, press "g" and "Enter" again. *
* *
*******************************************************************************
nt!DbgBreakPointWithStatus:
fffff807`4efff050 cc int 3
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\atlmfc.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\ObjectiveC.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\concurrency.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\cpp_rest.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\Kernel.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\stl.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\Windows.Data.Json.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\Windows.Devices.Geolocation.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\Windows.Devices.Sensors.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\Windows.Media.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\windows.natvis'
NatVis script unloaded from 'C:\Program Files\WindowsApps\Microsoft.WinDbg_1.2202.7001.0_neutral__8wekyb3d8bbwe\amd64\Visualizers\winrt.natvis'
Microsoft (R) Windows Debugger Version 10.0.22549.1000 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
Using NET for debugging
Opened WinSock 2.0
Waiting to reconnect...
a questo punto, sul terminale che avrete ancora aperto sulla VM, lanciate
shutdown -r -t 0
.Una volta riavviato l'OS target, il debugger inizierà a segnalarvi la connessione:
Codice:
Connected to target 192.168.74.1 on port 50010 on local IP 192.168.74.1.
You can get the target MAC address by running .kdtargetmac command.
Connected to Windows 10 19041 x64 target at (Sat Apr 30 19:32:15.489 2022 (UTC + 2:00)), ptr64 TRUE
Kernel Debugger connection established.
************* Path validation summary **************
Response Time (ms) Location
Deferred SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
Symbol search path is: SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
Executable search path is:
Windows 10 Kernel Version 19041 MP (1 procs) Free x64
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Machine Name:
Kernel base = 0xfffff802`3e800000 PsLoadedModuleList = 0xfffff802`3f42a230
System Uptime: 0 days 0:00:00.961
minio\security\base\lsa\security\driver\asyncsspi.cxx - SspiInitAsyncInterface
IOINIT: Built-in driver \Driver\hwpolicy failed to initialize with status - 0xC000025E
KDTARGET: Refreshing KD connection
DimpHidAddDevice: Failed to open device \\?\HID#VID_0E0F&PID_0003&MI_00#8&367bfb7c&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (err=5).
DimpHidAddDevice: Failed to open device \\?\HID#VID_0E0F&PID_0003&MI_01#8&12a4bdba&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030} (err=5).
DispBroker.Desktop.dll: 04/30/22 19:32:30 W. Europe Daylight Time: SessionHandlerBase::EvaluateTargets found new target
Concerning target: Id=0x0, Adapter=9bd8 connected to {NOEDID_15AD_0405_00000000_000F0000_0}
DfsDs RPC server started.
StartUI.SplitViewFrame
Arrivati a questo punto, vedrete nella casella di input dei comandi (
0: kd>
) la scritta "Debugger is running...". Dal menu in alto premete Break:
Codice:
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
* *
* You are seeing this message because you pressed either *
* CTRL+C (if you run console kernel debugger) or, *
* CTRL+BREAK (if you run GUI kernel debugger), *
* on your debugger machine's keyboard. *
* *
* THIS IS NOT A BUG OR A SYSTEM CRASH *
* *
* If you did not intend to break into the debugger, press the "g" key, then *
* press the "Enter" key now. This message might immediately reappear. If it *
* does, press "g" and "Enter" again. *
* *
*******************************************************************************
nt!DbgBreakPointWithStatus:
fffff802`3ebff740 cc int 3
nell'output vedrete questo.
5 - Kernel debugging
Prima di iniziare, clickate su File > Settings e inserite nel campo di testo "Symbol Path" il percorso
SRV*c:\Symbols*http://msdl.microsoft.com/download/symbols
, poi premete Ok; create sull'host la cartella Symbols in C:\
. Potete scegliere anche un altro percorso, l'importante è che modifichiate di conseguenza il percorso inserito in windbg.A questo punto come input al debugger date
.reload /f
. Questo forzerà il reload dei simboli; i simboli consentono di vedere i nomi delle funzioni e contengono altre informazioni.Tutto il necessario è installato. Ora iniziamo a giocare: premete Go, lasciando continuare l'esecuzione. Andate sul target e aprite Notepad, poi tornate sul debugger, e premete Break; noterete tutto freezato sul target. Andiamo a cercare Notepad tra i processi in esecuzione (lanciato senza il nome dell'immagine verranno mostrati tutti i processi):
Codice:
!process 0 0 Notepad.exe
nel mio caso:
Codice:
PROCESS ffffc8033c98e080
SessionId: 1 Cid: 21bc Peb: 41c271c000 ParentCid: 1230
DirBase: 11c4a9002 ObjectTable: ffffdd8edf3e8d00 HandleCount: 244.
Image: notepad.exe
la struttura che rappresenta un processo in Windows si chiama EPROCESS; potete vedere i campi che la compongono con
dt nt!_EPROCESS
e potete vedere quella che rappresenta il processo in questione con dt nt!_EPROCESS ffffc8033c98e080
(l'indirizzo è preso dall'output sopra).Bene, a questo punto, andiamo a guardare anche l'header di questa immagine, per farlo ci serve l'image base address; dall'output precedente, clickate su PEB. A questo punto vedrete un campo chiamato ImageBaseAddress: copiatene l'indirizzo.
Codice:
0: kd> !dh 00007ff7105f0000
File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
8664 machine (X64)
7 number of sections
4178AED3 time date stamp Fri Oct 22 08:55:15 2004
0 file pointer to symbol table
0 number of symbols
F0 size of optional header
22 characteristics
Executable
App can handle >2gb addresses
OPTIONAL HEADER VALUES
20B magic #
14.20 linker version
24A00 size of code
E000 size of initialized data
0 size of uninitialized data
24050 address of entry point
1000 base of code
----- new -----
00007ff7105f0000 image base
1000 section alignment
200 file alignment
2 subsystem (Windows GUI)
10.00 operating system version
10.00 image version
10.00 subsystem version
38000 size of image
400 size of headers
37B81 checksum
0000000000080000 size of stack reserve
0000000000011000 size of stack commit
0000000000100000 size of heap reserve
0000000000001000 size of heap commit
C160 DLL characteristics
High entropy VA supported
Dynamic base
NX compatible
Guard
Terminal server aware
0 [ 0] address [size] of Export Directory
2D0A8 [ 244] address [size] of Import Directory
36000 [ BD8] address [size] of Resource Directory
33000 [ 10EC] address [size] of Exception Directory
0 [ 0] address [size] of Security Directory
37000 [ 2D4] address [size] of Base Relocation Directory
2AC20 [ 54] address [size] of Debug Directory
0 [ 0] address [size] of Description Directory
0 [ 0] address [size] of Special Directory
0 [ 0] address [size] of Thread Storage Directory
266D0 [ 118] address [size] of Load Configuration Directory
0 [ 0] address [size] of Bound Import Directory
267E8 [ 900] address [size] of Import Address Table Directory
2C9C0 [ E0] address [size] of Delay Import Directory
0 [ 0] address [size] of COR20 Header Directory
0 [ 0] address [size] of Reserved Directory
SECTION HEADER #1
.text name
2490F virtual size
1000 virtual address
24A00 size of raw data
400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
60000020 flags
Code
(no align specified)
Execute Read
SECTION HEADER #2
.rdata name
9268 virtual size
26000 virtual address
9400 size of raw data
24E00 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
(no align specified)
Read Only
Debug Directories(3)
Type Size Address Pointer
cv 24 2b4e4 2a2e4 Format: RSDS, guid, 1, notepad.pdb
( 13) 43c 2b508 2a308
( 16) 24 2b944 2a744
SECTION HEADER #3
.data name
2738 virtual size
30000 virtual address
E00 size of raw data
2E200 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
(no align specified)
Read Write
SECTION HEADER #4
.pdata name
10EC virtual size
33000 virtual address
1200 size of raw data
2F000 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
(no align specified)
Read Only
SECTION HEADER #5
.didat name
178 virtual size
35000 virtual address
200 size of raw data
30200 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
C0000040 flags
Initialized Data
(no align specified)
Read Write
SECTION HEADER #6
.rsrc name
BD8 virtual size
36000 virtual address
C00 size of raw data
30400 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
40000040 flags
Initialized Data
(no align specified)
Read Only
SECTION HEADER #7
.reloc name
2D4 virtual size
37000 virtual address
400 size of raw data
31000 file pointer to raw data
0 file pointer to relocation table
0 file pointer to line numbers
0 number of relocations
0 number of line numbers
42000040 flags
Initialized Data
Discardable
(no align specified)
Read Only
Un altro esempio, visualizzare la Interrupt Dispatch Table:
Codice:
0: kd> !idt
Dumping IDT: fffff8073a862000
00: fffff80737812100 nt!KiDivideErrorFaultShadow
01: fffff80737812180 nt!KiDebugTrapOrFaultShadow Stack = 0xFFFFF8073A8669D0
02: fffff80737812240 nt!KiNmiInterruptShadow Stack = 0xFFFFF8073A8667D0
03: fffff807378122c0 nt!KiBreakpointTrapShadow
04: fffff80737812340 nt!KiOverflowTrapShadow
05: fffff807378123c0 nt!KiBoundFaultShadow
06: fffff80737812440 nt!KiInvalidOpcodeFaultShadow
07: fffff807378124c0 nt!KiNpxNotAvailableFaultShadow
08: fffff80737812540 nt!KiDoubleFaultAbortShadow Stack = 0xFFFFF8073A8663D0
09: fffff807378125c0 nt!KiNpxSegmentOverrunAbortShadow
0a: fffff80737812640 nt!KiInvalidTssFaultShadow
0b: fffff807378126c0 nt!KiSegmentNotPresentFaultShadow
0c: fffff80737812740 nt!KiStackFaultShadow
0d: fffff807378127c0 nt!KiGeneralProtectionFaultShadow
0e: fffff80737812840 nt!KiPageFaultShadow
10: fffff807378128c0 nt!KiFloatingErrorFaultShadow
11: fffff80737812940 nt!KiAlignmentFaultShadow
12: fffff807378129c0 nt!KiMcheckAbortShadow Stack = 0xFFFFF8073A8665D0
13: fffff80737812ac0 nt!KiXmmExceptionShadow
14: fffff80737812b40 nt!KiVirtualizationExceptionShadow
15: fffff80737812bc0 nt!KiControlProtectionFaultShadow
1f: fffff80737812c40 nt!KiApcInterruptShadow
20: fffff80737812cc0 nt!KiSwInterruptShadow
29: fffff80737812d40 nt!KiRaiseSecurityCheckFailureShadow
2c: fffff80737812dc0 nt!KiRaiseAssertionShadow
2d: fffff80737812e40 nt!KiDebugServiceTrapShadow
2f: fffff80737812f40 nt!KiDpcInterruptShadow
30: fffff80737812fc0 nt!KiHvInterruptShadow
31: fffff80737813040 nt!KiVmbusInterrupt0Shadow
32: fffff807378130c0 nt!KiVmbusInterrupt1Shadow
33: fffff80737813140 nt!KiVmbusInterrupt2Shadow
34: fffff807378131c0 nt!KiVmbusInterrupt3Shadow
35: fffff80737813468 nt!HalpInterruptCmciService (KINTERRUPT fffff80737af2f40)
36: fffff80737813470 nt!HalpInterruptCmciService (KINTERRUPT fffff80737af3180)
50: fffff80737813540 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0b3c0)
51: fffff80737813548 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0b500)
52: fffff80737813550 stornvme!NVMeHwMSIInterrupt (STORPORT) (KINTERRUPT ffff89017f53aa00)
53: fffff80737813558 HDAudBus!HdaController::Isr (KINTERRUPT ffff89017ef64b40)
60: fffff807378135c0 serial!SerialCIsrSw (KINTERRUPT ffff89017f53a8c0)
61: fffff807378135c8 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0b640)
62: fffff807378135d0 stornvme!NVMeHwMSIInterrupt (STORPORT) (KINTERRUPT ffff89017f53ab40)
63: fffff807378135d8 USBPORT!USBPORT_InterruptService (KINTERRUPT ffff89017f53a3c0)
dxgkrnl!DpiFdoLineInterruptRoutine (KINTERRUPT ffff89017ef64a00)
70: fffff80737813640 i8042prt!I8042MouseInterruptService (KINTERRUPT ffff89017f53a640)
71: fffff80737813648 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0b780)
72: fffff80737813650 storahci!AhciHwMSIInterrupt (STORPORT) (KINTERRUPT ffff89017f53ac80)
73: fffff80737813658 USBXHCI!Interrupter_WdfEvtInterruptIsr (KMDF) (KINTERRUPT ffff89017ef64c80)
80: fffff807378136c0 i8042prt!I8042KeyboardInterruptService (KINTERRUPT ffff89017f53a780)
81: fffff807378136c8 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0b8c0
82: fffff807378136d0 vmci!DllInitialize+0x1c10 (KINTERRUPT ffff89017ef0b140)
83: fffff807378136d8 USBXHCI!Interrupter_WdfEvtInterruptIsr (KMDF) (KINTERRUPT ffff89017ef64dc0)
91: fffff80737813748 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0ba00)
92: fffff80737813750 vmci!DllInitialize+0x1c10 (KINTERRUPT ffff89017ef0b280)
93: fffff80737813758 USBXHCI!Interrupter_WdfEvtInterruptIsr (KMDF) (KINTERRUPT ffff89017f53a000)
a1: fffff807378137c8 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0bb40)
a2: fffff807378137d0 ataport!IdePortInterrupt (KINTERRUPT ffff89017f53adc0)
a3: fffff807378137d8 USBXHCI!Interrupter_WdfEvtInterruptIsr (KMDF) (KINTERRUPT ffff89017f53a140)
b0: fffff80737813840 ACPI!ACPIInterruptServiceRoutine (KINTERRUPT ffff89017ef0bdc0)
b1: fffff80737813848 pci!ExpressRootPortMessageRoutine (KINTERRUPT ffff89017ef0bc80)
b2: fffff80737813850 ataport!IdePortInterrupt (KINTERRUPT ffff89017ef0b000)
b3: fffff80737813858 USBXHCI!Interrupter_WdfEvtInterruptIsr (KMDF) (KINTERRUPT ffff89017f53a280)
b4: fffff80737813860 USBPORT!USBPORT_InterruptService (KINTERRUPT ffff89017f53a500)
ce: fffff80737813930 nt!HalpIommuInterruptRoutine (KINTERRUPT fffff80737af3ba0)
d1: fffff80737813948 nt!HalpTimerClockInterrupt (KINTERRUPT fffff80737af3960)
d2: fffff80737813950 nt!HalpTimerClockIpiRoutine (KINTERRUPT fffff80737af3840)
d7: fffff80737813978 nt!HalpInterruptRebootService (KINTERRUPT fffff80737af3600)
d8: fffff80737813980 nt!HalpInterruptStubService (KINTERRUPT fffff80737af33c0)
df: fffff807378139b8 nt!HalpInterruptSpuriousService (KINTERRUPT fffff80737af32a0)
e1: fffff80737813240 nt!KiIpiInterruptShadow
e2: fffff807378139d0 nt!HalpInterruptLocalErrorService (KINTERRUPT fffff80737af34e0)
e3: fffff807378139d8 nt!HalpInterruptDeferredRecoveryService (KINTERRUPT fffff80737af3060)
fd: fffff80737813aa8 nt!HalpTimerProfileInterrupt (KINTERRUPT fffff80737af3a80)
fe: fffff80737813ab0 nt!HalpPerfInterrupt (KINTERRUPT fffff80737af3720)
Questa tabella viene utilizzata per la gestione di eccezioni, interrupt software e interrupt hardware. Il puntatore alla struttura base è mantenuto in un registro chiamato
idt
, che possiamo ovviamente leggere:
Codice:
0: kd> r @idtr
idtr=fffff8073a862000
Ho preso come esempio l'interrupt della tastiera (i8042prt); come nel caso dei processi, è possibile guardare questa struttura (KINTERRUPT):
Codice:
0: kd> dt nt!_KINTERRUPT ffff89017f53a780
+0x000 Type : 0n22
+0x002 Size : 0n288
+0x008 InterruptListEntry : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
+0x018 ServiceRoutine : 0xfffff807`3c586790 unsigned char i8042prt!I8042KeyboardInterruptService+0
+0x020 MessageServiceRoutine : (null)
+0x028 MessageIndex : 0
+0x030 ServiceContext : 0xffffb388`4ccd7780 Void
+0x038 SpinLock : 0
+0x040 TickCount : 0
+0x048 ActualLock : 0xffffb388`4ccd78e0 -> 0
+0x050 DispatchAddress : 0xfffff807`371f9360 void nt!KiInterruptDispatch+0
+0x058 Vector : 0x80
+0x05c Irql : 0x8 ''
+0x05d SynchronizeIrql : 0x8 ''
+0x05e FloatingSave : 0 ''
+0x05f Connected : 0x1 ''
+0x060 Number : 0
+0x064 ShareVector : 0 ''
+0x065 EmulateActiveBoth : 0 ''
+0x066 ActiveCount : 0
+0x068 InternalState : 0n0
+0x06c Mode : 1 ( Latched )
+0x070 Polarity : 0 ( InterruptPolarityUnknown )
+0x074 ServiceCount : 0
+0x078 DispatchCount : 0
+0x080 PassiveEvent : (null)
+0x088 TrapFrame : 0xffff810e`a75a1b00 _KTRAP_FRAME
+0x090 DisconnectData : (null)
+0x098 ServiceThread : (null)
+0x0a0 ConnectionData : 0xffffb388`4cd52d60 _INTERRUPT_CONNECTION_DATA
+0x0a8 IntTrackEntry : 0xffffb388`4cd1b920 Void
+0x0b0 IsrDpcStats : _ISRDPCSTATS
+0x110 RedirectObject : (null)
+0x118 PhysicalDeviceObject : (null)
Possiamo anche fare riferimento a una singola entry della tabella (ho considerato sempre la tastiera, che si trova all'indice 0x80):
Codice:
0: kd> dt @idtr + @@c++(0x80 * sizeof(nt!_KIDTENTRY64)) nt!_KIDTENTRY64
+0x000 OffsetLow : 0x36c0
+0x002 Selector : 0x10
+0x004 IstIndex : 0y000
+0x004 Reserved0 : 0y00000 (0)
+0x004 Type : 0y01110 (0xe)
+0x004 Dpl : 0y00
+0x004 Present : 0y1
+0x006 OffsetMiddle : 0x3781
+0x008 OffsetHigh : 0xfffff807
+0x00c Reserved1 : 0
+0x000 Alignment : 0x37818e00`001036c0
L'indirizzo che verrà invocato si compone dei 3 indici Low, Middle e Hight 0xfffff807378136c0; disassemblando il codice a quell'indirizzo, si trova:
Codice:
0: kd> u 0xfffff807378136c0
nt!KiIsrThunkShadow+0x400:
fffff807`378136c0 6a80 push 0FFFFFFFFFFFFFF80h
fffff807`378136c2 e939040000 jmp nt!KxIsrLinkageShadow (fffff807`37813b00)
fffff807`378136c7 cc int 3
fffff807`378136c8 6a81 push 0FFFFFFFFFFFFFF81h
fffff807`378136ca e931040000 jmp nt!KxIsrLinkageShadow (fffff807`37813b00)
fffff807`378136cf cc int 3
fffff807`378136d0 6a82 push 0FFFFFFFFFFFFFF82h
fffff807`378136d2 e929040000 jmp nt!KxIsrLinkageShadow (fffff807`37813b00)
la presenza di questa funzione chiamata Shadow, è dovuta al fix di Meltdown (KVA Shadow mitigating meltdown on Windows).
6 - Conclusione
In conclusione vi lascio alcuni link, in primis la debugger reference, che contiene i vari comandi per interagire con windbg più tante altre info.
Come seconda, altre due risorsee:
- il primo, più soft, è un mio intervento avvenuto qui sul forum: Come vengono realizzate le System Call?
- gli altri due sono in inglese, e sono davvero ben curati Interrupt Dispatching e Windows Kernel, che tratta anche le system call e la IDT (e faccio notare che lavora in Offensive Security)