2012-09-04 93 views
5

我读这篇文章:http://static.patater.com/gbaguy/day3pc.htm如果CS段寄存器更改会发生什么情况?

它包括句子

永远不要更改CS!

但是,如果您修改了CS段寄存器,会发生什么?为什么这么危险?

+2

'CS' =代码段。我想改变它是相当于(在某种意义上)到一个变形的'jmp'。 – valdo

+5

该文件看起来相当不可靠:“不要改变CS' !!,但你可以像这样读取'CS':'mov ds,cs';把'CS'的值放入'D'S。那么,在x86中,没有像'mov ds,cs'和其他任何'mov segreg,segreg'这样的指令。要读取'cs'的值,你可以使用'mov reg,cs; mov ds,reg'(其中'reg'可以是'ax','bx','cx'等等)或者'push cs;流行音乐ds'。此外,如果您决定不*更改'cs',则所有的中断调用都不成问题(例如BIOS,DOS和Linux服务)。 http://web.itu.edu。tr/kesgin/mul06/intel/instr/mov.html – nrz

+1

@nrz:通过'far'调用不能访问“Linux服务”(中断/系统调用的工作方式不同;即使这些会导致'cs ',_caller_无法控制'cs'的目标是什么,这是由操作系统在设置IDT条目/ syscall msrs时决定的)。同其他人一样,显然'cs'_can_可以被改变,只是除非目标代码段存在并且被设置为可以访问目标'eip',任何这样的调用都将导致'#GP'错误,并且该应用会中止。 –

回答

7

cs是代码段。 cs:ip,这意味着cs连同ip(指令指针)指向下一条指令的位置。因此,对csip或两者的任何更改都会更改下一条指令将被提取和执行的地址。

通常你改变csjmp(跳远),call(长调用),retfint3intiret。在8088和8086 pop cs也可用(操作码0x0F)。 pop cs在186+中不起作用,其中操作码0x0F保留用于多字节指令。 http://en.wikipedia.org/wiki/X86_instruction_listings

在跳远或长时间通话中没有任何内在危险。您只需知道您跳到哪里或打电话的位置,并且在保护模式下您需要有足够的权限才能执行此操作。在16位实模式下(例如DOS),您可以跳转并调用您想要的地址,例如。 jmp 0xF000:0xFFF0设置cs0xF000ip0xFFF0,这是BIOS代码的起始地址,因此重新启动计算机。不同的内存地址有不同的代码,因此会导致不同的结果,理论上可能会发生任何事情(如果跳转到用于格式化硬盘驱动器的BIOS代码,并使用有效的寄存器和/或堆栈值,则硬盘将被格式化'按照要求')。实际上,对于大多数地址,jmpcall可能会很快导致无效的操作码或一些其他异常(除以零,除溢出等)。

+0

只更改'cs'通常是错误的。通常'cs'和'xip'一起改变或者只是'xip'改变。 –

+3

@AlexeyFrunze那么,只更改'cs'而不更改/设置'ip' /'eip' /'rip'的唯一方法是'pop cs',它只在8088和8086中可用。在186+中, t改变'cs'而不改变/设置'ip' /'eip' /'rip'。 'pop cs'可能可用于8088/8086(或8088/8086仿真器)的混淆代码。 – nrz

0

在保护模式和长模式(即不是16位模式)下,包括CS的段寄存器不再只是一个额外的4位地址。它们以分段描述符的表格为索引,具有基本限制(正常基础= 0限制= 4GiB,即平坦内存模型),还具有其他属性。

代码段描述符确定CPU模式(例如,32位compat模式与64位长模式)。在64位内核上,64位用户空间进程可能会将某个far jmp转换为某些32位代码。这在实践中没有用,甚至在操作系统在上下文切换后返回到您的进程时可能会中断。

待办事项:挖掘链接,其中有人展示了如何做到这一点。我想甚至有一个关于这个问题的最近的问题,有关如何找到正确的细分数字的详细答案。

相关问题