如何根据 x86 段寄存器中的值计算地址?

逆向工程 视窗 ollydbg x86 登记 分割
2021-06-30 15:03:13

段寄存器中的 16 位值如何用于表示大内存地址?

ES 0023 32bit 0(FFFFFFFF)
CS 001B 32bit 0(FFFFFFFF)
SS 0023 32bit 0(FFFFFFFF)
DS 0023 32bit 0(FFFFFFFF)
FS 003B 32bit 7FFDF000 (FFF)
GS 0000 NULL

例如,003Bin如何FS转换为7FFDF000为什么0023inES001BinCS显然都翻译为0

我正在仔细阅读英特尔手册,但希望这里有人能比我阅读那些手册更快地帮助我...

2个回答

您正在查看 32 位寄存器(可能在 32 位进程中)。由于 32 位处理器段寄存器很少用作偏移地址,原因很简单,32 位足以表示相当大的地址范围。

相反,一些段寄存器 ( CS, SS, DS) 现在用于权限、内存保护和分页,而其他的则用作通用寄存器或操作系统特定结构(例如FS在 32 位窗口和GSlinux 和 64 位窗口中)。

要了解更多信息,我建议您阅读有关内存保护、保护模式和现代操作系统内存管理和分页的内容。

在保护模式下,段选择器是描述符表的索引(本地或全局表,取决于选择器的 TI 位)。描述符条目描述了段的基地址、限制(大小)和其他一些属性(数据或代码,16 位或 32 位)。有关更多信息,请参阅以下链接:

Windows 通常设置选择器,以便它们以 1:1 直接映射到虚拟地址,这就是为什么它们都以 0fs基数的原因。这是个例外,因为它用于快速寻址每个线程独立的线程信息块 (TIB)每个过程的。

但是,在 32 位内核上,您实际上可以使用未记录的函数设置自定义选择器映射NtSetLdtEntries请参阅此处了解更多信息: