使用 windbg 在内核模式下调试时如何中断程序的入口点?
How to break on the entry point of a program when debug in kernel mode with windbg?
我想在内核模式下调试一个程序,我想在程序的入口点中断,比如ollydbg
。但是我不能用 bp
打破它,因为程序没有启动,符号也无法加载。我找到了一些方法,但我认为它不是很好。
1.Break 在内核中的 CreateProcess
函数上。但我不知道我到底应该打破哪个功能,我认为 CreateProcess
和程序的入口点之间有很长的路要走。
2.Change cc
程序的入口点。但它需要其他工具,我应该更改字节变回的代码。我觉得很烦人。
3.With ollydbg
的帮助。在用 windbg 调试的虚拟机中用 ollydbg
调试程序。我不认为这是个好主意。
4.Usesxe ld
。它可以在 <<Advanced Windows Debugging>>
中的 Listing 3.29
上找到。我已经尝试过了,但我发现它只适用于第一次。而且我不知道休息后我到底应该做什么。
5.Break在入口函数上用bu
。但我也不知道我到底应该做什么。比如符号怎么加载?
6.Use.create
。不知道按我说的做对不对
我认为在使用 windbg
在内核模式下调试时在程序的入口点中断是一种常见的用法,而且我认为必须有一个很好的方法来使用强大的windbg
。最好的方法是什么?
对了,我想在内核模式下调试一个程序,因为我想得到程序的令牌值。我发现windbg在用户态下可以识别!token
的token,但是我不知道在用户态下如何获取token的值。貌似我只能在内核态获取token的值,对不对?
使用Windbg帮助文件中介绍的方法调试WinLogon。用您的用户模式应用程序替换 WinLogon:
Windbg |帮助 |目录 | Windows调试|调试技巧 |专业调试技术 |调试 WinLogon
IFEO 将启动您的用户模式应用程序并附加 ntsd.exe。从 ntsd.exe 开始,您可以使用 bu $exentry
在图像输入上设置断点,然后 g
继续。
在 ntsd.exe 进入您的用户模式进程的任何时候,您可以发出 .breakin
命令切换到内核模式调试。
您可以 运行 通过 ntsd -d 在目标中的任何 exe 来从主机中的内核模式调试器 运行 调试它
假设您正在 运行在 myhost
中安装虚拟机 mytarget
在我的主机中安装 windbg
为 myhost 设置符号路径即 srv*x:\xxxx*http:\xxxxxxxxxxxx
在主机中创建内核连接(下图选择最好的是串口连接)
X:\xxxx\windbg.exe -k com:pipe,port=\\.\pipe\debugPipe,resets=0,reconnect
在 mytarget 中安装 windbg
打开共享文件夹 z:\ 指向 myhost 中的 symbolcache 文件夹
在指向共享文件夹的 mytarget 中设置符号路径
运行 ntsd -d calc.exe
kd 将在 calc.exe 的 $exentry 与 Input Prompt
中断
只要显示输入提示,您就可以像使用本机用户模式调试器一样使用 kd
所以如果你设置 bp calc!Winmain 并发出 g kd 将在 calc.exe winmain
上中断
进入 kd 会话使用 .breakin
杂乱的东西,但一旦你习惯了(即记住文档)就会很好用
一个样本运行
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.pdbB7D84101\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
关于您最初的请求,我不确定您有兴趣找到什么令牌
如果获取 exe 的 EPROCESS->Token 是唯一的要求,则您不必 运行 任何 kd 会话
您可以使用本地内核调试会话(使用 kd -kl 或使用来自 sysinternals 的 livekd)获取 myhost 中所有 运行ning 进程的令牌
这是一个简单的脚本,它使用上述技术获取所有 运行ning 进程的 sid
:\>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"
结果
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"
我想在内核模式下调试一个程序,我想在程序的入口点中断,比如ollydbg
。但是我不能用 bp
打破它,因为程序没有启动,符号也无法加载。我找到了一些方法,但我认为它不是很好。
1.Break 在内核中的 CreateProcess
函数上。但我不知道我到底应该打破哪个功能,我认为 CreateProcess
和程序的入口点之间有很长的路要走。
2.Change cc
程序的入口点。但它需要其他工具,我应该更改字节变回的代码。我觉得很烦人。
3.With ollydbg
的帮助。在用 windbg 调试的虚拟机中用 ollydbg
调试程序。我不认为这是个好主意。
4.Usesxe ld
。它可以在 <<Advanced Windows Debugging>>
中的 Listing 3.29
上找到。我已经尝试过了,但我发现它只适用于第一次。而且我不知道休息后我到底应该做什么。
5.Break在入口函数上用bu
。但我也不知道我到底应该做什么。比如符号怎么加载?
6.Use.create
。不知道按我说的做对不对
我认为在使用 windbg
在内核模式下调试时在程序的入口点中断是一种常见的用法,而且我认为必须有一个很好的方法来使用强大的windbg
。最好的方法是什么?
对了,我想在内核模式下调试一个程序,因为我想得到程序的令牌值。我发现windbg在用户态下可以识别!token
的token,但是我不知道在用户态下如何获取token的值。貌似我只能在内核态获取token的值,对不对?
使用Windbg帮助文件中介绍的方法调试WinLogon。用您的用户模式应用程序替换 WinLogon:
Windbg |帮助 |目录 | Windows调试|调试技巧 |专业调试技术 |调试 WinLogon
IFEO 将启动您的用户模式应用程序并附加 ntsd.exe。从 ntsd.exe 开始,您可以使用 bu $exentry
在图像输入上设置断点,然后 g
继续。
在 ntsd.exe 进入您的用户模式进程的任何时候,您可以发出 .breakin
命令切换到内核模式调试。
您可以 运行 通过 ntsd -d 在目标中的任何 exe 来从主机中的内核模式调试器 运行 调试它
假设您正在 运行在 myhost
中安装虚拟机 mytarget在我的主机中安装 windbg
为 myhost 设置符号路径即 srv*x:\xxxx*http:\xxxxxxxxxxxx
在主机中创建内核连接(下图选择最好的是串口连接)
X:\xxxx\windbg.exe -k com:pipe,port=\\.\pipe\debugPipe,resets=0,reconnect
在 mytarget 中安装 windbg
打开共享文件夹 z:\ 指向 myhost 中的 symbolcache 文件夹
在指向共享文件夹的 mytarget 中设置符号路径
运行 ntsd -d calc.exe
kd 将在 calc.exe 的 $exentry 与 Input Prompt
中断只要显示输入提示,您就可以像使用本机用户模式调试器一样使用 kd 所以如果你设置 bp calc!Winmain 并发出 g kd 将在 calc.exe winmain
上中断进入 kd 会话使用 .breakin
杂乱的东西,但一旦你习惯了(即记住文档)就会很好用
一个样本运行
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.pdbB7D84101\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
关于您最初的请求,我不确定您有兴趣找到什么令牌
如果获取 exe 的 EPROCESS->Token 是唯一的要求,则您不必 运行 任何 kd 会话
您可以使用本地内核调试会话(使用 kd -kl 或使用来自 sysinternals 的 livekd)获取 myhost 中所有 运行ning 进程的令牌
这是一个简单的脚本,它使用上述技术获取所有 运行ning 进程的 sid
:\>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"
结果
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"