NEW: added -pull feature to pull all android apps from a device

This commit is contained in:
JohnE 2015-10-23 13:17:05 -07:00
parent b243367b5f
commit 9684ea7158
4 changed files with 120 additions and 4 deletions

60
dbfp.py
View File

@ -3,11 +3,17 @@
# #
import argparse import argparse
import time import time
import logging
from libs import fingerprint from libs import fingerprint
from libs import toolbox from libs import toolbox
from libs import android
BASE_DIR = "data"
def main(): def main():
# logging.basicConfig(filename='dbfp.log', level=logging.DEBUG)
logging.basicConfig(level=logging.DEBUG)
parseArgs() parseArgs()
# #
@ -39,6 +45,32 @@ def createFingerprint(filein, fileout, verbose, app_name, app_ver, notes):
else: else:
print db.getErrorString(retVal) 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(): def parseArgs():
print '***** ***** ***** *****' print '***** ***** ***** *****'
@ -53,21 +85,45 @@ def parseArgs():
parser.add_argument('-an', '--app_name', required=False) parser.add_argument('-an', '--app_name', required=False)
parser.add_argument('-av', '--app_version', required=False) parser.add_argument('-av', '--app_version', required=False)
parser.add_argument('-n', '--notes', 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('-v', '--verbose', action='store_true')
# parser.add_argument('-t', '--title', required=False) # parser.add_argument('-t', '--title', required=False)
args = parser.parse_args() 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() 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 # compare a sqlite database file to all fingerprints
if (args.fp and args.fpdir): if (args.fp and args.fpdir):
compareFingerprintDir(args.file, args.fp, args.fpdir) compareFingerprintDir(args.file, args.fp, args.fpdir)
return
# compare a sqlite database file to a fingerprint # compare a sqlite database file to a fingerprint
if (args.fp): if (args.fp):
compareFingerprint(args.file, args.fp) compareFingerprint(args.file, args.fp)
return
# create a fingerprint from the sqlite file # create a fingerprint from the sqlite file
filename = toolbox.ToolBox.parseFilename(args.file) filename = toolbox.ToolBox.parseFilename(args.file)
fileout = filename + "_" + timestr + '.json' fileout = filename + "_" + timestr + '.json'

59
libs/android.py Normal file
View File

@ -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

View File

@ -5,7 +5,7 @@
class FingerprintRunner: class FingerprintRunner:
""" """
Compare Finger Prints Compare Finger Prints from a directory
""" """
# #
@ -13,6 +13,6 @@ class FingerprintRunner:
return return
# #
def folderCompare(self, folder): def dirCompare(self, folder):
return return

View File

@ -25,6 +25,7 @@ def androidPullData():
print "Pulling data from directory {}".format("/data/data/"+fdir) print "Pulling data from directory {}".format("/data/data/"+fdir)
process = Popen(["adb", "pull", "/data/data/"+fdir], stdout=PIPE, stderr=PIPE, cwd=fdir) process = Popen(["adb", "pull", "/data/data/"+fdir], stdout=PIPE, stderr=PIPE, cwd=fdir)
stdout, stderr = process.communicate() stdout, stderr = process.communicate()
# if stderr: # if stderr:
# print "ERROR: {}".format(stderr) # print "ERROR: {}".format(stderr)
# else: # else: