dwarf-ng
Section: User Commands (1)
Updated: (c) 2007-2011 Fernando Iazeolla
Index
Return to Main Contents
NAME
dwarf-ng - a little and powerful object file manipulation tool.
SYNOPSIS
dwarf [ options ] [ file ]
DESCRIPTION
dwarf-ng
is a powerful object file manipulation tools in the spirit of gdb. with dwarf-ng you can read and edit all the file's section headers as well as the raw data. With dwarf-ng you can create and customize new file's header and it can be used as a compiler back-end to create executables/object files. dwarf-ng also permits to inject easily new headers and pieces of code/data into the file.
dwarf-ng currently handles Raw, elf (Elf32 and Elf64), PE (Portable executables, PE32 and PE+) and Mach-O (32 and 64 bit) files format. In the future new files type will be added.
OPTIONS
- -i, --interactive, --shell
-
interactive (shell mode)
- -c '{commands}', --command '{commands}'
-
command mode (executes commands)
For example,
dwarf -c 'print 2+2'
will output:
4
- -h, --help
-
print usage info
- -x < file >, --execute < file >
-
loads and executes file script.
- -v, --version
-
show dwarf-ng's version number
- If more than one or all options are given at the same time the execution order will be: 1)open the file in the command line, 2)loads file structures, 3)execute the script file(-x), 4)executes commands from command line(-c), 5)enter the shell(-i)
-
THE DWARF'S LANGUAGE
- COMMAND SEPARATOR
-
the command separator is the semicolon character ';' .
{cmd};{cmd}
- COMMENTS
-
a comment begins with the '#' symbol and ends at the end of the line (CRLF)
- VARIABLES
-
dwarf-ng
recognizes two types of variables: the normal variables (simply called variables) and the structured variables.
The normal variables are litteral words and are created by the user for normal variable operation (i.e. a=5; b=a+3; print b ).
The structured variables are created by dwarf when it loads a file into memory and are preceded by the dollar symbol ($). The structured variables reflects the opened file structure and they depends on the file type opened. So, for example, the Elf structured variables are different from the PE structured variables. Structured variables can be accessed in read or write mode like the normal variables. Structured variables syntax is similar to a C struct:
print $elf::ph_num will print the ph_num variable of the main header ($elf) of a Elf file.
$elf::sh_num=3 will modify the sh_num (number of section headers) in the main header ($elf) of the Elf file.
- EXPRESSIONS
-
Expressions EXPR are in the form : EXPR + EXPR, or EXPR - EXPR, or EXPR * EXPR, or EXPR / EXPR, or EXPR %EXPR. a single expression item can be a number (in decimal or hex form 10=0xa) or an offset. hex values are preceded by a 0x...example: a=0x10 (a is 16 decimal!).
- OFFSETS
-
offsets syntax is @foo< or @foo> where foo is a symbol referring to a specific file data structure. The major (>) or minor (<) symbol indicate if the offset point to the end (>) or the beginning (<) of the specified data structure. whith @< we indicate the beginning of the file. Whith @> wh indicate the end of the file. For example print @> will output the lenth of the file. Offsets return an integer and can be combined in any expressions EXPR (i.e. a=@>+3 will assign to the variable a the length of the file plus 3).
COMMANDS
- SAVE [ save | save filename ]
-
saves all the changes into the opened file. This action once performed is unreversible: changes will be permanently written on the disk.
- OPEN [ open filename ]
-
Loads the specified file and creates all related data structures associated to the file.
- WHILE [ while(expr) command(s) ]
-
a typical while construct. example: a=5;while(a>0){print a;a=a-1} (deprecated in version 0.3.x)
- IF-ELSE [ if(expr) command(s) | if(expr) command(s) else command(s) ]
-
a typical if-else costruct. example: a=5;if(a>1) {print "ok"} else {print "no"} (deprecated in version 0.3.x)
- PRINT [print expr | print %fmt expr ] -- alias pp
-
outputs the result of the expression (numerical or string). The %fmt force a different output mode. fmt indicates the output mode desired. Valid option for the output modes are: x for hex output, d or i for decimal, o for octal output. examples: print %x 16 (outputs 0xa), print %d 0xa (outputs 16).
- QUIT [ quit ]
-
exit dwarf-ng interpreter.
- INFO [ info ]
-
display info and main structures of the current working file.
- GROW [ growth expr ]
-
increase the size of the opened file.
- SHRINK [ shrink expr ]
-
decrease the size of the opened file.
- MOVE [ move expr1 expr2 expr3 | move expr1 +expr2 expr3 | move expr1 -expr2 expr3 ]
-
move blocks of file around. (expr1=from, expr2=[len|end], expr3=to). moves from expr1 to expr3. expr2 can be a len if precede by plus(+) or minus(-), otherwise it refers to an absolute address indicating the end of the from-end block to move. examples: move @< +10 @ph[0]>) moves 10 bytes from the beginning of the file to the end of the first(0) program's header.
- HELP [ help ]
-
display the inline shell help menu.
- INJECT [ inject expr1 expr2 expr3 expr4 | inject expr1 expr2 expr3 | inject expr1 expr2 ]
-
injects data inside the opened file. ( expr1=file|byte, expr2=offs-from, expr3=len, expr4=">>"(shift) )if expr1 is a string it refers to a file to be injected into the opened file. if expr1 is a numerical value it represent the byte to inject (eventually repeated) inside the opened file. expr2 indicates the offset from where to begin to inject. expr4 can be ">>" or omitted. if omitted the file is not growth by injecting data. expr3 can be a numerical value representing the len or the end-offset of the injecting data or cen be omitted. if expr3 is omitted dwarf uses a default len thas is 1 for the byte-injection or the file length for the file-injection.if expr4 is omitted expr3 can refer to the shift value (">>") or to the len-offset...dwarf is able to disambiguate. examples: inject 0 $ph[3]::offset 12 , writes 12 bytes of zeros at the absolute addres pointed from the variable $ph[3]::offset.
- CREATE [ create type offs shift [update]) ]
-
creates a new header. type is the header type, offs tells the offset where to create the header. offs is an integer an it refers to the position where to create the new header. update tells dwarf to update the other data structures of the new header presence (relocates offsets and section numbers).shift (">>") tells dwarf to eventually shift the opened file so that the new header does not overwrite portions of the file (!>> indicates to not groe the file).
- REMOVE [ remove type offs shift [update] ]
-
removes a header. see CREATE for parameters explanation.
- LEN [ len expr ]
-
grows or shrinks the opened file depending if expr is >0 or <0. LEN will call GROW or SHRINK depending on expr sign.
- CLOSE [ close ]
-
closes the opened file.
- DUMP [ dump [%fmt] expr ]
-
dumps portion of opened file from expr offset in various formats depending on %fmt. The %fmt force a different output mode. fmt is in the form: nnx (<number><letter>) where the letter x indicates the output mode desired, and the number nn indicates the number of bytes to output. Valid option for the output modes are: x for hex output, d or i for decimal putput s for string output c for char output, o for octal output,e (default) for a nice dump output. examples: dump @< (dumps the beginning of the file), dump %x3 @<+10 (displays 3 bytes in hex format from 10 positions from the beginning of the file).
- EXTRACT [ extract from len file ]
-
extract 'len' bytes from opened file from 'from' position and save it into a new file called 'file'.
- FILESIZE [ filesize [-h] ] -- alias fs
-
shows the size in bytes of the current working file. The -h option gives the result in human readable format.
- FILELIST [ filelist ] -- alias fl
-
display a list of all current opened files.
- FILEUSE [ fileuse expr ] -- alias fu
-
set expr number (taken from filelist command) file as current working file.
CONFIG FILE
- dwarfrc
-
dwarf-ng look for config files: /etc/dwarfrc first and then .dwarfrc in the $HOME directory. If no config file is founded dwarf-ng runs with default values. A snapshot of a config file il listed below:
#dwarf config file.
work_on_tmpcopy=yes #(yes|no)
verbose=0 #this is a comment
tmpdir="/tmp"
tmpname="dw_temp_filex"
where a comment line begins with a #.
FILE TYPES
- ELF
-
main elf struct: $elf
program header: $ph[0..n]
section header: $sh[0..n]
- PE
-
MZEXE struct: $mz
pe main header: $pe
$pe::FileHeader
$pe::OptionalHeader
PE section: $sect[0..n]
- MACH-O
-
Macho main header: $mac
load command: $lc[0..n]
Macho section: $lc::sect[0..n]
- MACH-O FAT BINARY (UNIVERSAL BINARY)
-
main fat header: $fat
file's architectures: $arch[0..n]
EXAMPLES
#//var assignment
a=5; print a
a=7
print a
b=3
c=a+b+7
print c
print %x c #prints c variable in hexadecimal format
#//structured variable
open myfile #open the file
info #prints file's main structures
print $elf #prints the main elf structure (assuming an elf file :) )
print $elf::ph_num #prints program header's number
$elf::ph_num=7 #sets program header number
a=$sh[7]::offset #puts into 'a' variable the 'offset' member of the 8th section header
print $ph #prints a list of all program header
print $sh[0] #prints the 1st section header details
#//offsets
print @< #prints the offset of the beginnig of the opened file (zero ;) )
print @> #prints the offset of the end of size (filesize ;) )
filesize #equivalent to print @>
a=@sh[1] #a is the offset of the beginning of the 2nd section header
c=@sh[1]< #c=a
b=@sh[1]> #b is the offset of the end of the 2nd section header
inject 0 $sh[4]::offset 10 #inject 10 times the value 0 (zero) from '$sh[4]::offset' offset
inject "vir.bin" @ph[4]> #inject the content of "vir.bin" file from the end of the 5th program header
#//header create
create "ph" @ph[2]> !>> #create a program header from the end of the 3rd program header's section
#and don't expand the file (it will overwrite data)
create "sh" @sh[4] >> #create a section header from the beginning of the 5th section and shift file so it won't overwrite data.
#old $sh[4] is now $sh[5] and the section created is $sh[4]
$elf::sh_num=$elf::sh_num+1 #remember to increase the section number from the main elf header
create "sh" @sh[4] >> ++ #the '++' option at the end updates automatically the number of section from the main header
and remember also to update the offset of the shifted sections manually
a=5
while(a<=$elf::sh_num)
{
$sh[a]::offset=$sh[a]::offset+$elf::sh_entsize
a=a+1
}
SEE ALSO
readelf(1), objdump(1), ht(1), otool(1), gdb(1), elf(5), elfsh(1), elfdump(1)
AUTHOR
Fernando Iazeolla < xnando _GUESS_ cryptolab.net > - founder & core developer.
COPYRIGHT
Copyright (C) 2007-2011 Fernando Iazeolla < xnando _GUESS_ cryptolab.net >
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Index
- NAME
-
- SYNOPSIS
-
- DESCRIPTION
-
- OPTIONS
-
- THE DWARF'S LANGUAGE
-
- COMMANDS
-
- CONFIG FILE
-
- FILE TYPES
-
- EXAMPLES
-
- SEE ALSO
-
- AUTHOR
-
- COPYRIGHT
-
This document was created by
man2html,
using the manual pages.
Time: 14:47:34 GMT, January 22, 2011