This all needs to be done on the computer with the fault. I cannot load my ntdll.dll
as it a different version and the addresses will be different to yours.
Download and install Debugging Tools for Windows
http://msdn.microsoft.com/en-us/windows/hardware/hh852363
Install the Windows SDK but just choose the debugging tools.
Create a folder called Symbols
in C:\
This allows WinDbg to get the symbols for your version of ntdll.dll. Start Windbg. File menu - Symbol File Path and enter
srv*C:\symbols*http://msdl.microsoft.com/download/symbols
then
Open ntdll in WinDbg as a crashdump.
It will show the load address.
Type in WinDbg
ln <modloadaddress> + 7c911780
This will give you the nearest symbol to the crash. It probably isn't useful but lets see.
You can also run VB6 under WinDbg (make sure WinDbg is run as admin). When you crash do a stack trace.
Also do an !Analyze
when you crash. It is meant for blue screens but will give info on appcrash.
Type in the WinDbg command prompt
!analyze -v
-v
stands for Verbose and if the crash was originated by a program, as opposed to hardware or a driver, it will appear in the middle of the listing.
eg
PROCESS_NAME: java.exe
IMAGE_NAME: ntkrnlmp.exe
PROCESS_NAME only appears in the analyze -v
output and only if a program originated the call that faulted.
WinDbg Commands
Open as Executable.
windbg -o -g -G c:\windows\system32\cmd.exe /k batfile.bat
You can press F12
to stop it and kb
will show the call stack (g
continues the program). If there's errors it will also stop and show them.
There is a breakpoint after loading but before any code is run. Press g
to continue. Likewise there is a breakpoint after all code has run but before it is unloaded.
Type lm
to list loaded modules, x *!*
to list the symbols and bp symbolname
to set a breakpoint
If programming in VB6 then this environmental variable link=/pdb:none
stores the symbols in the dll rather than separate files. Make sure you compile the program with No Optimisations and tick the box for Create Symbolic Debug Info. Both on the Compile tab in the Project's Properties.
Sample output from a nearest symbol search.
Loading Dump File [C:\Windows\System32\ntdll.dll] Symbol search path
is: srvc:\symbolshttp://msdl.microsoft.com/download/symbols
Executable search path is: ModLoad: 4b280000 4b3f9000
C:\Windows\System32\ntdll.dll eax=00000000 ebx=00000000 ecx=00000000
edx=00000000 esi=00000000 edi=00000000 eip=4b280000 esp=00000000
ebp=00000000 iopl=0 nv up di pl nz na pe nc cs=0000 ss=0000
ds=0000 es=0000 fs=0000 gs=0000 efl=00000000
ntdll!__guard_fids_table (ntdll+0x0): 4b280000 4d
dec ebp 0:000> ln 4b280000 + 65534 (4b2e5520)
ntdll!RtlInitializeBitMap+0x14 | (4b2e5540)
ntdll!TpCallbackUnloadDllOnCompletion
Sample stack trace.
You follow what function called what functions. So you read it from the bottom up. It has the first 4 parameters that were passed to the function. You find the debugger starts additional threads so we need to find our program's one.
~
Lists all threads
~<threadid> e <command>
Do a KB on all threads until you find the main one.
0:004> ~0 e kb
ChildEBP RetAddr Args to Child 04bdfc30
75ae325a 04bdfc70 00000000 00000000 USER32!NtUserGetMessage+0xc
04bdfc4c 00895eb6 04bdfc70 00000000 00000000 USER32!GetMessageW+0x2a
04bdfc8c 008a5b41 00890000 00000000 04e2336f notepad!WinMain+0xe6
04bdfd20 74ad3744 7f229000 74ad3720 10fde46e
notepad!WinMainCRTStartup+0x151 04bdfd34 7755a064 7f229000 b0c1107f
00000000 KERNEL32!BaseThreadInitThunk+0x24 04bdfd7c 7755a02f ffffffff
7757d7c9 00000000 ntdll!__RtlUserThreadStart+0x2f 04bdfd8c 00000000
008a59f0 7f229000 00000000 ntdll!_RtlUserThreadStart+0x1b
Assume that 04bdfc70 is an HWnd. Which it is because the documentation says so. But assume it an address of a string. This displays what is there.
ds 775a1300
or to look at the values
db 775a1300