def test_info(self): usb = self.usb local = self.local self.assertIsInstance(core.device_type(local), str) # need an iOS device self.assertEqual(core.device_type(usb), 'iOS') self.assertIsInstance(core.devices(), list) self.assertIsInstance(core.ps(local), list) self.assertIsInstance(core.apps(usb), list)
def main(args): from backend import core, rpc, syslog from backend.file import upload, download from backend.fs import FileSystem if args.action == 'devices': return core.devices() if not args.device: raise RuntimeError('NOTREACHED') device = core.get_device(args.device) if args.action == 'ps': return core.ps(device) if args.action == 'apps': return core.apps(device) if args.action == 'type': return core.device_type(device) target = args.pid or args.name agent = rpc.ProcessAgent(device, target) if target else \ rpc.AppAgent(device, args.app) agent.load() if args.action == 'rpc': return agent.invoke(args.method, *args.args) if args.action == 'syslog': syslog.pipe(agent) return fs = FileSystem(agent) if args.action == 'fs': method = getattr(fs, args.method) return method(*args.args) if args.action == 'download': download(fs, args.path) return if args.action == 'upload': upload(fs, args.path) return raise RuntimeError('NOTREACHED')
def test_fs(self): usb = frida.get_usb_device() self.assertEqual(device_type(usb), 'iOS', 'this unittest only works for iOS') agent = AppAgent(usb, 'com.apple.Preferences') agent.load() fs = FileSystem(agent) self.assertIsInstance(fs.ls('/etc'), list) self.assertIsInstance(fs.ls('~/tmp'), list) self.assertIsInstance(fs.read('/etc/passwd'), bytes) fs.cp('/etc/passwd', '~/tmp/test') fs.rm('~/tmp/test') fs.mkdir('~/tmp/testdir') fs.rm('~/tmp/testdir', json.dumps({'recursive': True})) self.assertIsInstance(fs.stat('~/tmp'), dict)
def setup(device: frida.core.Device): if device_type(device) != 'iOS': raise ValueError('This command is for iOS only') if installed(device): return True with (Path(__file__).parent / 'ent.xml').open('r') as fp: content = fp.read() pid = device.spawn('/bin/sh') session = device.attach(pid) script = session.create_script(read_agent()) script.load() script.exports.sign_debugserver(content) session.detach() device.kill(pid) return True
def install(device: frida.core.Device): if device_type(device) != 'iOS': raise ValueError('This command is for iOS only') pubkey = Path.home() / '.ssh' / 'id_rsa.pub' if not (pubkey.exists() and pubkey.is_file()): raise RuntimeError('id_rsa.pub does not exists') with pubkey.open('r') as fp: content = fp.read().strip() pid = device.spawn('/bin/sh') session = device.attach(pid) script = session.create_script(read_agent()) script.load() script.exports.copyid(content) session.detach() device.kill(pid) return True
def main(args): from backend import core, rpc, syslog from backend.file import upload, download from backend.fs import FileSystem from backend.ios.copyid import install from backend.ios.debugserver import setup from backend.ios.installer import apps if args.action == 'devices': return core.devices() if not args.device: raise RuntimeError('NOTREACHED') device = core.get_device(args.device) if args.action == 'ps': return core.ps(device) if args.action == 'apps': return core.apps(device) if args.action == 'type': return core.device_type(device) if args.action == 'ssh-copy-id': return install(device) if args.action == 'sign-debugserver': return setup(device) if args.action == 'port': return core.find_port(device) if args.action == 'location': return next(app['Path'] for app in apps(device) if app['CFBundleIdentifier'] == args.bundle) target = args.pid or args.name agent = rpc.ProcessAgent(device, target) if target else \ rpc.AppAgent(device, args.app) agent.load() if args.action == 'rpc': return agent.invoke(args.method, *args.args) if args.action == 'syslog': syslog.pipe(agent) return fs = FileSystem(agent) if args.action == 'fs': method = getattr(fs, args.method) return method(*args.args) if args.action == 'download': download(fs, args.path) return if args.action == 'upload': upload(fs, args.path) return raise RuntimeError('NOTREACHED')