title: Loading "/bin/sh" into a register
body: <p>I'm trying to write ASM code to spawn a shell.</p>
  
  <p>I've figured out that the syscall number for <code>__execve</code> is 0x3b or 59.</p>
  
  <p>I need to send <code>"/bin/sh"</code> as the first parameter, a pointer to <code>{"/bin/sh", NULL}</code> as the second parameter and <code>NULL</code> as the third parameter.</p>
  
  <p>By the convetions of x86_64 ASM on the Intel architecture - the first parameter is written into the <code>RDI</code> register, the second parameter is written into the <code>RSI</code> register and the final parameter is written into the <code>RDX</code> register.</p>
  
  <p>This is my code:</p>
  
  <pre><code>global _start
  
  section .text
  
  _start:
  
  jmp message
  
  mystart:
      xor     rax, rax
      push    rax
      push    rax
      pop     rdx     ; third parameter - NULL
      pop     rdi     ; first parameter - "/bin/sh"
      mov     rax, rdi    
      push    rax
      push    rsp
      pop     rsi     ; second parameter - pointer to {"/bin/sh", NULL}
      xor     rax, rax
      mov     al, 0x3b
      syscall
  
  
      xor rax, rax
      mov al, 0x3c
      xor rdi, rdi
      mov dil, 0x0a
      syscall
  
  message:
  
      call mystart
      db "/bin/sh"
  
  section .data
  </code></pre>
  
  <p>I use the following instructions to compile and link the code.</p>
  
  <pre><code>yasm -f elf64 shell.asm -o shell.o
  ld -o shell.out shell.o
  </code></pre>
  
  <p>The GDB dump of the <code>_start</code> function is as follows:</p>
  
  <pre><code>Dump of assembler code for function _start:
   0x0000000000400080 &lt;+0&gt;:   jmp    0x4000a3 &lt;_start+35&gt;
   0x0000000000400082 &lt;+2&gt;:   xor    rax,rax
   0x0000000000400085 &lt;+5&gt;:   push   rax
   0x0000000000400086 &lt;+6&gt;:   push   rax
   0x0000000000400087 &lt;+7&gt;:   pop    rdx
   0x0000000000400088 &lt;+8&gt;:   pop    rdi
   0x0000000000400089 &lt;+9&gt;:   mov    rax,rdi
   0x000000000040008c &lt;+12&gt;:  push   rax
   0x000000000040008d &lt;+13&gt;:  push   rsp
   0x000000000040008e &lt;+14&gt;:  pop    rsi
   0x000000000040008f &lt;+15&gt;:  xor    rax,rax
   0x0000000000400092 &lt;+18&gt;:  mov    al,0x3b
   0x0000000000400094 &lt;+20&gt;:  syscall 
   0x0000000000400096 &lt;+22&gt;:  xor    rax,rax
   0x0000000000400099 &lt;+25&gt;:  mov    al,0x3c
   0x000000000040009b &lt;+27&gt;:  xor    rdi,rdi
   0x000000000040009e &lt;+30&gt;:  mov    dil,0xa
  ---Type &lt;return&gt; to continue, or q &lt;return&gt; to quit---
   0x00000000004000a1 &lt;+33&gt;:  syscall 
   0x00000000004000a3 &lt;+35&gt;:  call   0x400082 &lt;_start+2&gt;
   0x00000000004000a8 &lt;+40&gt;:  pop    rsp
   0x00000000004000a9 &lt;+41&gt;:  (bad)  
   0x00000000004000aa &lt;+42&gt;:  (bad)  
   0x00000000004000ab &lt;+43&gt;:  .byte 0x69
   0x00000000004000ac &lt;+44&gt;:  outs   dx,BYTE PTR ds:[rsi]
   0x00000000004000ad &lt;+45&gt;:  pop    rsp
   0x00000000004000ae &lt;+46&gt;:  (bad)  
   0x00000000004000af &lt;+47&gt;:  jae    0x400119
  </code></pre>
  
  <p>As you can see the <code>(bad)</code> instructions are caused by <code>db "/bin/sh"</code>, what is wrong with this string? What is a <code>(bad)</code> instruction? How do I debug such problems in the future?</p>