首页
社区
课程
招聘
[求助]逆向x86BiosCall ()原理
发表于: 2013-5-9 20:14 5676

[求助]逆向x86BiosCall ()原理

2013-5-9 20:14
5676
有谁能逆向win7的HAL.dll里面个一个新的导出函数
NTHALAPI BOOLEAN x86BiosCall (ULONG, PX86BIOS_REGISTERS);
这个函数吗?

在windows下调用BIOS中断,应该要切换到实模式的吧?
x86BiosCall ()这个函数是如何实现调用BIOS中断的?这个函数有切换到实模式吗?
又如何切换回来到保护模式呢?求原理。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
2
好像IA32手册上说进入了保护模式就不能关掉了……
2013-5-9 20:17
0
雪    币: 1407
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
http://www.geoffchappell.com/studies/windows/km/hal/api/x86bios/index.htm
2013-5-9 22:46
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
翻墙把该网址内容down下来了。
DRAFT: Take more than your usual care.

The x86 BIOS Emulator
The HAL in both the x86 and x64 builds of Windows Vista has a set of functions for accessing the 16-bit
firmware that Windows started from. This firmware is better known as the ROM BIOS. It won’t surprise
anyone that the functions for doing this are all undocumented:

HalInitializeBios
x86BiosAllocateBuffer
x86BiosCall
x86BiosFreeBuffer
x86BiosReadMemory
x86BiosWriteMemory
What may surprise is the way it’s done. The HAL prepares a copy (apparently called a shadow) of relevant
areas of memory from the first megabyte, and implements a 16-bit emulator for “executing” the real-mode
code. To the emulator, the real-mode code is just a stream of bytes to interpret and act on. Registers that
the real-mode code would operate on when actually executing in real mode are instead just members of a
context structure in the HAL’s data. Where the real-mode code would read from or write to some memory in
its 1MB of physical address space, the HAL instead reads from or writes to corresponding addresses in the
shadow memory.

Note that the functions whose names begin with x86Bios more-or-less reproduce the Int10AllocateBuffer,
Int10CallBios, Int10FreeBuffer, Int10ReadMemory and Int10WriteMemory members of a
VIDEO_PORT_INT10_INTERFACE structure such as filled by the VideoPortQueryServices function. It seems a
reasonable hypothesis that the x86 BIOS emulator was developed (primarily, if not solely) so that int 10h
functionality for video drivers can be maintained on 64-bit Windows without the need to have these
systems support virtual-8086 execution.

Indeed, the emulator appears first in the x64 builds of version 5.2, for a set of functions that are
superseded now that the emulator has common functions for both builds:

HalCallBios
x86BiosExecuteInterrupt
x86BiosInitializeBiosEx
x86BiosTranslateAddress
The new emulator is initialised when the kernel calls the HalInitializeBios function. Thereafter, the BIOS’s
software-interrupt interface is available through the x86BiosCall function. This allows for an interrupt
number, for passing parameters in the general registers and the ds and es segment registers, and for
receiving results in the general registers. Where a software interrupt expects an address for data, the
x86BiosAllocateBuffer function may help by providing the address of a transfer buffer in the shadow
memory. Data can be read from or written to the transfer buffer, or to any address in the shadow memory,
through the functions x86BiosReadMemory and x86BiosWriteMemory.

Memory
The shadow memory allows for 1MB of addresses, but with holes. The contents of shadow memory in the
addressing holes is undefined. The addresses that are supported for emulation are:

the first 2KB, most notably including the real-mode interrupt vector table and PC-compatible BIOS data;
4KB at address 2000:0000 for use as a transfer buffer;
64KB at address 9000:0000, most notable for including the Extended BIOS Data Area;
128KB of PC-compatible video memory at address A000:0000;
256KB at address C000:0000, including the ROM BIOS.
The shadow memory at A000:0000 actually is mapped to the physical address 0x000A0000. Within any
range other than this and the one at 2000:0000, a page is undefined in shadow memory unless it is either
not in the memory map that the kernel receives from the loader or its memory type is
LoaderFirmwarePermanent or LoaderSpecialMemory.

Ports
Code interpreted by the emulator has access to all ports in the 64KB of I/O space, but the following may be
simulated:

the CMOS ports 70h and 71h;
ports B1h and B2h;
the PCI address ports 0CF8h to 0CFBh;
the PCI data ports 0CFCh to 0CFFh.
Instructions
The emulator supports all the general-purpose 80386 instructions, plus bswap, cmpxchg, rdtsc, xadd (which
were added for later processors), plus the system instruction smsw.

Decoding
Some quirks are known for the decoding of opcode sequences. Only one seems really noteworthy: the
bswap instruction is recognised only in the encoding that begins 0x0F 0xC8, i.e., to swap the bytes of the
eax register.

The adc, add, and, cmp, or, sbb, sub and xor are not supported in the encoding that begins with 0x82
(which Intel does list as valid, though the apparently equivalent encoding that begins with 0x80 is clearly
preferred).

The inc and dec encodings that begin with 0xFE are accepted for all values of the reg field in the second
byte: even for inc; odd for dec.

If the effective address for an opcode sequence that begins with 0x0F 0x01 is zero, then no matter what
instruction the sequence decodes to, all its bytes are more or less ignored. If the operand is based on the
bp or ebp register, then the default segment (for the next instruction) becomes ss. Prefixes that precede
the sequence carry to the next.

The bt, btc, btr and bts instructions in the encoding that begins with 0x0F 0xBA are accepted if the reg field
in the third byte is 0, 1, 2 or 3 respectively (not just 4, 5, 6 or 7).

Implementation
Most instructions operate on the shadow registers and the shadow memory in the expected way. The lock
prefix has no known effect. The wait instruction is ignored.

The rdtsc instruction is implemented to load edx:eax with the return value of KeQueryPerformanceCounter.

The smsw instruction is implemented as returning 0x2D, i.e., to have the PE, EM, TS and NE bits set and all
others clear. It is appropriate that the PE bit appears to be set even though the BIOS code executes with
real-mode addressing. Note however that the emulator always has the VM bit clear in the shadowed eflags
register, and the IOPL is always 0, too.

Interrupts do not clear the interrupt and trap flags for their handlers. Of course, when the emulator
interprets code, it does not provide for interruption or tracing, and it seems unlikely that any handlers will
depend on these flags to be clear. Interrupt 1Ah function B1h may be simulated. Interrupt 42h is ignored.

This page was created on 27th April 2009 and was last modified on 4th January 2010.

Copyright © 2009. Geoff Chappell. All rights reserved. Conditions apply.
2013-5-10 08:11
0
雪    币: 468
活跃值: (52)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
仿真器模拟执行16位BIOS指令?那么,BIOS硬件中断产生后,比如键盘中断,磁盘中断,硬中断产生按道理是执行实模式的中断服务程序,这又是如何处理的?
2013-5-10 08:21
0
游客
登录 | 注册 方可回帖
返回
//