利用LDT(局部描述符表) [英] Utilizing the LDT (Local Descriptor Table)

查看:391
本文介绍了利用LDT(局部描述符表)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做使用不同的细分除了默认的code和数据用户和内核部分的一些实验。我希望通过利用本地描述符表和modify_ldt系统调用来实现这一点。通过系统调用我已经建立在LDT新条目是一个段描述符与一个全局变量我想隔离的一个基本地址和4字节的限制。

I am trying to do some experiments using different segments besides the default code and data user and kernel segments. I hope to achieve this through use of the local descriptor table and the modify_ldt system call. Through the system call I have created a new entry in LDT which is a segment descriptor with a base address of a global variable I want to "isolate" and a limit of 4 bytes.

我尝试在C程序中,通过内联汇编我的自定义LDT项的段选择加载数据段寄存器,但当我尝试访问变量我收到分段错误。

I try to load the data segment register with the segment selector of my custom LDT entry through inline assembly in a C program, but when I try to access the variable I receive a segmentation fault.

我怀疑是有与胶印我的全局变量,并计算该地址时,超过我的自定义段的限制,因此造成了赛格故障的问题。

My suspicion is that there is an issue with the offset of my global variable, and when the address is calculated, it exceeds the limit of my custom segment therefore causing a seg fault.

有谁知道周围的工作这种情况呢?

Does anyone know of a work around to this situation?

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

Oh, by the way, this is on an x86 architecture in Linux. This is my first time asking a question like this on a forum, so if there is any other information that could prove to be useful, please let me know.

感谢您提前。

编辑:我意识到,我也许应该包括源$ C ​​$ C:)

I realized that I probably should include the source code :)

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;

赛格故障发生在去年的指令。

The seg fault occurs at that last instruction.

推荐答案

我只能猜测,因为我没有可用的组件给我。

I can only guess, since I don't have the assembly available to me.

我猜,在其中您会获得一个段错误的线被编译成这样的:

I'm guessing that the line at which you get a segfault is compiled to something like:

mov ds:[offset mx], 0x407cafe

其中,偏移MX 在程序的数据段偏移量为 MX (如果它是一个静态变量)或在堆栈(如果它是一个自动变量)。无论哪种方式,这个偏移量在编译时进行计算,而这正是将使用无论使用什么 DS 点。

Where offset mx is the offset to mx in the program's data segment (if it's a static variable) or in the stack (if it's an automatic variable). Either way, this offset is calculated at compile time, and that's what will be used regardless of what DS points to.

现在你所做的是创建一个新的细分市场,其基础是 MX 的地址,其限制或者是为0x4 0x4fff (取决于 G比特你没有指定)。

Now what you've done here is create a new segment whose base is at the address of mx and whose limit is either 0x4 or 0x4fff (depending on the G-bit which you didn't specify).

如果在 G比特 0,则限制为为0x4 ,并且由于它是极不可能的, MX 地址之间的为0x0 为0x4 code> DS ,当你访问偏移量 MX 你穿越极限新段内。

If the G-bit is 0, then the limit is 0x4, and since it's highly unlikely that mx is located between addresses 0x0 and 0x4 of the original DS, when you access the offset to mx inside the new segment you're crossing the limit.

如果在 G比特 1,则限制为 0x4fff 。现在,你会得到一个段错误只有在原始 MX 位于上述 0x4fff

If the G-bit is 1, then the limit is 0x4fff. Now you'll get a segfault only if the original mx was located above 0x4fff.

考虑到新的细分市场的基础是 MX ,您可以访问 MX 这样做:

Considering that the new segment's base is at mx, you can access mx by doing:

mov ds:[0], 0x407cafe

我不知道我怎么会去写,在C,虽然。

I don't know how I'd go about writing that in C, though.

这篇关于利用LDT(局部描述符表)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆