c - 使用 LDT(本地描述符表)

标签 c assembly x86

除了默认代码和数据用户和内核段之外,我正在尝试使用不同的段进行一些实验。我希望通过使用本地描述符表和 modify_ldt 系统调用来实现这一点。通过系统调用,我在 LDT 中创建了一个新条目,它是一个段描述符,具有我想要“隔离”的全局变量的基地址和 4 个字节的限制。

我尝试通过 C 程序中的内联汇编使用自定义 LDT 条目的段选择器加载数据段寄存器,但是当我尝试访问该变量时,我收到了段错误。

我怀疑我的全局变量的偏移量有问题,当计算地址时,它超出了我的自定义段的限制,因此导致段错误。

有人知道解决这种情况的方法吗?

哦,顺便说一句,这是在 Linux 中的 x86 架构上。这是我第一次在论坛上提出这样的问题,所以如果有任何其他信息可能被证明是有用的,请告诉我。

提前致谢。

编辑:我意识到我可能应该包括源代码:)

struct user_desc* table_entry_ptr = NULL;

/* Allocates memory for a user_desc struct */
table_entry_ptr = (struct user_desc*)malloc(sizeof(struct user_desc));

/* Fills the user_desc struct which represents the segment for mx */
table_entry_ptr->entry_number = 0;
table_entry_ptr->base_addr = ((unsigned long)&mx);
table_entry_ptr->limit = 0x4;
table_entry_ptr->seg_32bit = 0x1;
table_entry_ptr->contents = 0x0;
table_entry_ptr->read_exec_only = 0x0;
table_entry_ptr->limit_in_pages = 0x0;
table_entry_ptr->seg_not_present = 0x0;
table_entry_ptr->useable = 0x1;

/* Writes a user_desc struct to the ldt */
num_bytes = syscall( __NR_modify_ldt,
                   LDT_WRITE, // 1
                   table_entry_ptr,
                   sizeof(struct user_desc)
                   );

asm("pushl %eax");
asm("movl $0x7, %eax"); /* 0111: 0-Index 1-Using the LDT table 11-RPL of 3 */
asm("movl %eax, %ds");
asm("popl %eax");

mx = 0x407CAFE;

段错误发生在最后一条指令处。

最佳答案

我只能猜测,因为我没有可用的程序集。

我猜你得到段错误的行被编译成类似的东西:

mov ds:[offset mx], 0x407cafe

在哪里offset mxmx 的偏移量在程序的数据段中(如果它是静态变量)或在堆栈中(如果它是自动变量)。无论哪种方式,这个偏移量都是在编译时计算的,无论 DS 是什么,都会使用它。指向。

现在您在这里所做的是创建一个新段,其基地址为 mx。并且其限制是 0x40x4fff (取决于您未指定的 G-bit)。

如果G-bit为0,则极限为0x4 ,并且由于 mx 极不可能位于地址 0x0 之间和 0x4原件DS ,当您访问 mx 的偏移量时在新 segmentation 中,您正在跨越限制。

如果G-bit为1,则极限为0x4fff .现在只有在原始 mx 出现时才会出现段错误位于0x4fff之上.

考虑到新段的基数是 mx , 您可以访问 mx通过做:

mov ds:[0], 0x407cafe

不过,我不知道如何用 C 语言编写它。

关于c - 使用 LDT(本地描述符表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1771136/

相关文章:

c++ - 弄清楚晦涩的指针typedef

assembly - 最简单的链式加载引导管理器

c - 存档没有索引;运行 ranlib 添加一个(当在 Linux 上链接包含 MachO64 目标文件的 .a 时)

assembly - 用于设置奇偶校验、溢出和符号标志的 x86 指令

floating-point - 现代 x86 处理器是否原生支持十进制浮点运算?

通过引用调用、const 正确性和对引用结构的读写访问 - 未定义的行为

c - 如何抑制 “warning: cast to pointer from integer of different size”?

c - 文件之间的结构

exception - 在 Windows x86-64 下有多少异常被插入 32 位堆栈?

x86 - DEC VAX 与 IA-32 的字节顺序