Assembly 为什么BIOS入口点以WBINVD指令开始?
我正在研究我的机器(x86_64 Linux,IvyBridge)中的BIOS代码。我使用以下过程转储BIOS代码:Assembly 为什么BIOS入口点以WBINVD指令开始?,assembly,x86,boot,bios,Assembly,X86,Boot,Bios,我正在研究我的机器(x86_64 Linux,IvyBridge)中的BIOS代码。我使用以下过程转储BIOS代码: $ sudo cat /proc/iomem | grep ROM 000f0000-000fffff : System ROM $ sudo dd if=/dev/mem of=bios.dump bs=1M count=1 然后我使用radare2读取并反汇编二进制转储: $ r2 -b 16 bios.dump [0000:0000]> s 0xffff0 [
$ sudo cat /proc/iomem | grep ROM
000f0000-000fffff : System ROM
$ sudo dd if=/dev/mem of=bios.dump bs=1M count=1
然后我使用radare2
读取并反汇编二进制转储:
$ r2 -b 16 bios.dump
[0000:0000]> s 0xffff0
[f000:fff0]> pd 3
: f000:fff0 0f09 wbinvd
`=< f000:fff2 e927f5 jmp 0xff51c
f000:fff5 0000 add byte [bx + si], al
为了总结这一奇怪之处,此BIOS代码正在读取自身的0xffff0
,并将字节与0xea
进行比较,后者正是跳远的操作码:
f000:f52a b800f0 mov ax, 0xf000
f000:f52d 8ec0 mov es, ax
f000:f52f 6726a0f0ff00. mov al, byte es:[0xfff0] ; [0xfff0:1]=0
f000:f536 3cea cmp al, 0xea
如果它发现0xffff0
处的代码是一个远跳转,那么它将进入一个无限循环
更准确地说,APs(应用程序处理器)将在hlt
指令处无限循环,而BSP(引导处理器)将循环回起始0xffff0
。由于0xffff0
处的代码不会更改,因此我们可以得出结论,BSP将始终找到0xea
的字节,并且永远不会退出循环
那么自我检查的目的是什么?我很难相信这是一种天真的阻止修改的尝试。尽管很难推理,但请记住,加载
mov al,字节es:[0xfff0]
没有从BIOS第一条指令中读取,即使es
设置为0xf000
第一条指令是从0xFFFFF0
读取的,PCH也可能在重置时将0xf0000-0xfffff
别名为0xffff0000-0xffffffff
,因此当BSP启动时,它将执行您转储的代码。IIRC,除非明确唤醒,否则AP不会启动 然后BSP将继续初始化硬件(从转储判断)。
在某个时刻,它将为
0xf0000-0xfffff
设置属性映射,以引导对内存的读写操作(或只是先写后读)。最终结果是,当处理器(硬件线程)启动时,它将从闪存执行代码,直到执行跳远。
此时,根据实模式规则(非常类似于非实模式)正确计算
cs
base,指令将从0xf0000-0xfffff
(即从RAM)中提取。所有这些,而
cs
段值实际上没有改变
BSP将在某个点启动其多处理器初始化例程,在该例程中,它向每个人(包括他自己)广播一个INIT-SIPI-SIPI,该INIT-SIPI-SIPI将导致AP睡眠,并向BSP广播一个ljmp 0xf000:0xfff0
。这里的技巧是跳转的目标,
0xf000:0xfff0
,与wbinvd
指令的总线地址不同。可能还有其他东西,可能是另一个初始化程序 在初始化结束时,BIOS可以简单地将
0xf0000-0xfffff
的属性重置为闪存(因此可以进行软件重置),从而防止(并非有意)中间代码转储
这不是很有效,但bios通常不是代码的杰作
我没有足够的元素来确定发生了什么,我的观点是ljmp 0xf000:0xfff0
和mov al,byte es:[0xfff0]
不必从它们所在的相同区域读取。考虑到这一点,所有的赌注都是无效的。
只有正确的逆向工程才能说明问题 关于
wbinvd
,我在评论中建议它可能与热启动功能有关,Peter Cordes建议它可能与缓存作为RAM有关。这是有道理的,但我想永远也无法确定。
这也可能是cargo cult的一个案例,程序员认为基于谣言的指令是必要的 这实际上是标题问题的答案: Hadi BRISH:根据BIOS和系统管理模式内部的幻灯片14,UDK2010中有wbinv指令,但后来在UDK2012中被删除。也许这与安全有关。我不知道确切是什么 我可以确认,从2016年起,我的BIOS版本上的
0xfffff0
中不存在此指令
这里有一个更紧迫的问题,那就是与0xea的比较意味着什么
0xFFFFF0
处的重置向量包含90 90 E9 43 FC
,这是到0xFFFFF5-3bd
的相对跳跃,即0xfffffc38
,我的SEC核心PE32图像的入口点,来自0xffffca18
-0xffffffbb
:
0x00: DB E3 fninit
0x02: 0F 6E C0 movd mm0, eax //move BIST value to mm0
0x05: 0F 31 rdtsc
0x07: 0F 6E EA movd mm5, edx
0x0a: 0F 6E F0 movd mm6, eax //save tsc
0x0d: 66 33 C0 xor eax, eax //clear eax
0x10: 8E C0 mov es, ax
0x12: 8C C8 mov ax, cs
0x14: 8E D8 mov ds, ax
0x16: B8 00 F0 mov ax, 0xf000
0x19: 8E C0 mov es, ax
0x1b: 67 26 A0 F0 FF 00 00 mov al, byte ptr es:[0xfff0]
0x22: 3C EA cmp al, 0xea
0x24: 74 0E je 0x34 //if ea is at ffff0h then jump to the 0xf000e05b check
0x26: BA F9 0C mov dx, 0xcf9
0x29: EC in al, dx //read port 0xcf9
0x2a: 3C 04 cmp al, 4
0x2c: 75 25 jne 0x53
0x2e: BA F9 0C mov dx, 0xcf9 //perform hard reset since if CPU only reset is issued not all MSRs are restored to their defaults
0x31: B0 06 mov al, 6
0x33: EE out dx, al
0x34: 67 66 26 A1 F1 FF 00 00 mov eax, dword ptr es:[0xfff1]
0x3c: 66 3D 5B E0 00 F0 cmp eax, 0xf000e05b
0x42: 75 0F jne 0x53 //if the ptr16:16 of the EA instruction isn't 0xf000e05b, move to notwarmstart
0x44: B9 1B 00 mov cx, 0x1b //if it is equal, read bsp bit from apic_base msr
0x47: 0F 32 rdmsr
0x49: F6 C4 01 test ah, 1
0x4c: 74 41 je 0x8f //if the and operation with 00000001b produces a zero result i.e. it's an AP then jump to cli, hlt
0x4e: EA F0 FF 00 F0 ljmp 0xf000:0xfff0 //if it's the BSP and legacy bios is present, far jump to 0xffff0, exiting unreal mode
notwarmstart:
0x53: B0 01 mov al, 1
0x55: E6 80 out 0x80, al //send 1 as a debug POST code
0x57: 66 BE 68 FF FF FF mov esi, 0xffffff68
0x5d: 66 2E 0F 01 14 lgdt cs:[si] //loads 32&16 GDT pointer (not 16&6, due to 66 prefix) at 16bit address fff68 in si into GDTR (base:ffffff28 limit:003f).
//enter 16 bit protected mode//
0x62: 0F 20 C0 mov eax, cr0
0x65: 66 83 C8 03 or eax, 3 //Set PE bit (bit #0) & MP bit (bit #1)
0x69: 0F 22 C0 mov cr0, eax //Activate protected mode
0x6c: 0F 20 E0 mov eax, cr4
0x6f: 66 0D 00 06 00 00 or eax, 0x600 //Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
0x75: 0F 22 E0 mov cr4, eax
//set up selectors for 32 bit protected mode entry
0x78: B8 18 00 mov ax, 0x18 //segment descriptor at 0x18 in GDT is (raw): 00cf93000000ffff
0x7b: 8E D8 mov ds, ax
0x7d: 8E C0 mov es, ax
0x7f: 8E E0 mov fs, ax
0x81: 8E E8 mov gs, ax
0x83: 8E D0 mov ss, ax
0x85: 66 BE 6E FF FF FF mov esi, 0xffffff6e
0x8b: 66 2E FF 2C ljmp cs:[si] //transition to flat 32 bit protected mode and jump to address at 0x0:0xffffff6e aka. 0xffffff6e which is fffffcd8. CS contains 0 remember (it's the base that is 0xffff) so it will load the first entry.
//SEC continues at that address
0x8f: FA cli
0x90: F4 hlt
.
.
我们注意到我的代码与你的不同。与0xf000e05b
进行额外比较,并对0xcf9
进行读/写。此外,您的系统还包含我们在0xfffffff0
处看到的e9
跳转代码,这是因为您必须处于UEFI引导状态,因此在0xf0000
处没有旧版BIOS隐藏到旧版BIOS范围。在相对跳转之前,您的包含一个wbinvd
,而我的包含2个nop
s
edk2源代码中的一条线索是跳转到的代码称为“NotWarmStart”。代码本身就说明了问题
在我的中,如果EA位于0xffff0
,那么它会检查0xffff1
中的0xf000e05b
。如果存在0xf000e05b
,则检查BSP标志,如果是BSP标志,则跳到0xffff0
。如果不存在0xf000e05b
,它将跳转到16位+32位保护模式设置(称为“NotWarmStart”),然后跳转到32位平面保护模式(edk2称此PEI,但我认为PEI通常从PEI核心开始,它跳转到的代码实际上仍然是秒(鉴于此代码使用FSP设置CAR,如果BootGuard不存在,可以选择执行微码更新,然后将控制权传递给PEI core,它显然是我的SEC core PE32映像的代码部分中的一个地址,而PEI core映像条目位于0xffe91854
))在0x18实现
0x00: DB E3 fninit
0x02: 0F 6E C0 movd mm0, eax //move BIST value to mm0
0x05: 0F 31 rdtsc
0x07: 0F 6E EA movd mm5, edx
0x0a: 0F 6E F0 movd mm6, eax //save tsc
0x0d: 66 33 C0 xor eax, eax //clear eax
0x10: 8E C0 mov es, ax
0x12: 8C C8 mov ax, cs
0x14: 8E D8 mov ds, ax
0x16: B8 00 F0 mov ax, 0xf000
0x19: 8E C0 mov es, ax
0x1b: 67 26 A0 F0 FF 00 00 mov al, byte ptr es:[0xfff0]
0x22: 3C EA cmp al, 0xea
0x24: 74 0E je 0x34 //if ea is at ffff0h then jump to the 0xf000e05b check
0x26: BA F9 0C mov dx, 0xcf9
0x29: EC in al, dx //read port 0xcf9
0x2a: 3C 04 cmp al, 4
0x2c: 75 25 jne 0x53
0x2e: BA F9 0C mov dx, 0xcf9 //perform hard reset since if CPU only reset is issued not all MSRs are restored to their defaults
0x31: B0 06 mov al, 6
0x33: EE out dx, al
0x34: 67 66 26 A1 F1 FF 00 00 mov eax, dword ptr es:[0xfff1]
0x3c: 66 3D 5B E0 00 F0 cmp eax, 0xf000e05b
0x42: 75 0F jne 0x53 //if the ptr16:16 of the EA instruction isn't 0xf000e05b, move to notwarmstart
0x44: B9 1B 00 mov cx, 0x1b //if it is equal, read bsp bit from apic_base msr
0x47: 0F 32 rdmsr
0x49: F6 C4 01 test ah, 1
0x4c: 74 41 je 0x8f //if the and operation with 00000001b produces a zero result i.e. it's an AP then jump to cli, hlt
0x4e: EA F0 FF 00 F0 ljmp 0xf000:0xfff0 //if it's the BSP and legacy bios is present, far jump to 0xffff0, exiting unreal mode
notwarmstart:
0x53: B0 01 mov al, 1
0x55: E6 80 out 0x80, al //send 1 as a debug POST code
0x57: 66 BE 68 FF FF FF mov esi, 0xffffff68
0x5d: 66 2E 0F 01 14 lgdt cs:[si] //loads 32&16 GDT pointer (not 16&6, due to 66 prefix) at 16bit address fff68 in si into GDTR (base:ffffff28 limit:003f).
//enter 16 bit protected mode//
0x62: 0F 20 C0 mov eax, cr0
0x65: 66 83 C8 03 or eax, 3 //Set PE bit (bit #0) & MP bit (bit #1)
0x69: 0F 22 C0 mov cr0, eax //Activate protected mode
0x6c: 0F 20 E0 mov eax, cr4
0x6f: 66 0D 00 06 00 00 or eax, 0x600 //Set OSFXSR bit (bit #9) & OSXMMEXCPT bit (bit #10)
0x75: 0F 22 E0 mov cr4, eax
//set up selectors for 32 bit protected mode entry
0x78: B8 18 00 mov ax, 0x18 //segment descriptor at 0x18 in GDT is (raw): 00cf93000000ffff
0x7b: 8E D8 mov ds, ax
0x7d: 8E C0 mov es, ax
0x7f: 8E E0 mov fs, ax
0x81: 8E E8 mov gs, ax
0x83: 8E D0 mov ss, ax
0x85: 66 BE 6E FF FF FF mov esi, 0xffffff6e
0x8b: 66 2E FF 2C ljmp cs:[si] //transition to flat 32 bit protected mode and jump to address at 0x0:0xffffff6e aka. 0xffffff6e which is fffffcd8. CS contains 0 remember (it's the base that is 0xffff) so it will load the first entry.
//SEC continues at that address
0x8f: FA cli
0x90: F4 hlt
.
.
kd> !db [uc] 00000000`ffffff80
#ffffff80 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffff90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffffa0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffffb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffffc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffffd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
#ffffffe0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 58 4d ..............XM
#fffffff0 ea 5b e0 00 f0 30 36 2f-32 33 2f 39 39 00 fc 8f .[...06/23/99...
kd> !db [uc] fff80
# fff80 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fff90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffa0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffe0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 58 4d ..............XM
# ffff0 ea 5b e0 00 f0 30 36 2f-32 33 2f 39 39 00 fc 8f .[...06/23/99...
ffffff80 FF 46 A0 70 CC CC CC CC E9 1B F6 FF FF E9 26 F6 Fáp¦¦¦¦Ú.÷ Ú&÷
ffffff90 FF FF E9 71 F6 FF FF E9 7C F6 FF FF E9 3C FD FF Úq÷ Ú|÷ Ú<²
ffffffa0 FF E9 3C FD FF FF E9 75 FF FF FF 00 00 00 00 00 Ú<² Úu .....
ffffffb0 00 00 00 00 00 00 00 00 04 00 00 19 44 00 00 19 ............D...
ffffffc0 00 01 D9 FF 00 00 00 00 00 00 00 00 00 00 00 00 ..+ ............
ffffffd0 BF 50 41 EB 1D 00 00 00 00 00 00 00 00 00 00 00 +PAÙ............
ffffffe0 54 18 E9 FF EB FE CF 00 00 00 00 00 00 00 00 00 T.Ú Ù¦¤.........
fffffff0 90 90 E9 43 FC 00 00 00 FB 00 00 00 00 00 E9 FF ..ÚC³...¹.....Ú
lkd> !db fff80
# fff80 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fff90 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffa0 00 00 00 00 00 00 00 00-00 00 e9 e3 3b 00 00 00 ............;...
# fffb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# fffe0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
# ffff0 ea 5b e0 00 f0 30 37 2f-32 32 2f 31 36 00 fc 00 .[...07/22/16...