<epigraph>
  <attribution>R. W. Hamming</attribution>
  <simpara>You cannot have a science without measurement.</simpara>
</epigraph>

<simpara>
  Building executables from C source code is a complex task.
  An innocent looking call of
  <citerefentry>
    <refentrytitle>gcc</refentrytitle>
    <manvolnum>1</manvolnum>
  </citerefentry> will invoke a pre-processor, a multi-pass compiler,
  an assembler and finally a linker.
  Using all these tools to plant virus code into another executable
  makes the result either prohibitively large, or very dependent on
  the completeness of the target installation.
</simpara>
<simpara>
  Real viruses approach the problem from the other end. They are
  aggressively optimized for code size and do only what's absolutely
  necessary. Basically they just copy one chunk of code and patch a few
  addresses at hard coded offsets.
</simpara>
<para>
  However, this has drastic effects:
  <itemizedlist>
    <listitem>
      <simpara>
	Since we directly copy binary code, the virus is restricted
	to a particular hardware architecture.
      </simpara>
    </listitem>
    <listitem>
      <simpara>
        Code must be position independent.
      </simpara>
    </listitem>
    <listitem>
      <simpara>
        Code cannot use shared libraries; not even the C runtime library.
      </simpara>
    </listitem>
    <listitem>
      <simpara>
        We cannot allocate global variables in the data segment.
      </simpara>
    </listitem>
  </itemizedlist>
</para>
<simpara>
  There are ways to circumvent these limitations. But they are
  complicated and make the virus more likely to fail.
</simpara>

<sect2 id="executable.and.linkable.format"
  xreflabel="Executable and linkable format">
  <title>Executable and linkable format</title>

  <simpara>
    Another natural limitation of viruses is rigid dependency on the
    file format of target executables. These formats differ a lot.
    Even on the same hardware architecture and under the same
    operating system. Furthermore executable are not designed with
    post link-time modifications in mind. It's rare for a virus to
    support more than one infection method. This document is about
    the format used on recent versions of Linux, FreeBSD and Solaris.
  </simpara>

  <simpara>This format is well documented. Some public resources:</simpara>
  <itemizedlist>
    <listitem><simpara>
      Source code of Linux and FreeBSD.
      Admittedly not for the faint of heart.
      <footnote><simpara>
	A nice introduction for the uninitiated is &url.GUIDE.tlk.4.8;
      </simpara></footnote>
    </simpara></listitem> 
    <listitem><simpara>
      <filename>/usr/include/elf.h</filename>
      <footnote><simpara>
	Present on Linux (part of glibc), FreeBSD and SunOS.
      </simpara></footnote>
    </simpara></listitem> 
    <listitem><simpara>
      Portable Formats Specification, Version 1.1.
      <footnote>
	<simplelist>
	  <member>Canonical Postscript document:
	    &url.elf.spec.canonical;</member>
	  <member>A flat-text version:
	    &url.elf.spec.flat.text;</member>
	</simplelist>
      </footnote>
    </simpara></listitem> 
    <listitem><simpara>
      Linux Standard Base Specification &note.lsb.objformat;
    </simpara></listitem> 
    <listitem><simpara>
      Creating Really Teensy ELF Executables for Linux
      &note.teensy.executables;
    </simpara></listitem> 
  </itemizedlist>

  <simpara>A quote from the Portable Formats Specification:</simpara>
  <blockquote>
    <simpara>
      The Executable and Linking Format was originally developed
      and published by UNIX System Laboratories
      (<acronym>USL</acronym>) as part of the Application Binary
      Interface (<acronym>ABI</acronym>). The Tool Interface
      Standards committee (<acronym>TIS</acronym>) has selected
      the evolving <acronym>ELF</acronym> standard as a portable
      object file format that works on 32-bit Intel Architecture
      environments for a variety of operating systems.
    </simpara>
  </blockquote>
  <simpara>
    Actually <acronym>ELF</acronym> covers object files
    (<filename>.o</filename>), shared libraries
    (<filename>.so</filename>) and executable files.
    The Linux kernel <footnote><simpara>
      This means file <filename>vmlinux</filename>.
      <filename>vmlinuz</filename> is compressed and prefixed
      with a boot-sector. See &url.GUIDE.tlk.4.8;
    </simpara></footnote>
    is also a valid <acronym>ELF</acronym> file.
  </simpara>

</sect2>
<sect2 id="assembly.documentation"
  xreflabel="Assembly language documentation">
  <title>Assembly language documentation</title>

  <simpara>
    <acronym>ELF</acronym> is used for a variety of both 32 bit
    and 64 bit architectures. Obviously you need to handle
    assembly language for each platform. A good starting
    point is <quote>Linux Assembly</quote> &note.linuxassembly;
    and <quote>Assembly Language Related Web Sites</quote>.
    &note.raymoon.assembly;
  </simpara>

  <simpara>alpha specific sites:</simpara>
  <itemizedlist>
    <listitem><simpara>
      Assembly Language Programmer's Guide 
      &note.alpha.assembly;
    </simpara></listitem> 
  </itemizedlist>

  <simpara>i386 specific sites:</simpara>
  <itemizedlist>
    <listitem><simpara>
      Assembly-HOWTO. &note.HOWTO.assembly;
      Description of tools and sites for Linux.
    </simpara></listitem> 
    <listitem><simpara>
      FAQ of comp.lang.asm.x86 &note.faq.x86;
    </simpara></listitem> 
    <listitem><simpara>
      <quote>Robin Miyagi's Linux Programming</quote>
      &note.robin.miyagi; features a tutorial and interesting links.
    </simpara></listitem> 
    <listitem><simpara>
      <quote>Assembly resources</quote> &note.agner.org;
      covers advanced topics.
    </simpara></listitem> 
    <listitem><simpara>
      IA-32 Intel Architecture Software Developer's Manual
      &note.intel.pentium4;
    </simpara></listitem> 
    <listitem><simpara>
      <quote>The Place on the Net to Learn Assembly Language
	Programming</quote> &note.webster.assembly;
    </simpara></listitem> 
    <listitem><simpara>
      The Art of Assembly Language. 32-bit Linux Edition
      Featuring <acronym>HLA</acronym>. &note.art.of.assembly;
    </simpara></listitem> 
    <listitem><simpara>
      X86 Architecture, low-level programming, freeware
      &note.goosee.assembly;
    </simpara></listitem> 
    <listitem><simpara>
      Dr. Dobb's Microprocessor Resources &note.dobbs.assembly;
    </simpara></listitem> 
  </itemizedlist>

  <simpara>sparc specific sites:</simpara>
  <itemizedlist>
    <listitem><simpara>
      SPARC Assembly Language Reference Manual
      &note.sun.sparc.assembly;
    </simpara></listitem> 
    <listitem><simpara>
      A Laboratory Manual for the SPARC
      &note.maccabe.sparc.assembly;
    </simpara></listitem> 
  </itemizedlist>

</sect2>
<sect2 id="assemblers.and.disassemblers"
  xreflabel="Assemblers and disassemblers">
  <title>Assemblers and disassemblers</title>

  <simpara>
    A debugger lets you see what is going on <quote>inside</quote>
    another program while it executes. 
    <application>gdb</application> can also show a plain disassembly
    of the code, and can do so without executing a single instruction.
    This listing does not include a hex dump of opcodes, however.
    On the other hand pure disassemblers take shortcuts;
    they don't have a complete picture of the target executable.
  </simpara>
  <simpara>
    <application>objdump</application> is part of
    <application>GNU binutils</application>. It is advertised as a means
    to display information from object files. But
    <application>objdump</application> can also work on executables.
    And it provides option <option>--disassemble</option>.
    Since it does not resolve function names in shared libraries it
    cannot fully replace <application>gdb</application>, though.
  </simpara>
  <simpara>
    <application>GNU binutils</application> includes
    <application>readelf</application> since version 2.10.
    It is described to display the contents of ELF format files,
    regardless of target machine. Functionality of
    <application>readelf</application> and
    <application>objdump</application> overlap, but I think the
    output of the former is nicer. However, the tool is missing on old
    distributions like SuSE 6.0.
    <footnote><simpara>
      This might be the reason that
      <ulink url="../intro.html#credits">Silvio Cesare</ulink>
      does not mention <application>readelf</application>
      anywhere in his classic works.
    </simpara></footnote>
  </simpara>
  <simpara>
    Of course all GNU disassembly tools adhere to the syntax of
    the GNU assembler. Veterans of i386 programming consider this
    style repulsive, however. And while <application>gdb</application>
    provides statement <literal>set disassembly-flavor intel</literal>
    to lower the contrast, <application>objdump</application>
    has nothing similar. On platform i386 I will therefore use
    <application>nasm</application> and <application>ndisasm</application>
    where possible. This tool has absolutely no understanding of ELF
    (or any other file format). But for the scope of this document this
    is a feature. The calculations necessary to get at the interesting
    bytes are interesting themselves.
  </simpara>

</sect2>
<sect2 id="be.fertile.and.reproduce" xreflabel="Be fertile and reproduce">
  <title>Be fertile and reproduce</title>

  <simpara>
    The primary quality of this document is reproducabilty. Every 
    tiny bit of information should be proved by a working example.
    Since I don't trust myself all output files are rebuild for every
    release. All sections titled <quote>Output</quote> are real product
    of source code and shell scripts included in this document.
    Most numbers and calculations are processed by a
    <application>Perl</application> script parsing these output files.
  </simpara>
  <simpara>
    The document itself is written in DocBook,
    &note.sourceforge.docbook; a XML document type definition.
    &note.sgml.overview; Conversion to HTML is the last step of a
    Makefile that builds and runs all examples.
    However, this means that I can't provide one document comparing two
    platforms. Instead I set up everything for conditional compilation.
    I then build one consistent variation of the document on a single
    system.
  </simpara>
  <simpara>
    You are now reading the platform independent part.
    The links below lead to the actual examples.
    This part continues with general topics and larger chunks of
    source code.
  </simpara>

</sect2>
<sect2 id="i386.redhat.linux" xreflabel="i386-redhat-linux">
  <title><ulink url="i386-redhat-linux/index.html"
  >i386-redhat-linux</ulink></title>
  
  <simpara></simpara>

</sect2>
<sect2 id="sparc.debian.linux" xreflabel="sparc-debian-linux">
  <title><ulink url="sparc-debian-linux/index.html"
  >sparc-debian-linux</ulink></title>

  <simpara></simpara>

</sect2>
<sect2 id="dressing.up.binary.code" xreflabel="Dressing up binary code">
  <title>Dressing up binary code</title>

  <simpara>
    This script is used throughout the document to convert binary
    files into valid C code, i.e. definition of a byte array.
    This could have been a small filter written in
    <citerefentry> 
      <refentrytitle>perl</refentrytitle>
      <manvolnum>1</manvolnum>
    </citerefentry>, but we actually need a lot of features.
  </simpara>
  <simpara>
    We need to process the output of both
    <application>ndisasm</application> and
    <application>objdump</application>, one multiple platforms.
    Two examples for valid input:
  </simpara>
  <programlisting><inlinemediaobject><imageobject><imagedata
    fileref="../intro/example.asm.txt"
    format="linespecific"
  /></imageobject></inlinemediaobject></programlisting>
  <simpara>
    The <literal>__attribute__</literal> clause is explained in
    &yref.a.section.called.text;.
  </simpara>
  <simpara>
    Initializing the array with string literals (looking like
    <literal>\xDE\xAD\xBE\xEF</literal>) is easier. The terminating
    zero would not work with &yref.doing.it.in.c;, however.
    But then using a list of hexadecimal numbers introduces
    separating comas, requiring special treatment of the last line.
  </simpara>
  <simpara>
    If command line option <option>-last_line_is_ofs</option>
    is passed to the program then the last line of disassembly
    is meant to specify a offset into the code.
    Actually it's just the last byte of that line.
    You are free to use any dummy operation,
    like <literal>push byte 1</literal>.
    See &yref.target.infection; for an example.
  </simpara>

  <formalpara>
    <title>Source: src/platform/disasm.pl</title>
    <para>
      <programlisting><inlinemediaobject><imageobject><imagedata
        format="linespecific"
        fileref="../src/platform/disasm.pl"
      /></imageobject></inlinemediaobject></programlisting>
    </para>
  </formalpara>

</sect2>
