Windows调试工具**
主要简单介绍了Cdb、Ntsd、Kd、Windbg四个调试器,但是Windbg是唯一具有图形用户界面的调试器
Windbg介绍**
Windbg主要有三种命令:
标准命令,这些命令被内置到调试器中,它们对正在调试的目标进行操作。
元命令,这些命令以“.”开始。它们操作调试过程本身,而不是直接操作被调试的目标。
Bang(扩展)命令,这些命令以“!”开头,提供了调试器的强大功能。所有的扩展命令都是在扩展dll中实现的。默认情况下,调试器加载一组预定义的扩展dll,但可以从调试器目录或其他源加载其他dll.
Note:不用双击内核调试直接本地打开即可
因为目前windbg正在调试内核,调试器不在notepad.exe进程上下文中,为了达到目的,需要枚举系统中的进程并切换到notepad.exe
!process 0 0 //枚举所有进程
.process /i /r /p //切换到进程
kernel调试时windbg并不会加载用户态dll,但是切换到指定进程后可以加载用户态调试符号,如下:
.reload /user /f
线程介绍
输入命令 k显示当前线程堆栈,带有符号的地址的一般格式是“模块名!函数名+偏移量”。该偏移量是可选的,如果它恰好是这个函数的开始,则可以为零。
命令 ~ns表示切换线程
进程ID显示为十六进制,输入下面的命令可以将其转化为十进制,与任务管理器对比发现是正确的
也可以在十进制前加个前缀“0n”这样可以得到十六进制的结果
显示当前活动的线程
显示当前线程的teb(线程环境块),该命令显示的是幕后真实的结构,可以用dt命令查看实际结构
以下只显示了部分信息
我们可以点击查看NtTib
断点
下个断点
可以用bl命令查看断点,e表示启用,d表示禁用
因为下了断点,所以我们打开文件的时候windbg会断在这里
我们现在可以看看调用堆栈是什么样的
如果想知道正在打开的是什么文件。我们可以根据CreateFileW函数的调用约定来获得这些信息。由于这是一个64位进程(处理器是Intel/AMD),调用约定声明第一个整数/指针参数在RCX、RDX、R8和R9寄存器中传递。由于CreateFileW中的文件名是第一个参数,因此相关的寄存器是RCX。我们用命令r rcx查看寄存器,紧接着用 db 地址查看指向的内存,但是因为字符是ASCII所以看起来不是很方便,我们用 du 地址查看Unicode地址
如果不想用地址,也可以在寄存器前面加“@”
再下一个断点
u(unassemble)命令列出即将执行的8条指令,注意该值0x55已被复制到EAX寄存器中。这是NtCreateFile的系统服务编号,如第1章所述。所示的系统所有指令是导致转换到内核,然后执行NtCreateFile系统服务本身的指令。
可以用指令p(f10)单步运行,也可以用t(f11)步入函数中,单步执行到ret后,我们要知道在x64调用约定中,函数的返回值存储在EAX或RAX中。对于系统调用,它是一个无状态,所以EAX包含了返回的状态:
下一个NtWriteFile的断点,然后修改文件在保存的时候会断下来,紧接着用k查看调用堆栈
用u指令查看到,8 是NtWriteFile系统服务编号
本地内核调试
本地内核调试(LKD)与内核调试的区别就是无法下断点,只能看见系统当前运行状态。
按照书上的步骤,先在管理员权限下的cmd输入命令
bcdedit /debug on
然后重启系统,以管理员身份打开windbg,选择attach to kernel,然后选择Local,点击ok
本地内核调试详细教程
输入!process 0 0显示如下 输入.reload同样没用,按照他的提示输入命令!sym noisy,然后输入.reload,同时查看一下符号路径是否正确。最后得到现在的进程情况
PROCESS后的是进程的EPROCESS地址(内核空间);
SessionId表示进程所处的会话;
Cid是独一无二的进程ID(Client ID);
Peb是进程环境块(PEB)的地址,这个地址在用户空间中;
ParentCid是Parent Client ID)父进程的进程ID。注意,父进程可能不再存在,并且可以重用此ID;
DirBase是该进程的Master Page Directory的物理地址,用作虚拟地址转换的基础。在x64上,这被称为Pagr Map Level 4,在x86上,它是Page Directory Pointer Table(PDPT);
ObjectTable是指向进程的私有句柄表的指针;
HandleCount是进程的句柄数;
Image是可执行文件名或者是对于那些与可执行文件没有关联的程序的特殊进程名称(exp: Secure System,system)。
!process命令至少接受两个参数,第一个参数用EPROCESS地址表示感兴趣的进程,0表示所有进程。第二个参数是所需的详细信息级别,其中零表示最少的详细信息量(一个位掩码)。可以添加第三个参数来搜索特定的可执行文件。 列出所有正在运行的csrss.exe。
可以通过指定地址以及更高级别的详细信息来列出相关进程的详细信息
其余的命令等到具体用到的时候再一一查阅
内核驱动程序调试教程
我们调试在第四章写好的驱动程序,首先安装驱动,但是不能加载,因为加载就会进入驱动入口。(我们需要在入口下一个断点。
具体的调试过程其实和平时双机调试程序的时候差不多,因为这部分已经熟悉就不详细写了。