Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updated readme, fridump is a class now and has remote option #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Usage

How to:

fridump [-h] [-o dir] [-u] [-v] [-r] [-s] [--max-size bytes] process
fridump [-h] [-o dir] [-U] [-R] [-v] [-r] [-s] [--max-size bytes] process

The following are the main flags that can be used with fridump:

Expand All @@ -16,7 +16,8 @@ The following are the main flags that can be used with fridump:
optional arguments:
-h, --help show this help message and exit
-o dir, --out dir provide full output directory path. (def: 'dump')
-u, --usb device connected over usb
-U, --usb device connected over usb
-R, --remote device connected over network
-v, --verbose verbose
-r, --read-only dump read-only parts of memory. More data, more errors
-s, --strings run strings on all dump files. Saved in output dir.
Expand All @@ -31,8 +32,8 @@ For a process that is running on a USB connected device, you can use:

Examples:

fridump -u Safari - Dump the memory of an iOS device associated with the Safari app
fridump -u -s com.example.WebApp - Dump the memory of an Android device and run strings on all dump files
fridump -U Safari - Dump the memory of an iOS device associated with the Safari app
fridump -U -s com.example.WebApp - Dump the memory of an Android device and run strings on all dump files
fridump -r -o [full_path] - Dump the memory of a local application and save it to the specified directory

More examples can be found [here](http://pentestcorner.com/introduction-to-fridump/)
Expand Down
315 changes: 165 additions & 150 deletions fridump.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,153 +8,168 @@
import argparse
import logging

logo = """
______ _ _
| ___| (_) | |
| |_ _ __ _ __| |_ _ _ __ ___ _ __
| _| '__| |/ _` | | | | '_ ` _ \| '_ \\
| | | | | | (_| | |_| | | | | | | |_) |
\_| |_| |_|\__,_|\__,_|_| |_| |_| .__/
| |
|_|
"""


# Main Menu
def MENU():
parser = argparse.ArgumentParser(
prog='fridump',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(""))

parser.add_argument('process',
help='the process that you will be injecting to')
parser.add_argument('-o', '--out', type=str, metavar="dir",
help='provide full output directory path. (def: \'dump\')')
parser.add_argument('-U', '--usb', action='store_true',
help='device connected over usb')
parser.add_argument('-v', '--verbose', action='store_true',
help='verbose')
parser.add_argument('-r', '--read-only', action='store_true',
help="dump read-only parts of memory. More data, more errors")
parser.add_argument('-s', '--strings', action='store_true',
help='run strings on all dump files. Saved in output dir.')
parser.add_argument('--max-size', type=int, metavar="bytes",
help='maximum size of dump file in bytes (def: 20971520)')
args = parser.parse_args()
return args


print(logo)

arguments = MENU()

# Define Configurations
APP_NAME = arguments.process
DIRECTORY = ""
USB = arguments.usb
DEBUG_LEVEL = logging.INFO
STRINGS = arguments.strings
MAX_SIZE = 20971520
PERMS = 'rw-'

if arguments.read_only:
PERMS = 'r--'

if arguments.verbose:
DEBUG_LEVEL = logging.DEBUG
logging.basicConfig(format='%(levelname)s:%(message)s', level=DEBUG_LEVEL)


# Start a new Session
session = None
try:
if USB:
session = frida.get_usb_device().attach(APP_NAME)
else:
session = frida.attach(APP_NAME)
except Exception as e:
print("Can't connect to App. Have you connected the device?")
logging.debug(str(e))
sys.exit()


# Selecting Output directory
if arguments.out is not None:
DIRECTORY = arguments.out
if os.path.isdir(DIRECTORY):
print("Output directory is set to: " + DIRECTORY)
else:
print("The selected output directory does not exist!")
sys.exit(1)

else:
print("Current Directory: " + str(os.getcwd()))
DIRECTORY = os.path.join(os.getcwd(), "dump")
print("Output directory is set to: " + DIRECTORY)
if not os.path.exists(DIRECTORY):
print("Creating directory...")
os.makedirs(DIRECTORY)

mem_access_viol = ""

print("Starting Memory dump...")

script = session.create_script(
"""'use strict';

rpc.exports = {
enumerateRanges: function (prot) {
return Process.enumerateRangesSync(prot);
},
readMemory: function (address, size) {
return Memory.readByteArray(ptr(address), size);
}
};

""")
script.on("message", utils.on_message)
script.load()

agent = script.exports
ranges = agent.enumerate_ranges(PERMS)

if arguments.max_size is not None:
MAX_SIZE = arguments.max_size

i = 0
l = len(ranges)

# Performing the memory dump
for range in ranges:
base = range["base"]
size = range["size"]

logging.debug("Base Address: " + str(base))
logging.debug("")
logging.debug("Size: " + str(size))


if size > MAX_SIZE:
logging.debug("Too big, splitting the dump into chunks")
mem_access_viol = dumper.splitter(
agent, base, size, MAX_SIZE, mem_access_viol, DIRECTORY)
continue
mem_access_viol = dumper.dump_to_file(
agent, base, size, mem_access_viol, DIRECTORY)
i += 1
utils.printProgress(i, l, prefix='Progress:', suffix='Complete', bar=50)
print("")

# Run Strings if selected

if STRINGS:
files = os.listdir(DIRECTORY)
i = 0
l = len(files)
print("Running strings on all files:")
for f1 in files:
utils.strings(f1, DIRECTORY)
i += 1
utils.printProgress(i, l, prefix='Progress:', suffix='Complete', bar=50)
print("Finished!")


class Fridump:

def __init__(self, App_Name = None, Directory = None, USB = False, Remote = False, Debug_Level = logging.INFO, Strings = False, Max_Size = 20971520, Perms = 'rw-'):
self.arguments = None
self.session = None
self.parser = None
self.App_Name = App_Name
self.Directory = Directory
self.USB = USB
self.Remote = Remote
self.Debug_Level = Debug_Level
self.Strings = Strings
self.Max_Size = Max_Size
self.Perms = Perms
self.mem_access_viol = ""

def MENU(self):
logo = """
______ _ _
| ___| (_) | |
| |_ _ __ _ __| |_ _ _ __ ___ _ __
| _| '__| |/ _` | | | | '_ ` _ \| '_ \\
| | | | | | (_| | |_| | | | | | | |_) |
\_| |_| |_|\__,_|\__,_|_| |_| |_| .__/
| |
|_|
"""

self.parser = argparse.ArgumentParser(
prog='fridump',
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(""))
self.parser.add_argument('process',
help='the process that you will be injecting to')
self.parser.add_argument('-o', '--out', type=str, metavar="dir",
help='provide full output directory path. (def: \'dump\')')
self.parser.add_argument('-U', '--usb', action='store_true',
help='device connected over usb')
self.parser.add_argument('-R', '--remote', action='store_true',
help='device connected over network')
self.parser.add_argument('-v', '--verbose', action='store_true',
help='verbose')
self.parser.add_argument('-r', '--read_only', action='store_true',
help="dump read-only parts of memory. More data, more errors")
self.parser.add_argument('-s', '--strings', action='store_true',
help='run strings on all dump files. Saved in output dir.')
self.parser.add_argument('--max-size', type=int, metavar="bytes",
help='maximum size of dump file in bytes (def: 20971520)')

#Used to assing parsed information
self.arguments = self.parser.parse_args()
self.USB = self.arguments.usb
self.Remote = self.arguments.remote
self.Strings = self.arguments.strings
self.App_Name = self.arguments.process
self.Directory = self.arguments.out

if self.arguments.read_only:
self.Perms = 'r--'
else:
self.Perms = 'rw--'
self.Debug_Level = self.arguments.verbose

print(logo)

def String(self):
files = os.listdir(self.Directory)
i = 0
l = len(files)
for f1 in files:
utils.strings(f1, self.Directory)
i += 1
utils.printProgress(i, l, prefix='Progress:', suffix='Complete', bar=50)
print("Finished!")

def Session(self):
print(self.App_Name)
try:
if self.USB:
self.session = frida.get_usb_device().attach(self.App_Name)
elif self.Remote:
self.session = frida.get_remote_device().attach(self.App_Name)
else:
self.session = frida.attach(self.App_Name)
except Exception as e:
print("Cant connect to application. Have you connected the device?")
logging.debug(str(e))
sys.exit()

def Dir(self):

if self.Directory != None:
print(self.Directory)
if os.path.isdir(self.Directory):
print("Output directory is set to: ", self.Directory)
else:
print("The selected output directory does not exist!")
sys.exit(1)
else:
print("Current directory: ", str(os.getcwd()))
place = os.path.join(os.getcwd(), "dump")
self.Directory = place
if not os.path.exists(place):
print("Creating directory...")
os.makedirs(place)

def Script(self):

print("Starting Memory dump...")
script = self.session.create_script(
"""'use strict';

rpc.exports = {
enumerateRanges: function (prot) {
return Process.enumerateRangesSync(prot);
},
readMemory: function (address, size) {
return Memory.readByteArray(ptr(address), size);
}
};

""")
script.on("message", utils.on_message)
script.load()

agent = script.exports
print(self.Perms)
ranges = agent.enumerate_ranges(self.Perms)

if self.Max_Size is not None:
MAX_SIZE = self.Max_Size

i = 0
l = len(ranges)

# Performing the memory dump
for range in ranges:
base = range["base"]
size = range["size"]

logging.debug("Base Address: " + str(base))
logging.debug("")
logging.debug("Size: " + str(size))

if size > MAX_SIZE:
logging.debug("Too big, splitting the dump into chunks")
self.mem_access_viol = dumper.splitter(
agent, base, size, MAX_SIZE, self.mem_access_viol, self.Directory)
continue
self.mem_access_viol = dumper.dump_to_file(
agent, base, size, self.mem_access_viol, self.Directory)
i += 1
utils.printProgress(i, l, prefix='Progress:', suffix='Complete', bar=50)
print("")

if self.Strings:
self.String()

testobj = Fridump( )
testobj.MENU()
testobj.Session()
testobj.Dir()
testobj.Script()