WINDBG调试散乱随记
这是我从我寒假刚开始的调试笔记里面扒下来的,寒假最后一天,哥要潇洒地离去{:6_205:}滚去学校学习了。一、内存布局
Windows把虚拟内存空间划分为两个块,分别是内核空间与用户空间。通过页表项中的一个特殊标志位来区分内核模式和用户模式。在x86中,高2GB是为内核空间保留的,低2GB是用户空间。高2GB内存,对于所有进程来说都是一样的,但也有特殊,比如位于session和hyper空间中的。其实上面这段话的说话不是很准确,实际上,内存布局我可以画一张图来表示。
用户与内核之间有一个64kb大的间隙,这个空间通常不可访问。
OS执行某线程时,会修改一个因处理器而异(比如x86是CR3,ARM是TTBR)的寄存器,指向这个线程所属进程的页目录,所以,虚拟地址到物理地址的转换都是特定于进程的。
二、处理器初始化
内核开始运作时,会为每个处理器执行初始化,大部分初始化细节我也不懂,只能大略说说。每个处理器有一个PCR结构,用于保存一些重要的CPU信息和状态。x86上,这个结构体包含IDT基址和当前IRQL以及PRCB。PRCB包含了CPU类型、模型、速度、当前运行线程、下一个运行线程等信息。这些结构体都是没有文档介绍的,但可以通过WINDBG查看它们的定义。
内核模式下总是能通过特定寄存器访问到当前处理器的PCR,在x86上其保存于FS段上。Windows内核导出了PsGetCurrentProcess、PsGetCurrentThread用来获取当前进程的EPROCESS和EHTREAD。它们都是通过查询PCR/PRCB实现的。
三、错误、陷阱、中断
在现代计算机系统上,处理器通常通过一条数据总线与外围设备连接。当设备需要处理器的关注时,就会触发一个中断,让处理器暂停当前工作。从抽象化层面来看,每个中断关联到一个数字,作为索引从一个函数指针数组里面取出对应的函数地址并执行之,之后继续执行中断发生前的工作。这称为硬件中断,因为他们是通过硬件设备产生的。硬件中断本质是异步的。
处理器执行一条指令时,可能会陷入异常,熟知的异常有很多,比如除数为0,访问无效地址。异常可以分为两大类,错误与陷阱。其区别就在于运行时从哪里恢复。错误是可以修正的,比如缺页异常。陷阱是执行某些特定类型的指令产生的异常,比如x86下的systenter指令,Intel文档中声明,该指令会把EIP指向MSR 0x176,CS置为MSR 0x174,ESP置为MSR 0x175。值得注意的是,在奔腾2处理器前,使用int 2e指令。执行完后,EIP指向sysenter的下一条指令。
Inter体系中定义了元素个数为256个IDT数组。其中每一个元素定义了一个指出中断处理函数的结构体。IDT的首地址保存在一个特定寄存器中,称为IDTR,每个中断号作为索引访问该数组中的元素。0-31是预定义的保留中断,比如int3,软件断点,而32-255是用户自定义的中断。
每个元素对应的结构体如下。
(执行!dt -a)
**** Hidden Message *****
还有一些,篇幅有限,不一一列举了。全文完。
搬好小板凳,小手背后,准备听讲! 同最后一天 LYQingYe 发表于 2018-3-2 16:37
同最后一天
哈哈,同是天涯沦落人啊。这个学期贼短,我已经在期盼暑假了。{:5_121:} 謝謝分享文章,回覆學習一下 问一下,逆向看不懂楼主说的咋办 基础不好 感谢分享,学习 感谢分享教程。