用windbg内核模式调试用户态程序

原创  windbg 如何再内核模式调试用户空间的程序 收藏

1:使用!process 0 0 获取用户空间的所有的进程的信息

!process 0 0

**** NT ACTIVE PROCESS DUMP ****
    PROCESS 80a02a60  Cid: 0002    Peb: 00000000  ParentCid: 0000
    DirBase: 00006e05  ObjectTable: 80a03788  TableSize: 150.
    Image: System

。。。。。

2:使用.process /p + 你需要断的应用程序的EProcess地址切换到应用程序的地址空间

   例如:

.process  /p  0x80a02a60

3:重新加载user PDB文件

     .reload /f /user

4:使用非侵入式的切换进程空间

    .process /i /p 0x80a02a60

5:下应用层断点

bp

       bu

     都可以

========================

今天看windows创建进程的过程,第一个阶段怎么看都看明白,里面说要查看什么注册表,看看有debugger值什么的。后来查了下百度,原来就启动一个进程的一个小阶段被病毒广泛利用,也就是下面说的映像劫持技术。看来microsoft也有考虑不周的地方啊

==========================================================

windows映像劫持技术(IFEO)介绍以及常用解决方案 

前些日子在JM看到有关一个IFEO病毒的分析报告,就想写点什么和大家分享下!
为了使大家更详细了解映像胁持,在BAIDU找了一些相关知识点,在此,感谢那些原创作者!谢谢!
基本症状:可能有朋友遇到过这样的情况,一个正常的程序,无论把他放在哪个位置或者是重新用安装盘修复过的程序,都无法运行或者是比如运行A却成了执行B的程序了,而改名后却可以正常运行
既然我们是介绍IFEO技术相关,那我们就先介绍下:
一,什么是映像胁持(IFEO)?
所谓的IFEO就是Image File Execution Options
在是位于注册表的
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
由于这个项主要是用来调试程序用的,对一般用户意义不大。默认是只有管理员和local system有权读写修改。

我们大家一起来看网络上另一个朋友做得试验:
如上图了,开始-运行-regedit,展开到:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
然后选上Image File Execution Options,新建个项,然后,把这个项(默认在最后面)然后改成123.exe
选上123.exe这个项,然后默认右边是空白的,我们点右键,新建个“字串符”,然后改名为“Debugger"
这一步要做好,然后回车,就可以。。。再双击该键,修改数据数值(其实就是路径)。。
把它改为 C:\windows\system32\CMD.exe
(PS:C:是系统盘,如果你系统安装在D则改为D:如果是NT或2K的系统的话,把Windows改成Winnt,下面如有再T起,类推。。。)
好了,实验下。~ .
然后找个扩展名为EXE的,(我这里拿IcesWord.exe做实验),改名为123.exe。。。
然后运行之。。。嘿嘿。。出现了DOS操作框,不知情的看着一闪闪的光标,肯定觉得特鬼异~^_^。。
===============================

Debugger参数存在的本意是为了让程序员能够通过双击程序文件直接进入调试器里调试自己的程序,曾经调试过程序的朋友也许会有一个疑问,既然程序启动时都要经过IFEO这一步,那么在调试器里点击启动刚被Debugger参数送进来的程序时岂不是又会因为这个法则的存在而导致再次产生一个调试器进程?微软并不是傻子,他们理所当然的考虑到了这一点,因此一个程序启动时是否会调用到IFEO规则取决于它是否“从命令行调用”的,那么“从命令行调用”该怎么理解呢?例如我们在命令提示符里执行taskmgr.exe,这就是一个典型的“从命令行调用”的执行请求,而我们在点击桌面上、普通应用程序菜单里的taskmgr.exe时,系统都会将其视为由外壳程序Explorer.exe传递过来的执行请求,这样一来,它也属于“从命令行调用”的范围而触发IFEO规则了。为了与用户操作区分开来,系统自身加载的程序、调试器里启动的程序,它们就不属于“从命令行调用”的范围,从而绕开了IFEO,避免了这个加载过程无休止的循环下去。

由于Debugger参数的这种特殊作用,它又被称为“重定向”(Redirection),而利用它进行的攻击,又被称为“重定向劫持”(Redirection Hijack),它和“映像劫持”(Image Hijack,或IFEO Hijack)只是称呼不同,实际上都是一样的技术手段。

讲解完Debugger参数的作用,现在我们来看看“映像劫持”到底是怎么一回事,遭遇流行“映像劫持”病毒的系统表现为常见的杀毒软件、防火墙、安全检测工具等均提示“找不到文件”或执行了没有反应,于是大部分用户只能去重装系统了,但是有经验或者歪打正着的用户将这个程序改了个名字,就发现它又能正常运行了,这是为什么?答案就是IFEO被人为设置了针对这些流行工具的可执行文件名的列表了,而且Debugger参数指向不存在的文件甚至病毒本身!

以超级巡警的主要执行文件AST.exe为例,首先,有个文件名为kkk.exe的恶意程序向IFEO列表里写入AST.exe项,并设置其Debugger指向kkk.exe,于是系统就会认为kkk.exe是AST.exe的调试器,这样每次用户点击执行AST.exe时,系统执行的实际上是作为调试器身份的kkk.exe,至于本该被执行的AST.exe,此刻只能被当作kkk.exe的执行参数来传递而已,而由于kkk.exe不是调试器性质的程序,甚至恶意程序作者都没有编写执行参数的处理代码,所以被启动的永远只有kkk.exe自己一个,用户每次点击那些“打不开”的安全工具,实际上就等于又执行了一次恶意程序本体!这个招数被广大使用“映像劫持”技术的恶意软件所青睐,随着OSO这款超级U盘病毒与AV终结者(随机数病毒、8位字母病毒)这两个灭杀了大部分流行安全工具和杀毒软件的恶意程序肆虐网络以后,一时之间全国上下人心惶惶,其实它们最大改进的技术核心就是利用IFEO把自己设置为各种流行安全工具的调试器罢了,破解之道尤其简单,只需要将安全工具的执行文件随便改个名字,而这个安全工具又不在乎互斥量的存在,那么它就能正常运行了,除非你运气太好又改到另一个也处于黑名单内的文件名去了,例如把AST.exe改为IceSword.exe。

 

============================================

很激动。。解决我一个调试驱动非常头痛的问题。。。。

在这个过程中拜读了 znsoft的文章和高端调试的 文章,的确很牛。。。。

链接如下:

http://bbs.driverdevelop.com/htm_data/125/0901/115354.html

http://advdbg.org/blogs/advdbg_system/articles/1492.aspx

但是里面还有很多没有说到的地方,这里在补充下 。。。

1. pdb文件要和源码还有程序是一个版本。。在windbg中设置好pdb文件和源码的目录。

2. bp hello!add 下断点 。。。

3.在要调试的程序的里加入如下代码,

int main(void)

{

     __asm  int 3;

}

这样程序一开始就断下来。。

4. !process 0 0 列举所有的进程,找到 需要调试的进程的EPROCESS。

PROCESS 810d65d8  SessionId: 0  Cid: 0654    Peb: 7ffd3000  ParentCid: 00d4
    DirBase: 07361000  ObjectTable: e11cbaa0  HandleCount:  38.
    Image: conime.exe

PROCESS 81180020  SessionId: 0  Cid: 0624    Peb: 7ffdf000  ParentCid: 04e4
    DirBase: 07860000  ObjectTable: e1bd31f0  HandleCount:   7.
    Image: hello.exe

5. .process  81180020  切换到需要调试的进程的上下文。。

6.  .reload /user 加载符号列表。。

7. 这时候在windbg中就能看到断点出变成红色的了 。。

这个顺序就能保证在kd模式调试ring3程序了。。。

 

==============

在内核调试会话中设置用户态断点

使用内核调试会话也可以执行一些用户态调试任务,比如向位于用户态的模块设置断点。但这样做与使用用户态调试器有什么不同呢?我们就以向NTDLL.dll模块的ZwTerminateProcess函数(Stub)为例谈谈二者的区别。

区别一、在内核调试会话中设置这个断点的“难度”略大些。这是因为NTDLL不属于内核态的模块,所以内核会话通常不会加载这个模块(的符号),因此当执行bp命令时很可能被自动蜕化为bu命令。

0: kd> bp ntdll!ZwTerminateProcess
Bp expression 'ntdll!ZwTerminateProcess' could not be resolved, adding deferred bp

恢复执行后,一般的操作也不会触发调试器来加载NTDLL模块和解决这个未决的断点。因此再中断下来,重新加载符号也可能没有用:

2: kd> .reload
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
.............................................................................................................................
Loading User Symbols

Loading unloaded module list
........
2: kd> bl
0 eu             0001 (0001) (ntdll!ZwTerminateProcess)

使用.reload命令强制加载这个模块也不那么容易:

0: kd> .reload /s /f ntdll.dll

"ntdll.dll" was not found in the image list.
Debugger will attempt to load "ntdll.dll" at given base 00000000.

Please provide the full image name, including the extension (i.e. kernel32.dll)
for more reliable results.Base address and size overrides can be given as
.reload =,.
Unable to add module at 00000000

那么该如何设置呢?方法一需要以下几步:

1.A 使用!process命令显示当前进程:

kd> !process
PROCESS 80af22a0  SessionId: none  Cid: 0000    Peb: 00000000  ParentCid: 0000
    DirBase: 00039000  ObjectTable: e1001e38  HandleCount: 240.
    Image: Idle

如果像上面这样是IDLE进程或者是System这些没有用户态的进程,那么就需要执行下面一步,否则跳到1.C。

1.B 使用!process 0 0命令列出所有进程,然后选一个普通的Windows进程,并切换到这个进程:

kd> !process 0 0
**** NT ACTIVE PROCESS DUMP ****

...
PROCESS 82748330  SessionId: 0  Cid: 0110    Peb: 7ffde000  ParentCid: 059c
    DirBase: 13076000  ObjectTable: e1a55640  HandleCount:  72.
    Image: notepad.exe

kd> .PROCESS 82748330
Implicit process is now 82748330
WARNING: .cache forcedecodeuser is not enabled

1.C 执行.reload或.reload /user重新加载符号:

kd> .reload
Connected to Windows XP 2600 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
................................................................................................
Loading User Symbols
...............................
Loading unloaded module list
..............................
kd> lm m ntdll
start    end        module name
7c800000 7c8c3000   ntdll      (pdb symbols)          d:\symbols\ntdll.pdb\9A2A73EBE8194059A14361915257B0B01\ntdll.pdb

第二种看起来可能更费事的方法就是在系统服务的内核函数设置断点,断点命中后,执行栈回溯这样的命令,再执行.reload(加/user会省些时间,不是必须)。例如:

0: kd> bp nt!NtTerminateProcess
0: kd> g

Breakpoint 2 hit
nt!NtTerminateProcess:
81a1b043 8bff            mov     edi,edi
0: kd> kv
ChildEBP RetAddr  Args to Child             
9f272d54 8188c96a 00000000 00000000 0021f998 nt!NtTerminateProcess
9f272d54 77c20f34 00000000 00000000 0021f998 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 9f272d64)
WARNING: Frame IP not in any known module. Following frames may be wrong.
0021f998 7682d873 00000000 77e8f3b0 ffffffff 0x77c20f34
...

0: kd> .reload
Connected to Windows Vista 6000 x86 compatible target, ptr64 FALSE
Loading Kernel Symbols
..............................................................................................................................
Loading User Symbols
..................

再执行kv:
0: kd> kv
ChildEBP RetAddr  Args to Child             
9f272d54 8188c96a 00000000 00000000 0021f998 nt!NtTerminateProcess
9f272d54 77c20f34 00000000 00000000 0021f998 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 9f272d64)
0021f978 77c20580 77bfa35f 00000000 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0021f97c 77bfa35f 00000000 00000000 00af0e70 ntdll!NtTerminateProcess+0xc (FPO: [2,0,0])
0021f998 7682d872 00000000 77e8f3b0 ffffffff ntdll!RtlExitUserProcess+0x39 (FPO: [Non-Fpo])

此时可以确信内核调试会话已经加载NTDLL的符号了,再显示断点:

0: kd> bl
0 e 77c20574     0001 (0001) ntdll!NtTerminateProcess
2 e 81a1b043     0001 (0001) nt!NtTerminateProcess

这个显示表明内核调试会话已经落实了这个用户态的断点。

如果是在加载NTDLL模块后再执行bp命令,恢复执行后,KD会有一个提示告诉我们它成功的向断点位置写入了INT 3。

0: kd> bp ntdll!ZwTerminateProcess
0: kd> bl
0 e 77c20574  0001 (0001) ntdll!NtTerminateProcess

0: kd> g
KD: write to 77c20574  ok

相对而言,如果是在用户态调试会话中,因为NTDLL会被映射到所有用户态进程中,而且ZwTerminateProcess是导出的函数,所以bp ntdll!ZwTerminateProcess会非常顺利的执行。

区别二、断点的作用范围不同,在内核调试会话中设置的ntdll!NtTerminateProcess断点会影响所有进程(可能有特例),而在用户态调试中对这个位置设置的断点只对当前进程有效。举例来说,刚才在内核调试会话中设置bp断点时的当前进程是notepad,但是当我们关闭计算器进程时这个断点也会命中。甚至当我们新启动一个WinMine程序,然后关闭它时,断点也会命中。

相对而言,如果是在调试notepad进程的用户态调试会话中对ntdll!NtTerminateProcess设置一个断点,那么这绝不会影响其它进程。

那么为什么有这个差异呢?

首先解释一下,为什么在内核调试会话中设置的断点会影响所有进程。还是通过试验来说明,我们先想办法观察到我们设置的断点所对应的INT 3指令。当KD落实我们的断点后,将目标再中断到调试器,这时无论是直接观察线性地址还是物理地址,都看不到INT 3:

1: kd> dd 77c20574
77c20574  000152b8 0300ba00 12ff7ffe 900008c2
77c20584  000153b8 0300ba00 12ff7ffe 900008c2
77c20594  000154b8 0300ba00 12ff7ffe 00498dc3
77c205a4  000155b8 0300ba00 12ff7ffe 00498dc3
77c205b4  000156b8 0300ba00 12ff7ffe 00498dc3
77c205c4  000157b8 0300ba00 12ff7ffe 900010c2
77c205d4  000158b8 0300ba00 12ff7ffe 900018c2
77c205e4  000159b8 0300ba00 12ff7ffe 900010c2

0: kd> !pte 77c20574    
               VA 77c20574
PDE at 00000000C0601DF0    PTE at 00000000C03BE100
contains 000000001C9AC867  contains 000000001DDDD025
pfn 1c9ac ---DA--UWEV    pfn 1dddd ----A--UREV

0: kd> !dd 1dddd574
#1dddd574 000152b8 0300ba00 12ff7ffe 900008c2
#1dddd584 000153b8 0300ba00 12ff7ffe 900008c2
#1dddd594 000154b8 0300ba00 12ff7ffe 00498dc3
#1dddd5a4 000155b8 0300ba00 12ff7ffe 00498dc3
#1dddd5b4 000156b8 0300ba00 12ff7ffe 00498dc3
#1dddd5c4 000157b8 0300ba00 12ff7ffe 900010c2
#1dddd5d4 000158b8 0300ba00 12ff7ffe 900018c2
#1dddd5e4 000159b8 0300ba00 12ff7ffe 900010c2

这是因为调试器在将目标中断到调试器之前会恢复已经设置的断点,按Ctrl+Alt+D启用WinDBG与KD的通信过程后就可以看到这样的信息:

DbgKdRestoreBreakPoint(1) returns 00000000

当恢复执行时,WinDBG会重新把断点写入:

DbgKdWriteBreakPoint(77c20574) returns 00000000, 1

那么如何观察到写入的INT 3呢?一种很惬意的方法就是使用ITP这样的硬件调试器,用了ITP,对付这样的任务真是手到擒来(图1)。

图1 使用硬件调试器观察断点指令(0xCC)

因为NTDLL是映射到所有进程中的,所以每个进程执行NtTerminateProcess函数时都会撞见这个0xCC,于是乎这个断点对所有进程都起作用也就在情理之中了。

下面再说说另一种情况,也就是在用户态调试器中对ntdll!NtTerminateProcess设置断点,难道这时就没有把0xCC写在大家都会“撞见”的地方么?的确如此。

我们在内核调试会话中使用bc *命令清除所有断点,并恢复执行一次,而且通过ITP观察确保刚才的0xcc已经不在。然后在目标系统中启动系统中自带的NTSD来调试计算器程序,并使用bp ntdll!NtTerminateProcess设置一个断点。恢复执行一次,以便让调试器写入这个断点。然后退出计算器程序,这时计算器程序会中断到NTSD,NTSD中不做分析,直接用g命令恢复执行,这下,我们前面设置的nt!NtTerminateProcess断点会命中,也就是中断到内核调试器中。

在内核调试器中,观察nt!NtTerminateProcess所对应的线性地址:

1: kd> dd 77c20574
77c20574  000152cc 0300ba00 12ff7ffe 900008c2
77c20584  000153b8 0300ba00 12ff7ffe 900008c2
77c20594  000154b8 0300ba00 12ff7ffe 00498dc3
77c205a4  000155b8 0300ba00 12ff7ffe 00498dc3
77c205b4  000156b8 0300ba00 12ff7ffe 00498dc3
77c205c4  000157b8 0300ba00 12ff7ffe 900010c2
77c205d4  000158b8 0300ba00 12ff7ffe 900018c2
77c205e4  000159b8 0300ba00 12ff7ffe 900010c2

睁大眼睛看那个0xCC,对的,这里的确有0xCC。因为内核断点已经取消了,这一定是用户态调试器写入的。

接下来的问题是,既然这里有0xCC,那么为什么不影响其它进程呢?注意这个线性地址与前面的一模一样。

其中的奥妙在于这个线性地址已经不再是前面那个物理地址了:

1: kd> !pte 77c20574
               VA 77c20574
PDE at 00000000C0601DF0    PTE at 00000000C03BE100
contains 00000000012E0867  contains 00000000049BD025
pfn 12e0 ---DA--UWEV    pfn 49bd ----A--UREV

虽然还同是一个线性地址,但是它现在对应的物理地址变成了49bd574。观察这个物理地址,其内容与刚才使用线性地址的得到的结果是一样的:

1: kd> !dd 49bd574
# 49bd574 000152cc 0300ba00 12ff7ffe 900008c2
# 49bd584 000153b8 0300ba00 12ff7ffe 900008c2
# 49bd594 000154b8 0300ba00 12ff7ffe 00498dc3
# 49bd5a4 000155b8 0300ba00 12ff7ffe 00498dc3
# 49bd5b4 000156b8 0300ba00 12ff7ffe 00498dc3
# 49bd5c4 000157b8 0300ba00 12ff7ffe 900010c2
# 49bd5d4 000158b8 0300ba00 12ff7ffe 900018c2
# 49bd5e4 000159b8 0300ba00 12ff7ffe 900010c2

而此时,物理地址1dddd574那里根本没有0xCC。

说到这里,谜团基本揭开了。事实上, 对于一个普通的进程,系统会把NTDLL的代码映射给它,如果这个进程始终很普通,那么它便会永远使用这份映射过来的代码。但是当它要修改代码时,系统会执行所谓的Copy on Write动作,为其复制一份,让它来写。结合我们的情况,当在用户态调试会话中向NTDLL中设置断点时,系统为其复制了一份代码,让它去写,因此它写入的断点只有它自己“撞的到”,不会影响其它进程。但是当在内核会话中写入断点时,因为是内核调试引擎执行的写动作,所以没有触发Copy on Write,因此KD写入的断点写在了公共的代码上,会影响到使用这个公共代码的所有进程。

posted on 2008年11月18日 22:19 由 Raymond

# re: 在内核调试会话中设置用户态断点 @ 2008年11月19日 0:01 我靠,有ITP当然惬意了
强烈鄙视用ITP的啊
其实那个CC直接readprocessmemory都可以看到的啦,只是WINBDG隐藏了

MJ0011

# re: 在内核调试会话中设置用户态断点 @ 2008年11月19日 10:54 学习了。。
还有MJ说的是哪个CC可以用readprocessmemory读?难道说的是物理内存的那个?不理解啊。。。

nightxie

# re: 在内核调试会话中设置用户态断点 @ 2008年11月19日 13:57 学习

chenzf

# re: 在内核调试会话中设置用户态断点 @ 2008年11月19日 20:15 对于WinDBG调试器,每次中断给用户前会恢复所有软件断点,所以在WinDBG中看不到它自己社的断点。当让WinDBG恢复目标运行后,断点恢复了,所以是可以用ReadProcessMemory看到。

Raymond

# re: 在内核调试会话中设置用户态断点 @ 2008年11月22日 16:05 这时无论是直接观察线性地址还是物理地址,都看不到INT 3:
1: kd> dd 77c20574
77c20574 000152cc 0300ba00 12ff7ffe 900008c2
77c20584 000153b8 0300ba00 12ff7ffe 900008c2
笔误?
线性地址里看到了CC。。。

diyhack

# re: 在内核调试会话中设置用户态断点 @ 2009年9月5日 23:23 To diyhack, 本来应该是Copy/Paste时搞错了,已经纠正,多谢!

Raymond

# re: 在内核调试会话中设置用户态断点 @ 2009年12月15日 16:37 这个其实没有必要在kd里面看,可以在windbg中设断点,然后用另外一个调试器实例,以非入侵的方式查相应地址,即可发现调试器在后台做的手脚
# re: 在内核调试会话中设置用户态断点 @ 2008年11月19日 20:15
对于WinDBG调试器,每次中断给用户前会恢复所有软件断点,所以在WinDBG中看不到它自己社的断点。当让WinDBG恢复目标运行后,断点恢复了,所以是可以用ReadProcessMemory看到。

skyworth

=============================================

怎么在内核调试模式调应用程序(驱动程序,应用程序一锅汇了)

 

http://advdbg.org/blogs/advdbg_system/articles/1492.aspx
先看一下上面的张银奎大侠的文章,然后我们再分析一下怎么做。
看了上面的文章,也许你已经成功了,那就没必要看下面的文字 ,如果你还没有明白,我们就实操一下:
环境:
双机内核模式调试状态,即通过windbg连接另一台机器调试驱动,不管对方是真机还是虚拟机。此时,我们可以调试驱动程序(我假设你已经会调驱动,并且环境准备好了,想调的应用程序的pdb文件也准备好了).
通常,我们可能会在目标机(被调试的机器上)再运行一个windbg或者用vc的远程调式工具进行调试。但是我现在的所有工程,包括测试程序都是用winddk编译的,改用vc调试比较麻烦,现在就是想在调驱动的同时继续调试我的测试程序,这样方便又直接。
现在处于kd> 状态 ,可以直接设置驱动程序的断点,但是你要是设置应用程序的断点,会收到错误消息,说找不到这个模块。好,我们就来记它能找到:
!process 0 0
会出列进程相关信息,如
PROCESS 820a36d0  SessionId: 0  Cid: 07cc    Peb: 7ffd9000  ParentCid: 01d4
    DirBase: 09b00220  ObjectTable: e18ecc48  HandleCount: 104.
    Image: alg.exe
PROCESS 820d2020  SessionId: 0  Cid: 0118    Peb: 7ffdf000  ParentCid: 00c4
    DirBase: 09b00260  ObjectTable: e19252b0  HandleCount: 470.
    Image: explorer.exe
PROCESS 82232b58  SessionId: 0  Cid: 016c    Peb: 7ffdf000  ParentCid: 0118
    DirBase: 09b002c0  ObjectTable: e188c9d8  HandleCount:  76.
    Image: epsng_certd.exe
PROCESS 82170020  SessionId: 0  Cid: 00d8    Peb: 7ffde000  ParentCid: 0118
    DirBase: 09b002a0  ObjectTable: e1916e98  HandleCount:  36.
    Image: VMwareTray.exe
PROCESS 821353d8  SessionId: 0  Cid: 0170    Peb: 7ffdc000  ParentCid: 0118
    DirBase: 09b002e0  ObjectTable: e1c8e138  HandleCount: 128.
    Image: VMwareUser.exe
找到你关心的进程 ,如 explorer.exe ,它的进程 PROCESS 值,其实就是EPROCESS, 为 820d2020 

然后,你要切换进程上下文
.Process  820d2020   注意:这里的Process 前面有一个点,不要看成你的显示器上的灰尘
这样,就处于这个进程上下文了。
.reload /user  加载用户模式符号文件  (保证你的符号文件处于正确的目录中)
然后就可以直接 下断点了,比如
bp explorer!xxxxfunc
其它的没啥区别了

 

找到你关心的进程 ,如 explorer.exe ,它的进程ID为 820d2020  
应该是EPROCESS,不然菜鸟会晕的.

 

wowo说的对,是EPROCESS 不是进程ID, 老鸟们一看值就知道我的笔误,小鸟们....抱歉了,但是确可以实操.haha
每个值前面其实都有值的名称,那天太兴奋了,就随口这么一说,抱歉各位...

你可能感兴趣的:(模式,程序,内核,调试,windbg)