购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.10 导出函数

导出函数主要供保护模式下的Loader调用。导出函数提供了一种从保护模式进入实模式,再从实模式返回保护模式的机制。为什么要有这样的需求呢?这是因为从保护模式进入实模式后,默认的中断(从0地址开始)不可能再使用,原因是IDT位置发生了变化(不在0地址)。如果我们需要使用,必须有一种方法转换回原先的模式,IDT中断描述符也必须指向原来的位置(0地址)。SU模块的设计者在这一点上设计得非常好。因为NTLDR并未破坏原有的中断体系,切换回实模式后还能继续使用。但是这种切换非常耗费资源,当我们在Loader运行阶段时,WinDbg可能已经连接上了,但是WinDbg是不可能跟踪导入函数去调试的,只能按F10键步过。

下面介绍两个宏:ENTRY_FRAME和EXIT_FRAME。ENTRY_FRAME实现了从内核代码段跳转到SU代码段,这个跳转是段间跳转。开始的时侯,转到SU模块后,还是保护模式。

第一个push操作的是SU代码段58H,第二个push操作的是函数地址,retf完成了段间转换。跳到SU段之后保存必要的寄存器,设置SU数据段寄存器,设置SU栈位置。

宏EXIT_FRAME则实现从SU模块返回到Loader模块。

为了复制参数,我们定义了第三个宏MAKE_STACK_FRAME。它有两个参数,第一个指明参数的大小,第二个指定参数的位置。ENTRY_FRAME宏指定的栈顶位置保存在ebx中了,所以MAKE_STACK_FRAME宏的第二个参数总是ebx。注意,每一个参数的大小是4B,但在复制时每次只复制2B。因为在实模式下,为了保护参数安全,通常是按2B计算的,这里的代码改成4B移动也不成问题,因为这个复制过程也还是在保护模式下完成的。%macro MAKE_STACK_FRAME 2

那么,我们是如何进入实模式的呢?这个过程并不复杂,只要将cr0的相关标志清除,再加载原有的IDT即可。

2.10.1 读写扇区

下列代码展示了如何从保护模式下转到实模式,调用扇区读写函数ReadWriteSector。要从保护模式转到实模式,只需要调用RealMode函数即可。ReadWriteSector函数在讲解MBR时已具体介绍过,这里并没有什么不同。

2.10.2 获取物理内存块

下列代码展示了如何进入实模式去获取某个物理内存块的信息,同样是通过RealMode进入实模式,调用Int15E820函数去获得物理内存块信息。

2.10.3 检测硬件

最后一段汇编代码是为了能在实模式下进行硬件信息检测。不过由于硬件检测过程依赖于NTDETECT.COM,在使用前需要加载在10000H位置上,这是约定的位置,所以进入实模式后,直接跳转去10000H执行即可,执行完成会返回来。调用检测过程主要在Loader发起,我们会明显感觉到整个过程变慢。 e/2S9PHXV2CiV+lTeeKyLgfeAhf2aByTpdR9A1SsLvFfalbqT6hnM1Z4F/eQyMM3

点击中间区域
呼出菜单
上一章
目录
下一章
×