Smashing the stack example3.c confusion

混江龙づ霸主 提交于 2019-12-04 03:08:51

That's not how I interpret the article. The way I understand it he wants to modify the return address so that the x = 1; assignment is skipped, i.e. he wants function to return to where the printf would be executed.

As you can see in your disassembly, the assignment is 8 bytes (c7 44 24 1c 01 00 00 00), hence moving the return address 8 bytes forward would move it past this instruction. As for the "We used a test value first" comment.. maybe he just means that he looked at the code in a disassembler to figure out the length, or that he experimented with different offsets(?).

The displacement in the article is wrong, it should be 10 bytes. When a function is called (or a jump is executed), the return address is set to equal the instruction pointer + the current instruction size:

ret = IP + Curr_Inst_size

So when the call to the function returns, the instruction pointer should equal 0x80004a8 (0x80004a3 + the call instruction size):

    0x80004a3 <main+19>:    call   0x8000470 <function>
--> 0x80004a8 <main+24>:    addl   $0xc,%esp            
    0x80004ab <main+27>:    movl   $0x1,0xfffffffc(%ebp)
    0x80004b2 <main+34>:    movl   0xfffffffc(%ebp),%eax

However, you want to set the instruction pointer to 0x80004b2 instead, to skip the assignment, you also, inevitably, have to skip another instruction (addl $0xc,%esp) to get there, or in other words, you need to add (0x80004b2-0x80004a8) bytes, or 10 bytes, to the instruction pointer to skip those two instructions:

    0x80004a3 <main+19>:    call   0x8000470 <function>
    0x80004a8 <main+24>:    addl   $0xc,%esp            
    0x80004ab <main+27>:    movl   $0x1,0xfffffffc(%ebp)
--> 0x80004b2 <main+34>:    movl   0xfffffffc(%ebp),%eax 

The actual instruction size depends on the operands, machine type etc.. But in this example, the addl is 3 bytes long, and the movl is 7 bytes long. You could check the x86 Instruction Set Reference for the exact instruction size, or you could compile and disassemble this code, you will see that those two instructions are 10 bytes long:

int main()
{
    asm("addl  $0xc,%esp\n\
         movl  $0x1,0xfffffffc(%ebp)");

}

gdb:

0x08048397 <+3>: 83 c4 0c               add    $0xc,%esp
0x0804839a <+6>: c7 45 fc 01 00 00 00   movl   $0x1,-0x4(%ebp)

There's also a discussion here and here about this exact same issue in example 3.

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