How to use WER to create a dump with the application data and the handles - windows

Here is my registry:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps]
"DumpType"=dword:00000000
"CustomDumpFlags"=dword:00000006
According to this article DumpType=0 means custom dump and then CustomDumpFlags is taken into account. According to this article CustomDumpFlags=6 means MiniDumpWithFullMemory | MiniDumpWithHandleData, where:
MiniDumpWithFullMemory - Include all accessible memory in the process. The raw memory data is included at the end, so that the initial structures can be mapped directly without the raw memory information. This option can result in a very large file.
MiniDumpWithHandleData - Include high-level information about the operating system handles that are active when the minidump is made.
Now I have a crash-me application, so I run it, it crashes, the dump is created in %userprofile%\AppData\Local\CrashDumps, I open it in windbg and see the following line there:
User Mini Dump File with Full Memory: Only application data is
available
Which is equivalent to CustomDataFlags=2
So, how am I expected to create a dump with the handle data in it? If possible, I would like to use no third parties.
My OS is Windows 8 or Windows 2008R2 server or higher.

Try .dumpdebug, which is an undocumented command. At the top of the output there should be the flags:
0:006> .dumpdebug
----- User Mini Dump Analysis
MINIDUMP_HEADER: Version A793 (62F0) NumberOfStreams 15 Flags 41826
0002 MiniDumpWithFullMemory
0004 MiniDumpWithHandleData
0020 MiniDumpWithUnloadedModules
0800 MiniDumpWithFullMemoryInfo
1000 MiniDumpWithThreadInfo
40000 MiniDumpWithTokenInformation
If you dislike the verbose output, you can filter it with a find command on the shell:
.shell -ci ".dumpdebug" find "MiniDumpWith"

Related

How do I get handles information from a full-dump of a windows process?

I'm trying to debug an issue with what may be handle leak. I have a dump created on a remote windows machine and I would like to see the handles information. I'm using WinDbg. I have seen some articles from the MSDN and from other sources, like https://www.codeproject.com/Articles/6988/Debug-Tutorial-Part-5-Handle-Leaks, but I can't get it to work, so I need some help.
I tried the next
Using !handles or !devhandles - these have failed. I either get no export handles found or a failure to load kdexts. Apparently kernel debugging is not enabled.
I found winxp/kdexts.dll in my path (given from .chain command) but it wouldn't load - .load kdexts yields `DebugExtensionInitializeFailed1 with error code 0x80004005.
Using !handle - with !handle -? I get help for the command but when I try something else, I get "Unable to read handle information". For example,
!handle - I expected a full list of handles
!handle 0 0
!handle 0 0 file
My setup
The remote process is Windows server 2012 (64bit), just as my own machine
I'm using the latest WinDbg from the windows sdk 10
I have a full dump, created by right-clicking task manager
I need some help if possible
Do I need to do kernel-debugging in order to view the list of handles from the dump?
Is it possible at all to do kernel-debugging on a full dump created from task-manager? Or is it required that the dump be taken differently?
How can I know if a given dump file includes the handle information?
How can I use the !handle command properly?
Is there any other alternative, such as using visual studio, another utility, etc.?
I'd appreciate any help
!tamir
your dump was probably a dump taken without handle information
you may use dumpchk.exe that comes with windbg installation to see if Handle Stream exists in the dump
if you have control over dump creation check how to use .dump /ma with windbg
or you may also explore sysinternals procdump.exe
and also make sure you are using the correct bitted debugger for the dump in question
a sample path
D:\>dir /s /b "c:\Program Files (x86)\Windows Kits\10\Debuggers\cdb.exe"
c:\Program Files (x86)\Windows Kits\10\Debuggers\arm\cdb.exe
c:\Program Files (x86)\Windows Kits\10\Debuggers\arm64\cdb.exe
c:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe
c:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe
here is a sample dump creation with and without handle stream in the dump
:000> .dump /ma d:\madump.dmp
Creating d:\madump.dmp - mini user dump
Dump successfully written
0:000> .dump d:\nomadump.dmp
Creating d:\nomadump.dmp - mini user dump
Dump successfully written
0:000> q
analysing both the dumps with dumpchk and checking for streams present
dumpchk nomadump.dmp > nomachk.txt
dumpchk madump.dmp > machk.txt
D:\>type machk.txt |grep -i number.*stream
NumberOfStreams 17
D:\>type nomachk.txt |grep -i number.*stream
NumberOfStreams 13
diff
D:\>diff -y machk.txt nomachk.txt
Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64 Microsoft (R) Windows Debugger Version 10.0.17763.132 AMD64
Loading Dump File [D:\madump.dmp] | Loading Dump File [D:\nomadump.dmp]
User Mini Dump File with Full Memory: Only application d | User Mini Dump File: Only registers, stack and portions of me
----- User Mini Dump Analysis ----- User Mini Dump Analysis
MINIDUMP_HEADER: MINIDUMP_HEADER:
Version A793 (A063) Version A793 (A063)
NumberOfStreams 17 | NumberOfStreams 13
Flags 441826 | Flags 40000
0002 MiniDumpWithFullMemory <
0004 MiniDumpWithHandleData <
0020 MiniDumpWithUnloadedModules <
0800 MiniDumpWithFullMemoryInfo <
1000 MiniDumpWithThreadInfo <
40000 MiniDumpWithTokenInformation 40000 MiniDumpWithTokenInformation
400000 MiniDumpWithIptTrace <
if you feel enterprising take a look here for some hints to deciphering a dump without windbg /dbgeng
forgot to post the result of doing !handle on both dumps
D:\>cdb -c "!handle;q" -z nomadump.dmp |awk /Reading/,/quit/"
0:000> cdb: Reading initial command '!handle;q'
ERROR: !handle: extension exception 0x80004002.
"Unable to read handle information"
quit:
D:\>cdb -c "!handle;q" -z madump.dmp |awk /Reading/,/quit/"
0:000> cdb: Reading initial command '!handle;q'
Handle 0000000000000004
Type File
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxSNIPxxxxxxxxx
Handle 0000000000000128
Type Mutant
Handle 000000000000012c
Type
Handle 0000000000000180
Type File
70 Handles
Type Count
None 27
Event 13
File 8
Directory 2
Mutant 1
Semaphore 2
Key 6
IoCompletion 2
TpWorkerFactory 2
ALPC Port 1
WaitCompletionPacket 6
quit:
Check the tool which was used for creating the crash dump. Perhaps it provides an option to include handle data.
Task Manager includes handle data by default
Visual Studio includes handle data by default
In WinDbg, .dump can be used with the /mh switch to include handle data. /ma is a shortcut for /mfFhut, so it also includes handle data.
ProcDump automatically includes handle data.
Windows Error Reporting LocalDumps can be configured with a Registry value called CustomDumpFlags.
If you create the dump programmatically yourself with MiniDumpWriteDump(), use MINIDUMP_TYPE::MiniDumpWithHandleData.

How do I find out a program version from a core dump? Can I write it there myself?

I have a core file, but I am uncertain which version of the program produced it. When I use the file command, I get only the binary name, not the version.
% file core.20200730-1203
core.20200730-1203: ELF 64-bit LSB core file, x86-64, version 1 (SYSV), SVR4-style, from 'qdrouterd -c /tmp/qdrouterd.json', real uid: 0, effective uid: 0, real gid: 0, effective gid: 0, execfn: '/usr/sbin/qdrouterd', platform: 'x86_64'
I can try to give my debugger multiple binaries in turn that I guess are close in version, and see what works and what doesn't.
I believe that the solution is to put a string constant with the version into the program code. Core dumps contain the program code, because it is loaded into memory for execution, and therefore I should be able to recover it using the strings command.
Currently, the program contains the following, where QPID_DISPATCH_VERSION is a preprocessor macro.
qd_log(router->log_source, QD_LOG_INFO, "Version: %s", QPID_DISPATCH_VERSION);
I am able to get to it, with
% strings core.20200730-1203 | grep -A3 -B3 "Version: "
Activating management agent on $_management_internal
router
Router Engine Instantiated: id=router-default-0 instance=1596103149 max_routers=128
Version: 1.13.0-SNAPSHOT
Router started in Interior mode, area=0 id=router-default-0
Container Name: router-default-0
Milan
but this is probably just an accident, a log line which was still present in the memory at the moment of crash.
What is a reliable way to encode and recover the version information?

cannot edit ghostprint ppd in Windows 10

I had some difficulty posing my problem in a way that the Title filter found pleasing. The real problem is that modifying only the GhostPDF.PDD file in the GS9.26 installation in Windows 10 doesn't seem to affect the output after a re-installation using Windows 10 Device Installer.
I print to a networked Sun SPARCprinter 1 which is controlled by Ghostprint (script?) compiled to run on SunOS 4.1.4. This has worked successfully for some years printing output from Windows XP using Adobe's PS driver and a SPARCstation PPD cobbled together from samples found on the net.
I've installed Artifex's 9.26 on Windows 10 and output to an LPR printer (The Sun). The output works, is recognized as PS output by the Sun, but produces a number of FATAL errors.
I need to edit the Windows Ghostscript installation to output PS files which are more suitable for the Sun.
So to my simple question: Do I need to modify anything in the Ghostscript Windows 10 installation other than the Ghostpdf.PPD file?
additional info:
SPARCstation 10 information:
SunOS 4.1.4
arcad# gcc -dumpversion
2.95.2 Note: I had to bootstrap this version up from the early GCC which could be compiled with the SunOS 4.1.4 C compiler. I had the impression I couldn't bring it up any further but could be mistaken.
arcad# gs --help
Aladdin Ghostscript 6.01 (2000-03-17)
Copyright (C) 2000 Aladdin Enterprises ...
Usage: gs [switches] [file1.ps file2.ps ...]
Most frequently used switches: (you can use # in place of =)
-dNOPAUSE no pause after page | -q `quiet', fewer messages
-g<width>x<height> page size in pixels | -r<res> pixels/inch resolution
-sDEVICE=<devname> select device | -dBATCH exit after last file
-sOutputFile=<file> select output file: - for stdout, |command for pipe,
embed %d or %ld for page #
Input formats: PostScript PostScriptLevel1 PostScriptLevel2 PDF
.....
For more information, see /usr/local/share/ghostscript/6.01/doc/Use.htm.
Note: I think this is the most recent GS version I can compile with this gcc version
printcap section:
gp|GhostPrinter:\
:lp=/dev/lpvi0:sd=/var/spool/gsprintspool:lf=/var/spool/gsprintspool/log:\
:mx#0:sh:if=/usr/local/libexec/lpfilter-gps:
Typical spool file - "....." indicates stuff not included here"
arcad# more dfA004DESKTOP-M8C5I86
%!PS-Adobe-3.0
%%Title: Document
%%Creator: PScript5.dll Version 5.2.2
%%CreationDate: 12/14/2018 19:56:8
%%For: jferg
%%BoundingBox: (atend)
%%Pages: (atend)
%%Orientation: Portrait
%%PageOrder: Special
%%DocumentNeededResources: (atend)
%%DocumentSuppliedResources: (atend)
%%DocumentData: Clean7Bit
%%TargetDevice: (Ghostscript) (3010) 815
%%LanguageLevel: 3
%%EndComments
%%BeginDefaults
%%PageBoundingBox: 0 0 612 792
%%ViewingOrientation: 1 0 0 1
%%EndDefaults
.....
%%EndResource
userdict /Pscript_WinNT_Incr 230 dict dup begin put
%%BeginResource: file Pscript_FatalError 5.0 0
userdict begin/FatalErrorIf{{initgraphics findfont 1 index 0 eq{exch pop}{dup
length dict begin{1 index/FID ne{def}{pop pop}ifelse}forall/Encoding
{ISOLatin1Encoding}stopped{StandardEncoding}if def currentdict end
/ErrFont-Latin1 exch definefont}ifelse exch scalefont setfont counttomark 3 div
cvi{moveto show}repeat showpage quit}{cleartomark}ifelse}bind def end
%%EndResource
userdict begin/PrtVMMsg{vmstatus exch sub exch pop gt{[
quires more memory than is available in this printer.)100 500
more of the following, and then print again:)100 485
put format, choose Optimize For Portability.)115 470
ce Settings page, make sure the Available PostScript Memory is accur--More--(2%)
ce the number of fonts in the document.)115 440
ocument in parts.)115 425 12/Times-Roman showpage
Error: Low Printer VM ]%%)= true FatalErrorIf}if}bind def end
2016 ge{/VM?{pop}bind def}{/VM? userdict/PrtVMMsg get def}ifelse
.....
SPARCprinter PDD file which works with Adobe PS in Windows XP:
john#hp2:~/sun-stuff/cups-sparc$ more SPARCprinter2.ppd
*PPD-Adobe: "4.1"
*% PostScript(R) Printer Description File for SPARCprinter
*% Date: 94/01/14
*% Copyright 1994 Sun Microsystems, Inc. All Rights Reserved.
*% Permission is granted for redistribution of this file as
*% long as this copyright notice is intact and the contents
*% of the file is not altered in any way from its original form.
*% End of Copyright statement
*% Changed margins on SPARCprinter JAF 3-3-2017
*FormatVersion: "4.1"
*FileVersion: "1.10"
*LanguageEncoding: ISOLatin1
*LanguageVersion: English
*PCFileName: "SPRN.PPD"
*Product: "(SPARCprinter)"
*PSVersion: "(3.000) 0"
*ModelName: "SPARCprinter"
*ShortNickName: "SPARCprinter"
*NickName: "SPARCprinter"
*% ==== Device Capabilities ===============
*LanguageLevel: "3"
*Extensions: CMYK Composite
*FreeVM: "4194304"
*ColorDevice: False
*DefaultColorSpace: Gray
*VariablePaperSize: False
*TTRasterizer: None
*FileSystem: False
..... more of the usual stuff
I don't really understand why you have installed Ghostscript on Windows. Windows is perfectly capable of producing PostScript files all of its own. In addition, the PPD file doesn't actually do very much, it is simply a text file with descriptions of the capabilities of the printer.
So the real problem is, or seems to be, that your SUN setup doesn't like the PostScript being produced by the new version of Windows.
You don't say how you are printing the PostScript file. not how your printer is 'controlled by Ghostscript' (I'm not aware of any product called Ghostprint, there is a GSPrint as part of GSView, but that's really for Windows).
Assuming you are using Ghostscript on your Sparc workstation to drive the pritner, then the most likely problem I would say is that you are using an old version of Ghostscript on the workstation, and it doesn't like the PostScript being generated by the newer version of Windows.
If you had included the transcript from the workstation Ghostscript installation it might be possible to say more but without that I'm rather guessing.
Another possibility is that you are using the ps2write device in Ghostscript to produce PostScript files on Windows. I can't think why you would be doing that, but it sort of fits your description. In that case editing the PPD file will have no effect, because Ghostscript doesn't use it.
Now the ps2write device emits level 2 PostScript, the clue is in the name, and its possible again that your Sparc setup is so elderly that it doesn't understand level 2, or doesn't fully implement it. In which case you will probably get errors. Again, if you were to provide the text of the error messages this would help!
In the latter case, you are frankly out of luck. We dropped support for level 1 PostScript output some time ago, what with level 2 being 28 years old now and level 3 coming up on 20. If you need language level 1 output you will have to go back to a very old version of Ghostscript. Something like 9.07 (from 5 and a half years ago) was the last version that included the pswrite device.
With effort you could take the pswrite device and upgrade it so that it works with the current version of Ghostscript
[EDIT]
My word, that's a really old version of Ghostscript!
You could try building a new version to replace it, but I also don't know if current code will compile on gcc 2.95. It 'should' because we only expect C89, but the third party libraries (which are essential) may very well not compile.
The PostScript file you quoted has been produced by Windows, not by Ghostscript (%%Creator: PScript5.dll Version 5.2.2). So it seems likely to me that your problem is the PostScript being produced by the newer version of Windows doesn't work with your 18 year old version of Ghostscript. That's not actually entirely surprising.
If you look at the DSC comments it says:
%%LanguageLevel: 3
And your Ghostscript information says that it supports language levels 1 and 2. At the time the level 3 spec had only just been published (1999), and clearly the maintainers back then hadn't had time to fully implement it.
Note that the ghostpdf.ppd file is intended for use with Ghostscript as a 'print to PDF' printer along with the RedMon port monitor.
Now its not obvious to me which PPD file you are using, but..... Both the ghostpdf.ppd file and the sparcprinter ppd file have :
*LanguageLevel: "3"
That tells the PostScript driver that it can use language level 3, which your Sparc Ghostscript doesn't support. You could try changing that to:
*LanguageLevel: "2"
and see if that makes a difference (you will have to uninstall the printers from Windows and re-install them with the modified PPD file).
If it doesn't work, the only other thing I can think of is to use the Ghostscript you installed on the Windows system, and preprocess the PostScript file produced by Windows before you send it on. You can use the ps2write device in Ghostscript 9.26 to take in the level 3 file, and produce a level 2 file. It might be a bit bigger, but it ought to work.
To do that on Windows you would use something like:
gswin64c -sDEVICE=ps2write -sOutputFile=out.ps <input.ps>
The file 'out.ps' should then be a level 2 PostScript file. I can't guarantee that the output will then work the old version of Ghostscript on your Sparc, but you stand a chance!

Unable to get full user-mode stacktrace while kernel debugging in windbg

I have a virtual Windows 7 x64 machine on a Windows 10 host, and I kernel debug it with windbg 10.0.10586.567. I'm running my own application on it, which I have full source and private symbols for. Whenever I break in and ask for stack traces of the app's threads, the backtrace always stops when one of my application's binaries are "hit."
So for instance, if I break in, switch to the process, and request a stacktrace with !thread [thread address] 1f, I get something like this (note the "early" zero return address at the last line):
fffff880`0534e870 fffff800`026d6992 nt!KiSwapContext+0x7a
fffff880`0534e9b0 fffff800`026d81a2 nt!KiCommitThreadWait+0x1d2
fffff880`0534ea40 fffff800`029c7a2e nt!KeDelayExecutionThread+0x186
fffff880`0534eab0 fffff800`026d08d3 nt!NtDelayExecution+0x59
fffff880`0534eae0 00000000`76e7165a nt!KiSystemServiceCopyEnd+0x13 (TrapFrame # fffff880`0534eae0)
00000000`00276708 000007fe`fcf91203 ntdll!NtDelayExecution+0xa
00000000`00276710 00000001`410e7dd9 KERNELBASE!SleepEx+0xab
00000000`002767b0 00000000`00000000 MyApp!MainMessageLoop+0x4b1 [d:\whatever\path\myapplication.cpp # 3024]
This looks very similar to when you you are missing a binary while debugging a user-mode dump (lack of unwind data) of an x64 process, except in that case the stack trace usually does not stop "this sudden", rather it goes astray at that point, and shows bogus values.
Some extra info/things I tried:
I have the correct symbol paths set up (both the Microsoft symbol server, and a local folder on the host with matching PDBs, even though the latter is not needed for just the stack trace)
I have a binary path set up (.exepath) containing matching binaries on the host (I've made absolutely sure of this; copied the binaries directly from the guest to the host machine)
If I put a breakpoint in one of the app's exported DLL functions, then when the debugger breaks in, I get a one-liner stack trace like this: 0000000000274b40 0000000000000000 MyAppDLL!SomeExportedFunction+0x32 [d:\whatever\path\myapplicationDLL.cpp # 232]
I've tried virtually every combination of commands to get a stacktrace (.process /i, .process /r /p, !process -1 7, .reloads, .reload /users, .reload /f MyApp.exe, !thread [address] 1f, etc.) with no success
Tried with an older version of windbg (6.11.0001.404) as well, same result
Also tried on Windows 8.1 as a guest with the very same binaries, same result
!sym noisy output (irrelevant lines omitted):
0: kd>.process /i [address]
0: kd>g
0: kd>.reload /user
0: kd> !process -1 2
0: kd> !thread [address] 1f
[...]
DBGHELP: d:\symbolcache\MyApp.pdb\76931C5A6C284779AD2F916CA324617E1\MyApp.pdb already cached
DBGHELP: MyApp - private symbols & lines
[...]
lmvm MyApp output:
[...]
Loaded symbol image file: MyApp.exe
Image path: C:\MyApp\MyApp.exe
[...]
Any ideas?
I accidentally stumbled into a linker switch that solves this problem: /DEBUGTYPE with the PDATA argument. If you link your binaries with this switch, unwind information will be copied into your PDBs.
I recompiled/relinked the application in question with /DEBUGTYPE:CV,PDATA (/DEBUGTYPE:CV is the default if /DEBUG is specified, see the documentation), now everything works like a charm, I always get full call stacks.
One strange aspect of this: windbg happily uses unwind data found in the PDBs, but ignores the very same data in the mapped binaries (both on the host machine).
This is not a perfect solution to the problem (or any solution at all, one might say), but I'm providing this provisional answer with a workaround.
You should be able to get the information you want, albeit not so well-formatted using something like dps #rsp L10.
In x86-64 you don't have a parallel of the x86 ebp-chain, but the return addresses are still on the stack. Those will give you the functions in the stack, and the values between them will be the arguments passed to the functions (and saved registers on the stack, etc.). A random example from Google (as I'm not on my Windows machine right now):
0:017> dps #rsp
00000000`1bb0fbb8 00000000`00000020
00000000`1bb0fbc0 00000000`00000000
00000000`1bb0fbc8 00000000`008bc6c6 Dolphin!ReadDataFromFifoOnCPU+0xb6 [d:\sources\comex\source\core\videocommon\fifo.cpp # 245]
00000000`1bb0fbd0 00000000`1ba0ffeb
00000000`1bb0fbd8 00000000`00000020
00000000`1bb0fbe0 00000000`00000020
00000000`1bb0fbe8 00000000`00000800
00000000`1bb0fbf0 00000000`1ba0ffeb
00000000`1bb0fbf8 00000000`008c2ff5 Dolphin!InterpretDisplayListPreprocess+0x45 [d:\sources\comex\source\core\videocommon\opcodedecoding.cpp # 87]
00000000`1bb0fc00 00000000`00000000
00000000`1bb0fc08 00000000`008bc041 Dolphin!RunGpu+0x81 [d:\sources\comex\source\core\videocommon\fifo.cpp # 389]
00000000`1bb0fc10 00000000`8064cbc0
00000000`1bb0fc18 00000000`1bb0fcc0
00000000`1bb0fc20 00000000`00000000
00000000`1bb0fc28 00000000`008c2dda Dolphin!OpcodeDecoder_Preprocess+0x14a [d:\sources\comex\source\core\videocommon\opcodedecoding.cpp # 326]
00000000`1bb0fc30 00000000`8064cbe0
Given that you have symbols, the return addresses are easily distinguishable.
The unwind data is lazy loaded for user mode modules, so it's not going to be mapped unless someone needs it. Unfortunately the kernel debugger doesn't force the information to be present for user images, so sometimes you get this behavior. You can see if the data is mapped or not by dumping the PE header (!dh) and checking the state of the Exception Directory (!pte imagename+offset).
Given that you own the app, try forcing the information to be resident by doing a stack walk NOP somewhere in your app:
PVOID stack[2];
(VOID)CaptureStackBackTrace(0, 2, (PVOID*)&stack, NULL);
That doesn't guarantee the entire directory will be present, but usually good enough.

How to break on the entry point of a program when debug in kernel mode with windbg?

I want to debug a program in kernel mode, and I want to break on the entry point of the program like ollydbg. But I can't break it with bp because the program is not start and the symbol can't be loaded. I have found some way to do it but I think it's not so good.
1.Break on the CreateProcess function in kernel. But I don't know which function exactly should I break and I think there is a long way between CreateProcess and the entry point of the program.
2.Change the entry point of the program with cc. But it needs other tools and I should change the code where the byte changed back. I think it is annoying.
3.With the help of ollydbg. Debugging the program with ollydbg in a virtual machine which is debugged with windbg. I don't think that it is a good idea.
4.Use sxe ld. It can be found on Listing 3.29 in <<Advanced Windows Debugging>>. I have tried it but I found that it only works on the first time. And I don't know what exactly should I do after the break.
5.Break on the entry function with bu. But I don't know what exactly I should do either. For example, how to load the symbol?
6.Use .create. I don't know whether it is properly or not to do what I said.
I think that it is a common use to break on the entry point of a program when debug in kernel mode with windbg , and I think that there must be a good way to do that with the powerful windbg. What's the best way to do it?
By the way, I want to debug a program in kernel mode because I want to get the token vaule of the program. I found that the windbg can identify the token with !token in user mode, but I don't know how to get the value of token in user mode. It seems that I can only get the value of token in the kernel mode, right or wrong?
you can run any exe in the target via ntsd -d to debug it from the kernel mode debugger running in the host
assuming you are running a virtual machine mytarget inside myhost
install windbg in myhost
set symbol path for myhost viz srv*x:\xxxx*http:\xxxxxxxxxxxx
create a kernel connection in the host (choose the best shown below is a serial connnection)
X:\xxxx\windbg.exe -k com:pipe,port=\\.\pipe\debugPipe,resets=0,reconnect
install windbg in mytarget
open a shared folder z:\ pointing to the symbolcache folder in myhost
set symbolpath in mytarget pointing to the shared folder
run ntsd -d calc.exe
kd will break on $exentry of calc.exe with Input Prompt
as long as Input prompt is shown you are using kd like a native usermode debugger
so if you set a bp calc!Winmain and issue g kd will break on calc.exe winmain
to get to kd session use .breakin
messy stuff but will work well once you get accustomed (ie memorizing the docs)
a sample run
kd> g <-------------- kd session running in myhost
CommandLine: calc.exe
Symbol search path is: srv*z:\
*http://msdl.microsoft.com/download/symbols
ntdll!DbgBreakPoint:
7c90120e cc int 3
.sympath
NOTE: The symbol path for this ntsd is relative to where
ntsd.exe is running, not where kd.exe is running.
Symbol search path is: srv*z:\
*http://msdl.microsoft.com/download/symbols
Expanded Symbol search path is: srv*z:\
*http://msdl.microsoft.com/download/symbols
.reload /f calc.exe
lm m calc
start end module name
01000000 0101f000 calc (pdb symbols) z:\calc.pdb\3B7D84101\calc.pdb
0:000> version <--------------------usermode session in kd via ntsd -d
version
Windows XP Version 2600 (Service Pack 3) UP Free x86 compatible
Live user mode: <Local>
command line: 'ntsd -d calc.exe' Debugger Process 0x3F8
? $exentry;? calc!WinmainCrtstartup
Evaluate expression: 16852085 = 01012475
Evaluate expression: 16852085 = 01012475
as to your original request i am not sure what token you are interested to find
if getting the EPROCESS->Token of your exe is the only requirement you dont have to run any kd session
you can get the token of all running process in myhost with a local kernel debugging session (either using kd -kl or by using livekd from sysinternals)
here is a simple script which fetches the sid of all running process employing the above technique
:\>cat sid.txt
!for_each_process "r $t0 =(##c++(((nt!_eprocess *) ##Process )->Token.Object)) &
##(~7); r $t1 = ##c++(((nt!_token *) #$t0 )->UserAndGroups->Sid);!sid #$t1 1; ?
? (char *)((nt!_eprocess *) ##Process )->ImageFileName "
:\>kd -kl -c "$$>a< sid.txt;q"
result
WARNING: Local kernel debugging requires booting with kernel
debugging support (/debug or bcdedit -debug on) to work optimally.
lkd> kd: Reading initial command '$$>a< sid.txt;q'
SID is: S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
char * 0x8ac729a4
"System"
SID is: S-1-5-18 (Well Known Group: NT AUTHORITY\SYSTEM)
char * 0x8a35729c
"smss.exe"
SID is: S-1-5-20 (Well Known Group: NT AUTHORITY\NETWORK SERVICE)
char * 0x8a3619ac
"svchost.exe"
SID is: S-1-5-19 (Well Known Group: NT AUTHORITY\LOCAL SERVICE)
char * 0x8a36ef14
"svchost.exe"
SID is: S-1-5-21-602162358-1801674531-1417001333-1003 (User: XXXXXX\Admin)
char * 0x8a261b64
"explorer.exe"
Use the method described in the Windbg help file for debugging WinLogon. Substitute your user mode app for WinLogon:
Windbg | Help | Contents | Windows Debugging | Debugging Techniques | Specialized Debugging Techniques | Debugging WinLogon
IFEO will start your user mode app and attach ntsd.exe. From ntsd.exe, you can set a break point on image entry with bu $exentry then g to continue.
At any point that ntsd.exe is broken into your user mode process, you can issue .breakin command to switch to kernel mode debugging.

Resources