public 0.5.2 release :)

This commit is contained in:
dash
2019-05-13 16:57:27 +02:00
parent 55f10eac19
commit d9a4209bcd
13 changed files with 1729 additions and 1 deletions

596
lib/FUDGEanalyse.py Executable file
View File

@@ -0,0 +1,596 @@
import re
import os
import sys
import queue
import time
import struct
import binascii
import threading
import lib.FUDGEheader as FUDGEheader
from lib.FUDGEheader import TYPES
nor=0x1
ver=0x2
dbg=0x3
def dbgprint():
print ("nothing")
class ANALYSE(object):
def __init__(self):
"""
infile - the file to analyse
stat - os.stat results of self.infile
fftype - the current type of pattern test
plugin - choosen pluginclass to test for
lonelyplugin- choosen lonely plugin for test
fd - the filedescriptor of open and close
search - the search string/bytes
string - for convert2hex
data - the binary data field, where the bytes are filled in
offset - the offset delivered back for writing to self.cut
extract_cnt - number of the found files in file
extract - shall we extract anything?
cut - dict for offsets for the extractfile method
outdir - output directory for putting files
outname - name of the output files part
reportfile - name of the status report
files - list with paths of extracted files
"""
# not in use yet
# self.threads = [] # list of overall threads
# self.thread_cnt = 20 # amount of threads
# erm, check what those are used for :>
self.string=""
self.data=[]
# ff magic search variables
# FIXME must get cleaned up
self.target_queue=queue.Queue() # all plugins to test
self.result_queue=queue.Queue() # all results from the test
self.offset=0 # offset for self.cut, does not need to be global
self.cut={} # this will be replaced with result_queue
self.set_offset=0 # ??
self.set_string=0 # ??
self.length=0 # does not need to be global, can also migrate to local
# category and plugin variables
# what a MESS, this *must* get cleaned up
# FIXME
self.fftype=None # type of the pattern test, see header files
self.ff_cat=None # category to test for
self.plugin=None # pluginclass to test for
self.lonelyplugin=None # one plugin test only, named lonely plugin
self.search=None
# threading variables
self.thread_cnt=20 # default value of concurrent threads is 20
self.thread_alive=0 # variable for actually running threads
self.thread_list=[] # list for all active threads, not active gets removed
# file variables
self.fd=None # filedescriptor of target file
self.instat=None # results of os.stat against infile
self.infile=None # the file to analyze
# output variables
self.outdir=None # output directory
self.outprefix="FF-Extract" # prefix of every file written to output directory
# reporting variables
self.report=False # generate report if variable is True
self.reportname=None # name of the status report file
self.reportfiles=[] # list of files extracted files, for reporting
# logging options
self.debug=False
self.verbose=False
# extraction variables
self.extract=False # extract found files if variable is True
self.extract_cnt=0 # number of files found
# variables for strings search mechanism
self.str_analysis=False
self.str_minlen=4
self.str_filter="([a-zA-Z0-9 \.\-]{"+str(self.str_minlen)+",})"
self.str_resdict={}
self.str_anadict={}
# misc tool variables
self.__author__="dash"
self.__version__="0.5.2"
self.__tool__="FirmwareFudger"
self.__date__="May of 2019"
def privileges(self):
if self.stat.st_uid != os.getuid():
print ("[!] Attention file owner is %d" % self.stat.st_uid)
return False;
else:
return True;
def ffprint(self,data,level):
''' printing wrapper for:
* normal
* verbose
* debug
output
'''
if self.verbose==True and level==ver:
print (data)
elif self.debug==True and level==dbg:
print (data)
elif level==nor:
print (data)
return 0;
def printargs(self):
''' output information about the file
'''
size=self.instat.st_size
Kilo=1024.0
Mega=1048576.0
print ("[+] Fudger Version %s - Fileinformation" % self.__version__)
print ("[+] Filename %s" % self.infile)
if size<=Mega:
sizeK=size/Kilo
print ("[+] Size %.2fK - %dB" % (sizeK,size))
elif size>=Mega:
sizeM=size/Mega
sizeK=size/Kilo
print ("[+] Size %.2fM - %.2fK - %dB" % (sizeM,sizeK,size))
else:
print ("[+] Size %d" % size)
print ("[+] User %d" % self.instat.st_uid)
print ("[+] Group %d" % self.instat.st_gid)
#print "[+] Search for %s" % self.search
def openfile_fd(self):
''' simple open file operation and return fd
'''
try:
self.instat=os.stat(self.infile)
#print ("[+] Open %s" % (self.infile))
fd=open(self.infile,"rb")
except PermissionError as e:
print ('[-]',e)
return -1
except IsADirectoryError as e:
print ('[-]',e)
return -1
except FileNotFoundError as e:
print ('[-]',e)
return -1
return fd;
def openfile(self):
''' simple open file operation
'''
try:
self.instat=os.stat(self.infile)
print ("[+] Open %s" % (self.infile))
self.fd=open(self.infile,"rb")
except PermissionError as e:
print ('[-]',e)
return -1
except IsADirectoryError as e:
print ('[-]',e)
return -1
except FileNotFoundError as e:
print ('[-]',e)
return -1
def closefile(self):
''' simple closefile operaiton'''
print ("[+] Close %s" % self.infile)
self.fd.close()
def create_dir(self):
''' method for checking outdir and properties
and order creation
'''
if self.outdir != None:
try:
result=os.stat(self.outdir)
return 0;
except FileNotFoundError as e:
self.__create_dir()
elif self.outdir==None and self.extract==True:
# self.outdir is not specified, but it has been asked to extract data
# let us generate a directory for that usecase
dirname = self.infile.replace('/','_')
dirname = dirname.replace('..','_')
dirname = dirname.replace('.','_')
dirname = dirname.replace('!','_')
dirname = dirname.replace('-','_')
dirname = dirname.lower()
self.outdir=dirname
try:
result=os.stat(self.outdir)
return 0;
except FileNotFoundError as e:
self.__create_dir()
return 0;
def __create_dir(self):
''' this function tests if the output directory does exist, if not a new
one is created. if the name exists but it is not a directory
an error is thrown and the process is aborted.
'''
try:
print ("[+] Creating directory %s" % (self.outdir))
os.mkdir(self.outdir)
return(0)
except OSError as e:
print ("[-] Error %d %s" % (e.args[0], e.args[1]))
return(1)
def convert2array(self):
for byte in range(len(self.string)):
print ("\'%c\'," % self.string[byte],)
def ff_fill_targetqueue(self,category,plugin):
''' here starts the calls for the magic behind the scenes
category and plugin type are delivered and the target queue is build up
self.target_queue - consists of all information necessary for finding magic and
later extraction
'''
# print (TYPES[testtype][plugin])
header1=TYPES[category][plugin][1]
header2=TYPES[category][plugin][2]
name=TYPES[category][plugin][3]
desc=TYPES[category][plugin][4]
suffix=TYPES[category][plugin][5]
# now fill up the target queue
self.target_queue.put({ 'category':category,\
'plugin':plugin,\
'Header1':header1,\
'Header2':header2,\
'name':name,\
'desc':desc,\
'suffix':suffix})
#print (self.target_queue.qsize())
return 0;
def __checkheader(self,target):
''' new version of checkheader, that time with impressive speed
as a simpler search algorithm is used and an awesome class: re
and not working :(
'''
fd=self.openfile_fd()
#print ('[d] __checkheader')
header1=target['Header1']
category=target['category']
plugin=target['plugin']
suffix=target['suffix']
name=target['name']
hh=''
cut={}
# due a not sooo good design of ff database this has to be done
# obviously ff database needs a redesign :)
for i in header1:
hh = hh+i
# lets create our re pattern
hh = re.escape(hh)
hh=bytes(hh,'latin-1')
re_comp=re.compile(hh)
#print ('[v] Checking %s' % target['name'])
#print ('[d] Header1:',header1)
#print ('[d] HH:',hh)
for match in re.finditer(re_comp, fd.read()):
#print('match', match.span())
#print('match.group',match.group())
offstart, offend = match.span()
print ("[+] FOUND %s at Offset %d to %d" % (target['name'],offstart,offend))
#print(match.span(), match.group())
dataend=self.instat.st_size
cut={'offstart':offstart,'offend':offend,'dataend':dataend,'category':category,'plugin':plugin,'suffix':suffix}
#print ('checkheader:',cut)
self.result_queue.put(cut)
# self.str_resdict[match.span()]=match.group()
cut={}
self.extract_cnt+=1
fd.close()
def checkheader(self):
''' threaded checkheader wrapper
'''
while self.target_queue.qsize()>0:
# set current thread count
self.thread_alive=len(self.thread_list)
# check if we have crossed the limit of maximum threads
if self.thread_alive<self.thread_cnt:
# get a value from the target queue
target=self.target_queue.get()
# set variables for the thread, make it daemon and start it
thrd = threading.Thread(target=self.__checkheader,args=(target,))
thrd.daemon=True
thrd.start()
# add the thread to our list
self.thread_list.append(thrd)
#print ('thrd cnt: %d' % len(self.thread_list))
# this part watches that dead threads can join and it is removed from the list
for entry in self.thread_list:
if entry.isAlive()==False:
entry.join()
self.thread_list.remove(entry)
def seekinto(self):
allbytes=""
self.fd=open(self.infile,"rb")
self.fd.seek(0,0)
self.fd.seek(self.set_offset,0)
for byte in self.fd.read(self.length):
byte=binascii.hexlify(byte)
allbytes=allbytes + "\\x"+byte
print ("%s" % allbytes,)
def manglefile(self):
mangle_file=open(self.infile,"r")
for part in range(self.extract):
mangle_file.seek(0,0)
mangle_file.seek(self.cut[part],0)
readbytes=mangle_file.read(8)
print ("read %s " % readbytes)
mangle_file.close()
mangle_file=open(self.infile,"r+")
mangle_file.seek(0,0)
mangle_file.seek(self.cut[part],0)
mangle_file.write(self.set_string)
mangle_file.close()
def extractcount(self):
''' let's print some information about the files to extract
'''
print ("[+] Found %d possible types" % (self.extract_cnt))
return 0;
def extractdata(self):
''' simple wrapper function, which gets called by program
'''
# ram some info
self.extractcount()
# lets go to file extraction
self.extractfile()
return 0;
def extractfile(self):
""" its working just need some cleanups, and small fixes """
if self.extract_cnt == 0:
self.ffprint('[-] Sorry, nothing to extract. Counter is zer0.',nor)
return -1;
if self.extract==False:
return -1
exo_file=open(self.infile,"rb")
# as long as we have results in the queue
while self.result_queue.qsize()>0:
# place result in target variable
target = self.result_queue.get()
#cut[self.extract_cnt]=(offstart,offend,dataend,category,plugin,suffix)
# print (target)
# print (len(target))
offstart=target['offstart']
suffix=target['suffix']
if suffix==None:
suffix=''
# go to start of file
exo_file.seek(0,0)
exo_file.seek(offstart,0)
#print (self.cut)
#print (self.cut[part])
FILENAME=self.outdir+"/"+self.outprefix+"-"+str(self.extract)+"-"+str(offstart)+"." + suffix
print ("[+] FILENAME: %s" % FILENAME)
try:
exw_file=open(FILENAME,"wb")
except PermissionError as e:
print ('[-] ',e)
return -1;
# data to write to the extracted file
# please note that currently the end of the
# original file is the end - for reasons ;)
TOWRITE=(self.instat.st_size)-offstart
# depending on the file size this might get problematic
buf = exo_file.read()
exw_file.write(buf)
# close the file
exw_file.close()
#lets add it to files if reportfile shall be written
self.reportfiles.append(FILENAME)
def generateReport(self):
print ("[+] Found %d extracted files" % len(self.files))
print
print ("file Report")
print ("="*11)
for extracted in self.files:
#print "[+] %s " % extracted
os.spawnl(os.P_WAIT,"/usr/bin/file","file",extracted)
def __print_categories(self):
''' sub-method for printing all categories
'''
print ('[+] Categories')
for cat in FUDGEheader.TYPES_DEF:
print ('\t%s' % cat)
return 0;
def showplugins(self,cat=None):
""" all plugins currently supported by FF own database
"""
i=0
if cat!=None:
if cat in FUDGEheader.TYPES_DEF:
print ("[+] Plugins:")
# print ('[v] FOUND %s' % cat)
catid = FUDGEheader.TYPES_DEF[cat]
print ("[+] %s:" % cat)
for plugin in range(len(FUDGEheader.TYPES[catid])):
print ("\t\t- %s - %s" % (FUDGEheader.TYPES[catid][plugin][FUDGEheader.NAME],FUDGEheader.TYPES[catid][plugin][FUDGEheader.DESC]))
i+=1
else:
print ('[-] Category "%s" does not exist' % cat);
self.__print_categories()
return -1;
# show all plugins supported
else:
for fftype in range(len(FUDGEheader.TYPES)):
if fftype==0:
stringtype="FS"
elif fftype==1:
stringtype="EXEC"
elif fftype==2:
stringtype="PACKERS"
elif fftype==3:
stringtype="DOCS"
elif fftype==4:
stringtype="BOOT"
elif fftype==5:
stringtype="ASM"
elif fftype==6:
stringtype="PICTURES"
elif fftype==7:
stringtype="DEVICES"
elif fftype==8:
stringtype="CRYPTO"
# elif fftype==9:
# stringtype="CRYPTO"
print ("%s:" % stringtype)
for plugin in range(len(FUDGEheader.TYPES[fftype])):
print ("\t\t- %s - %s" % (FUDGEheader.TYPES[fftype][plugin][FUDGEheader.NAME],FUDGEheader.TYPES[fftype][plugin][FUDGEheader.DESC]))
i+=1
print ("\n[+] Found %d plugins." % i)
print ("[+] Done")
#####################################
# #
# strings analysis section #
# #
#####################################
def strings_analysis(self):
''' method for analysing and giving hints to the analyst
self.str_resdict, the result dictionary of self.string_search method
self.str_anadict, the reuslt dictionary for self.string_analysis method
'''
ana = open('supply/strings.txt','r')
# read strings supply file
for line in ana.readlines():
# is it a comment, no? then proceed
if not line.startswith('#'):
a = line.split(';')
needle=a[0]
desc=a[1]
tools=a[2]
for k in self.str_resdict.keys():
if self.str_resdict[k].find(needle)!=-1:
self.str_anadict[needle]=(needle,desc,tools)
print ('[+] %s - %s - %s' % (needle,desc,tools))
print ('[+] Found %d interesting string(s) during analysis.' % len(self.str_anadict))
ana.close()
return 0;
def strings_output(self):
''' method for writing results of strings search
self.str_resdict, the result dictionary of self.string_search method
'''
return 0;
def strings_search(self):
''' this method does the work of the unix userland tool "strings"
it searches a binary for possible strings, for later manual
analysis. in this particular case an automatic analysis is added
as well to hint the analyst on something interesting found
self.str_minlen, the default is 4
self.str_filter, the regular expression filter
self.str_resdict, the result dictionary with string, start/end position
'''
# variables for strings search mechanism
self.openfile()
# print (re.findall(re_filter, str(self.fd.read())))
for match in re.finditer(self.str_filter, str(self.fd.read())):
#print('match', match.span())
#print('match.group',match.group())
# print(match.span(), match.group())
self.str_resdict[match.span()]=match.group()
# place this somewhere else later
self.strings_analysis()

BIN
lib/FUDGEanalyse.pyc Normal file

Binary file not shown.

813
lib/FUDGEheader.py Executable file
View File

@@ -0,0 +1,813 @@
#complete list
TYPES = 0x00
#categories
FS = 0x00
EXEC = 0x01
PACKERS = 0x02
DOCS = 0x03
BOOT = 0x04
ASM = 0x05
PICTURES = 0x06
DEVICES = 0x07
#ROUTERS = 0x08
CRYPTO = 0x08
#Filesystem Type Definitions
MSDOS = 0x00
CRAMFS1 = 0x01
CRAMFS2 = 0x02 #difference is another searchstring
ROM1FS = 0x03
SQUASHFS1 = 0x04 #difference is another searchstring
SQUASHFS2 = 0x05
FAT32 = 0x06
CDUNIX = 0x07
ADF = 0x08
SGI = 0x09
SGIXFS = 0x0a
ST40 = 0x0b
CBM = 0x0c
WINIMAGE = 0x0d
COB = 0x0e
UFS1 = 0x0f
QEMU1 = 0x10
JFFSL = 0x11
JFFSB = 0x12
JFFS2L = 0x13
JFFS2B = 0x14
FAT12 = 0x15
FAT16 = 0x16
#Executeable File Definitions
ELF = 0x00
BFLT = 0x01
PE = 0x02
MSDOSCOM = 0x03
DOSCOM = 0x04
SPSSPORTABLE= 0x05
SPSSSYSTEM = 0x06
PPCPEF = 0x07
#Packing Specific definitions
ZIP1 = 0x00
ZIP2 = 0x01
BZIP = 0x02
GZIP = 0x03
ACE = 0x04
TAR = 0x05
TRX1 = 0x06
TRX2 = 0x07
LZMA = 0x08
UPX = 0x09
GNUTAR = 0x0A
CRUSH = 0x0B
HLSQZ = 0x0B
SQWEZ = 0x0C
HPAK = 0x0D
LZOP = 0x0E
MDCD = 0x0F
MSCOMPRESS = 0x10
INSTALLSHIELD = 0x11
PAQ = 0x12
JARARJ = 0x13
STUFFIT = 0x14
VAX3 = 0x15
VAX5 = 0x16
ARCHIVE = 0x17
ARCHIVEFILE = 0x18
HRB = 0x19
RISCOS = 0x1a
HAP = 0x1b
LIM = 0x1c
FREEZE = 0x1d
ZOO = 0x1e
RAR = 0x1f
EET = 0x20
RZIP = 0x21
SQSH = 0x22
ISC = 0x23
NWFILE = 0x24
DSIGDCC = 0x25
ARJ = 0x26
#Document Fileformats
PDF = 0x00
DOC = 0x01
RTF = 0x02
#Bootloader Definitions
UBOOT = 0x00
#Assembler object codes
AVR = 0x00
#Image Files(pictures etc.)
GIMPXCF = 0x00
#Devices Specific Firmware characteristics
LTRX1 = 0x00
LTRX2 = 0x01
WGR614BOOT = 0x02
WGR614 = 0x03
#Router Specific Firmware characteristics specifications
#Crypto stuff, certificates, keys, typical indications of crypto
DSAPRIV = 0x00 #-----BEGIN DSA PRIVATE KEY----- -----END DSA PRIVATE KEY-----
RSAPRIV = 0x01 #-----BEGIN RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
SSHPUB = 0x02 # ssh-dss
CACERT = 0x03 #-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----
CERTREQ = 0x04 #-----BEGIN CERTIFICATE REQUEST----- -----END CERTIFICATE REQUEST-----
PGPMSG = 0x05 #-----BEGIN PGP MESSAGE----- -----END PGP MESSAGE-----
#Header definitions
HEADER1 = 0x01 #start header
HEADER2 = 0x02 #stop trailer/header
NAME = 0x03 #the format name
DESC = 0x04 #teh description
SUFFIX = 0x05 #the ending of the file, some tools want to have a proper ending, gzip for instance
CHANCE = 0x06 #chance calculator, if at least "chance" bytes are correct print out possibility...
TOOLS = 0x07 #tools of trade to work with that kind of files
#Filesystem Specifications
#
#still much too add
###########################################
TYPES = { FS: { \
MSDOS:{ \
HEADER1: ('M','Z','H','H'),\
HEADER2: None,\
NAME: 'MSDOS',\
DESC: "MSDOS - Filesystem",\
SUFFIX: 'img',\
CHANCE: 2},
CRAMFS1:{ \
HEADER1: ('\x45','\x3d','\xcd','\x28'),\
HEADER2: None,\
NAME: 'CRAMFS1',\
DESC: "CRAMFS - Compressed ROMFS",\
SUFFIX: 'img',\
CHANCE: 2},
CRAMFS2:{ \
HEADER1: ('C','o','m','p','r','e','s','s','e','d','\x20','R','O','M','F','S'),\
HEADER2: None,\
NAME: 'CRAMFS2',\
DESC: "CRAMFS2 - Compressed ROMFS",\
SUFFIX: 'img',\
CHANCE: 8},
ROM1FS:{ \
HEADER1: ('-','r','o','m','1','f','s'),\
HEADER2: None,\
NAME: 'ROM1FS',\
DESC: "ROM1FS - ROM FILE SYSTEM",\
SUFFIX: 'img',\
CHANCE: 3},
SQUASHFS1:{ \
HEADER1: ('h','s','q','s'),\
HEADER2: None,\
NAME: 'SQUASHFS',\
DESC: "SQUASHFS - Big Endian",\
SUFFIX: 'img',\
CHANCE: 2},
SQUASHFS2:{ \
HEADER1: ('s','q','s','h'),\
HEADER2: None,\
NAME: 'SQUASHFS2',\
DESC: "SQUASHFS - Little Endian",\
SUFFIX: 'img',\
CHANCE: 2},
FAT32:{ \
HEADER1: ('\x46','\x41','\x54','\x33','\x32'),\
HEADER2: None,\
NAME: 'FAT32',\
DESC: "FAT32 - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
FAT12:{ \
HEADER1: ('\x46','\x41','\x54','\x31','\x32'),\
HEADER2: None,\
DESC: "FAT12 - Filessystem",\
NAME: 'FAT12',\
SUFFIX: 'img',\
CHANCE: 2},
FAT16:{ \
HEADER1: ('\x46','\x41','\x54','\x31','\x36'),\
HEADER2: None,\
NAME: 'FAT16',\
DESC: "FAT16 - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
CDUNIX:{ \
HEADER1: ('\x01','\x43','\x44','\x30','\x30','\x31','\x01'),\
HEADER2: None,\
NAME: 'CDUNIX',\
DESC: "CDUNIX - Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
ADF:{ \
HEADER1: ('D','O','S','\x00'),\
HEADER2: None,\
NAME: 'ADF',\
DESC: "ADF - Amiga Filessystem",\
SUFFIX: 'img',\
CHANCE: 2},
SGI:{ \
HEADER1: ('\x0B','\xE5','\xA9','\x41'),\
HEADER2: None,\
NAME: 'SGI',\
DESC: "SGI - SGI disk label (volume header)",\
SUFFIX: 'img',\
CHANCE: 2},
SGIXFS:{ \
HEADER1: ('\x58','\x46','\x53','\x42'),\
HEADER2: None,\
NAME: 'SGIXFS',\
DESC: "SGI XFS - filesystem data",\
SUFFIX: 'img',\
CHANCE: 2},
ST40:{ \
HEADER1: ('\x13','\xa9','\xf1','\x7e'),\
HEADER2: None,\
NAME: 'ST40',\
DESC: "ST40 - component image format",\
SUFFIX: 'img',\
CHANCE: 2},
CBM:{ \
HEADER1: ('C','B','M'),\
HEADER2: None,\
NAME: 'POWER64',\
DESC: "Power 64 - C64 Emulator Snapshot",\
SUFFIX: 'img',\
CHANCE: 2},
WINIMAGE:{ \
HEADER1: ('W','I','N','I','M','A','G','E'),\
HEADER2: None,\
NAME: 'WinImage',\
DESC: "WinImage - WinImage Archive data",\
SUFFIX: 'img',\
CHANCE: 2},
COB:{ \
HEADER1: ('C','o','B','1'),\
HEADER2: None,\
NAME: 'COB1',\
DESC: "CoB1 - lantronix html/webserver filesystem",\
SUFFIX: 'img',\
CHANCE: 2},
UFS1:{ \
HEADER1: ('\x00','\x01','\x19','\x54'),\
HEADER2: None,\
NAME: 'UFS1',\
DESC: "UFS1 - Unix Fast File system [v1] (little-endian)",\
SUFFIX: 'img',\
CHANCE: 2},
QEMU1:{ \
HEADER1: ('\x51','\x46','\x49','\xfb'),\
HEADER2: None,\
NAME: 'QEMU1',\
DESC: "QEMU1 - Qemu Image, Format: Qcow",\
SUFFIX: 'img',\
CHANCE: 2},
JFFSL:{ \
HEADER1: ('\x31','\x39','\x38','\x34'),\
HEADER2: None,\
NAME: 'JFFS1_LE',\
DESC: "JFFS1 - version 1, little endian",\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
SUFFIX: 'img',\
CHANCE: 2},
JFFSB:{ \
HEADER1: ('\x34','\x38','\x39','\x31'),\
HEADER2: None,\
NAME: 'JFFS1_BE',\
DESC: "JFFS1 - version 1, big endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2},
JFFS2L:{ \
HEADER1: ('\x85','\x19','\x03','\x20'),\
HEADER2: None,\
NAME: 'JFFS2_LE',\
DESC: "JFFS2 - version 2, little endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2},
JFFS2B:{ \
HEADER1: ('\x19','\x85','\x20','\x03'),\
HEADER2: None,\
NAME: 'JFFS2_BE',\
DESC: "JFFS2 - version 2, big endian",\
SUFFIX: 'img',\
TOOLS: "mtd-tools, mkfs.jffs etc.",\
CHANCE: 2}
},
EXEC: {
ELF:{ \
HEADER1: ('\x7f','E','L','F'),\
HEADER2: None,\
NAME: 'ELF',\
DESC: "ELF - File Format",\
SUFFIX: 'elf',\
CHANCE: 2},
BFLT:{ \
HEADER1: ('b','F','L','T'),\
HEADER2: None,\
NAME: 'BFLT',\
DESC: "bFLT - File Format",\
SUFFIX: 'bflf',\
CHANCE: 2},
PE:{ \
HEADER1: ('P','E','\x00','\x00'),\
HEADER2: None,\
NAME: 'PE',\
DESC: "PE - File Format",\
SUFFIX: 'exe',\
CHANCE: 2},
MSDOSCOM:{ \
HEADER1: ('\xfc','\x57','\xf3','\xa5','\xc3'),\
HEADER2: None,\
NAME: 'COM',\
DESC: "COM executable for MS-DOS",\
SUFFIX: 'com',\
CHANCE: 2},
DOSCOM:{ \
HEADER1: ('\xfc','\x57','\xf3','\xa4','\xc3'),\
HEADER2: None,\
NAME: 'COMDOS',\
DESC: "COM executable for DOS",\
SUFFIX: 'com',\
CHANCE: 2},
SPSSPORTABLE:{ \
HEADER1: ('\xc1','\xe2','\xc3','\xc9'),\
HEADER2: None,\
NAME: 'SPSS',\
DESC: "SPSS Portable File",\
SUFFIX: None,\
CHANCE: 2},
SPSSSYSTEM:{ \
HEADER1: ('$','F','L','2'),\
HEADER2: None,\
NAME: 'SPSS2',\
DESC: "SPSS System File",\
SUFFIX: None,\
CHANCE: 2},
PPCPEF:{ \
HEADER1: ('J','o','y','!','p','e','f','f','p','w','p','c'),\
HEADER2: None,\
NAME: 'PPC_PEF',\
DESC: "header for PowerPC PEF executable",\
SUFFIX: None,\
CHANCE: 2}
},
PACKERS: {
ZIP1:{ \
HEADER1: ('\x50','\x4b','\x03','\x04'),\
HEADER2: None,\
NAME: 'ZIP1',\
DESC: "ZIP1 - Phil Katz ",\
SUFFIX: 'zip',\
CHANCE: 2},
ZIP2:{ \
HEADER1: ('\x50','\x4b','\x01','\x02'),\
HEADER2: None,\
NAME: 'ZIP2',\
DESC: "ZIP2 - Phil Katz ",\
SUFFIX: 'zip',\
CHANCE: 2},
BZIP:{ \
HEADER1: ('\x42','\x5a','\x68'),\
HEADER2: None,\
NAME: 'BZIP',\
DESC: "BZIP - a block-sorting file compressor",\
SUFFIX: 'bz2',\
CHANCE: 2},
GZIP:{ \
HEADER1: ('\x1f','\x8b'),\
HEADER2: None,\
NAME: 'GZIP',\
DESC: "GZIP - Lempel-Ziv coding (LZ77)",\
SUFFIX: 'gz',\
CHANCE: 2},
ACE:{ \
HEADER1: ('*','*','A','C','E','*','*'),\
HEADER2: None,\
NAME: 'ACE',\
DESC: "ACE - e-merge GmbH - winace.com",\
SUFFIX: 'ace',\
CHANCE: 2},
TAR:{ \
HEADER1: ('\x00','u','s','t','a','r','\x00'),\
HEADER2: None,\
NAME: 'TAR',\
DESC: "TAR - tape archiver",\
SUFFIX: 'tar',\
CHANCE: 2},
TRX1:{ \
HEADER1: ('\x30','\x52','\x44','\x48'),\
HEADER2: None,\
NAME: 'TRX1',\
DESC: "TRX1 - ",\
SUFFIX: None,\
CHANCE: 2},
TRX2:{ \
HEADER1: ('H','D','R','0'),\
HEADER2: ('0','R','D','H'),\
NAME: 'TRX2',\
DESC: "TRX2 - ",\
SUFFIX: None,\
CHANCE: 2},
LZMA:{ \
HEADER1: ('\x5d','\x00','\x00','\x80'),\
HEADER2: None,\
NAME: 'LZMA',\
DESC: "LZMA - Lempel-Ziv-Markov chain-Algorithm",\
SUFFIX: 'lzma',\
CHANCE: 2},
UPX:{ \
HEADER1: ('U','P','X','!'),\
HEADER2: None,\
NAME: 'UPX',\
DESC: "UPX - Ultimate Packer for eXecuteables",\
SUFFIX: 'upx',\
CHANCE: 2},
GNUTAR:{ \
HEADER1: ('u','s','t','a','r','\x20','\x20','\x00'),\
HEADER2: None,\
NAME: 'GNUTAR',\
DESC: "GNUTAR - tar == teer + tape archiver",\
SUFFIX: 'tar',\
CHANCE: 2},
CRUSH:{ \
HEADER1: ('C', 'R', 'U', 'S', 'H'),\
HEADER2: None,\
NAME: 'CRUSH',\
DESC: "CRUSH - Crush archive data",\
SUFFIX: None,\
CHANCE: 2},
HLSQZ:{ \
HEADER1: ('H', 'L', 'S', 'Q', 'Z'),\
HEADER2: None,\
NAME: 'HLSQZ',\
DESC: "HLSQZ - Squeeze It archive data",\
SUFFIX: None,\
CHANCE: 2},
SQWEZ:{ \
HEADER1: ('S', 'Q', 'W', 'E', 'Z'),\
HEADER2: None,\
NAME: 'SQWEZ',\
DESC: "SQWEZ - archive data",\
SUFFIX: None,\
CHANCE: 2},
HPAK:{ \
HEADER1: ('H', 'P', 'A', 'K'),\
HEADER2: None,\
NAME: 'HPAK',\
DESC: "HPAK - archive data",\
SUFFIX: None,\
CHANCE: 2},
LZOP:{ \
HEADER1: ('\x89','\x4c','\x5a','\x4f','\x00','\x0d','\x0a','\x1a','\x0a'),\
HEADER2: None,\
NAME: 'LZOP',\
DESC: "LZOP - lzop comrpressed data",\
SUFFIX: None,\
CHANCE: 2},
MDCD:{ \
HEADER1: ('M', 'D', 'm', 'd'),\
HEADER2: None,\
NAME: 'MDCD',\
DESC: "MDCD - archive data",\
SUFFIX: None,\
CHANCE: 2},
MSCOMPRESS:{ \
HEADER1: ('\x88','\xf0','\x27'),\
HEADER2: None,\
NAME: 'MS',\
DESC: "MS Compress archive data",\
SUFFIX: None,\
CHANCE: 2},
INSTALLSHIELD:{ \
HEADER1: ('\x13','\x5d','\x65','\x8c'),\
HEADER2: None,\
NAME: 'MSIS',\
DESC: "InstallShield - Z archive Data",\
SUFFIX: None,\
CHANCE: 2},
PAQ:{ \
HEADER1: ('\xaa','\x40','\x5f','\x77','\x1f','\xe5','\x82','\x0d'),\
HEADER2: None,\
NAME: 'PAQ',\
DESC: "PAQ - archive data",\
SUFFIX: None,\
CHANCE: 2},
JARARJ:{ \
HEADER1: ('\x1a','J','a','r','\x1b'),\
HEADER2: None,\
NAME: 'JAR',\
DESC: "JAR (ARJ Software, Inc.) archive data",\
SUFFIX: 'arj',\
CHANCE: 2},
STUFFIT:{ \
HEADER1: ('S','t','u','f','f','I','t'),\
HEADER2: None,\
NAME: 'STUFFIT',\
DESC: "StuffIt Archive",\
SUFFIX: 'stuffit',\
CHANCE: 2},
VAX3:{ \
HEADER1: ('\x65','\xff','\x00','\x00'),\
HEADER2: None,\
NAME: 'VAX3',\
DESC: "VAX 3.0 archive",\
SUFFIX: None,\
CHANCE: 2},
VAX5:{ \
HEADER1: ('\x3c','\x61','\x72','\x3e'),\
HEADER2: None,\
NAME: 'VAX5',\
DESC: "VAX 5.0 archive",\
SUFFIX: None,\
CHANCE: 2},
ARCHIVE:{ \
HEADER1: ('=','<','a','r','>'),\
HEADER2: None,\
NAME: 'AR',\
DESC: "archive",\
SUFFIX: 'ar',\
CHANCE: 2},
ARCHIVEFILE:{ \
HEADER1: ('21','3c','61','72'),\
HEADER2: None,\
NAME: 'ARfile',\
DESC: "archive file",\
SUFFIX: 'ar',\
CHANCE: 2},
HRB:{ \
HEADER1: ('\xc0','H','R','B'),\
HEADER2: None,\
NAME: 'HRB',\
DESC: "Harbour HRB file",\
SUFFIX: 'hrb',\
CHANCE: 2},
RISCOS:{ \
HEADER1: ('A','r','c','h','i','v','e'),\
HEADER2: None,\
NAME: 'RISCOS',\
DESC: "RISC OS archive (ArcFS format)",\
SUFFIX: None,\
CHANCE: 2},
HAP:{ \
HEADER1: ('\x91','\x33','H','F'),\
HEADER2: None,\
NAME: 'HAP',\
DESC: "HAP archive data",\
SUFFIX: None,\
CHANCE: 2},
LIM:{ \
HEADER1: ('L','I','M','\x1a'),\
HEADER2: None,\
NAME: 'LIM',\
DESC: "LIM archive data",\
SUFFIX: None,\
CHANCE: 2},
FREEZE:{ \
HEADER1: ('\x1f','\x9f','\x4a','\x10','\x0a'),\
HEADER2: None,\
NAME: 'FREEZE',\
DESC: "Freeze archive data",\
SUFFIX: None,\
CHANCE: 2},
ZOO:{ \
HEADER1: ('\xfd','\xc4','\xa7','\xdc'),\
HEADER2: None,\
NAME: 'ZOO',\
DESC: "Zoo archive data",\
SUFFIX: None,\
CHANCE: 2},
RAR:{ \
HEADER1: ('R','a','r','!'),\
HEADER2: None,\
NAME: 'RAR',\
DESC: "RAR archive data",\
SUFFIX: 'rar',\
CHANCE: 2},
EET:{ \
HEADER1: ('\x1e','\xe7','\xff','\x00'),\
HEADER2: None,\
NAME: 'EET',\
DESC: "EET archive",\
SUFFIX: None,\
CHANCE: 2},
RZIP:{ \
HEADER1: ('R','Z','I','P'),\
HEADER2: None,\
NAME: 'RZIP',\
DESC: "rzip compressed data",\
SUFFIX: None,\
CHANCE: 2},
SQSH:{ \
HEADER1: ('S','Q','S','H'),\
HEADER2: None,\
NAME: 'SQUISH',\
DESC: "squished archive data (Acorn RISCOS)",\
SUFFIX: None,\
CHANCE: 2},
ISC:{ \
HEADER1: ('I','S','c','('),\
HEADER2: None,\
NAME: 'CAB',\
DESC: "InstallShield CAB",\
SUFFIX: None,\
CHANCE: 2},
NWFILE:{ \
HEADER1: ('P','a','c','k','e','d','\\',' ','F','i','l','e','\\'),\
HEADER2: None,\
NAME: 'NETWARE',\
DESC: "Personal NetWare Packed File",\
SUFFIX: None,\
CHANCE: 2},
DSIGDCC:{ \
HEADER1: ('D','S','I','G','D','C','C'),\
HEADER2: None,\
NAME: 'CROSSEPAC',\
DESC: "CrossePAC archive data",\
SUFFIX: None,\
CHANCE: 2},
ARJ:{ \
HEADER1: ('\x60','\xea'),\
HEADER2: None,\
NAME: 'ARJ',\
DESC: "ARJ",\
SUFFIX: 'arj',\
CHANCE: 2}
},
DOCS: { \
PDF:{ \
HEADER1: ('\x25','\x50','\x44','\x46','\x2e'),\
HEADER2: None,\
NAME: 'PDF',\
DESC: "PDF - Portable Document Format",\
SUFFIX: 'pdf',\
CHANCE: 2},
DOC:{ \
HEADER1: ('\xd0','\xcf','\x11','\xe0','\xa1','\xb1','\x1a','\xe1'),\
HEADER2: None,\
NAME: 'DOC',\
DESC: "DOC - Microsoft Document Format",\
SUFFIX: 'doc',\
CHANCE: 2},
RTF:{ \
HEADER1: ('{','\\','\\','r','t','f'),\
HEADER2: None,\
NAME: 'RTF',\
DESC: "RTF - Rich Text Format data",\
SUFFIX: 'rtf',\
CHANCE: 2}
},
BOOT: { \
UBOOT:{ \
HEADER1: ('\x27','\x05','\x19','\x56'),\
HEADER2: None,\
NAME: 'UBOOT',\
DESC: "UBOOT - PPCBoot Image - maybe bootloader",\
SUFFIX: 'uboot',\
CHANCE: 2}
},
ASM: { \
AVR:{ \
HEADER1: ('a','v','a','o','b','j'),\
HEADER2: None,\
NAME: 'AVR',\
DESC: "AVR assembler object code",\
SUFFIX: 'avr',\
CHANCE: 2}
},
PICTURES: { \
GIMPXCF:{ \
HEADER1: ('g','i','m','p','\\',' ','x','c','f'),\
HEADER2: None,\
NAME: 'GIMP_XCF',\
DESC: "GIMP XCF image data",\
SUFFIX: 'xcf',\
CHANCE: 2}
},
DEVICES: { \
LTRX1:{ \
HEADER1: ('D','S','T','-','L','T','R','X'),\
HEADER2: None,\
NAME: 'LTRX1',\
DESC: "LTRX1 - Lantronics Firmware Part detected",\
SUFFIX: None,\
CHANCE: 2},
LTRX2:{ \
HEADER1: ('L','T','R','X'),\
HEADER2: None,\
NAME: 'LTRX2',\
DESC: "LTRX2 - Lantronics Firmware Part detected",\
SUFFIX: None,\
CHANCE: 2},
WGR614BOOT:{ \
HEADER1: ('*','#','$','^'),\
HEADER2: None,\
NAME: 'NETGEAR_BOOT',\
DESC: "NETGEAR WGR614v9 Bootware - unknown bootloader maybe",\
SUFFIX: None,\
CHANCE: 2},
WGR614:{ \
HEADER1: ('@','U','1','2','H','0','9','4','T'),\
HEADER2: None,\
NAME: 'NETGEAR_FW',\
DESC: "NETGEAR WGR614v9 Firmware",\
SUFFIX: None,\
CHANCE: 2}
},
CRYPTO: {
DSAPRIV:{ \
HEADER1: ('-----BEGIN DSA PRIVATE KEY-----'),\
HEADER2: ('-----END DSA PRIVATE KEY-----'),\
NAME: 'DSAPRIV',\
DESC: "DSAPRIV - Private Key in DSA Format",\
SUFFIX: None,\
CHANCE: 2},
RSAPRIV:{ \
HEADER1: ('-----BEGIN RSA PRIVATE KEY-----'),\
HEADER2: ('-----END RSA PRIVATE KEY-----'),\
NAME: 'RSAPRIV',\
DESC: "RSAPRIV - Private Key in RSA Format",\
SUFFIX: None,\
CHANCE: 2},
SSHPUB:{ \
HEADER1: ('ssh-dss'),\
HEADER2: None,\
NAME: 'SSHDSS',\
DESC: "SSHDSS - Public ssh key",\
SUFFIX: None,\
CHANCE: 2},
CACERT:{ \
HEADER1: ('-----BEGIN CERTIFICATE-----'),\
HEADER2: ('-----END CERTIFICATE-----'),\
NAME: 'CACERT',\
DESC: "CACERT - Certificate Format",\
SUFFIX: None,\
CHANCE: 2},
CERTREQ:{ \
HEADER1: ('-----BEGIN CERTIFICATE REQUEST-----'),\
HEADER2: ('-----END CERTIFICATE REQUEST-----'),\
NAME: 'CERTREQ',\
DESC: "CERTREQ - Certificate Request Format",\
SUFFIX: None,\
CHANCE: 2},
PGPMSG:{ \
HEADER1: ('-----BEGIN PGP MESSAGE-----'),\
HEADER2: ('-----END PGP MESSAGE-----'),\
NAME: 'PGPMSG',\
DESC: "PGPMSG - Pretty Good Privacy Message Format",\
SUFFIX: None,\
CHANCE: 2},
}
}
TYPES_DEF = { 'FS':FS,\
'EXEC':EXEC,\
'PACKERS':PACKERS,\
'DOCS':DOCS,\
'BOOT':BOOT,\
'ASM':ASM,\
'PICTURES':PICTURES,\
'DEVICES':DEVICES,\
'CRYPTO':CRYPTO
}

BIN
lib/FUDGEheader.pyc Normal file

Binary file not shown.

4
lib/__init__.py Executable file
View File

@@ -0,0 +1,4 @@
"""
Fudge init library
"""

BIN
lib/__init__.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.