Intended Use
------------
The bastard is a disassembler which is intended to be controlled by a more
sophisticated front end [e.g. a Gtk or ncurses UI]; as such it consists
primarily of a disassemblty engine for opcode decoding/analysis, and a database
of disassembled code, symbols, and comments. In the future, higher-level
decompilation features such as library/compiler signatures will be added.

When a controlling front-end launches the bastard [usually through a call to
popen(), though scripting languages can simply fork and exec], commands are
sent to the bastard via STDIN, and data is read from the bastard via STDOUT;
alternatively, a the name of a file or FIFO can be used in place of either
STDIN or STDOUT by using the -i and -o command-line switches. 

The bastard is controlled by calling its api commands; a full list of these
commands is provided in include/api.h, though a typical disassembly will look
like
   LoadTarget("/home/work/target");   //path of target is passed
	SetFileType("ELF");					  //"ELF" is a script in formats/
	SetCPUType( "i686" );				  //"i386" is a lib in arch/
	DisassembleFull();					  //DisassembleForward from entry point
Once these commands are run, the file has gone through its initial disassemble,
and may be modified or printed using a number of API commands, such as
PrintAddress(rva), GetName(rva), AddComment(rva, text), and so on. 

In order to fit in with the unix style of tools, the bastard has been designed
to work as an interpreter --in the manner of perl, gnuplot, awk, and so on-- 
and thus when launched without redirected input its built-in CLI can be used
to do disassembly. The CLI supports API calls and macros [via the SeerC
interpreter]; in addition, it has command aliases [such as "L", which provides
the four steps listed above] and incorporates the GNU readline library for
tab-completion, command line history, and line editting. Thus the bastard can
be used without any front-end at all, if desired.


Typical Operation
-----------------
The typical use of the bastard consists of four stages:
    1. Load the target
    2. Disassemble it
    3. Muck with it
    4. Print or save the results
Steps 1, 2, and 4 are of the most concern starting out; when functional, the
bastard should provide a reasonable disassembly which can be produced with
minimal effort [hence the "LOAD" or "L" command]. 

"Loading the target" consists of specifying the path of the target, choosing a
file format, and setting the CPU type; alternatively, an existing bastard
database [.bdb] can be loaded. The file type must be a script under formats/
[these are SeerC scripts which have full access to the bastard API and internal
structures]; the CPU will be loaded from a .so under the processors/ directory
when libopcodes is finally replaced with a real disassembler. Note that file
type defaults to ELF and cpu to x86 if neither are specified.

When the target is loaded, the bastard creates a ./.bdb directory and proceeds
to copy the target into this directory; the copy of the target is then memory
mapped, and a typhoon database is created in .bdb. When the target is saved,
this .bdb directory is tar/gz'ed into target.bdb; as such it contains a full
binary image of the target as well as a complete disassembly database. Note
that the typhoon files can be viewed "offline" with the dbdview utility
included in utils/.

"Disassembling the target" refers to choosing a range of the target to
disassemble -- the functions for this are DisassembleFull(),
DisassembleSection(char *name), DisassembleForward(long rva), and
DisassembleRange(long from, int size). DisassembleForward performs flow-of-
execution disassembly on the target, starting with address 'rva'; it is called
by DisassembleFull() with the target's entry point as an argument.

The disassembly performs the creation of xrefs, data items, and basic naming
of addresses based on the symbol table of the target. Further naming of
addresses, commenting, creation of structures and functions, and so forth will
be handled by the user while "mucking with the target", though primitive
attempts at these will eventually be incorporated into the actual disassembly.

"Printing or saving the target" syncs the mmap'ed file and makes a tarball of 
the .bdb directory; the .bdb dir is removed when the target is unloaded. When
saving or printing the file, the asmsprintf() function in api.c used; this 
function allows the user or front-end to specify the format of the line using
printf-like formatting codes, specifically
     %a - rva                %p - pa
     %m - mnemonic           %n - name
     %d - dest operand       %c - comment
     %s - source operand     %x - xrefs
     %b - raw bytes          %S - section
Thus asmsprintf("%a\t%m\t%s, %d\t;%c\n", rva) would produce a line such as
 080401089	mov	eax, ebx	; typical reg move
in the output. Note that 'printing' a range of lines or an entire file sends
the data to STDOUT; thus a controlling process with a 60-line disassembly
window would have the bastard print 60 addresses, copy the output from STDOUT
to its internal buffer, perform any syntax highlighting and formatting, and
display those 60 lines in its disassembly window. The asmsprintf function was
designed with this in mind; it allows the fields to be separated with arbitrary
delimiters. It should be pointed out that asmsprintf() will not actually be
called by the user or the controlling process; the line format will be stored
in an environment variable, and the PrintAddress, PrintRange, and
PrintNumAddress [print a specified number of lines] will be used instead.


Layout of the Source
--------------------
The source code is in four files:
    bastard.c  -- startup, error handling, and command loop code
    api_*.c    -- bastard API functions [most of the code]
    macro.c    -- Seer initialization/interface; CLI code
    db.c       -- Typhoon initialization and management code
The distinction between one file and the next can get pretty fuzzy; in general,
the 'useful' code is in api.c, while the other files contain support code which
is used primarily to interface with the user, the controlling process, or the
embedded database/interpreter/readline libraries. This structure has caused 
api.c to become large and unwieldly; in the future it may be broken up into
files based on subsystem [loading, imports, names, etc].

When loaded, the program runs as follows:
   main()-->initialize data structures;
         |->call ReadPrefs();
         |->handle command-line options;
         |->call doSeer() to initalize seer;
         |->call doTyphoon() to initialize typhoon;
         |->install sighandler userkill();
         |->loop calling GetCmd() until exit;
         -->cleanup;
    GetCmd()-->call readline() to get command;
            |->call TranslateCmd() to parse command;
            -->pass CLI aliases to handlers; API calls to Seer
...everything else is dependent on user decisions. Note that CLI aliases such
as "L" are handled via direct calls, while all API calls are compiled into a 
temporary seer script and executed; this means that CLI commands will be
marginally faster than standard API calls, and that potential problems exist in
API calls due to the intermediate Seer layer. This is to be considered a
'design tradeoff' in order to make the API calls work the same from the CLI,
from a controlling process, and from user-written Seer scripts. 


Disassembly
-----------
The disassembly functions in the bastard are:
  InitDisassembler(char *dis);
  DisassembleFull();
  DisassembleSection(char *sec);
  DisassembleRange(long rva, int size);
  DisassembleForward(long rva);
  disasmCB(FILE *s, char *fmt, ...);
  GetOpType(char *op);
  AnalyzeCurrInst();
Of these, the first five are API functions; they are used to choose the
disassembler [based on processor type; called by SetCPUType()] and to determine
the method of disassembly ["dumb section", "dumb range", "smart"] used. The 
remaining functions are utility functions used to create a code object [along
with associated data objects, xrefs, and so forth] for each disassembled
address. The disassembly process is generally as follows:
  InitDisassembler() --> register callback disasmCB();
  DisassembleXXXX()  --> (libopcodes fn*)  --> disasmCB();
                     |-> DefineAddr( curr_addr );
                     --> AnalyzeCurrInst() --> GetOpType();
Note that libopcodes is in the process of being replaced; however the code
currently appears as discussed above. Each Disassemble* function loops through
a range of addresses [e.g. an entire section] and calls the disassembler
function, the DefineAddr() API function, and the AnalyzeCurrInst() function on
an address. By the time AnalyzeCurrInst() is called, a CODE object called
curr_inst has been created and filled with the rva, mnemonic, and operands of
the current instruction; AnalyzeCurrInst() then determined the mnemonic and 
operand types, creates data objects and xrefs if needed, and inserts the CODE
object into the database.
  

Database
--------
The bastard uses an embedded Typhoon database to manage information about the
target; this is used instead of linked lists due to the typhoon support for
offline DB browsing, and its flexibility -- however there is a noticeable
performance decrease when using the Typhoon DB instead of a series of internal
linked lists. Once again, this is considered to be a design tradeoff; revision
of the Typhoon source code may be necessary in the future, to increase response
time.

The database consists of the following tables:
  SECTION      -- a program section or segment
  ADDRESS      -- an address [code or data] within the program
  CODE         -- an asm instruction associated with an ADDRESS
  XREF         -- a reference from one ADDRESS to another
  NAME         -- a symbolic name associated with an ADDRESS
  CONSTANT     -- a named constant applied to immediate values
  EXPORT       -- a program entry point or exported function
  IMPORT       -- an external address referred to by the program
  COMMENT      -- a user-supplied comment associated with an ADDRESS
  FUNCTION     -- a sequence of code in the target ended in a RET instruction
  F_INLINE     -- a block of oft-repeated code in the target, e.g. a C macro
  STRING       -- an ADDRESS object that consists of an ASCII string
  STRUCTURE    -- a logical, named structure applied to ADDRESS objects
  SEER_MACRO   -- a user-supplied, precompiled SeerC macro 
Note that while these tables have been sketched out in include/bdb.h, many of
them have not been finalized; these will be extended when the appropriate
functionality has been added to the disassembler. The database is intended to
be a convenient means of saving and retrieving data about a target between
sessions; as such all information regarding the target should be stored in the
database.


Coding Conventions
------------------
None ;)

Functions should return 0 on error and >0 on success; the proper way to 
return with error is to use
	return( SetLastError( int error_code ) );
which will return 0, and set the global _last_bastard_error which can be
retrieved via GetLastError() and GetLastErrorString().


Status
------
Somewhat functional. Currently coding a replacement for libopcodes.
