Windbg ethread - IrpList location - windows

I'm currently struggling to make sense of the output from Windbg.
What I'm trying to do is find out how many IRPs (Interrupt Request Packets) are queued in a particular thread, so here is what I currently have:
lkd> !thread
THREAD fffffa8001fce270
IRP List:
fffffa8001cf3b60
...
So this tells me that the current thread has one IRP in it's list, and it's address.
However, the next command is what's confusing me slightly:
lkd> ??#$thread->IrpList
struct _LIST_ENTRY
[ 0xfffffa8001cf3b80 - 0xfffffa8001cf3b80 ]
+0x000 Flink 0xfffffa8001cf3b80 _LIST_ENTRY [ 0xfffffa8001fce658 - 0xfffffa8001fce658]
+0x000 Blink 0xfffffa8001cf3b80 _LIST_ENTRY [ 0xfffffa8001fce658 - 0xfffffa8001fce658]
All of this information is coming out of the _ETHREAD structure, and according to windbg the offset for the 'IrpList' element in the structure is 0x3e8.
So if the thread (_ETHREAD) starts at offset 0xfffffa8001fce270, the IrpList element should be at offset 0xfffffa8001fce658 (0xfffffa8001fce270 + 0x3e8)
However, I don't fully understand why windbg is reporting the IRP List entry at offset 0xfffffa8001cf3b80.
I'm probably getting the wrong end of the stick here, but if anyone can point me in the right direction, I'd greatly appreciate it.
Thanks

The list address is not 0xfffffa8001cf3b80. That's the address of the list entry in the IRP, which is at IRP+0x20 (0xfffffa8001cf3b60 + 0x20 = 0xfffffa8001cf3b80). The list entry address in the ETHREAD is 0xfffffa8001fce658 (0xfffffa8001fce658 - fffffa8001fce270 = 0x3e8).

Related

Can WinDBG display information about an arbitrary heap address?

Does WinDBG provide a way of displaying type information (dt?) for a plain heap address?
I am looking at a scenario where paged heap and user mode stack traces are not available. While analysing the heap I was tracking down excessive heap usage and I found various objects in the heap that were referencing a certain memory address.
Mainly
!heap -srch [UserPtr] +0x30
returned objects like this:
0:004> !heap -srch 00000224ceade3a0+30
_HEAP # 224ceaa0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00000224ceae3ac0 045c 0000 [00] 00000224ceae3ad0 045ac - (busy)
_HEAP # 224ceaa0000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
00000224ceae8080 0346 045c [00] 00000224ceae8090 03454 - (busy)
Now due to missing user mode stack traces !heap -p -a [UserPtr] returns nothing.
So here I am, I know that actually 0x00000224ceae3ad0 and 0x00000224ceae8090 are the culprits. Well actually [UserPtr]+0x30 (48 bytes) for a reason I yet have to find out but I am stuck here. (I created a small sample where I was able to verify the address, so at least in the sample I am quite sure that the address are correct)
Is there something useful I can do at this point to gain more information about those address beside !address [Addr] which does not really help much.
Since I know size and address I could wade around in the heap and see what I can find but that seems random.
Any hints on how to get more data would be great.
For what it is worth: I am on a NT Heap with LFH.
Edit:
In my sample I of course know the data types but in the real world scenario I am facing these types are unknown to me, even with access to code it might be not obvious which instance of what objects points to this address beside coincidental matches of sizes.
if the UserPtr contained a vftable windbg will normally decode it in the output as below
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
029b1428 0030 0007 [00] 029b1430 00168 - (busy)
dbgeng!Debugger::DataModel::Host::HostModule::`vftable'
as raymond commented you can use dps like dps poi(UserPtr) or print individual entries
0:004> .printf "%y\n" , poi(029b1430)
dbgeng!Debugger::DataModel::Host::HostModule::`vftable' (59cde364)
0:004> .printf "%y\n" , poi(poi(029b1430)+2c)
dbgeng!Debugger::DataModel::Host::BaseSymbol::GetFullyQualifiedName (59f79670)
0:004> .printf "%y\n" , poi(poi(029b1430)+28)
dbgeng!Debugger::DataModel::Host::HostModule::IsEqual (59f77680)

Pinning a DLL in memory (increase reference count)

I am trying to run an application, but the application exits due to an access violation. Running the application in the debugger I can see that this is caused by an unloaded library. I can not wait for the next release of the application, so I'm trying to workaround the problem.
I wonder whether WinDbg provides a way of increasing the reference count of a loaded module, similar to the C++ LoadLibrary() call. I could then break on module loads and increase the reference count on the affected DLL to see if I can use the application then.
I have already looked for commands starting with .load, !load, .lock, !lock, .mod and !mod in WinDbg help. .load will load the DLL as an extension into the debugger process, not into the target process.
Update
Forgot to mention that I have no source code, so I can't simply implement a LoadLibrary() call as a workaround and recompile.
The comment by Hans Passant leads me to .call and I tried to use it like
.call /v kernel32!LoadLibraryA("....dll")
but it gives the error message
Symbol not a function in '.call /v kernel32!LoadLibraryA("....dll")'
Update 2
Probably the string for the file name in .call should be a pointer to some memory in the target process instead of a string which resides in WinDbg.exe where I type the command. That again means I would probably mean to allocate some memory to store the string inside, so this might become more complex.
Using .call in windbg as always been finicky to me. I believe you are having trouble with it because kernel32 only has public symbols so the debugger doesn't know what it's arguments look like.
So let's look at some alternatives...
The easy way
You can go grab a tool like Process Hacker, which I think is a wonderful addition to any debugger's tool chest. It has an option to inject a DLL into a process.
Behind the scenes, it calls CreateRemoteThread to spawn a thread in the target process which calls LoadLibrary on the chosen DLL. With any luck, this will increase the module reference count. You can verify that the LoadCount has been increased in windbg by running the !dlls command before and after the dll injection.
The hard way
You can also dig into the internal data structures Windows uses to keep track of a process's loaded modules and play with the LoadCount. This changes between versions of Windows and is a serious no-no. But, we're debugging, so, what the hell? Let's do this.
Start by getting a list of loaded modules with !dlls. Suppose we care about your.dll; we might see something like:
0x002772a8: C:\path\to\your.dll
Base 0x06b80000 EntryPoint 0x06b81000 Size 0x000cb000 DdagNode 0x002b3a10
Flags 0x800822cc TlsIndex 0x00000000 LoadCount 0x00000001 NodeRefCount 0x00000001
We can see that the load count is currently 1. To modify it, we could use the address printed before the module path. It is the address of the the ntdll!_LDR_DATA_TABLE_ENTRY the process holds for that module.
r? #$t0 = (ntdll!_LDR_DATA_TABLE_ENTRY*) 0x002772a8
And, now you can change the LoadCount member to something larger as so:
?? #$t0->LoadCount = 2
But, as I said, this stuff changes with new versions of Windows. On Windows 8, the LoadCount member was moved out of _LDR_DATA_TABLE_ENTRY and into a new ntdll!_LDR_DDAG_NODE structure. In place of it, there is now an ObsoleteNodeCount which is not what we want.
On Windows 8, we would run the following command instead:
?? #$t0->DdagNode->LoadCount = 2
And, time to check our work...
0x002772a8: C:\path\to\your.dll
Base 0x06b80000 EntryPoint 0x06b81000 Size 0x000cb000 DdagNode 0x002b3a10
Flags 0x800822cc TlsIndex 0x00000000 LoadCount 0x00000002 NodeRefCount 0x00000001
Awesome. It's 2 now. That'll teach FreeLibrary a lesson about unloading our DLLs before we say it can.
The takeaway
Try the easy way first. If that doesn't work, you can start looking at the internal data structures Windows uses to keep track of this kind of stuff. I don't provide the hard way hoping you'll actually try it, but that it might make you more comfortable around the !dlls command and those data structures in the future.
Still, all modifying the LoadCount will afford you is confirmation that you are seeing a DLL get unloaded before it should have. If the problem goes away after artificially increasing the LoadCount, meaning that you've confirmed your theory, you'll have to take a different approach to debugging it -- figuring out when and why it got unloaded.
A dll that is linked while compiling will normally have a LoadCount of -1 (0xffff) and it is not Unloadable Via FreeLibrary
so you can utilize the loadModule Event to break on a Dynamically Loaded Module and increase the LoadCount during the Event
Blink of InLoadOrderModuleList (last dll Loaded in the process) when on initial break at ntdll!Dbgbreak() xp-sp3 for an arbitrary console app which uses a dll
0:000> dt ntdll!_LDR_DATA_TABLE_ENTRY FullDllName LoadCount ##((( #$peb)->Ldr)->InLoadOrderModuleList.Blink)
+0x024 FullDllName : _UNICODE_STRING "C:\WINDOWS\system32\GDI32.dll"
+0x038 LoadCount : 0xffff <----------- not unloadable via FreeLibrary
setting up break on Specific Module Load
0:000> sxe ld skeleton
0:000> g
ModLoad: 10000000 10005000 C:\skeleton.dll
ntdll!KiFastSystemCallRet:
7c90e514 c3 ret
the LoadModule Breaks on MapSection so Ldr isnt yet updated
0:000> dt ntdll!_LDR_DATA_TABLE_ENTRY FullDllName LoadCount ##((( #$peb)->Ldr)->InLoadOrderModuleList.Blink)
+0x024 FullDllName : _UNICODE_STRING "C:\WINDOWS\system32\GDI32.dll"
+0x038 LoadCount : 0xffff
go up until the Ldr is updated
0:000> gu;gu;gu
ntdll!LdrpLoadDll+0x1e9:
7c91626a 8985c4fdffff mov dword ptr [ebp-23Ch],eax ss:0023:0013fa3c=00000000
blink showing the last loaded Module notice loadCount 0 not updated yet
0:000> dt ntdll!_LDR_DATA_TABLE_ENTRY FullDllName LoadCount ##((( #$peb)->Ldr)->InLoadOrderModuleList.Blink)
+0x024 FullDllName : _UNICODE_STRING "C:\skeleton.dll"
+0x038 LoadCount : 0
dump the LoadEntry of the module
0:000> !dlls -c skeleton
Dump dll containing 0x10000000:
**0x00252840:** C:\skeleton.dll
Base 0x10000000 EntryPoint 0x10001000 Size 0x00005000
Flags 0x00000004 LoadCount 0x00000000 TlsIndex 0x00000000
LDRP_IMAGE_DLL
increase load count arbitrarily and redump (process attach hasnt been called yet)
0:000> ed 0x252840+0x38 4
0:000> !dlls -c skeleton
Dump dll containing 0x10000000:
0x00252840: C:\skeleton.dll
Base 0x10000000 EntryPoint 0x10001000 Size 0x00005000
Flags 0x00000004 LoadCount 0x00000004 TlsIndex 0x00000000
LDRP_IMAGE_DLL
run the binary
0:000> g
dll is loaded into the process break with ctrl+break
Break-in sent, waiting 30 seconds...
(aa0.77c): Break instruction exception - code 80000003 (first chance)
ntdll!DbgBreakPoint:
7c90120e cc int 3
dump and see system has updated the loadcount to our count+1 also process attach has been called
0:001> !dlls -c skeleton
Dump dll containing 0x10000000:
0x00252840: C:\skeleton.dll
Base 0x10000000 EntryPoint 0x10001000 Size 0x00005000
Flags 0x80084004 LoadCount 0x00000005 TlsIndex 0x00000000
LDRP_IMAGE_DLL
LDRP_ENTRY_PROCESSED
LDRP_PROCESS_ATTACH_CALLED
btw use ken johnsons (skywing) sdbgext !remotecall instead of .call
it doesnt require Private Symbols
.load sdbgext
!remotecall kernel32!LoadLibraryA 0 "c:\skeleton.dll" ; g
should load the dll in the process
or use
!loaddll "c:\\skeleton.dll" from the same extension
kernel32!LoadLibraryA() will be run when execution is resumed
0:002> g
kernel32!LoadLibraryA() [conv=0 argc=4 argv=00AC0488]
kernel32!LoadLibraryA() returned 10000000
Simplest way - get .dll path and LoadLibrary it.
It will increase .dll reference count and .dll will not be released.

atmel at91sam9g20 ethernet register addresses

I have no real experience with hardware programming. I would like to know how to find out which registers, i.e their addresses, are used for an ethernet connection to send and receive information in a processer. In particular, for ATMEL's at91sam9g20 processor. I have searched the documentation and I'm not sure of the following of what I've found:
-Transmit data: signal name ETX0-ETX3. Receive data: signal name ERX0-ERX3.
Also, Offset: 0x18 Receive Buffer Queue Pointer Register and offset: 0x1C Transmit Buffer Queue Pointer Register.
I would appreciate any help as I'm very stuck on this issue.
Thank you
In the procesor documentation you find the following:
chapter 8 - general memory mapping - this gives the offset of the EMAC memory block as 0xFFFC:4000
chapter 36 - description of the Ethernet MAC subsystem
item 36.3.2 - memory interface - tells how the memory buffers for RX and TX is set up
item 36.5 - user interface - table 36-6 gives the names and offsets to all registers used by the subsystem
The signals (=pins) and register offsets you describe are correct.

How to list threads in WinDbg (kernel debugging)

Does anyone know how I can list all threads in WinDbg while kernel debugging. I have found older references that say '~' but that does not work.
Specifically I am looking to the find the ID of a thread that caused an event, namely a breakpoint.
Thanks.
~ only works in user mode. To list all threads on the system, it's !process 0 1 as I recall (it's been awhile).
"Specifically I am looking to the find the ID of a thread that caused an event, namely a breakpoint."
This statement doesn't make much sense to do from kernel mode. Can you descrive more about what your scenario is?
Edit: Ah, now I get it. You want to know which thread you're currently in right now. Give !thread a go.
You can always use the #$thread pseudo register to reference the current thread object:
0: kd> r #$thread
$thread=fffff80002c02cc0
If you want the ID of the thread, you'll need to dig it out of the ETHREAD. Luckily, the #$thread is typed as a pointer to an ETHREAD if you're using the C++ evaluator:
0: kd> ?? #$thread->Cid
struct _CLIENT_ID
+0x000 UniqueProcess : 0x00000000`00001408 Void
+0x008 UniqueThread : 0x00000000`0000144c Void
-scott

On MacOSX/PPC, suggestions on how to catch KERN_PROTECTION_FAILURE at 0x0000000000000000

This is a real time MMO client, at some random point it will crash with a jump to 0, and the stack frame is unreadable. The crash reporter (and GDB) will report thread 0 crashed:
XC_BAD_ACCESS (SIGBUS)
KERN_PROTECTION_FAILURE at 0x0000000000000000
and
srr0=lr=exception address=0
How can I catch where this error occurs?
If your stack pointer (r1) and link register are trashed then it's not looking good. However, it's possible that some other registers may still have the value of a frame pointer in them - for example non-leaf functions often seen to move the address to they return to to/from the stack via r0.
Other than that there's a couple of tricks you could pull - assuming that there is nothing mapped in the processes' address space at address 0x0 (which appears to be the case from the EXEC_BAD_ACCESS error) you could write a simple preload library which mapped page zero; which would allow you to add a breakpoint at 0x0; which may give you more info on what's going on.

Resources