title: Why is ebx saved in the stack frame of a simple function, calling gets?
body: <p>I am trying to write a buffer overflow exercise in c for students.</p>
  
  <p>Normally the stack frame consists of the function parameters, the return address, the base pointer and local variables. But I detected, that sometimes additional registers are saved along with the base pointer. I remember from class that calee saved registers have to be saved before they are used. But there are cases where the compilation of C code produces assembly, which saves and uses registers apperently without purpose. Please explain this behaviour to me.</p>
  
  <p>Assume the main function</p>
  
  <pre><code>int main (int argc, char** argv) {
      func();
  
      return 0;
  }
  </code></pre>
  
  <p>and the function</p>
  
  <pre><code>void func() {
      char buf[5];
      strcpy(buf,"AAAA");
      strcpy(buf,"BBBB");
  }
  </code></pre>
  
  <p>If I debug the resulting executable with gdb</p>
  
  <pre><code>break func
  run
  info frame
  </code></pre>
  
  <p>everything is fine and the stack frame only contains ebp and eip.</p>
  
  <p>If I use</p>
  
  <pre><code>void func() {
      char buf[5];
      gets(buf);
  }
  </code></pre>
  
  <p>I get</p>
  
  <pre><code> Saved registers:
    ebx at 0xffffd1cc, ebp at 0xffffd1d0, eip at 0xffffd1d4
  </code></pre>
  
  <p>So ebx is additionally saved in the stack frame? Why? If I run</p>
  
  <pre><code>disas func
  </code></pre>
  
  <p>I get</p>
  
  <pre><code>Dump of assembler code for function func:
     0x56555730 &lt;+0&gt;: push   %ebp
     0x56555731 &lt;+1&gt;: mov    %esp,%ebp
     0x56555733 &lt;+3&gt;: push   %ebx
     0x56555734 &lt;+4&gt;: sub    $0x8,%esp
     0x56555737 &lt;+7&gt;: call   0x5655576e &lt;__x86.get_pc_thunk.ax&gt;
     0x5655573c &lt;+12&gt;:    add    $0x18c4,%eax
  =&gt; 0x56555741 &lt;+17&gt;:    lea    -0x9(%ebp),%edx
     0x56555744 &lt;+20&gt;:    push   %edx
     0x56555745 &lt;+21&gt;:    mov    %eax,%ebx
     0x56555747 &lt;+23&gt;:    call   0x56555590 &lt;gets@plt&gt;
     0x5655574c &lt;+28&gt;:    add    $0x4,%esp
     0x5655574f &lt;+31&gt;:    nop
     0x56555750 &lt;+32&gt;:    mov    -0x4(%ebp),%ebx
     0x56555753 &lt;+35&gt;:    leave  
     0x56555754 &lt;+36&gt;:    ret    
  End of assembler dump.
  </code></pre>
  
  <p>So ebx is saved. Ok. But what is it used for? eax is moved in ebx before calling gets(). But it is not used afterwards. The old ebx is just restored from the stack before leaving and returning. It seems useless.
  Btw. Whats the whole <code>call get_pc_thunk</code> stuff?</p>
  
  <p>Comparable behaviour, if I use printf instead of gets:</p>
  
  <pre><code>void func() {
      char buf[5];
      strcpy(buf, "AAAA");
      printf("%s",buf);
  }
  </code></pre>
  
  <p>gdb output:</p>
  
  <pre><code>(gdb) info frame
  Stack level 0, frame at 0xffffd1d8:
   eip = 0x56555741 in func (/home/mischa/stuff/test/test.c:35); saved eip = 0x56555779
   called by frame at 0xffffd1e0
   source language c.
   Arglist at 0xffffd1d0, args: 
   Locals at 0xffffd1d0, Previous frame's sp is 0xffffd1d8
   Saved registers:
    ebx at 0xffffd1cc, ebp at 0xffffd1d0, eip at 0xffffd1d4
  (gdb) disas func
  Dump of assembler code for function func:
     0x56555730 &lt;+0&gt;: push   %ebp
     0x56555731 &lt;+1&gt;: mov    %esp,%ebp
     0x56555733 &lt;+3&gt;: push   %ebx
     0x56555734 &lt;+4&gt;: sub    $0x8,%esp
     0x56555737 &lt;+7&gt;: call   0x56555780 &lt;__x86.get_pc_thunk.ax&gt;
     0x5655573c &lt;+12&gt;:    add    $0x18c4,%eax
  =&gt; 0x56555741 &lt;+17&gt;:    movl   $0x41414141,-0x9(%ebp)
     0x56555748 &lt;+24&gt;:    movb   $0x0,-0x5(%ebp)
     0x5655574c &lt;+28&gt;:    lea    -0x9(%ebp),%edx
     0x5655574f &lt;+31&gt;:    push   %edx
     0x56555750 &lt;+32&gt;:    lea    -0x17f0(%eax),%edx
     0x56555756 &lt;+38&gt;:    push   %edx
     0x56555757 &lt;+39&gt;:    mov    %eax,%ebx
     0x56555759 &lt;+41&gt;:    call   0x565555a0 &lt;printf@plt&gt;
     0x5655575e &lt;+46&gt;:    add    $0x8,%esp
     0x56555761 &lt;+49&gt;:    nop
     0x56555762 &lt;+50&gt;:    mov    -0x4(%ebp),%ebx
     0x56555765 &lt;+53&gt;:    leave  
     0x56555766 &lt;+54&gt;:    ret    
  End of assembler dump.
  </code></pre>
  
  <p>Can someone please explain this to me?</p>
  
  <p>I use cmake for compiling with the following CMakeLists.txt:</p>
  
  <pre><code>cmake_minimum_required (VERSION 2.8)
  
  # projectname is the same as the main-executable
  project(test)
  
  # compile with 32 bit
  add_definitions('-m32')
  
  # Disable compiler optimization
  add_definitions('-O0')
  
  # include debugging information
  add_definitions('-g')
  
  # Align items on the stack to 4 bytes. This makes stuff easier.
  # See https://stackoverflow.com/questions/1061818/stack-allocation-padding-and-alignment
  add_definitions('-mpreferred-stack-boundary=2')
  
  # disable compiler buffer overflow protection
  add_definitions('-z execstack -z norelro -fno-stack-protector')
  
  # executable source code
  add_executable(test test.c)
  </code></pre>
  
  <p>cmake seems to use gcc.</p>