我不确定这个问题应该放在这里还是在reverseengineering.stackexchange.com
引用维基百科:
在 8086 处理器中,中断表称为 IVT(中断向量表)。IVT 始终驻留在内存中的同一位置,范围从 0x0000 到 0x03ff,由 256 个四字节实模式远指针(256 × 4 = 1024 字节内存)组成。
这是我在 qemu 监视器中发现的:
(qemu) xp/128xw 0
0000000000000000: 0xf000ff53 0xf000ff53 0xf000e2c3 0xf000ff53
0000000000000010: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000020: 0xf000fea5 0xf000e987 0xf000d62c 0xf000d62c
0000000000000030: 0xf000d62c 0xf000d62c 0xf000ef57 0xf000d62c
0000000000000040: 0xc0005526 0xf000f84d 0xf000f841 0xf000e3fe
0000000000000050: 0xf000e739 0xf000f859 0xf000e82e 0xf000efd2
0000000000000060: 0xf000d648 0xf000e6f2 0xf000fe6e 0xf000ff53
0000000000000070: 0xf000ff53 0xf000ff53 0xf0006aa4 0xc0008930
0000000000000080: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000090: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000c0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000d0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000e0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000000f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000100: 0xf000ec59 0xf000ff53 0xf000ff53 0xc0006730
0000000000000110: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000120: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000130: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000140: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000150: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000160: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000170: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
0000000000000180: 0x00000000 0x00000000 0x00000000 0x00000000
0000000000000190: 0x00000000 0x00000000 0x00000000 0xf000ff53
00000000000001a0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001b0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
00000000000001c0: 0xf000d611 0xf000ec4e 0xf000ec4e 0xf000ec4e
00000000000001d0: 0xf000d61a 0xf000d623 0xf000d608 0xf000ec4e
00000000000001e0: 0xf000ff53 0x00000000 0xf000ff53 0xf000ff53
00000000000001f0: 0xf000ff53 0xf000ff53 0xf000ff53 0xf000ff53
我不确定如何理解这些价值观。它看起来不像一个中断描述符表(取消引用这些值会给出所有空值)。那么我到底在看什么?
无论您的固件包含什么。
在理想的现代系统上,处理器根本不会进入实模式,正如我在这篇题为“现代 64 位英特尔芯片 PC 以何种模式运行引导扇区? ”的 SU 问答中所解释的那样?,物理内存的第一个 KiB 与 Johan Myréen 在这里的另一个答案中所说的一样无关紧要。但是许多现代固件(仍然)具有兼容性支持,这意味着
这些数据结构之一是实模式 IVT。旧的实模式固件 API 基于
int
指令,实模式 IVT 由固件填充,作为其初始化的一部分,并带有指向这些指令的各种固件处理例程的指针。保护模式系统软件不需要旧的实模式固件API,并且从不以实模式运行处理器,因此物理内存的前1KiB中的实模式IVT未被使用。(记住,v8086 保护模式不寻址物理地址 00000000 及以上。它寻址逻辑地址 00000000 及以上,由页表转换。)在现代 EFI 系统中,固件将物理内存的内存映射移交给操作系统引导程序,告诉它哪些部分保留给固件用于其自身的保护模式 API 目的,以及操作系统可以自由继续使用哪些部分作为其物理内存池。理论上,物理内存的第一页可以属于后一类。
在实践中,首先,固件通常将物理内存的第一页标记为“引导服务代码”,这意味着操作系统可以声明它并继续将其用作其物理内存池的一部分,但仅在引导之后- EFI 固件的时间服务已被操作系统关闭,固件减少为仅提供其运行时服务。
xe 用另一个程序以更易于阅读的形式解码为:add_efi_memmap
在Finnbarr P. Murphy 显示的 Linux 内核日志(带有选项)中可以看到一个示例:其次,在实践中,Linux 明确忽略了这个物理内存范围,即使固件说它可以继续使用它。您会发现,在 EFI 和非 EFI 固件上,一旦 Linux 拥有物理内存映射,它就会对其进行修补(在名为 的函数中
trim_bios_range
),从而产生内核日志消息,例如:这不是为了应对现代 EFI 固件,实模式 IVT 不是固件 API 的一部分,而是为了应对旧的 PC98 固件,它是固件 API 的一部分,但固件会报告它(通过相同的 API)作为物理内存,可以被操作系统轻松覆盖。
因此,虽然从理论上讲,物理内存范围可以包含任意代码或数据,具体取决于内核内存分配器和按需分页虚拟内存的瞬时需求;实际上,Linux 只是保持不变,因为固件最初设置它。
在您的系统上,固件已经用实模式 IVT 条目填充它。当然,实模式 IVT 条目只是 16:16 远指针,如果您使用 2 字节 hexdump 查看内存,您实际上可以非常清楚地看到这一点。一些例子:
iret
.进一步阅读
最初的 8086 处理器架构(在 80286+ 处理器中实现为实模式)与在保护模式下运行的 Linux 无关。物理地址 0 处没有中断向量表,而是使用包含中断描述符的中断描述符表。IDT 可以位于内存中的任何位置。
Linux 内核从固件(BIOS 或 EFI)获取物理内存映射,它告诉哪些物理内存页帧可用,哪些是保留的或不存在的。可用页框的范围不是连续的,但通常有很大的漏洞。传统上,x86 Linux 内核跳过了物理内存的启动,即使它被标记为可用。因此,Linux 内核不使用物理地址 0。
转储内存
这是在系统内部转储内存内容与必须在外部进行的另一种方法:
分析
000c0000 以上的部分可能与引导加载程序有关。为什么我会怀疑这个?位置处的代码 55aah
参考:引导签名 - BIOS000c0000
通常可以作为内存中的标记,用于触发 BIOS 运行辅助引导加载程序等内容。但是,鉴于此 55aah 出现在 c0000h-effffh 范围内,这部分很可能是 PNP 扩展标头:
参考:BIOS 引导规范53 岁...
至于开头的53ffh数据。我不清楚那实际上是什么。进一步研究它很可能是在 BIOS 的 MBR 引导加载移交给 Linux 内核引导之后 Linux 内核在那里写的东西。
进一步挖掘,我能够从一篇名为:通过 /dev/mem 进行恶意代码注入的研究论文中找到这一段:
参考