Stacks & Breaks
  • Home
    • Home #1
      • Infinite Scroll Load More
      • Infinite Load More Posts
      • Home Featured Video
      • Home with Left Sidebar
      • Home with Sticky Sidebar
      • Standard Layout
      • Classic Layout
    • Home #2
      • Grid Layout
      • Grid with Sidebar
      • Grid 2 Columns Layout
      • List Layout
      • Masonry Layout
      • Masonry with Sidebar
      • Masonry 2 Columns Layout
      • Boxed Layout
      • Overlay Layout
    • Home #3
      • Mixed Layout
      • Mixed Style 2 Layout
      • Photography Layout
      • Magazine Layout 1
      • Magazine Layout 2
      • Magazine Layout 3
      • 1st Overlay Then Grid
      • 1st Overlay Then List
      • 1st Standard Then Grid
    • Home #4
      • 1st Standard Grid Sidebar
      • 1st Standard Then Grid 2
      • 1st Standard Then List
      • 1st Standard Then Boxed
      • 1st Classic Then Grid
      • 1st Classic Grid Sidebar
      • 1st Classic Then Grid 2
      • 1st Classic Then List
      • 1st Classic Then Boxed
  • Sliders
    • Slider #1
      • Home with Slider 1
      • Home with Slider 2
      • Home with Slider 3
      • Home with Slider 4
      • Home with Slider 5
      • Home with Slider 6
      • Home with Slider 7
      • Home with Slider 8
      • Home with Slider 9
    • Slider #2
      • Home with Slider 10
      • Home with Slider 11
      • Home with Slider 12
      • Home with Slider 13
      • Home with Slider 14
      • Home with Slider 15
      • Home with Slider 16
      • Home with Slider 17
      • Home with Slider 18
    • Slider #3
    • Slider #4
      • Home with Slider 28
      • Home with Slider 29
      • Home with Slider 30
      • Home with Slider 35
      • Home with Slider 36
      • Home with Slider 37
      • Home with Slider 38
      • Home Penci Slider 1
      • Home Penci Slider 2
  • Features
  • Coding
  • Guide
  • Resources
  • Portfolio
    • Masonry 3 Columns
    • Masonry 2 Columns
    • Masonry with Sidebar
    • Grid 3 Columns
    • Grid with Sidebar
    • Grid 2 Columns
    • Single Portfolio
  • Shop
  • Home with Slider 19
  • Home with Slider 20
  • Home with Slider 21
  • Home with Slider 22
  • Home with Slider 23
  • Home with Slider 24
  • Home with Slider 25
  • Home with Slider 26
  • Home with Slider 27
  • Post Templates
  • Headers
  • Menu Item Style 2
  • Real Awesome Gallery
  • Post Formats
  • Pages
  • Typography
  • Template Style 1
  • Template Style 2
  • Template Style 3
  • Style 3 with Parallax
  • Template Style 4
  • Style 4 with Parallax
  • Template Style 5
  • Style 5 with Parallax
  • Template Style 6
  • Style 6 with Parallax
  • Template Style 7
  • Style 7 with Parallax
  • Template Style 8
  • Style 8 with Parallax
  • Template Style 9
  • Style 9 with Parallax
  • Template Style 10
  • Style 10 with Parallax
  • Header Style 1
  • Header Style 2
  • Header Style 3
  • Header Style 4 (Centerd)
  • Header Style 5 (Centerd)
  • Header Style 6
  • Header Style 7
  • Header Style 8
  • Header Style 9
  • Standard Post
  • Gallery Post
  • Video Post
  • Audio Post
  • Quote Post
  • Link Post
  • Youtube Post
  • Vimeo Post
  • Soundcloud Audio
  • Self-hosted Audio
  • About me
  • Contact Me
  • Page Left Sidebar
  • Page Full Width
  • Page 404

Latest Video

Popular Posts

  • 1

    Computer Architecture (Windows/Intel): What a system debug engineer needs to know?

    November 2, 2020
  • 2

    Courses to Jumpstart Your Development Career

    January 25, 2019
  • 3

    Wireshark Basics Playlist

    November 2, 2020
@2021 - All Right Reserved. Designed and Developed by PenciDesign
Debugging

Forcing Symbols to match in WinDbg

by dnaadmin November 2, 2020
written by dnaadmin

Use the Microsoft Symbol Server to obtain debug symbol files

http://support.microsoft.com/kb/311503

other useful commands:

!symfix
.reload
!analyze -v
!sym noisy
.symopt+ 0×40
.sympath SRV*f:\localsymbols*http://msdl.microsoft.com/download/symbols

Sometimes we could have a dump which does not load .pdb files even though they are present in the dump folder. The reason for the load failure is not necessarily every time a code change but could be just a rebuild of the source code. In such cases if you force load the .pdb file you should get a call stack that makes sense but you got to be good at API’s and libraries to make sure the stack makes sense. So until you get a proper .pdb file you can force load a .pdb file and work on the dump.

0:000> .symopt
Symbol options are 0×30377:
0×00000001 – SYMOPT_CASE_INSENSITIVE
0×00000002 – SYMOPT_UNDNAME
0×00000004 – SYMOPT_DEFERRED_LOADS
0×00000010 – SYMOPT_LOAD_LINES
0×00000020 – SYMOPT_OMAP_FIND_NEAREST
0×00000100 – SYMOPT_NO_UNQUALIFIED_LOADS
0×00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
0×00010000 – SYMOPT_AUTO_PUBLICS
0×00020000 – SYMOPT_NO_IMAGE_SEARCH

These flags determine how and what symbols will be loaded. These options also determine whether line number information should be loaded or not.

So in our debugging scenario if we want to load symbols in a loose manner, i.e., without strict mapping of .pdb with .exe we will have to enable the following option…

0×00000040 – SYMOPT_LOAD_ANYTHING

In windbg we do this via…

0:000> .symopt+ 0x40
Symbol options are 0x30377:
0x00000001 – SYMOPT_CASE_INSENSITIVE
0x00000002 – SYMOPT_UNDNAME
0x00000004 – SYMOPT_DEFERRED_LOADS
0x00000010 – SYMOPT_LOAD_LINES
0x00000020 – SYMOPT_OMAP_FIND_NEAREST
0x00000040 – SYMOPT_LOAD_ANYTHING <———– Prevents validation of .pdb file
0x00000100 – SYMOPT_NO_UNQUALIFIED_LOADS
0x00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
0x00010000 – SYMOPT_AUTO_PUBLICS
0x00020000 – SYMOPT_NO_IMAGE_SEARCH

To re-enable strict mapping between .exe and .pdb use

0:000> .symopt- 0x40
Symbol options are 0x30377:
0x00000001 – SYMOPT_CASE_INSENSITIVE
0x00000002 – SYMOPT_UNDNAME
0x00000004 – SYMOPT_DEFERRED_LOADS
0x00000010 – SYMOPT_LOAD_LINES
0x00000020 – SYMOPT_OMAP_FIND_NEAREST
0x00000100 – SYMOPT_NO_UNQUALIFIED_LOADS
0x00000200 – SYMOPT_FAIL_CRITICAL_ERRORS
0x00010000 – SYMOPT_AUTO_PUBLICS
0x00020000 – SYMOPT_NO_IMAGE_SEARCH

Note the +/- in the above command. ‘+’ enables, ‘-‘ disables.

Alternative way

.reload /f /i test.exe

The /i in above command tells the debugger to ignore any symbol mismatch and just load up the PDB/Symbol file.

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Debugging

Setting Symbols in WinDbg

by dnaadmin November 2, 2020
written by dnaadmin

The symbol path specifies locations where the Windows debuggers (WinDbg, KD, CDB, NTST) look for symbol files. Microsoft OS symbols are located at: https://msdl.microsoft.com/download/symbols

You can set the symbols in multiple ways:

  1. If you are an active debugger, setting it up in the environment path is the best option. You can directly set the _NT_SYMBOL_PATH in the environment variable path Ex: _NT_SYMBOL_PATH=srv*C:\Symbols\MsSymbols*http://msdl.microsoft.com/download/symbols
  2. GUI via the WinDbg interface:  In WinDbg’s GUI you can access symbol settings from:–(Menu) File->Symbol File Path … (Ctrl+S)
  3. Using Command line on WinDbg prompt

Useful Commands:

–.sympath-> get/set path for symbol search

–.sympath ->+XY append XY directory to the searched symbol path

–!sym noisy ->instructs the debugger to display information about its search for symbols

–ld kernel32 ->load symbols for kernel32.dll

–ld * ->load symbols for all modules

–.reload ->reloads symbol information

–x kernel32!*->examine and list all symbols in kernel32

–x kernel32!*LoadLibrary* ->list all symbols in kernel32 which contain *LoadLibrary*

–dt ntdll!*->display all variables in ntdll

Combining cache* and srv*

If you include the string cache*; in your symbol path, symbols loaded from any element that appears to the right of this string are stored in the default symbol cache directory on the local computer. For example, the following command tells the debugger to use a symbol server to get symbols from the store at https://msdl.microsoft.com/download/symbols and cache them in the default symbol cache directory.

.sympath cache*;srv*https://msdl.microsoft.com/download/symbols

If you include the string cache*localsymbolcache; in your symbol path, symbols loaded from any element that appears to the right of this string are stored in the localsymbolcache directory.

For example, the following command tells the debugger to use a symbol server to get symbols from the store at https://msdl.microsoft.com/download/symbols and cache the symbols in the c:\MySymbols directory. .sympath cache*c:\MySymbols;srv*https://msdl.microsoft.com/download/symbols

The first rule for anyone thinking of using the Windows debugger is to get the current version. The debugger is updated on a routine basis and as a result it really is important to ensure that you grab the latest and greatest version. As of the writing of this article, the current version can be found at:

http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx.

There is usually a release version as well as a pre-release version available. Grab either one – they are very likely to be better than the debugger version you are using.

If you plan on building your own debugger extensions (probably not likely when you first get started, but once you use this debugger you’ll be chomping at the bit to add your own extensions to it) make sure you choose a “custom” installation and install the debugger SDK – otherwise you won’t have the header files and libraries you need.

OK. Having downloaded the debugger the first challenge is normally getting the symbols set up. Fortunately, the debugger team at Microsoft has made this incredibly easy. If you go back to the same place you got the debugger (http://www.microsoft.com/whdc/DevTools/Debugging/default.mspx) you will see information about using the symbol server as well as downloading the symbols for various versions of Windows. We strongly recommend that you use the symbol server whenever possible, especially when getting started with the debugger. To set up symbols using the symbol server you will need to set up a temporary storage area – any directory within your file system will do the trick If your disk space is at a premium and you are using NTFS, make sure you turn on compression for that temporary storage area. For example, on my system I place the symbols in f:\symbols\websymbols but you can put them anywhere – even on a network drive. Then, once I start up the debugger and before I start debugging anything I set up the initial symbol path. Do this by pressing Ctrl+S or by choosing “Symbol File Path” from the File menu. This will pop up a little dialog box where you enter your symbol file search path. So in my case I entered:

srv*f:\symbols\websymbols*http://msdl.microsoft.com/download/symbols.

Having done this, you can now attempt to connect to your remote system (if you are doing live debugging) or your crash dump (if you are doing post-mortem debugging). In either case the debugger will ask you if you want to save the workspace. You want to say YES here because that will record that symbol path as your base symbol path. Now, when you create a new workspace it will always start with this path (note that if you have existing workspaces, this will not update them).

Alternatively, if you forgot to setup your symbol search path to start with and the debugger scolds you — or if you can’t remember the syntax of the symbol server’s search path — you can always break-in and tell the debugger to setup your symbol path for you:

.symfix f:\symbols\websymbols

Where f:\symbols\websymbols is, once again, the location of my local symbol store.

You can go back and add additional paths at any time – these will be specific to the thing you are currently debugging, so they won’t show up in your base workspace. Each additional path should be separated using a semi-colon (;). So if my driver symbols are in z:\mydriver, I would then have the following in my symbol search path:

srv*f:\symbols\websymbols*http://msdl.microsoft.com/download/symbols;z:\mydriver

Suppose, however, that the debugger is telling you that it cannot find your symbols or the symbols for OS modules (oh, like ntoskrnl.exe since the debugger is pretty much useless if it cannot find those symbols). In that case you can enable noisy symbols, so the debugger will report to you where it is looking for symbols. In our experience, once you can see where the debugger is looking, you will know where it is not looking and hence why it cannot find your symbols. Maybe you’ve entered the path incorrectly (WinDBG does not have a built-in spell checker, nor does it have any fuzzy logic module that says “oh, gee, they must have meant this OTHER directory with a very similar name). Maybe the symbols really do not match (hey, it happens) but at least you’ll know where the debugger is checking!

At this point you should have everything set up and working. Happy Debugging!

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Device Drivers

Making sense of Device objects & Driver Objects from a dump

by dnaadmin November 2, 2020
written by dnaadmin

The !devstack extension displays a formatted view of the device stack associated with a device object.
The !devnode extension displays information about a node in the device tree.
1. WDM driver archecture is the layer structure.
2. Each device function has a device node.
3. Device node is made by device objects.

 

1: kd> !devstack fffffa800201e830 (One of the device objects in the device node) !DevObj !DrvObj !DevExt ObjectName
fffffa800201e4d0 \Driver\kbdclass fffffa800201e620 KeyboardClass0
> fffffa800201e830 \Driver\i8042prt fffffa800201e980 fffffa8001a8f060 \Driver\ACPI fffffa8000c7b970 0000005e
!DevNode fffffa8001a90610 :
DeviceInst is “ACPI\PNP0303\4&27dc0b59&0”
ServiceName is “i8042prt”

1: kd> !DevNode fffffa8001a90610 1 (!devnode command can show us the device node information)DevNode 0xfffffa8001a90610 for PDO 0xfffffa8001a8f060
InstancePath is “ACPI\PNP0303\4&27dc0b59&0”
ServiceName is “i8042prt”
TargetDeviceNotify List – f 0xfffff8a000c5cb70 b 0xfffff8a000c5cb70
State = DeviceNodeStarted (0x308)
Previous State = DeviceNodeEnumerateCompletion (0x30d)
1: kd> !devobj fffffa8001a8f060 Device object (fffffa8001a8f060) is for:
0000005e \Driver\ACPI DriverObject fffffa8000c394e0
Current Irp 00000000 RefCount 1 Type 00000032 Flags 00003040
Dacl fffff9a100094441 DevExt fffffa8000c7b970 DevObjExt fffffa8001a8f1b0 DevNode fffffa8001a90610
ExtensionFlags (0x00000800)
Unknown flags 0x00000800
AttachedDevice (Upper) fffffa800201e830 \Driver\i8042prtDevice queue is not busy.
1: kd> dt nt!_device_object fffffa8001a8f060
+0x000 Type : 3
+0x002 Size : 0x150
+0x004 ReferenceCount : 1
+0x008 DriverObject : 0xfffffa80`00c394e0 _DRIVER_OBJECT
+0x010 NextDevice : 0xfffffa80`01a52720 _DEVICE_OBJECT
+0x018 AttachedDevice : 0xfffffa80`0201e830 _DEVICE_OBJECT
+0x020 CurrentIrp : (null)
+0x028 Timer : (null)
+0x030 Flags : 0x3040
+0x034 Characteristics : 0x80
+0x038 Vpb : (null)
+0x040 DeviceExtension : 0xfffffa80`00c7b970 (The device extension is not the fixed structure) +0x048 DeviceType : 0x32
+0x04c StackSize : 5 ”
+0x050 Queue :
+0x098 AlignmentRequirement : 0
+0x0a0 DeviceQueue : _KDEVICE_QUEUE
+0x0c8 Dpc : _KDPC
+0x108 ActiveThreadCount : 0
+0x110 SecurityDescriptor : 0xfffff8a0`00094440
+0x118 DeviceLock : _KEVENT
+0x130 SectorSize : 0
+0x132 Spare1 : 1
+0x138 DeviceObjectExtension : 0xfffffa80`01a8f1b0 _DEVOBJ_EXTENSION
+0x140 Reserved : (null)
1: kd> dt _DEVOBJ_EXTENSION 0xfffffa80`01a8f1b0 (Show the device object extension)nt!_DEVOBJ_EXTENSION
+0x000 Type : 13
+0x002 Size : 0
+0x008 DeviceObject : 0xfffffa80`01a8f060 _DEVICE_OBJECT
+0x010 PowerFlags : 0x10 (device/system power state information) +0x018 Dope : (null)
+0x020 ExtensionFlags : 0x800
+0x028 DeviceNode : 0xfffffa80`01a90610 +0x030 AttachedTo : (null) +0x038 StartIoCount : 0
+0x03c StartIoKey : 0
+0x040 StartIoFlags : 0
+0x048 Vpb : (null)
+0x050 DependentList : _LIST_ENTRY [ 0xfffffa80`01a8f200 – 0xfffffa80`01a8f200 ] +0x060 ProviderList : _LIST_ENTRY [ 0xfffffa80`01a8f210 – 0xfffffa80`01a8f210 ] In the WIndbg !devnode xxxxxxxx 1 command, it will show show the InstancePath, ServiceName, State, PreviousState.
2: kd> dt _device_node
nt!_DEVICE_NODE
+0x000 Sibling : Ptr64 _DEVICE_NODE
+0x008 Child : Ptr64 _DEVICE_NODE
+0x010 Parent : Ptr64 _DEVICE_NODE
+0x018 LastChild : Ptr64 _DEVICE_NODE
+0x020 PhysicalDeviceObject : Ptr64 _DEVICE_OBJECT
+0x028 InstancePath : _UNICODE_STRING
+0x038 ServiceName : _UNICODE_STRING
+0x048 PendingIrp : Ptr64 _IRP
+0x050 Level : Uint4B
+0x058 Notify : _PO_DEVICE_NOTIFY
+0x0c0 PoIrpManager : _PO_IRP_MANAGER
+0x0e0 State : _PNP_DEVNODE_STATE
+0x0e4 PreviousState : _PNP_DEVNODE_STATE
+0x0e8 StateHistory : [20] _PNP_DEVNODE_STATE
+0x138 StateHistoryEntry : Uint4B
+0x13c CompletionStatus : Int4B
+0x140 Flags : Uint4B
+0x144 UserFlags : Uint4B
+0x148 Problem : Uint4B
+0x150 ResourceList : Ptr64 _CM_RESOURCE_LIST
+0x158 ResourceListTranslated : Ptr64 _CM_RESOURCE_LIST
+0x160 DuplicatePDO : Ptr64 _DEVICE_OBJECT
+0x168 ResourceRequirements : Ptr64 _IO_RESOURCE_REQUIREMENTS_LIST
+0x170 InterfaceType : _INTERFACE_TYPE
+0x174 BusNumber : Uint4B
+0x178 ChildInterfaceType : _INTERFACE_TYPE
+0x17c ChildBusNumber : Uint4B
+0x180 ChildBusTypeIndex : Uint2B
+0x182 RemovalPolicy : UChar
+0x183 HardwareRemovalPolicy : UChar
+0x188 TargetDeviceNotify : _LIST_ENTRY
+0x198 DeviceArbiterList : _LIST_ENTRY
+0x1a8 DeviceTranslatorList : _LIST_ENTRY
+0x1b8 NoTranslatorMask : Uint2B
+0x1ba QueryTranslatorMask : Uint2B
+0x1bc NoArbiterMask : Uint2B
+0x1be QueryArbiterMask : Uint2B
+0x1c0 OverUsed1 :
+0x1c8 OverUsed2 :
+0x1d0 BootResources : Ptr64 _CM_RESOURCE_LIST
+0x1d8 BootResourcesTranslated : Ptr64 _CM_RESOURCE_LIST
+0x1e0 CapabilityFlags : Uint4B
+0x1e8 DockInfo :
+0x208 DisableableDepends : Uint4B
+0x210 PendedSetInterfaceState : _LIST_ENTRY
+0x220 LegacyBusListEntry : _LIST_ENTRY
+0x230 DriverUnloadRetryCount : Uint4B
+0x238 PreviousParent : Ptr64 _DEVICE_NODE
+0x240 DeletedChildren : Uint4B
+0x244 NumaNodeIndex : Uint4B
+0x248 ContainerID : _GUID
+0x258 OverrideFlags : UChar
+0x259 RequiresUnloadedDriver : UChar
+0x260 PendingEjectRelations : Ptr64 _PENDING_RELATIONS_LIST_ENTRY

“!drvobj Driver Name | PDRIVER_OBJECT pointer” will list all of the devices that a driver has created. I typically invoke this call with “!drvobj Driver Name.” For instance,

0: kd> !drvobj \Driver\i8042prt
Driver object (82158040) is for:
\Driver\i8042prt
Driver Extension List: (id , addr)

Device Object list:
8213c3d0 82153738

Once you have a list of devices, you can pass a device pointer to either !devobj or !devstack to get more information. !devobj will work for any type of device object and will give the device name, device extenion, current irp (for StartIo) and lot more information.

0: kd> !devobj 8213c3d0
Device object (8213c3d0) is for:
\Driver\i8042prt DriverObject 82158040
Current Irp 00000000 RefCount 0 Type 00000027 Flags 00002004
DevExt 8213c488 DevObjExt 8213c768
ExtensionFlags (0xe0000000) DOE_RAW_FDO, DOE_BOTTOM_OF_FDO_STACK,
DOE_DESIGNATED_FDO
AttachedDevice (Upper) 8213c250 \DRIVER\VERIFIER
AttachedTo (Lower) 8213c820 \DRIVER\VERIFIER
Device queue is not busy.

If the device is a pnp device object (FDO, PDO, filter, doesn’t matter), !devstack will show you the entire stack of devices. This can give you a better picture of the environment that your device is executing in. In the following example, I am dumping the device which controsl the PS2 mouse. Furthermore, the device stack is being verifier by driver verifier which is why you see the 2 device objects created by \Driver\VERIFIER.

0: kd> !devstack 8213c3d0
!DevObj !DrvObj !DevExt ObjectName
8213b030 \Driver\Mouclass 8213b0e8 PointerClass0
8213c250 \DRIVER\VERIFIER 8213c308
> 8213c3d0 \Driver\i8042prt 8213c488
8213c820 \DRIVER\VERIFIER 8213c8d8
822923e8 \Driver\ACPI 822b2270 00000050
!DevNode 8228f4c8 :
DeviceInst is “ACPI\PNP0F13\4&1506bb2e&0”
ServiceName is “i8042prt”

Using either !devobj or !devstack, you can get your device extension and then dump it. This is useful if you have a BSOD where you know your driver is at fault, but the callstack itself does not have any backpointers to your device or the needed context.

0: kd> dt 8213c488 i8042prt!_PORT_MOUSE_EXTENSION
+0x000 Self : 0x8213c3d0 _DEVICE_OBJECT
+0x004 InterruptObject : 0x81f44bb0 _KINTERRUPT
+0x008 InterruptSpinLock : 0
+0x00c TopOfStack : 0x8213c820 _DEVICE_OBJECT
+0x010 PDO : 0x822923e8 _DEVICE_OBJECT
[…]

Finally, if you have a pnp device object, you can see the information that power maintains on your device object by running !podev. In the following example, I ran !podev when an Sx irp was being sent to the mouse stack (by setting a bp on i8042prt!I8xPower)

1: kd> !podev 0x8213c3d0
Device object is for:
DriverObject 82158040
Current Irp 00000000 RefCount 0 Type 00000000 AttachedDev 8213c250 DevFlags 00002004 DO_POWER_PAGABLE
Device queue is not busy.
Device Object Extension: 8213c768:
PowerFlags: 00000110 =>SystemState=0 DeviceState=1 syact
Dope: 00000000:

For instance, if your driver calls PoSetPowerState() properly for each S and D irp, the PowerFlags will indicate the current S and D state of the device (i8042prt only calls it for D irps). PowerFlags also can tell you if there is an S or D irp active on your device (unfortunately, not the PIRP value itself which would be useful); in this case, there is an S irp active as indicated by the “sysact” output. By continuing on and keeping the same breakpoint, I can see when a device power irp is active

1: kd> !podev 0x8213c3d0
[…] PowerFlags: 00000410 =>SystemState=0 DeviceState=1 dvact
November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Debugging

0x9F BugCheck with Param 3? Here is how you go about it

by dnaadmin November 2, 2020
written by dnaadmin

This post is for driver or kernel developers/enthusiasts who have encountered a Blue Screen of Death on Windows where the bugcheck code is 0x9F, DRIVER_POWER_STATE_FAILURE, and parameter 1 is 0x3. There are a few variants on DRIVER_POWER_STATE_FAILURE, but this one is when a device object has been blocking an IRP for too long a time.

If you’re not familiar with IRPs, you should probably back up and learn the basics. Check out Power IRPs for individual devices. I’m not going to explain them here, but when a device connected to the system is making a power transition, it is responsible for completing that power transition within 2 minutes.

So, if your computer is trying to go to sleep and you have a webcam connected to it that should go to sleep along with the system, the driver for that webcam needs to complete the power IRP within two minutes. If it doesn’t, a watchdog timer fires and the system bugchecks with code 9F, parameter 3. Two minutes should be ample time for any device to complete a power IRP; if it takes more than that, it usually means there is a deadlock somewhere in the system.

You will need:

1. A kernel or full dump

9Fs are different than other crashes in that it’s not a single faulting line of source code. A wonderful debugging mentor of mine describes solving 9Fs as “untangling a chain of dependencies”. You need a full view of the system in order to confidently make a diagnosis here, in most cases. A minidump often won’t provide enough information.

2. WinDBG or KD set up to debug a crash dump

I know that my readers have a wide range of technical skills – if you don’t know how to use at least the basics WinDBG or KD to kernel debug, you may want to start there. See Getting Started with Windows Debugging. Once you have WinDBG set up and your crash dump opened, be sure you have somewhere to take notes. Personally, I’m crazy about WinDBG’s Scratch Pad functionality. Here’s a tiny picture of the WinDBG workspace I use for crash dumps (bigger picture here) – see how I have my notes right there in the same window on the top left. You’ll have to figure out whatever works for you if you haven’t already, though.

My WinDBG workspace

Basic steps to solve a 9F 3

9Fs range from extremely easy problems that you can solve in 2 minutes to extremely difficult that several experienced engineers will scratch their heads at for days. We’re going to stick with an easier one. The steps I describe here are the foundation of solving any 9F 3.

1. Start with .bugcheck to find out the stuck power IRP

We need to know which power IRP is stuck. This will be in bugcheck parameter 4.

0: kd> .bugcheck
Bugcheck code 0000009F
Arguments 00000000`00000003 ffffe000`0cb6f060 fffff803`5e245990 ffffe000`18d4aa50

Cool, our power IRP is ffffe00018d4aa50. Write this down in your notes so you can easily copy/paste it later.

2. Look at IRPs and IRP worker threads with !irp and !poaction 2

First, we want to check out the IRP worker threads that are in the 2nd section of !poaction. !poaction is useful for any crash involving a power transition, such as bugcheck 0x9F 3. You can experiment with looking at the full output of the command on your own.

We want to see if our IRP is being serviced by one of the IRP worker threads.

0: kd> !poaction 2

Allocated power irps (PopIrpList - fffff8035c9624f0)
  IRP: ffffe000188818f0 (wait-wake/S4), PDO: ffffe0000cbe46a0
  IRP: ffffe0000e846830 (wait-wake/S4), PDO: ffffe0000cbf96a0
  IRP: ffffe0000c01c5c0 (wait-wake/S4), PDO: ffffe0000b7a1c20
  IRP: ffffe0000b4b0b80 (wait-wake/S4), PDO: ffffe0000cb83060
  IRP: ffffe0000c1ae2d0 (wait-wake/S4), PDO: ffffe0000cb3a060
  IRP: ffffe000166cc010 (set/S4), PDO: ffffe0000cb6f060, CURRENT: ffffe0000cae86f0, NOTIFY: ffffe0000cb970a0
  IRP: ffffe00012d9e170 (wait-wake/S4), PDO: ffffe0000cb838d0
  IRP: ffffe00018d4aa50 (set/D3,), PDO: ffffe0000cb6f060, CURRENT: ffffe0000cae86f0
  IRP: ffffe000172bb0d0 (wait-wake/S4), PDO: ffffe0000cc0b6a0
  IRP: ffffe0000d220a60 (wait-wake/S4), PDO: ffffe0000cc03060

Irp worker threads (PopIrpThreadList - fffff8035c961100)
  THREAD: ffffe0000aafd840 (static)
  THREAD: ffffe0000ab35040 (static)
  THREAD: ffffe0000f29c640 (dynamic)
  THREAD: ffffe0000bec16c0 (dynamic)
  THREAD: ffffe0000dbf0840 (dynamic)
  THREAD: ffffe000181b0040 (dynamic)
  THREAD: ffffe0000f229840 (dynamic)
  THREAD: ffffe0000cbc3840 (dynamic)
  THREAD: ffffe0000c5135c0 (dynamic)
  THREAD: ffffe0000bdc5840 (dynamic)
  THREAD: ffffe0000be1e040 (dynamic)
  THREAD: ffffe0000f187040 (dynamic)
  THREAD: ffffe0000ae0e740 (dynamic), IRP: ffffe00018d4aa50, DEVICE: ffffe0000cbaee20
  THREAD: ffffe000191fd040 (dynamic)
  THREAD: ffffe00017948840 (dynamic)

Look at that! We see our IRP is a Set/D3 IRP and that it’s being serviced by that worker thread ffffe0000ae0e740. Write that thread down.

If our stuck IRP isn’t here, don’t despair – see what’s going on in IRP worker threads using the techniques below that are running to see if you can get a better picture of what’s going on in the system. At this point, you can look at the IRP itself with !irp to get some ideas about where it’s stuck.

Output truncated to the interesting bits for brevity:

0: kd> !irp ffffe000`18d4aa50
Irp is active with 11 stacks 9 is current (= 0xffffe00018d4ad60)
 No Mdl: No System Buffer: Thread 00000000:  Irp stack trace.  
     cmd  flg cl Device   File     Completion-Context

>[IRP_MJ_POWER(16), IRP_MN_SET_POWER(2)]
            0  1 ffffe0000cae86f0 00000000 00000000-00000000    pending
	       \Driver\A38CCID
			Args: 00015600 00000001 00000004 00000003

Hmm, it’s pending in some driver called A38CCID. Seems suspicious. We’ll get back to that.

3. Look at the IRP worker thread with !thread or .thread

We saw our stuck IRP is being serviced in that IRP worker thread. Let’s check it out! You can see detailed information about the thread with !thread ffffe0000ae0e740 or you can switch to the thread context with .thread ffffe0000ae0e740. For space/readability, I’ll do the latter.

0: kd> .thread ffffe0000ae0e740
Implicit thread is now ffffe000`0ae0e740
0: kd> kc
  *** Stack trace for last set context - .thread/.cxr resets it
 # Call Site
00 nt!KiSwapContext
01 nt!KiSwapThread
02 nt!KiCommitThreadWait
03 nt!KeWaitForSingleObject
04 a38ccid
05 a38ccid
06 a38ccid
07 a38ccid
08 a38ccid
09 a38ccid
0a a38ccid
0b a38ccid
0c Wdf01000!FxIrp::PoCallDriver
0d Wdf01000!FxPkgFdo::_PowerPassDown
0e Wdf01000!FxPkgFdo::PowerReleasePendingDeviceIrp
0f Wdf01000!FxPkgPnp::PowerGotoDxIoStopped
10 Wdf01000!FxPkgPnp::PowerGotoDNotZeroIoStopped
11 Wdf01000!FxPkgPnp::PowerEnterNewState
12 Wdf01000!FxPkgPnp::PowerProcessEventInner
13 Wdf01000!FxPkgPnp::PowerProcessEvent
14 Wdf01000!FxPkgFdo::LowerDevicePower
15 Wdf01000!FxPkgFdo::DispatchDeviceSetPower
16 Wdf01000!FxPkgPnp::Dispatch
17 Wdf01000!DispatchWorker
18 Wdf01000!FxDevice::Dispatch
19 Wdf01000!FxDevice::DispatchWithLock
1a nt!PopIrpWorker
1b nt!PspSystemThreadStartup
1c nt!KxStartSystemThread

You can see immediately what’s happening here. WDF is passing down a power IRP to our device, whose driver is a38ccid.sys. It never completes the power IRP, so the machine falls over when its two minutes are up. We don’t have the symbols for that driver since it’s not part of Windows, but we can look at it anyway:

0: kd> !lmi a38ccid
Loaded Module Info: [a38ccid] 
         Module: a38ccid
   Base Address: fffff800210c0000
     Image Name: a38ccid.sys
   Machine Type: 34404 (X64)
     Time Stamp: 55691a7e Fri May 29 19:03:42 2015
           Size: f800
       CheckSum: 18772
Characteristics: 22  
Debug Data Dirs: Type  Size     VA  Pointer
             CODEVIEW    77,  cf38,    cf38 RSDS - GUID: {FA73C7E5-9828-482F-BDDB-9A0F69E150C2}
               Age: 1, Pdb: c:\winddk\7600.16385.1\unified_driver-src\acsccid\latest\objfre_win7_amd64\amd64\acsdrvx64.pdb
     Image Type: MEMORY   - Image read successfully from loaded memory.
    Symbol Type: NONE     - PDB not found from image header.
    Load Report: no symbols loaded

If you own the driver that shows up here, you can take some extra steps to see what your driver is doing wrong that’s causing it to hold that power IRP for 2 minutes before completing it. If you don’t, there’s not much you can do to solve it, but you at least know who the culprit is. You can look up the name of the faulting driver online is and report a bug to their engineering team. In this case, a38ccid.sys is a smart card reader driver.

4. Other things to try: !stacks 2

Once you suspect a driver is at fault, you should see which thread stacks it shows up in. Sometimes you’ll see smoking guns. For example, maybe your driver that you identified in step 3 is calling WdfSpinlockAcquire in another thread, which may indicate that they have a textbook deadlock somewhere.

Try it out on your own dump! Output truncated to the interesting parts.

0: kd> !stacks 2 a38ccid
4.000d14  ffffe0000ba79040 fc006b27 Blocked    nt!KiSwapContext+0x76
                                        nt!KiSwapThread+0x15a
                                        nt!KiCommitThreadWait+0x149
                                        nt!KeWaitForMultipleObjects+0x24e
                                        a38ccid+0x159e
                                        nt!PspSystemThreadStartup+0x41
                                        nt!KxStartSystemThread+0x16
   4.001154  ffffe0000ae0e740 fbef43a7 Blocked    nt!KiSwapContext+0x76
                                        nt!KiSwapThread+0x15a
                                        nt!KiCommitThreadWait+0x149
                                        nt!KeWaitForSingleObject+0x375
                                        a38ccid+0x284d
                                        a38ccid+0x303b
                                        a38ccid+0x81c9
                                        a38ccid+0x8db5
                                        a38ccid+0x20f4
                                        a38ccid+0x87c5
                                        a38ccid+0xa710
                                        a38ccid+0x988c
                                        Wdf01000!FxPkgFdo::_PowerPassDown+0x6d
                                        Wdf01000!FxPkgFdo::_PowerPassDown+0x6d
                                        Wdf01000!FxPkgFdo::PowerReleasePendingDeviceIrp+0x44
                                        Wdf01000!FxPkgPnp::PowerGotoDxIoStopped+0x180
                                        Wdf01000!FxPkgPnp::PowerGotoDNotZeroIoStopped+0x9
                                        Wdf01000!FxPkgPnp::PowerProcessEventInner+0x234
                                        Wdf01000!FxPkgPnp::PowerProcessEventInner+0x234
                                        Wdf01000!FxPkgPnp::PowerProcessEvent+0x25f
                                        Wdf01000!FxPkgFdo::DispatchDeviceSetPower+0x65
                                        Wdf01000!FxPkgFdo::DispatchDeviceSetPower+0x65
                                        Wdf01000!FxPkgPnp::Dispatch+0xb2
                                        Wdf01000!FxDevice::DispatchWithLock+0x111
                                        Wdf01000!FxDevice::DispatchWithLock+0x111
                                        Wdf01000!FxDevice::DispatchWithLock+0x111
                                        nt!PopIrpWorker+0x1f6
                                        nt!PspSystemThreadStartup+0x41
                                        nt!KxStartSystemThread+0x16

Our faulty driver is in two different stacks right now and each of them is waiting on something. There’s a KeWaitForMultipleObjects in the first stack and a KeWaitForSingleObject in the second stack, which we recognize to also be the IRP worker thread. It’s impossible to tell for sure without the symbols, but it looks like they have a bug in their synchronization. These threads might waiting on each other, which would be a deadlock. If not, they’re waiting on something else that is never happening. Either way, we can say with a high degree of confidence that a83ccid.sys is the culprit here.

5. Other things to try: !running -it

Sometimes your stuck IRP is the victim of activity on some other processor. You can view what’s running on all processors to see if anything looks suspicious. Use !running -it.

Note: This particular case isn’t a good candidate for !running -it, so I’ve omitted the output. I’d like to give a different example that makes use of !running -it in a different post.

Solving the puzzle

If you follow those steps, you will often be able to tell if your system exhibits the symptoms of a 3rd party (non-Windows) device driver blocking the power IRP from being completed. There are a multitude of other causes for DRIVER_POWER_STATE_FAILURE with a stuck IRP, but a faulty 3rd party driver is among the most common ones.

To me, there are few things more satisfying than solving a nice bugcheck 0x9F 3. I speculate that it’s weird to have a favorite BSOD crash to debug, but I find it very methodical and engaging with a fascinating view into the system, to boot. I’m a sucker for puzzles, though. Shoot me an email if you have any for me.

Happy debugging!

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
BasicsDebugging

Windbg Basics

by dnaadmin November 2, 2020
written by dnaadmin

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Debugging

Dumping a module’s memory space (via WinDbg)

by dnaadmin November 2, 2020
written by dnaadmin

The command .WRITEMEM allows us to save memory into a disk file. The cool thing about it is that we can save modules too, because they are just raw memory.

Syntax

.writemem FileName Range

Usage

0:026> lm
start end module name
00400000 00427000 mtgdi (deferred)
5a700000 5acaf000 mfc90d (deferred)
63df0000 63f13000 MSVCR90D (deferred)
71270000 71283000 dwmapi (deferred)
72cf0000 72d70000 UxTheme (deferred)
73470000 73475000 MSIMG32 (deferred)
73b90000 73b9d000 MFC90ENU (deferred)
74fd0000 75053000 COMCTL32 (deferred)
751d0000 751dc000 CRYPTBASE (deferred)
751e0000 75240000 SspiCli (deferred)
75240000 75259000 sechost (deferred)
75260000 75ea6000 SHELL32 (deferred)
75ee0000 75f8c000 msvcrt (deferred)
75fd0000 76060000 GDI32 (deferred)
76150000 76250000 kernel32 (deferred)
76250000 762ed000 USP10 (deferred)
763b0000 76410000 IMM32 (deferred)
76410000 7649f000 OLEAUT32 (deferred)
764a0000 764e4000 KERNELBASE (deferred)
765c0000 766b0000 RPCRT4 (deferred)
766b0000 76733000 CLBCatQ (deferred)
76a00000 76aa0000 ADVAPI32 (deferred)

(S) .break Works similar to break in C and C++ 0n19 0x13 0001 0011

76ce0000 76d37000 SHLWAPI (deferred)
76f40000 77040000 USER32 (deferred)
77040000 7710c000 MSCTF (deferred)
77110000 7726b000 ole32 (deferred)
77640000 7764a000 LPK (deferred)

Now let’s save MFC90ENU.DLL from the list above:
0:026> .writemem c:\downloads\MFC90ENU.dll 73b90000 (73b9d000 – 0x1)
Writing d000 bytes……………………..

Note the “- 0x1” above. If we don’t do that the command will fail because the debugger will try to write from the base address to the end address inclusive.
Another approach we can use is to get the size of the module and use it as one of the parameters:
0:026> ? 73b9d000 – 73b90000
Evaluate expression: 53248 = 0000d000

0:026> .writemem c:\downloads\MFC90ENU.dll 73b90000 L 0000d000

Writing d000 bytes……………………..

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Debugging

User profile corruption in the registry [REGISTRY_ERROR (51)]

by dnaadmin November 2, 2020
written by dnaadmin

REGISTRY_ERROR (51)
Something has gone badly wrong with the registry. If a kernel debugger is available, get a stack trace. It can also indicate that the registry got an I/O error while trying to read one of its files, so it can be caused by hardware problems or filesystem corruption. It may occur due to a failure in a refresh operation, which is used only in by the security system, and then only when resource limits are encountered.
Arguments:
Arg1: 00000003, (reserved)
Arg2: 00000004, (reserved)
Arg3: e82372f8, depends on where Windows bugchecked, may be pointer to hive
Arg4: 00000000, depends on where Windows bugchecked, may be return code of HvCheckHive if the hive is corrupt.

0: kd> !reg hivelist

-------------------------------------------------------------------------------------------------------------
| HiveAddr |Stable Length|Stable Map|Volatile Length|Volatile Map|MappedViews|PinnedViews|U(Cnt)| BaseBlock | FileName
-------------------------------------------------------------------------------------------------------------
| e1008a68 | 13000 | e1008ac8 | 1000 | e1008c04 | 0 | 0 | 0| e1015000 | <NONAME>
| e101a4e0 | 901000 | e1023000 | 40000 | e101a67c | 202 | 0 | 0| e101e000 | SYSTEM
| e1938188 | d000 | e19381e8 | 4000 | e1938324 | 0 | 0 | 0| e193a000 | <NONAME>
| e1968290 | 8000 | e19682f0 | 0 | 00000000 | 3 | 0 | 0| e1d39000 | \SystemRoot\System32\Config\SAM
| e1cab270 | 3d000 | e1cab2d0 | 1000 | e1cab40c | 16 | 0 | 0| e1d32000 | emRoot\System32\Config\SECURITY
| e1c9f448 | 3f70000 | e1e37000 | 1000 | e1c9f5e4 | 256 | 0 | 0| e1d71000 | temRoot\System32\Config\DEFAULT
| e1d75a80 | 7d5d000 | e1ee3000 | 23000 | e1d75c1c | 254 | 12 | 0| e1d37000 | emRoot\System32\Config\SOFTWARE
| e1ba30d0 | 37000 | e1ba3130 | 1000 | e1ba326c | 17 | 0 | 0| e1b9e000 | tings\NetworkService\ntuser.dat
| e1ba8060 | 1000 | e1ba80c0 | 0 | 00000000 | 1 | 0 | 0| e1b8e000 | \Microsoft\Windows\UsrClass.dat
| e1afc068 | 3b000 | e1afc0c8 | 1000 | e1afc204 | 17 | 0 | 0| e1b3d000 | ettings\LocalService\ntuser.dat
| e1d6e2a0 | 1000 | e1d6e300 | 0 | 00000000 | 1 | 0 | 0| e1b39000 | \Microsoft\Windows\UsrClass.dat
[...]
| e82372f8 | 106000 | e8237358 | 0 | 00000000 | 55 | 4 | 0| e514c000 | ings\User123\NTUSER.DAT
[…]
————————————————————————————————————-

0: kd> dt _CMHIVE e82372f8
nt!_CMHIVE
+0x000 Hive : _HHIVE
+0x2d0 FileHandles : [3] 0x80002234 Void
+0x2dc NotifyList : _LIST_ENTRY [ 0x0 - 0x0 ]
+0x2e4 HiveList : _LIST_ENTRY [ 0xe7a38d64 - 0xe4d9fc9c ]
+0x2ec HiveLock : _EX_PUSH_LOCK
+0x2f0 ViewLock : 0x877b0120 _KGUARDED_MUTEX
+0x2f4 WriterLock : _EX_PUSH_LOCK
+0x2f8 FlusherLock : _EX_PUSH_LOCK
+0x2fc SecurityLock : _EX_PUSH_LOCK
+0x300 LRUViewListHead : _LIST_ENTRY [ 0xe6160170 - 0xe3d71978 ]
+0x308 PinViewListHead : _LIST_ENTRY [ 0xe2714fe0 - 0xe108d9e0 ]
+0x310 FileObject : 0x89ecf310 _FILE_OBJECT
+0x314 FileFullPath : _UNICODE_STRING "\Device\HarddiskVolumeX\Documents and Settings\User123\NTUSER.DAT"
+0×31c FileUserName : _UNICODE_STRING “\??\E:\Documents and Settings\User123\NTUSER.DAT”
+0×324 MappedViews : 0×37
+0×326 PinnedViews : 4
+0×328 UseCount : 0
+0×32c SecurityCount : 9
+0×330 SecurityCacheSize : 9
+0×334 SecurityHitHint : 0n0
+0×338 SecurityCache : 0xe74d5008 _CM_KEY_SECURITY_CACHE_ENTRY
+0×33c SecurityHash : [64] _LIST_ENTRY [ 0xe3f80228 - 0xe5901ef0 ]
+0×53c UnloadEvent : (null)
+0×540 RootKcb : (null)
+0×544 Frozen : 0 ”
+0×548 UnloadWorkItem : (null)
+0×54c GrowOnlyMode : 0 ”
+0×550 GrowOffset : 0
+0×554 KcbConvertListHead : _LIST_ENTRY [ 0xe823784c - 0xe823784c ]
+0×55c KnodeConvertListHead : _LIST_ENTRY [ 0xe8237854 - 0xe8237854 ]
+0×564 CellRemapArray : (null)
+0×568 Flags : 1
+0×56c TrustClassEntry : _LIST_ENTRY [ 0xe8237864 - 0xe8237864 ]
+0×574 FlushCount : 0
+0×578 CreatorOwner : (null)

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
Debugging

Stuck in the Apps Debug mode for a Kernal Crash dump?

by dnaadmin November 2, 2020
written by dnaadmin

 

!wow64exts.sw Switches between x86 and native mode.

I’d like to introduce you to how to switch to a kernal mode from a apps mode.

This is how a apps mode prompt looks like:

0:001> 

The wow64 stuff in the call stack and the x64 registers do not tell us much.

To get the meaningful 32bit look of the application, you need to switch the processor mode that the debugger uses to 32bit by entering either .effmach x86 or !wow64exts.sw in windbg. The two commands are basically same. You should see output like the following:

0:001> !wow64exts.sw
Switched to 32bit mode

0:001:x86>

The call stack looks very different now. Particularly you do not see any wow64 and wow64cpu modules in the stack.

 

Note: The above solution works for the kernel mode dump of an x64 system too when you try to see the thread call stacks of a running 32bit process.

You can find more info @https://msdn.microsoft.com/en-us/library/windows/desktop/aa384163(v=vs.85).aspx

November 2, 2020 0 comments
0 FacebookTwitterPinterestEmail
  • 1
  • 2
  • 3
  • 4
  • 5
  • …
  • 7

Archives

  • February 2022
  • June 2021
  • November 2020
  • January 2019

Categories

  • Architecture
  • Backend
  • Basics
  • Blocks
  • Debugging
  • Device Drivers
  • Frontend
  • Guide
  • Interview
  • Network
  • Resources

Archives

  • February 2022
  • June 2021
  • November 2020
  • January 2019

Categories

  • Architecture
  • Backend
  • Basics
  • Blocks
  • Debugging
  • Device Drivers
  • Frontend
  • Guide
  • Interview
  • Network
  • Resources

Meta

  • Log in
  • Entries feed
  • Comments feed
  • WordPress.org

About Me

About Me

Freelance Developer

My name is Brian, freelance developer based in London, UK. Welcome to my internet journal where I started my learning journey.

Keep in touch

Facebook Twitter Linkedin Youtube Github

Resources

  • All the “Truth” you need to know about “Truth Table”

    February 19, 2022
  • Registers & Computer Memory Primer for x86

    February 19, 2022
  • Top listing blocks and reviews

    June 29, 2021

Recent Posts

  • All the “Truth” you need to know about “Truth Table”

    February 19, 2022
  • Registers & Computer Memory Primer for x86

    February 19, 2022
  • Top listing blocks and reviews

    June 29, 2021
  • Step list block

    June 29, 2021
  • How to blocks

    June 29, 2021

Categories

  • Architecture (5)
  • Backend (6)
  • Basics (6)
  • Blocks (3)
  • Debugging (11)
  • Device Drivers (1)
  • Frontend (6)
  • Guide (6)
  • Interview (6)
  • Network (1)
  • Resources (6)

Sign Up for Weekly Newsletter

Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.

[rh_mailchimp action=”//fleek.us10.list-manage.com/subscribe/post?u=4b4bbda55bb6deb367e6f52d9&id=6b32851a5b” inputname=”b_4b4bbda55bb6deb367f52d9_6b32851a5b” flat=1 button=”Subscribe” placeholder=”Email address”]

Frontend

  • All the “Truth” you need to know about “Truth Table”

    February 19, 2022
  • Registers & Computer Memory Primer for x86

    February 19, 2022
  • Top listing blocks and reviews

    June 29, 2021
  • Step list block

    June 29, 2021

Subscribe Newsletter

  • Facebook
  • Twitter
  • Linkedin
  • Youtube
  • Email
  • Github
  • Stack-overflow

Read alsox

Windbg Basics

November 2, 2020

Dumping a module’s memory space (via WinDbg)

November 2, 2020

Lauterbach Basics Playlist

November 2, 2020

Shopping Cart

Close

No products in the cart.

Close