diff --git a/dbfp.py b/dbfp.py index 46e5ce0..f235a48 100644 --- a/dbfp.py +++ b/dbfp.py @@ -3,11 +3,17 @@ # import argparse import time +import logging from libs import fingerprint from libs import toolbox +from libs import android + +BASE_DIR = "data" def main(): + # logging.basicConfig(filename='dbfp.log', level=logging.DEBUG) + logging.basicConfig(level=logging.DEBUG) parseArgs() # @@ -39,6 +45,32 @@ def createFingerprint(filein, fileout, verbose, app_name, app_ver, notes): else: print db.getErrorString(retVal) +# +def fingerprintDir(): + ap = android.AndroidAppPull() + isRoot = ap.isADBRoot(); + if (not isRoot): + print "ERROR: adb is not running as root, exec 'adb root'" + return + + logging.info("isRoot == {}".format(isRoot)) + + mkdir(BASE_DIR) + + dir_names = ap.getAppsDir() + for dir_name in dir_names: + ap.pullApp(BASE_DIR, dir_name) + # logging.info("DIR:: {}".format(dir_names[0])) + # ap.pullApp(dir_names[0]) + +def mkdir(fdir): + retval = False + try: + check_call(["mkdir", fdir]) + retval = True + except: + return retval + # def parseArgs(): print '***** ***** ***** *****' @@ -53,21 +85,45 @@ def parseArgs(): parser.add_argument('-an', '--app_name', required=False) parser.add_argument('-av', '--app_version', required=False) parser.add_argument('-n', '--notes', required=False) + parser.add_argument('-pull', '--pull', required=False, action='store_true') parser.add_argument('-v', '--verbose', action='store_true') # parser.add_argument('-t', '--title', required=False) args = parser.parse_args() - if (args.file is None) and (args.fp is None): + if (args.file): + filename = toolbox.ToolBox.parseFilename(args.file) + fileout = filename + "_" + timestr + '.json' + createFingerprint(args.file, fileout, args.verbose, args.app_name, args.app_version, args.notes) + elif (args.fp and args.fpdir): + compareFingerprintDir(args.file, args.fp, args.fpdir) + elif (args.fp): + compareFingerprint(args.file, args.fp) + elif (args.pull): + fingerprintDir() + else: parser.print_help() - exit() + return + + + if (args.pull): + fingerprintDir() + return + + if (args.file is None) or (args.fp is None) or (args.pull is None): + parser.print_help() + return # compare a sqlite database file to all fingerprints if (args.fp and args.fpdir): compareFingerprintDir(args.file, args.fp, args.fpdir) + return + # compare a sqlite database file to a fingerprint if (args.fp): compareFingerprint(args.file, args.fp) + return + # create a fingerprint from the sqlite file filename = toolbox.ToolBox.parseFilename(args.file) fileout = filename + "_" + timestr + '.json' diff --git a/libs/android.py b/libs/android.py new file mode 100644 index 0000000..290c63c --- /dev/null +++ b/libs/android.py @@ -0,0 +1,59 @@ +# +# +# +import os +import re +import logging +from subprocess import Popen, PIPE, check_call + +# logger = +# +class AndroidAppPull: + """ + Tools to discover and pull apps from Android device using adb + """ + + # + def getAppsDir(self): + dir_names = [] + stderr = '' + # call adb shel command to parse the file system + process = Popen(["adb", "shell", "ls", "-l", "/data/data"], stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + + if (0 < stdout.find('failed')): + logging.error("Error executing adb shell") + logging.info("Make sure adb is in root mode, 'adb root'") + + strings = stdout.split('\n') + for sstr in strings: + results = re.search(r'\s(\w+\.[\w|\.]+)', sstr) + if results: + dir_names.append(results.group(1)) + return dir_names + + # bdir: base directory + # fdir: file directory + def pullApp(self, bdir, fdir): + logging.info("[{}]".format(fdir)) + cdir = bdir + os.path.sep + fdir + try: + check_call(["mkdir", fdir]) + except: + logging.error("ERROR: problem creating directory {}".format(fdir)) + return + logging.info("Pulling data from directory {}".format("/data/data/"+cdir)) + process = Popen(["adb", "pull", "/data/data/"+fdir], stdout=PIPE, stderr=PIPE, cwd=cdir) + stdout, stderr = process.communicate() + return stdout, stderr + + + def isADBRoot(self): + retval = False + process = Popen(["adb", "root"], stdout=PIPE, stderr=PIPE) + stdout, stderr = process.communicate() + # string "adbd is already running as root" will be returned + if (0 < stdout.find('already running')): + retval = True + return retval + diff --git a/libs/fingerprint_comp.py b/libs/fingerprint_comp.py index 59fe90b..9d75657 100644 --- a/libs/fingerprint_comp.py +++ b/libs/fingerprint_comp.py @@ -5,7 +5,7 @@ class FingerprintRunner: """ - Compare Finger Prints + Compare Finger Prints from a directory """ # @@ -13,6 +13,6 @@ class FingerprintRunner: return # - def folderCompare(self, folder): + def dirCompare(self, folder): return diff --git a/tools/pull_android_data.py b/tools/pull_android_data.py index f09f364..db10fe5 100644 --- a/tools/pull_android_data.py +++ b/tools/pull_android_data.py @@ -25,6 +25,7 @@ def androidPullData(): print "Pulling data from directory {}".format("/data/data/"+fdir) process = Popen(["adb", "pull", "/data/data/"+fdir], stdout=PIPE, stderr=PIPE, cwd=fdir) stdout, stderr = process.communicate() + # if stderr: # print "ERROR: {}".format(stderr) # else: