<epigraph>
  <attribution>Arthur C. Clarke</attribution>
  <simpara>
    Any sufficiently advanced technology is indistinguishable from magic.
  </simpara>
</epigraph>

<simpara>
  For the first example I'll present the simplest piece of code that
  still gives sufficient feedback. Our aim is to implant it into
  <filename>/bin/sh</filename>.
  On practically every recent installation of &config.HOSTTYPE; the
  following code will emit three magic letters instead of just
  dumping core.
</simpara>

<formalpara>
  <title>Source: &config.PRE;/magic_elf/magic_elf.c</title>
  <para>
    <programlisting><inlinemediaobject><imageobject><imagedata
      format="linespecific"
      fileref="../../&config.PRE;/magic_elf/magic_elf.c"
    /></imageobject></inlinemediaobject></programlisting>
  </para>
</formalpara>

<formalpara>
  <title>Command: &config.PRE;/magic_elf/cc.sh</title>
  <para>
    <programlisting><inlinemediaobject><imageobject><imagedata
      format="linespecific"
      fileref="../../&config.PRE;/magic_elf/cc.sh"
    /></imageobject></inlinemediaobject></programlisting
  ></para>
</formalpara>
<formalpara>
  <title>Output: &config.OUT;/magic_elf/magic_elf</title>
  <para>
    <programlisting><inlinemediaobject><imageobject><imagedata
      format="linespecific"
      fileref="../../&config.OUT;/magic_elf/magic_elf"
    /></imageobject></inlinemediaobject></programlisting
  ></para>
</formalpara>

<sect2 id="how.it.works" xreflabel="How it works">
  <title>How it works</title>

  <sect3>
    <title>Digested answer</title>
    <simpara>
      The three letters are part of the signature of
      <acronym>ELF</acronym> files. Executables created by
      <citerefentry>
	<refentrytitle>ld</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry> are always mapped into the same memory region.
      That's why the program can find its own header at a predictable
      virtual address.
    </simpara>
  </sect3>

  <sect3>
    <title>Short answer</title>
    <simpara>
      RTFM. &note.jargon.RTFM; Just read all of &yref.ELF.specification;.
    </simpara>
  </sect3>

  <sect3 id="sort.of.an.answer" xreflabel="Sort of an answer">
    <title>Sort of an answer</title>
    <simpara>
      <constant>&calc.base.addr;</constant> is not a natural constant,
      but happens to be the default base address of
      <acronym>ELF</acronym> executables produced by
      <citerefentry>
	<refentrytitle>ld</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry> on &config.ARCH;.
      Option <option>-Ttext ORG</option> and
      <option>--section-start SECTIONNAME=ORG</option> of
      <application>GNU ld</application> should allow to change it,
      but I didn't get it working.
      Anyway, the layout of executables produced by
      <citerefentry>
	<refentrytitle>ld</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry> is straight forward.
    </simpara>
    <orderedlist>
      <listitem><simpara>
	One <acronym>ELF</acronym> header -
	<structname>&config.ELF.EHDR;</structname>
      </simpara></listitem><listitem><simpara>
	Program headers - <structname>&config.ELF.PHDR;</structname>
      </simpara></listitem><listitem><simpara>
	Program interpreter (not if statically linked)
      </simpara></listitem><listitem><simpara>
	Code
      </simpara></listitem><listitem><simpara>
	Data
      </simpara></listitem><listitem><simpara>
	Section headers - <structname>&config.ELF.SHDR;</structname>
      </simpara></listitem>
    </orderedlist>
    <simpara>
      Everything from the start of the file to the last byte of code
      is mapped into one segment (colloquially named <quote>code</quote> or
      <quote>text</quote>) that begins at the base address.
      There is a whole chapter called <xref linkend="readelf"/> describing
      tools to view all these details.
      In the meantime I will show fancy ways to get by without.
    </simpara>
  </sect3>

</sect2>
<sect2>
  <title>Strings and dumps</title>

  <simpara>
    What would you do if you knew nothing about <acronym>ELF</acronym>
    and just asked yourself how that example works? How can you go sure
    that the executable file really contains those three letters?
  </simpara>

  <simplesect>
    <title>strings</title>

    <simpara>
      A good start for finding text in binary files is
      <citerefentry>
	<refentrytitle>strings</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry>.
    </simpara>
    <formalpara>
      <title>Command: &config.PRE;/magic_elf/strings.sh</title>
      <para>
	<programlisting><inlinemediaobject><imageobject><imagedata
	  format="linespecific"
	  fileref="../../&config.PRE;/magic_elf/strings.sh"
	/></imageobject></inlinemediaobject></programlisting>
      </para>
    </formalpara>
    <formalpara>
      <title>Output: &config.OUT;/magic_elf/strings</title>
      <para>
	<programlisting><inlinemediaobject><imageobject><imagedata
	  format="linespecific"
	  fileref="../../&config.OUT;/magic_elf/strings"
	/></imageobject></inlinemediaobject></programlisting>
      </para>
    </formalpara>

    <simpara>
      The leading <literal>1:</literal> is written by
      <citerefentry>
	<refentrytitle>grep</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry>
      and tells that our three-letter word is the first found string.
      This gives some help where we can find it in a hex dump. 
      It is difficult to search strings in such a dump because of
      line breaks. Interactive tools like
      <citerefentry>
	<refentrytitle>hexedit</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry> or
      <citerefentry>
	<refentrytitle>khexedit</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry> might be useful.
    </simpara>

  </simplesect>
  <simplesect>
    <title>od</title>

    <simpara>
      The traditional tool for dumps is called
      <citerefentry>
	<refentrytitle>od</refentrytitle>
	<manvolnum>1</manvolnum>
      </citerefentry>, the abbreviation for <quote>octal dump</quote>.
      The classic version does provide hexadecimal output, but
      unfortunately not for single bytes. Option <option>-x</option>
      outputs <quote>words</quote>, which are defined to be two bytes.
      This does not matter on big-endian machines like the sparc,
      but on i386 and alpha it is quite confusing.
    </simpara>
    <simpara>
      On both Linux and SunOS <application>od</application> features
      option <option>-tx1</option> to get byte-wise hexadecimals.
      FreeBSD's <application>od</application> has no equivalent.
      Another interesting option is <option>-N count</option> which
      reads no more than <literal>count</literal> bytes of input.
      Again it is not available on FreeBSD.
    </simpara>
    <formalpara>
      <title>Command: &config.PRE;/magic_elf/od/&config.UNAME;.sh</title>
      <para>
	<programlisting><inlinemediaobject><imageobject><imagedata
	  format="linespecific"
	  fileref="../../&config.PRE;/magic_elf/od/&config.UNAME;.sh"
	/></imageobject></inlinemediaobject></programlisting>
      </para>
    </formalpara>
    <formalpara>
      <title>Output: &config.OUT;/magic_elf/od</title>
      <para>
	<programlisting><inlinemediaobject><imageobject><imagedata
	  format="linespecific"
	  fileref="../../&config.OUT;/magic_elf/od"
	/></imageobject></inlinemediaobject></programlisting>
      </para>
    </formalpara>

  </simplesect>
  <simplesect>
    <title>hexdump</title>

    <simpara>
      <application>hexdump</application> features user defined formats.
      It is a typical ingredient of Linux and FreeBSD installations,
      but not shipped with SunOS.
    </simpara>

    &xml.magic.of.elf.hexdump;

  </simplesect>
  <simplesect>
    <title>xxd</title>

    <simpara>
      <application>xxd</application> is part of
      <application>vim</application>. &note.vim; And though that
      can't be called installation core it comes pretty close on
      Linux distributions.
    </simpara>

    &xml.magic.of.elf.xxd;

    <simpara>
      Anyway, at this point we can guess that file offset 1 and
      <literal>&calc.base.addr; + 1</literal> are not coincidental.
      A test program might help.
    </simpara>

  </simplesect>
</sect2>
<sect2 id="address.of.main" xreflabel="The address of main">
  <title>The address of main</title>

  <formalpara>
    <title>Source: &config.PRE;/magic_elf/addr_of_main.c</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.PRE;/magic_elf/addr_of_main.c"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>
  <formalpara>
    <title>Output: &config.OUT;/magic_elf/addr_of_main</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.OUT;/magic_elf/addr_of_main"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>
  <simpara>
    Note that the output of <literal>%p</literal> is not
    standardized. Some platforms print a leading <literal>0x</literal>,
    some don't. Even <literal>%#p</literal> does not guarantee a leading
    <literal>0x</literal>.
    Anyway, output looks good. The byte at address
    <literal>&calc.base.addr; + 0</literal> is equal to that at file
    offset 0. And &calc.magic.elf.addr.main.X; is a plausible address
    of function <function>main</function>.
  </simpara>

</sect2>
<sect2>
  <title>Other roads to <acronym>ELF</acronym></title>

  <formalpara>
    <title>Source: &config.PRE;/magic_elf/other_perl.pl</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.PRE;/magic_elf/other_perl.pl"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>
  <formalpara>
    <title>Output: &config.OUT;/magic_elf/other_perl</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.OUT;/magic_elf/other_perl"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>

  <formalpara>
    <title>Source: &config.PRE;/magic_elf/other_exe.sh</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.PRE;/magic_elf/other_exe.sh"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>
  <formalpara>
    <title>Output: &config.OUT;/magic_elf/other_exe</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
	fileref="../../&config.OUT;/magic_elf/other_exe"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>

  &xml.magic.of.elf.other.magic;
      
</sect2>
