【问题标题】:EIP register value goes over 100 bytesEIP 寄存器值超过 100 字节
【发布时间】:2020-05-02 17:42:06
【问题描述】:

嘿,我很难解决我的作业。

然后 x86 处理器执行命令 EIP 寄存器(计数器)值增加 1 个字节或几个字节,具体取决于命令的类型。我们必须使用哪些指令所以 EIP 值可能超过 100 个字节?

答案是:JMP |添加 |子 |推 |新西兰 |穆尔 |电话 | JZ

据我所知,EIP 是我们不能使用的特殊情况寄存器。它被称为扩展指令指针。而要将它的值增加到 100 字节以上,我们需要找出每个命令对 EIP 值增加了多少?

【问题讨论】:

  • 通常指令是按顺序执行的,不会跳过任何指令。哪些指令可能导致程序乱序执行?

标签: assembly x86 byte cpu-registers eip


【解决方案1】:

任何这些指令都可以#PF(页面错误异常)在内存操作数上(或其他方式取决于指令)并将 CS:EIP 更改为从 IDT 加载的全新值。例如push dword [0]。这包括将 EIP 更改超过 100,除非您当前的 EIP 在页面错误异常处理程序地址的 100 字节内。

或者,如果我们正在讨论异常处理程序返回的位置,如果您的进程为 SIGSEGV 安装了 signal 处理程序,内核可以传递该信号,从而有效地将您的进程中的 EIP 更改为您的 segfault信号处理程序。

但我认为问题的意图是通过特定的所需相对量来更改 EIP,例如到达另一个代码块。 (也不会更改代码段 CS,因此如果您从那里开始,您将保持在用户模式。)即距离当前 EIP 100 个字节距离。措辞很尴尬,可以理解为将 EIP 设置为任何 absolute 值 > 100,但 x86 分支是相对的,这样问题更有意义。

正如@zx485 指出的那样,您需要一个控制转移指令,也就是跳转或分支。 386(即任何具有 EIP 而不仅仅是 16 位 IP 的机器)支持jcc rel32 条件近跳转以及较短的jcc rel8 短跳转,因此条件跳转可以到达整个 32 位地址空间中的任何位置,与jmp rel32call rel32https://www.felixcloutier.com/x86/jcc.

但即使是 jcc rel8(如 JZ 或 JNZ)或 jmp rel8 编码也可以达到相对于指令结尾的 -128 到 +127 个字节。 (有符号 8 位 2 的补码分支位移。)

【讨论】:

    【解决方案2】:

    对此有几个可能的答案:

    1. 使用相对的JMP rel8:许多汇编器使用这样的语法:

      JMP $+100 
      

      其中$ 是 EIP 的当前值(JMP 的开头),100 是要添加到该位置的十进制值。 JMP 本身占用两个字节 - 从指令编码中的 100 计算中减去。所以代码是

      EB 62               (Address after the JMP + 98d=62h)
      
    2. 您可以使用JNZJZ 等条件跳转,它们的功能相同。

    3. 你也可以像这样使用相对的CALL rel32

      CALL $+100
      

      在这种情况下,指令长度不同( =5 )。计数在 CALL 之后 开始,所以指令是

      E8 5F 00 00 00      (Address after the CALL + 95d=5Fh)
      

      注意CALL后面的地址在跳转执行前也是PUSH入栈的。

    4. 指令 ADD, SUB, PUSH, MUL 对 EIP 没有任何影响,除了它们自己的指令长度提前。

      因此您也可以将它们按顺序组合以推进 100 个字节,但这个答案是微不足道的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-12
      • 1970-01-01
      • 2020-08-13
      • 2015-02-10
      • 1970-01-01
      • 2015-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多