EIP register value goes over 100 bytes

前提是你 提交于 2021-01-28 19:34:53

问题


Hey I am having hard time solving my homework.

Then x86 processor executes commands EIP register(counter) value increases by 1 byte or by a few bytes depending on command's type. Which instructions we have to use so EIP value may go over 100 bytes?

Answers are: JMP | ADD | SUB | PUSH | JNZ | MUL | CALL | JZ

As I get the idea, EIP is special case register which we can't use. It's called Extended Instruction Pointer. And to increase it's value over 100 bytes, we need to find how much each command is adding to EIP value?


回答1:


Any of those instructions could #PF (page fault exception) on a memory operand (or other ways depending on the instruction) and change CS:EIP to a totally new value loaded from the IDT. e.g. push dword [0]. That would include changing EIP by more than 100 unless your current EIP is within 100 bytes of the page-fault exception handler's address.

Or if we're talking about where the exception handler returns, if your process had a signal handler installed for SIGSEGV, the kernel could deliver that signal, effectively changing EIP within your process to your segfault signal handler.

But I think the intent of the question is about changing EIP by a specific desired relative amount, e.g. to reach another block of code. (Also not changing CS, the code-segment, so you stay in user-mode if you were there to start with.) I.e. 100 bytes away from the current EIP. The phrasing is awkward and could be read as setting EIP to any absolute value > 100, but x86 branches are relative and the question makes more sense that way.

As @zx485 points out, you need a control transfer instruction, aka a jump or branch. 386 (i.e. any machine with an EIP not just 16-bit IP) supports jcc rel32 conditional near jump as well as the shorter jcc rel8 short jump, so conditional jumps can reach anywhere in the entire 32-bit address space, same as jmp rel32 and call rel32. https://www.felixcloutier.com/x86/jcc.

But even a jcc rel8 (like JZ or JNZ) or jmp rel8 encoding can reach from -128 to +127 bytes relative to the end of the instruction. (Signed 8-bit 2's complement branch displacement.)




回答2:


There are several possible answers to this:

  1. Use a relative JMP rel8: Many asemblers use a syntax like this:

    JMP $+100 
    

    where $ is the current value of EIP (the beginning of the JMP) and 100 is the decimal value to add to this position. The JMP itself occupies two bytes - which are subtracted from the 100 calculation in the instruction encoding. So the code is

    EB 62               (Address after the JMP + 98d=62h)
    
  2. You can use conditional jumps like JNZ and JZ which function in the same way.

  3. You can also use a relative CALL rel32 like this:

    CALL $+100
    

    In this case the instruction length is different ( =5 ). The count starts after the CALL, so the instruction is

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

    Note that the address after the CALL is also PUSHed to the stack before the jump is executed.

  4. The instructions ADD, SUB, PUSH, MUL do not have any influence on EIP except for advancing it by their own instruction length.

    So you could also just combine them sequentially to progress 100 bytes, but that answer is trivial.



来源:https://stackoverflow.com/questions/59760180/eip-register-value-goes-over-100-bytes

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!