Archive for August, 2009

Reading Notebook: 31-August-09

Monday, August 31st, 2009

Coming back to reading after holidays

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

Per session objects \Sessions\n\BaseNamedObjects (p. 158)

OpenXXX / CreateXXX race condition: solution CreateXXXEx (p. 159)

Most objects are temporary (p. 159) - I got an idea for a bugtation “Most bugs are permanent”

Name retention by handle access vs. reference retention by pointer access (pp. 159 - 160) - most objects have a few references but some are referenced a lot:

0: kd> !handle

[...]

002c: Object: fffffa80047db0d0  GrantedAccess: 000f01ff Entry: fffff880078c70b0
Object: fffffa80047db0d0  Type: (fffffa8003c0bdc0) Desktop
    ObjectHeader: fffffa80047db0a0 (old version)
        HandleCount: 61  PointerCount: 7534
        Directory Object: 00000000  Name: Default

[...]

Deferred object delete operation (p. 160)

Resource accounting (pp. 161 - 162) - it would be nice to have an example here using object header structures

Name squatting (p. 164)

Private namespaces in Vista, CreatePrivateNamespace for user apps, solution to name squatting attacks (p. 164)

CheckForOtherInstanceMutex (p. 166) - Windows API legacy: search for a window with the same class can be used for single instancing

Sound Mixer in Vista/W2k8 (p. 166) - this is the great feature I didn’t know about

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 18-August-09

Tuesday, August 18th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

Using Process Explorer diff. highlighting to see handle leaks (p. 151)

Similarity of handle tables to virtual-2-physical mapping tables on x86 (pp. 151 - 152) - Seems the theoretical handle limit value for x86 is 512 * 512 * 511 = 133,955,584 (if I didn’t miss anything)

Testlimit tool (pp. 152 - 153) - I try it for my book Software Defect Construction: Simulation and Modeling of Software Bugs (ISBN: 978-1906717759) and also for later crash dump analysis volumes

!devhandles WinDbg command, searching for open files (p. 155) - it looks like it is done through device prefix to a file name; I’ve done simple text search for a file name if known through all handle tables: http://www.dumpanalysis.org/blog/index.php/2008/05/30/who-opened-that-file/

!obtrace monitors more than !htrace (p. 156)

nt!_OBJECT_TYPE.Key is pool tag, needed to enable object reference tracing (p. 157)

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 17-August-09

Monday, August 17th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

TpWorkerFactory (thread pools), TmRm, TmTx, TmTm, TmEn executive objects (p. 137)

Object structure (p. 138) - I created a simplified UML diagram when I was investigating object signaling: http://www.dumpanalysis.org/blog/index.php/2008/03/06/signaled-objects/. Here’s another example of how to get an object header from the dispatcher address a thread is waiting for:

THREAD fffffa800579f060  Cid 0ee8.113c  Teb: 000000007ef9b000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
     fffffa800538bc10  ProcessObject
Not impersonating
DeviceMap                 fffff88006972f30
Owning Process            fffffa8005ad1c10       Image:         WINWORD.EXE
Attached Process          N/A            Image:         N/A
Wait Start TickCount      29919495       Ticks: 4883905 (0:21:09:49.406)
Context Switch Count      3           Â
UserTime                  00:00:00.000
KernelTime                00:00:00.000
Win32 Start Address 0×0000000073433619
Stack Init fffffa6004bc8db0 Current fffffa6004bc8940
Base fffffa6004bc9000 Limit fffffa6004bc3000 Call 0
Priority 10 BasePriority 8 PriorityDecrement 2 IoPriority 2 PagePriority 5
Kernel stack not resident.
Child-SP          RetAddr           Call Site
fffffa60`04bc8980 fffff800`0186d28a nt!KiSwapContext+0×7f
fffffa60`04bc8ac0 fffff800`0186e68a nt!KiSwapThread+0×2fa
fffffa60`04bc8b30 fffff800`01ae2368 nt!KeWaitForSingleObject+0×2da
fffffa60`04bc8bc0 fffff800`018670f3 nt!NtWaitForSingleObject+0×98
fffffa60`04bc8c20 00000000`75ec3d09 nt!KiSystemServiceCopyEnd+0×13 (TrapFrame @ fffffa60`04bc8c20)
00000000`049deec8 00000000`00000000 0×75ec3d09

0: kd> dt _DISPATCHER_HEADER fffffa800538bc10
nt!_DISPATCHER_HEADER
   +0×000 Type             : 0×3 ”
   +0×001 Abandoned        : 0 ”
   +0×001 Absolute         : 0 ”
   +0×001 NpxIrql          : 0 ”
   +0×001 Signalling       : 0 ”
   +0×002 Size             : 0×30 ‘0′
   +0×002 Hand             : 0×30 ‘0′
   +0×003 Inserted         : 0 ”
   +0×003 DebugActive      : 0 ”
   +0×003 DpcActive        : 0 ”
   +0×000 Lock             : 3145731
   +0×004 SignalState      : 0
   +0×008 WaitListHead     : _LIST_ENTRY [ 0xfffffa80`04ca25f8 - 0xfffffa80`0566bca8 ]

0: kd> dt _OBJECT_HEADER
nt!_OBJECT_HEADER
   +0x000 PointerCount     : Int8B
   +0x008 HandleCount      : Int8B
   +0x008 NextToFree       : Ptr64 Void
   +0x010 Type             : Ptr64 _OBJECT_TYPE
   +0x018 NameInfoOffset   : UChar
   +0x019 HandleInfoOffset : UChar
   +0x01a QuotaInfoOffset  : UChar
   +0x01b Flags            : UChar
   +0x020 ObjectCreateInfo : Ptr64 _OBJECT_CREATE_INFORMATION
   +0x020 QuotaBlockCharged : Ptr64 Void
   +0x028 SecurityDescriptor : Ptr64 Void
   +0×030 Body             : _QUAD

0: kd> dt _OBJECT_HEADER fffffa800538bc10-30
nt!_OBJECT_HEADER
   +0×000 PointerCount     : 55
   +0×008 HandleCount      : 5
   +0×008 NextToFree       : 0×00000000`00000005
   +0×010 Type             : 0xfffffa80`03bcd840 _OBJECT_TYPE
   +0×018 NameInfoOffset   : 0 ”
   +0×019 HandleInfoOffset : 0 ”
   +0×01a QuotaInfoOffset  : 0 ”
   +0×01b Flags            : 0×20 ‘ ‘
   +0×020 ObjectCreateInfo : 0xfffffa80`0489c010 _OBJECT_CREATE_INFORMATION
   +0×020 QuotaBlockCharged : 0xfffffa80`0489c010
   +0×028 SecurityDescriptor : 0xfffff880`06d9825b
   +0×030 Body             : _QUAD

Here is another example of how to get the name of an object if it exists (38 is the size of x64 _OBJECT_HEADER, _QUAD is 8 bytes):

0: kd> dt _OBJECT_HEADER fffffa80047da830
nt!_OBJECT_HEADER
   +0×000 PointerCount     : 175
   +0×008 HandleCount      : 116
   +0×008 NextToFree       : 0×00000000`00000074
   +0×010 Type             : 0xfffffa80`03c0b080 _OBJECT_TYPE
   +0×018 NameInfoOffset   : 0×20 ‘ ‘
   +0×019 HandleInfoOffset : 0×30 ‘0′
   +0×01a QuotaInfoOffset  : 0 ”
   +0×01b Flags            : 0×20 ‘ ‘
   +0×020 ObjectCreateInfo : 0xfffff800`01990fa0 _OBJECT_CREATE_INFORMATION
   +0×020 QuotaBlockCharged : 0xfffff800`01990fa0
   +0×028 SecurityDescriptor : 0xfffff880`0678a6fc
   +0×030 Body             : _QUAD

0: kd> dt _UNICODE_STRING fffffa80047da830-38+20
nt!_UNICODE_STRING
 “WinSta0″
   +0×000 Length           : 0xe
   +0×002 MaximumLength    : 0xe
   +0×008 Buffer           : 0xfffff880`00969660  “WinSta0″

Pointer count >= Handle count (p. 139)

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 12-August-09

Wednesday, August 12th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

int 2e is still available for legacy calls (p. 126)

rdmsr WinDbg command (p. 126)

Zw… as fake interrupts (p. 129) - here is another view (remember that there are ntdll!Nt… and nt!Nt… functions): http://www.dumpanalysis.org/blog/index.php/2007/04/10/yet-another-look-at-zw-and-nt-functions/

KiServiceTable entries on x64 (p. 132)

WinObj (pp. 133 - 134) - I also use !object WinDbg command to navigate the tree: 

0: kd> !object \
Object: fffff88000005d50  Type: (fffffa8003bacdc0) Directory
    ObjectHeader: fffff88000005d20 (old version)
    HandleCount: 0  PointerCount: 49
    Directory Object: 00000000  Name: \

    Hash Address          Type          Name
    ---- -------          ----          ----
     01  fffff88000005420 Directory     ObjectTypes
     03  fffffa8004bcd320 Event         NETLOGON_SERVICE_STARTED
     05  fffff88000952910 SymbolicLink  SystemRoot
     06  fffff880000e7900 Directory     Sessions
     07  fffffa8004b4d2b0 ALPC Port     MmcssApiPort
     08  fffffa8004839750 Event         DSYSDBG.Debug.Trace.Memory.270
         fffff880000138d0 Directory     ArcName
     09  fffff88000072bb0 Directory     NLS
         fffffa8004ce7cd0 ALPC Port     XactSrvLpcPort
     10  fffff880000079f0 Directory     GLOBAL??
         fffff880000e5ab0 Directory     Windows
         fffffa8004b80ee0 Event         LanmanServerAnnounceEvent
     11  fffff880000e7ab0 Directory     RPC Control
     13  fffffa80046bfd20 Event         EFSInitEvent
     14  fffffa8003eb5940 Device        clfs
         fffff88000962d20 SymbolicLink  Dfs
     15  fffffa8004690270 ALPC Port     SeRmCommandPort
         fffffa80047b3b00 Event         CsrSbSyncEvent
     16  fffff880000071c0 SymbolicLink  DosDevices
         fffffa80051ab8d0 Device        Cdfs
     17  fffff88000965b20 Directory     KnownDlls32
         fffffa8004c20060 ALPC Port     AELPort
         fffffa800487d620 Event         EFSSrvInitEvent
     18  fffff880000131e0 Key           \REGISTRY
         fffffa8004ca0a60 ALPC Port     WindowsErrorReportingServicePort
     19  fffff880061859f0 Directory     BaseNamedObjects
     21  fffff880000735c0 Directory     UMDFCommunicationPorts
         fffffa8004a67900 ALPC Port     SmSsWinStationApiPort
         fffffa8004251840 Event         UniqueInteractiveSessionIdEvent
     22  fffff88006117200 Directory     KnownDlls
         fffffa80054c6c80 Device        FatCdrom
         fffffa8005597b00 Device        Fat
     23  fffff8800008d2f0 Directory     FileSystem
         fffff88000005a20 Directory     KernelObjects
         fffffa8004059ad0 Device        Ntfs
     26  fffff88000005870 Directory     Callback
         fffffa800482fd90 ALPC Port     SeLsaCommandPort
     28  fffff88000009850 Directory     Security
     29  fffffa8004aeaa90 ALPC Port     UxSmsApiPort
     30  fffff880000135a0 Directory     Device
         fffffa80048776c0 Event         EFSSmbInitEvent
     32  fffffa8004876060 ALPC Port     LsaAuthenticationPort
     34  fffffa80046bf060 ALPC Port     SmApiPort
         fffff880066b2b00 Section       LsaPerformance
         fffffa80047aa840 Event         UniqueSessionIdEvent
     36  fffff8800008d4a0 Directory     Driver
         fffffa8004879eb0 Event         SAM_SERVICE_STARTED

0: kd> !object \Driver
Object: fffff8800008d4a0  Type: (fffffa8003bacdc0) Directory
    ObjectHeader: fffff8800008d470 (old version)
    HandleCount: 0  PointerCount: 76
    Directory Object: fffff88000005d50  Name: Driver

    Hash Address          Type          Name
    ---- -------          ----          ----
     01  fffffa800468e440 Driver        NetBT
         fffffa8004317ba0 Driver        PptpMiniport
         fffffa80042b49e0 Driver        usbuhci
         fffffa8003d64b90 Driver        Wdf01000
     02  fffffa8005532700 Driver        MYFAULT
         fffffa8004b82e70 Driver        mpsdrv
     03  fffffa800407f740 Driver        disk
         fffffa8004afe900 Driver        lltdio
         fffffa8004693ab0 Driver        PSched
         fffffa800453fc80 Driver        NDProxy
     04  fffffa8004c00e70 Driver        HTTP
     06  fffffa80042b02c0 Driver        usbehci
         fffffa80042a6a60 Driver        tunnel
     07  fffffa8003eba7c0 Driver        partmgr
     08  fffffa8004c50940 Driver        PEAUTH
         fffffa800430ee10 Driver        iScsiPrt
         fffffa80042d7dd0 Driver        b57nd60a
         fffffa8003c116f0 Driver        ACPI_HAL
     09  fffffa8004675e70 Driver        RDPENCDD
         fffffa800407e060 Driver        spldr
     10  fffffa800430ce10 Driver        Rasl2tp
         fffffa80040392c0 Driver        storflt
         fffffa8004269ad0 Driver        HidUsb
     11  fffffa8004dc5c00 Driver        AsyncMac
         fffffa8003bad7f0 Driver        PnpManager
     12  fffffa8004673610 Driver        Null
         fffffa800431f7e0 Driver        rdpdr
     14  fffffa80042dbbf0 Driver        Serenum
         fffffa8003ef27b0 Driver        CLFS
     15  fffffa80042f3d50 Driver        Serial
         fffffa80046729c0 Driver        RDPCDD
         fffffa8003ee97b0 Driver        KSecDD
         fffffa8003ebc7c0 Driver        volmgr
     16  fffffa8004333a30 Driver        umbus
         fffffa80040eb490 Driver        crcdisk
     17  fffffa80047b0e00 Driver        Win32k
     18  fffffa8004329730 Driver        mouclass
         fffffa80046894d0 Driver        Smb
     19  fffffa8003f47db0 Driver        msisadrv
     20  fffffa8004321510 Driver        kbdclass
     21  fffffa800407de70 Driver        volsnap
         fffffa800479ca60 Driver        mouhid
     22  fffffa80046c3550 Driver        nsiproxy
         fffffa8004673420 Driver        VgaSave
         fffffa8003bbfe70 Driver        WMIxWDM
     23  fffffa8003fab360 Driver        Wanarpv6
         fffffa8004678060 Driver        tdx
         fffffa8004671730 Driver        RasAcd
         fffffa800431d820 Driver        RasSstp
     25  fffffa8004319e70 Driver        RasPppoe
         fffffa80042b69c0 Driver        HDAudBus
     26  fffffa8004c68a00 Driver        secdrv
     27  fffffa80042dfe70 Driver        Parport
         fffffa800426a240 Driver        kbdhid
     28  fffffa8004b00a30 Driver        rspndr
         fffffa8004328a10 Driver        TermDD
     29  fffffa80046586a0 Driver        HdAudAddService
         fffffa8003f79710 Driver        pci
         fffffa800432c7d0 Driver        mssmbios
         fffffa8003eb87c0 Driver        volmgrx
     30  fffffa80042db370 Driver        cdrom
         fffffa8003ee3750 Driver        NDIS
     31  fffffa800432b420 Driver        swenum
     32  fffffa800433de70 Driver        usbhub
         fffffa8003f272a0 Driver        Tcpip
     33  fffffa80042aabc0 Driver        intelppm
         fffffa8003ec18f0 Driver        atapi
     34  fffffa800468d7c0 Driver        AFD
         fffffa800430a710 Driver        NdisTapi
         fffffa8003ec1e70 Driver        mountmgr
         fffffa8003ebee70 Driver        intelide
     35  fffffa8004c84db0 Driver        tcpipreg
         fffffa800465a060 Driver        ksthunk
     36  fffffa8004311640 Driver        NdisWan
         fffffa8003d96060 Driver        ACPI

It might be interesting to signal these events manually and see what happens:

0: kd> !object \KernelObjects
Object: fffff88000005a20  Type: (fffffa8003bacdc0) Directory
    ObjectHeader: fffff880000059f0 (old version)
    HandleCount: 0  PointerCount: 18
    Directory Object: fffff88000005d50  Name: KernelObjects

    Hash Address          Type          Name
    ---- -------          ----          ----
     00  fffffa8003c0f920 Event         MemoryErrors
     02  fffffa8003bfc510 Event         LowNonPagedPoolCondition
     04  fffffa80047be6b0 Session       Session1
     05  fffffa8003bef740 Event         SuperfetchScenarioNotify
         fffffa8003bef7c0 Event         SuperfetchParametersChanged
     06  fffffa8003c0b4e0 Event         BootLoaderTraceReady
     12  fffffa8003c0fa20 Event         HighCommitCondition
     14  fffffa8003bfb590 Event         HighNonPagedPoolCondition
         fffffa8003bfd590 Event         HighMemoryCondition
     21  fffff88000009060 KeyedEvent    CritSecOutOfMemoryEvent
     23  fffffa8003c0f9a0 Event         MaximumCommitCondition
     25  fffffa8003bfb510 Event         LowCommitCondition
     26  fffffa8003bfc590 Event         HighPagedPoolCondition
     28  fffffa8003c0e5d0 Event         LowMemoryCondition
     32  fffffa8003bfd510 Event         LowPagedPoolCondition
         fffffa80047ac520 Session       Session0
     34  fffffa8003bef6c0 Event         PrefetchTracesReady

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 11-August-09

Tuesday, August 11th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

SEH for 64-bit (p. 116) - here is an example from x64 W2K8

0:000> kn
 # Child-SP          RetAddr           Call Site
00 00000000`0016f358 00000000`76d8679a ntdll!ZwReadFile+0xa
01 00000000`0016f360 000007fe`fdedfc9a kernel32!ReadFile+0×8a
02 00000000`0016f3f0 000007fe`fdedfa3b advapi32!ScGetPipeInput+0×3a
03 00000000`0016f440 000007fe`fdede00d advapi32!ScDispatcherLoop+0×9a
04 00000000`0016f540 00000000`ffa11dca advapi32!StartServiceCtrlDispatcherW+0×176
05 00000000`0016f7e0 00000000`ffa124b2 svchost!wmain+0×110
06 00000000`0016f810 00000000`76d8be3d svchost!ScCreateWellKnownSids+0×301
07 00000000`0016f850 00000000`76ec6a51 kernel32!BaseThreadInitThunk+0xd
08 00000000`0016f880 00000000`00000000 ntdll!RtlUserThreadStart+0×1d

0:000> !exchain
9 stack frames, scanning for handlers...
Frame 0×01: kernel32!ReadFile+0×8a (00000000`76d8679a)
  ehandler kernel32!_C_specific_handler (00000000`76d7dcbc)

Frame 0×04: advapi32!StartServiceCtrlDispatcherW+0×176 (000007fe`fdede00d)
  ehandler advapi32!_GSHandlerCheck_SEH (000007fe`fdf6ab88)

Frame 0×06: svchost!ScCreateWellKnownSids+0×301 (00000000`ffa124b2)
  ehandler svchost!_C_specific_handler (00000000`ffa13ea4)

Frame 0×08: ntdll!RtlUserThreadStart+0×1d (00000000`76ec6a51)
  ehandler ntdll!_C_specific_handler (00000000`76ed9518)

VEH is user-mode only (p. 116) - Here is an article from Matt Pietrek about vectored exception handling: http://msdn.microsoft.com/en-us/magazine/cc301714.aspx

Debug object (p. 116) - coincidentally, today I wrote a case study where we can see how an exception dispatcher sends a message: http://www.dumpanalysis.org/blog/index.php/2009/08/11/stack-trace-collection-suspended-threads-not-my-version-special-process-main-thread-and-blocked-lpc-chain-threads-pattern-cooperation/. Also here is another case study showing the flow of exception processing originated from user mode and space: http://www.dumpanalysis.org/blog/index.php/2007/12/07/interrupts-and-exceptions-explained-part-6/

First and second chance exception handling (p. 117) - some time ago I was interested in this mystery and wrote this post: http://www.dumpanalysis.org/blog/index.php/2008/05/22/demystifying-first-chance-exceptions-part-1/

Wercon.exe (p. 120)

WER processing overview (pp. 120 - 125) - some time ago when Vista appeared I did experiments with TestDefaultDebugger.exe (similar to Accvio.exe): http://www.dumpanalysis.org/blog/index.php/2007/05/19/inside-vista-error-reporting-part-1/ 

LocalDumps registry key values (p. 123)

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 10-August-09

Monday, August 10th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

message-based interrupts and IoConnectInterruptEx (p. 106) - if we look at API (http://msdn.microsoft.com/en-us/library/aa490464.aspx) and compare it with IoConnectInterrupt (http://msdn.microsoft.com/en-us/library/ms801597.aspx) we would see that it now accepts only one structure parameter and it is a union of various structures including FULLY_SPECIFIED that contains all previous parameters from IoConnectInterrupt

DPC objects (p. 107)

1: kd> dt _KDPC
nt!_KDPC
   +0x000 Type             : UChar
   +0x001 Importance       : UChar
   +0x002 Number           : Uint2B
   +0x008 DpcListEntry     : _LIST_ENTRY
   +0x018 DeferredRoutine  : Ptr64     void
   +0x020 DeferredContext  : Ptr64 Void
   +0x028 SystemArgument1  : Ptr64 Void
   +0x030 SystemArgument2  : Ptr64 Void
   +0x038 DpcData          : Ptr64 Void

Kernel processes DPCs when IRQL is about to drop below DPC level (p. 107)

Idle thread also processes DPCs (p. 108)  - here are some code fragments:

nt!KiIdleLoop+0x1b:
80545d57 mov     cl,2
80545d59 call    dword ptr [nt!_imp_HalClearSoftwareInterrupt (804d80b4)]
80545d5f call    nt!KiRetireDpcList (80545e1e)

nt!KiIdleLoop+0x31:
80545d6d mov     ecx,1Ch
80545d72 call    dword ptr [nt!_imp_KfRaiseIrql (804d802c)]
80545d78 sti
80545d79 lea     ecx,[ebx+540h]
80545d7f call    nt!KeAcquireQueuedSpinLockAtDpcLevel (80540a90)

80545d84 mov     esi,dword ptr [ebx+128h]
80545d8a mov     edi,dword ptr [ebx+124h]
80545d90 cmp     byte ptr [esi+50h],0
80545d94 jne     nt!KiIdleLoop+0×97 (80545dd3)

nt!KiIdleLoop+0x9d:
80545dd9 call    nt!KeReleaseQueuedSpinLockFromDpcLevel (80540abc)
80545dde mov     ecx,2
80545de3 call    dword ptr [nt!_imp_KfLowerIrql (804d8030)]

80545de9 lea     ebp,[ebx+980h]
80545def jmp     nt!KiIdleLoop+0×10 (80545d4c)

on x64 it looks like IRQL management is done via CR8 Task Priority Register:

1: kd> uf KfRaiseIrql
nt!KfRaiseIrql:
fffff800`018b00e0 mov     rax,cr8
fffff800`018b00e4 movzx   ecx,cl
fffff800`018b00e7 mov     cr8,rcx
fffff800`018b00eb ret

1: kd> uf KeLowerIrql
nt!KeLowerIrql:
fffff800`018b0110 movzx   eax,cl
fffff800`018b0113 mov     cr8,rax
fffff800`018b0117 ret

1: kd> uf KiIdleLoop

[...]

nt!KiIdleLoop+0x5a:
fffff800`01871e6a mov     rcx,rbx
fffff800`01871e6d call    nt!KiRetireDpcList (fffff800`01870bc0)

[...]

Threaded DPC - passive IRQL on a real-time thread (p. 110)

APC interrupts and objects (p. 112)

1: kd> dt _KAPC
nt!_KAPC
   +0x000 Type             : UChar
   +0x001 SpareByte0       : UChar
   +0x002 Size             : UChar
   +0x003 SpareByte1       : UChar
   +0x004 SpareLong0       : Uint4B
   +0x008 Thread           : Ptr64 _KTHREAD
   +0x010 ApcListEntry     : _LIST_ENTRY
   +0x020 KernelRoutine    : Ptr64     void
   +0x028 RundownRoutine   : Ptr64     void
   +0x030 NormalRoutine    : Ptr64     void
   +0x038 NormalContext    : Ptr64 Void
   +0x040 SystemArgument1  : Ptr64 Void
   +0x048 SystemArgument2  : Ptr64 Void
   +0x050 ApcStateIndex    : Char
   +0x051 ApcMode          : Char
   +0x052 Inserted         : UChar

DPC queue is system-wide, APC queue is thread-specific (p. 112)

kernel APC (special vs. normal (called by associated special)) and user APC (execute at passive level)  (pp. 112 - 113)

Guarded region (special and normal APC) vs. Critical region (normal APC) (p. 112)

POSIX signals are emulated by APC (p. 112)

Thread suspension, termination and APC (p. 112)  - see thread stack with ExitThread / PsExitSpecialApc in wait chain pattern case study: http://www.dumpanalysis.org/blog/index.php/2007/12/14/crash-dump-analysis-patterns-part-42a/

APC delivery reorders wait queues (p. 114)

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 06-August-09

Thursday, August 6th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

saved IRQL before breakin !irql (p. 95) - not available prior to W2K3

0: kd> !irql
nt!_KPRCB.DebuggerSavedIRQL not found, error : 0x4.
Saved IRQL not available prior to Windows Server 2003

passive IRQL for user-mode code (p. 96) - I can imagine thet user-space code can be at higher level IRQL when a function pointer is used to call a function from user space but that would be still kernel mode (not the distinction between mode and space here)

inter-processor interrupt (IPI) (p. 96)

kernrate uses profile IRQL level of real-time clock to record RIP (p. 97) - never used before, give it a try later

CMCI (correctible machine check interrupt) (p. 97)

explanation for IRQL_NOT_LESS_OR_EQUAL (pp. 100 - 101) - a few years ago I was pondering about this and created a UML sequence diagram to convince myself: http://www.dumpanalysis.org/blog/index.php/2007/03/06/bugchecks-depicted-irql_not_less_or_equal/

KiInterruptTemplate (p. 101)  - it seems saves the current thread state. On x64 W2K8 we get this disassembled code:

1: kd> u KiInterruptTemplate
nt!KiInterruptTemplate:
fffff800`01869270 push    rax
fffff800`01869271 push    rbp
fffff800`01869272 lea     rbp,[nt!KiInterruptDispatchNoEOI+0x250 (fffff800`018691e0)]
fffff800`01869279 jmp     qword ptr [rbp+50h]
fffff800`0186927c int     3
fffff800`0186927d int     3
fffff800`0186927e int     3
fffff800`0186927f int     3

Then we disassemble fffff800`018691e0 address (I put here only the beginning):

1: kd> uf fffff800`018691e0
nt!KiInterruptDispatchNoEOI:
fffff800`01868f90 push    rsi
fffff800`01868f91 sub     rsp,150h
fffff800`01868f98 mov     rsi,rbp
fffff800`01868f9b lea     rbp,[rsp+80h]
fffff800`01868fa3 mov     byte ptr [rbp-55h],0
fffff800`01868fa7 mov     qword ptr [rbp-50h],rax
fffff800`01868fab mov     qword ptr [rbp-48h],rcx
fffff800`01868faf mov     qword ptr [rbp-40h],rdx
fffff800`01868fb3 mov     qword ptr [rbp-38h],r8
fffff800`01868fb7 mov     qword ptr [rbp-30h],r9
fffff800`01868fbb mov     qword ptr [rbp-28h],r10
fffff800`01868fbf mov     qword ptr [rbp-20h],r11
fffff800`01868fc3 test    byte ptr [rbp+0F0h],1
fffff800`01868fca je      nt!KiInterruptDispatchNoEOI+0×5d (fffff800`01868fed)

DispatchCode UINT4B array (p. 104) - these are bytes from KiDispatchInterrupt, for example, 0×56535554 from p. 103 are just the first 4 bytes in reverse order from x86 (32-bit) system (WINXP):

nt!KiInterruptTemplate:
80545711 54              push    esp
80545712 55              push    ebp
80545713 53              push    ebx
80545714 56              push    esi
80545715 57              push    edi
80545716 83ec54          sub     esp,54h
80545719 8bec            mov     ebp,esp
8054571b 89442444        mov     dword ptr [esp+44h],eax
8054571f 894c2440        mov     dword ptr [esp+40h],ecx
80545723 8954243c        mov     dword ptr [esp+3Ch],edx

Windows as a task - IntervalZero (p. 105)

- Dmitry Vostokov @ SoftwareGeneralist.com -

Reading Notebook: 05-August-09

Wednesday, August 5th, 2009

Comments in italics are mine and express my own views, thoughts and opinions

Windows Internals by M. Russinovich, D. Solomon and A. Ionescu:

trap as exception or interrupt transfer from a thread to a fixed OS location (p. 85) - Long time ago I was interested in exception processing and how it relates to crash dumps. I wrote a few investigative posts and put them on this page: http://www.dumpanalysis.org/blog/index.php/interrupts-and-exceptions-explained/

viewing IDT (pp. 88 - 89) - here is the output of the first part of IDT from typical x86 kernel dump:

0: kd> !idt -a

Dumping IDT:

00: 805421b0 nt!KiTrap00
01: f620a4f6 ati2mtag+0x1774F6
02: Task Selector = 0x0058
03: f620a59c ati2mtag+0x17759C
04: 805428c0 nt!KiTrap04
05: 80542a20 nt!KiTrap05
06: 80542b94 nt!KiTrap06
07: 8054320c nt!KiTrap07
08: Task Selector = 0x0050
09: 80543610 nt!KiTrap09
0a: 80543730 nt!KiTrap0A
0b: 80543870 nt!KiTrap0B
0c: 80543ad0 nt!KiTrap0C
0d: 80543dbc nt!KiTrap0D
0e: 805444b8 nt!KiTrap0E
0f: 805447f0 nt!KiTrap0F
10: 80544910 nt!KiTrap10
11: 80544a4c nt!KiTrap11
12: Task Selector = 0×00A0
13: 80544bb4 nt!KiTrap13
14: 805447f0 nt!KiTrap0F
15: 805447f0 nt!KiTrap0F
16: 805447f0 nt!KiTrap0F
17: 805447f0 nt!KiTrap0F
18: 805447f0 nt!KiTrap0F
19: 805447f0 nt!KiTrap0F
1a: 805447f0 nt!KiTrap0F
1b: 805447f0 nt!KiTrap0F
1c: 805447f0 nt!KiTrap0F
1d: 805447f0 nt!KiTrap0F
1e: 805447f0 nt!KiTrap0F
1f: 806e710c hal!HalpApicSpuriousService
20: 00000000
21: 00000000
22: 00000000
23: 00000000
24: 00000000
25: 00000000
26: 00000000
27: 00000000
28: 00000000
29: 00000000
2a: 805419de nt!KiGetTickCount
2b: 80541ae0 nt!KiCallbackReturn
2c: 80541c90 nt!KiSetLowWaitHighThread
2d: 8054261c nt!KiDebugService
2e: 80541461 nt!KiSystemService
2f: 805447f0 nt!KiTrap0F
30: 80540b20 nt!KiUnexpectedInterrupt0
31: 80540b2a nt!KiUnexpectedInterrupt1
32: 80540b34 nt!KiUnexpectedInterrupt2
33: 80540b3e nt!KiUnexpectedInterrupt3
34: 80540b48 nt!KiUnexpectedInterrupt4
35: 80540b52 nt!KiUnexpectedInterrupt5
36: 80540b5c nt!KiUnexpectedInterrupt6
[…]

here is the output from my x64 machine (we see that KiTrap0E was renamed to KiPageFault):

1: kd> !idt

Dumping IDT:

00: fffff80001865180 nt!KiDivideErrorFault
01: fffff80001865240 nt!KiDebugTrapOrFault
02: fffff80001865380 nt!KiNmiInterrupt Stack = 0xFFFFFA60005F5D40
03: fffff800018656c0 nt!KiBreakpointTrap
04: fffff80001865780 nt!KiOverflowTrap
05: fffff80001865840 nt!KiBoundFault
06: fffff80001865900 nt!KiInvalidOpcodeFault
07: fffff80001865ac0 nt!KiNpxNotAvailableFault
08: fffff80001865b80 nt!KiDoubleFaultAbort Stack = 0xFFFFFA60005F1D40
09: fffff80001865c40 nt!KiNpxSegmentOverrunAbort
0a: fffff80001865d00 nt!KiInvalidTssFault
0b: fffff80001865dc0 nt!KiSegmentNotPresentFault
0c: fffff80001865ec0 nt!KiStackFault
0d: fffff80001865fc0 nt!KiGeneralProtectionFault
0e: fffff800018660c0 nt!KiPageFault
10: fffff80001866400 nt!KiFloatingErrorFault
11: fffff80001866540 nt!KiAlignmentFault
12: fffff80001866600 nt!KiMcheckAbort Stack = 0xFFFFFA60005F3D40
13: fffff80001866940 nt!KiXmmException
1f: fffff80001895290 nt!KiApcInterrupt
2c: fffff80001866ac0 nt!KiRaiseAssertion
2d: fffff80001866b80 nt!KiDebugServiceTrap
2f: fffff800018aeb60 nt!KiDpcInterrupt
37: fffff80001d58630 hal!HalpApicSpuriousService (KINTERRUPT fffff80001d585a0)
3f: fffff80001d586d0 hal!HalpApicSpuriousService (KINTERRUPT fffff80001d58640)
51: fffffa8003ec5c90 USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec5c00)
                  HDAudBus!HdaController::Isr (KINTERRUPT fffffa8003ec5900)
61: fffffa8003ec5510 serial!SerialCIsrSw (KINTERRUPT fffffa8003ec5480)
72: fffffa8003ec5690 USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec5600)
82: fffffa8003ec5a50 USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec59c0)
92: fffffa8003ec5b10 USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec5a80)
                  USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec56c0)
a2: fffffa8003ec5810 USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec5780)
                  USBPORT!USBPORT_InterruptService (KINTERRUPT fffffa8003ec5540)
b0: fffffa8003ec58d0 NDIS!ndisMiniportMessageIsr (KINTERRUPT fffffa8003ec5840)
b1: fffffa8003ec5f90 acpi!ACPIInterruptServiceRoutine (KINTERRUPT fffffa8003ec5f00)
b2: fffffa8003ec5bd0 ataport!IdePortInterrupt (KINTERRUPT fffffa8003ec5b40)
                  ataport!IdePortInterrupt (KINTERRUPT fffffa8003ec5e40)
                  ataport!IdePortInterrupt (KINTERRUPT fffffa8003ec5d80)
                  ataport!IdePortInterrupt (KINTERRUPT fffffa8003ec5cc0)
c1: fffff80001d58310 hal!HalpBroadcastCallService (KINTERRUPT fffff80001d58280)
d1: fffff800018611a0 nt!KiSecondaryClockInterrupt
d2: fffff80001d583b0 hal!HalpHpetRolloverInterrupt (KINTERRUPT fffff80001d58320)
df: fffff80001d58270 hal!HalpApicRebootService (KINTERRUPT fffff80001d581e0)
e1: fffff800018710a0 nt!KiIpiInterrupt
e3: fffff80001d58770 hal!HalpLocalApicErrorService (KINTERRUPT fffff80001d586e0)
fd: fffff80001d58810 hal!HalpProfileInterrupt (KINTERRUPT fffff80001d58780)
fe: fffff80001d588b0 hal!HalpPerfInterrupt (KINTERRUPT fffff80001d58820)
ff: 0000000000000000

x64 uses only APIC (p. 90) - !pic doesn’t work for x86 kernel dumps:

1: kd> !pic
!pic is for X86 targets only.

priority is thread attr. and IRQL is interrupt source attr. (p. 93) - orthogonality. I also created a few UML sequence diagrams in the past to illustrate the point: http://www.dumpanalysis.org/blog/index.php/2007/03/06/bugchecks-depicted-irql_not_less_or_equal/

Lazy IRQL - no PIC changes unless real interrupt (p. 93)

masked interrupts (by IRQL) may be serviced by another processor (p. 94)

APC level is thread-local, rescheduling doen’t block them (p. 94)

- Dmitry Vostokov @ SoftwareGeneralist.com -