Skip to content

Instantly share code, notes, and snippets.

@jpstotz
Created April 3, 2025 09:20
Show Gist options
  • Select an option

  • Save jpstotz/7fc7303783ed4e7af5662748ef1104c9 to your computer and use it in GitHub Desktop.

Select an option

Save jpstotz/7fc7303783ed4e7af5662748ef1104c9 to your computer and use it in GitHub Desktop.

Revisions

  1. jpstotz created this gist Apr 3, 2025.
    47 changes: 47 additions & 0 deletions prepare-frida-gadget.py
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,47 @@
    # Automatically download the iOS gadget file for the currently used Frida version.
    # The gadget .xz file is downloaded to the same directory where frida expects the
    # gadget dylib. After download the file is decompresed and written to gadget-ios.dylib

    import os
    import shutil
    import sys
    from pathlib import Path
    import logging

    import requests
    import frida
    import lzma

    logging.basicConfig(stream=sys.stderr, level=logging.INFO, format='[%(levelname)5s] %(message)s', datefmt='%H:%M:%S')

    frida_ver = frida.__version__

    gadget_filename = f'frida-gadget-{frida_ver}-ios-universal.dylib.xz'

    cache_dir = os.environ.get('XDG_CACHE_HOME')
    if cache_dir is None:
    cache_dir = os.path.join(Path.home(), '.cache')

    frida_dir = os.path.join(cache_dir, 'frida')
    os.makedirs(frida_dir, exist_ok=True)

    frida_gadget_file = os.path.join(frida_dir, 'gadget-ios.dylib') # file that Frida expects
    downloaded_gadget_file = os.path.join(frida_dir, gadget_filename)

    if os.path.exists(downloaded_gadget_file):
    logging.info('Download gadget already exists: %s', downloaded_gadget_file)
    else:
    logging.info('Download frida-gadget-%s-ios-universal.dylib.xz to %s', frida_ver, downloaded_gadget_file)
    download_url = f'https://github.com/frida/frida/releases/download/{frida_ver}/{gadget_filename}'
    tmp_file = downloaded_gadget_file + '.tmp'
    with requests.get(download_url, stream=True) as response:
    response.raise_for_status()
    with open(tmp_file, 'wb') as out_file:
    shutil.copyfileobj(response.raw, out_file)
    os.replace(tmp_file, downloaded_gadget_file)


    logging.info("Decompressing %s to %s", downloaded_gadget_file, frida_gadget_file)
    with open(frida_gadget_file, 'wb') as out_file:
    with lzma.LZMAFile(downloaded_gadget_file, mode='rb') as uncompressed:
    shutil.copyfileobj(uncompressed, out_file)