ACPI调试
Linux内核调试
Windows内核调试
 
  调试战役
调试原理
新工具观察
 
  Linux
Windows Vista
Windows
 
  Linux驱动
WDF
WDM
 
  PCI Express
PCI/PCI-X
USB
无线通信协议
 
  64位CPU
ARM
IA-32
  CPU Info Center
 
  ACPI标准
系统认证
Desktop
服务器
 
  Embedded Linux
嵌入式开发工具
VxWorks
WinCE
嵌入式Windows
沪ICP备05041459号
About AdvDbg Consult Train Services Products Tools Community Contact   登录 | 注册

也谈用Bochs调试NTLDR

今天聊点启动扇区的小玩意~ 关于用 Bochs 启动 / 调试 Win32 的 Ntldr。


其实这是一个很老的话题了,早在我上大二的时候,绿盟的 tk前辈 就在文章《用Bochs调试NTLDR》中有过一定的尝试。不过,如果仅仅是为了调试 252KB 大小的 Ntldr 就创建出 500MB 的虚拟硬盘文件似乎显得大材小用了些;而真正在 Bochs 上用“NT安装光盘的ISO文件”或“直接用光盘安装”调试 Win32 内核又一定会让你有一种奔向黑洞的感觉... 所以我们还是以小为美,写个软盘引导扇区的代码作为桩吧~


等到真正去写这段代码的时候,一个 BIOS INT13 调用上的 Bug 却花了我将近一个下午的时间用 Bochs 单步调试,这占到了整个研究时间的1/3,而且过程非常郁闷。由此也可见汇编语言和调试技术相辅相成的关系及重要性 —— 而这正是 Advdbg.org 一直以来所强调的。


关于编码:
软盘 FAT12/16 文件系统的文档、资料多的满天飞,写代码实际是不困难的。回想一下只有两个小地方需要留点意:(1) LBA 到 CHS 的转换;(2) FAT12 的 FATEntry (文件链表) 拼接。
-- 关于前者,这个问题实际可转化为“IMB当年是如何定义磁盘写入顺序的?” —— 您只需牢记“CHS”就是进位的原则即可(S -> H -> C)。
-- 关于后者,这是个依赖文件系统特性,随文件系统变化而变化的问题。以 FAT12 为例,奇数 FATEntry 和偶数 FATEntry 的拼接方法是不一样的。和偶数的直接 0xFFFh Mask 操作相比,奇数 FATEntry 需要先 SHR 一下,以过滤一些无用信息。


关于截图:
(1) NTLDR 选用 Win32-XP SP2 下的。

(2) 程序在 25*80 字符模式下启动 NTLDR,每加载一个扇区打印一个“.”号,所以您可以轻易计算出图中 NTLDR 的大小。
    PS: 关于25*80 字符模式:

                    00(00h)                          79(4fh)
               00(00h)┏━━━━━━━━━━━━━━━━┓
                      ┃                                ┃
                      ┃                                ┃
                      ┃                                ┃
                      ┃     显示器  25*80 显示方式     ┃
                      ┃                                ┃
                      ┃                                ┃
                      ┃                                ┃
               24(18h)┗━━━━━━━━━━━━━━━━┛






(3) 调试 NTLDR。如您所见 NTLDR 被我加载到基址 4000:0000h 开始处,由于没有处理 NtDetect.com 等模块,所以这里的调试也只是部分调试。





NUPT   WANGyu

 
 
 
 
 
 
 
 

posted on Sunday, December 23, 2007 4:04 PM 由 WANGyu

# re: 也谈用Bochs调试NTLDR @ Monday, December 24, 2007 9:12 AM

写代码之前顺便分析了一下 ReactOS 0.33v 的 FAT12,发现一个 Bug,也记录一下。


代码如下:
mov bx,7e0h ; We will load the root directory sector
mov es,bx ; Right after the boot sector in memory
xor bx,bx ; We will load it to [0000:7e00h]
xor cx,cx ; Zero out CX
inc cx ; Now increment it to 1, we are reading one sector
xor di,di ; Zero out di
push es ; Save ES because it will get incremented by 20h
........

从代码的注释里我们看到,Brian Palmer 想把 FAT 的根目录区加载到内存地址 0000:7e00h,可是赋值的时候事与愿违:
mov bx,7e0h ; We will load the root directory sector
mov es,bx ; Right after the boot sector in memory

这样的赋值显然是 0000: 07e0,而不是 0000:7e00h,呵呵,这算是一个写代码时的笔误~


跟踪一下确认这个 Bug 的存在:
<bochs:71> dump_cpu
eax:0x00000013, ebx:0x00000000, ecx:0x00000001, edx:0x00000000
ebp:0x00007c00, esp:0x00007bf0, esi:0x000000e0, edi:0x00000000
eip:0x00007cc9, eflags:0x00000046, inhibit_mask:0
cs:s=0x0000, dl=0x0000ffff, dh=0x00009b00, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
--Note!-> es:s=0x07e0 <-Note!-- dl=0x7e00ffff, dh=0x00009300, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
gs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=1
ldtr:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
tr:s=0x0000, dl=0x00000000, dh=0x00000000, valid=0
gdtr:base=0x00000000, limit=0xffff
idtr:base=0x00000000, limit=0xffff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000010, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000


那个 push es 的压栈 (这个压栈是关键) 也打印一下:
<bochs:72> print-stack
00007bf0 [00007bf0] 07e0 ; <--- Bug! ----
00007bf2 [00007bf2] 0000 ; API Address of PutChars()
00007bf4 [00007bf4] 0000 ; API Address of ReadCluster()
00007bf6 [00007bf6] 0000 ; API Address of ReadSectors()
00007bf8 [00007bf8] 0b40 ; \
00007bfa [00007bfa] 0000 ; / total sector count of the boot drive.
00007bfc [00007bfc] 0021 ; \
00007bfe [00007bfe] 0000 ; / the start of the data area.
00007c00 [00007c00] 3ceb ; <--- SS:BP ---
00007c02 [00007c02] 4690
00007c04 [00007c04] 4c72
00007c06 [00007c06] 7264
00007c08 [00007c08] 2e31
00007c0a [00007c0a] 0030
00007c0c [00007c0c] 0102
00007c0e [00007c0e] 0001


小 Bug~ 懒得上报了,因为 FAT12 是鸡肋,不会有人去真正关注它们的。

WANGyu

# re: 也谈用Bochs调试NTLDR @ Monday, December 24, 2007 9:18 AM

我在想,和 PE 相比,磁盘里的空闲空间大的更是吓人。

如果有 rk 直接操作这些扇区里的空闲空间,那岂不是非常难以发现?

打住~ 还是先逆了 AK922.sys 再说。

WANGyu

# re: 也谈用Bochs调试NTLDR @ Monday, December 24, 2007 9:53 PM

尽管NTLDR的调试版本(在DDK中有)支持被WinDBG通过串行口调试,但是工作的并不是很好。使用虚拟机调试是个不错的方法。建议继续深入跟踪一下NTLDR的工作过程,比如切换CPU模式和初始化启动过程所需内存的部分。调试版本的NTLDR是如何支持调试的(和WinDBG对话),也是我想知道的。

Raymond

# re: 也谈用Bochs调试NTLDR @ Tuesday, December 25, 2007 1:51 PM

360 公司的 MJ0011 前辈说是搞定了~ 有机会我请教他一把...

http://www.debugman.com/read.php?tid=782

“终于把涉及ntldr & hal & KiSystemStartup的部分调试OK啦~在没有调试器的情况下用猥琐方法逼近~~~”

WANGyu

# re: 也谈用Bochs调试NTLDR @ Tuesday, December 25, 2007 3:55 PM

严重关注 MJ 的“64号端口”方法

http://hi.baidu.com/mj0011/blog/item/09e7c53f6795aec67d1e7111.html

WANGyu

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 4:18 PM

杩欐鏃堕棿瀹堕噷涓鐩存湁鐐逛簨锛孋lassic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:11 PM

杩欐鏃堕棿瀹堕噷涓鐩存湁鐐逛簨锛孋lassic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:11 PM

杩欐鏃堕棿瀹堕噷涓鐩存湁鐐逛簨锛孋lassic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:14 PM

杩欐鏃堕棿瀹堕噷涓鐩存湁鐐逛簨锛孋lassic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:18 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:26 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# 鐭枃涓鍒 @ Tuesday, July 29, 2008 5:28 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Tuesday, July 29, 2008 5:28 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Tuesday, July 29, 2008 5:36 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Wednesday, July 30, 2008 8:22 AM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Wednesday, July 30, 2008 8:26 AM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Wednesday, July 30, 2008 8:30 AM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Wednesday, July 30, 2008 8:31 AM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Thursday, July 31, 2008 12:20 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Thursday, July 31, 2008 12:25 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

# NTFS鐭枃涓鍒 @ Thursday, July 31, 2008 12:28 PM

杩欐鏃堕棿瀹堕噷鏈夌偣浜嬶紝Classic Readings 鐗堝潡涓鐩存病鏉ュ緱鍙婃悶(鍙槸涓婁紶浜嗕袱绡?OSR 鐨勬枃绔犫斺斻奤nderstanding and Using Execution Context in Windows...

AdvDbg System Section

 
Legal Notice Privacy Statement Corporate Governance Corporate Governance
(C)2004-2005 Advanced Debugging Ltd. All Rights Reserved.