【问题标题】:What would happen if the CS segment register is changed? (And how would you do so?)如果 CS 段寄存器改变会发生什么? (你会怎么做?)
【发布时间】:2012-08-29 03:03:00
【问题描述】:

我看了这篇文章:http://static.patater.com/gbaguy/day3pc.htm

它包括句子

永远不要改变 CS!!

但是如果你确实修改了CS 段寄存器会发生什么呢?为什么这么危险?

【问题讨论】:

  • CS = 代码段。我想改变它(在某种意义上)等同于变态的jmp
  • 该文件似乎很不可靠:“永远不要更改CS!!,但您可以像这样阅读CSmov ds,cs;将CS 的值放入@987654330 @S。”好吧,在 x86 中没有像 mov ds,cs 这样的指令,也没有任何其他 mov segreg,segreg。要读取cs 的值,您可以使用mov reg,cs; mov ds,reg(其中reg 可以是axbxcx 等...)或push cs; pop ds。此外,如果您决定永远不更改cs,则所有中断调用都没有问题(例如BIOS、DOS 和Linux 服务)。 web.itu.edu.tr/kesgin/mul06/intel/instr/mov.html
  • @nrz:不存在通过far 调用访问的“Linux 服务”之类的东西(中断/系统调用的工作方式不同;即使这些导致cs 发生变化,调用者 无法控制目标cs 将是什么,这由操作系统在设置IDT 条目/系统调用msrs 时决定)。确认所有其他内容,显然cs 可以 被更改,除非目标代码段存在并且设置为目标eip 是可访问的,任何这样的调用都会导致#GP 错误,应用程序将中止。
  • 刚刚阅读了由原始问题链接的文档:我确实想知道为什么现在没有最终受虐狂的人会尝试 16bit x86 汇编编程。如果有的话,那会伤到你的大脑,让你在余生中停止组装......
  • @FrankH “Linux 服务”是指int 0x80(32 位)或syscall(64 位)。我同意你关于为什么不学习 x86 16 位汇编的评论。我认为现在没有任何理由开始使用 x86 16 位汇编学习汇编,即使那是我十多年前开始学习的(在 DOS 环境中)。我目前正在学习 Linux 64 位汇编,我相信它在未来很多年都会有用。

标签: assembly x86 x86-16


【解决方案1】:

cs 是代码段。 cs:ip,表示csip(指令指针)一起指向下一条指令的位置。因此,对csip 或两者的任何更改都会更改获取和执行下一条指令的地址。

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

跳远或远距离呼叫本身并没有什么危险。您只需要知道您在哪里跳转或呼叫,并且在受保护模式下您需要有足够的权限来执行此操作。在 16 位实模式(例如 DOS)中,您可以跳转并调用您想要的任何地址,例如。 jmp 0xF000:0xFFF0cs 设置为0xF000,将ip 设置为0xFFF0,这是BIOS 代码的起始地址,从而重新启动计算机。不同的内存地址有不同的代码,因此会导致不同的结果,理论上一切可能都会发生(如果你跳转到用于格式化硬盘驱动器的 BIOS 代码,具有有效的寄存器和/或堆栈值,那么硬盘驱动器将被格式化'按照要求')。实际上,jmp's 和 call's 到大多数地址可能很快就会导致无效的操作码或其他一些异常(除以零、除数溢出等)。

【讨论】:

  • 只更改cs 通常是错误的。通常csxip 一起更改或者只是xip 更改。
  • @AlexeyFrunze 好吧,只有在不更改/设置 ip/eip/rip 的情况下仅更改 cs 的唯一方法是 pop cs,仅在 8088 和 8086 中可用。在 186+ 中,如果不更改/设置 ip/eip/rip,则无法更改 cspop cs 可能用于针对 8088/8086(或 8088/8086 模拟器)的混淆代码。
【解决方案2】:

在保护模式和长模式(即非 16 位模式)下,包括 CS 在内的段寄存器不再只是额外的 4 位地址。它们索引到段描述符表中,具有基数 + 限制(正常基数=0 限制=4GiB,即平面内存模型),但也具有其他属性。

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

TODO:挖掘一个链接,其中有人展示了如何执行此操作。我认为最近甚至有一个关于此的问题,其中详细回答了如何找到正确的分段编号。

【讨论】:

    猜你喜欢
    • 2018-11-17
    • 2021-01-16
    • 2010-11-08
    • 2019-03-13
    • 1970-01-01
    • 2018-09-18
    • 2019-01-09
    • 1970-01-01
    • 2011-09-17
    相关资源
    最近更新 更多