Skip to content

Instantly share code, notes, and snippets.

@miticollo
Last active October 17, 2024 03:27
Show Gist options
  • Save miticollo/6e65b59d83b17bacc00523a0f9d41c11 to your computer and use it in GitHub Desktop.
Save miticollo/6e65b59d83b17bacc00523a0f9d41c11 to your computer and use it in GitHub Desktop.
How to build frida server for iOS jailbroken devices

Here, I'll show you how to compile Frida for both rootfull and rootless jailbreaks.

TL;DR

On Dopamine/Fugu15 Max or palera1n you can add my repo (open the link in your favorite browser on your jailbroken iDevice).

The DEBs you will install are build using the following instructions.

Update 2024-02-29

Starting from version 16.1.5 Frida supports rootless and rootfull JB. So you can add https://build.frida.re/ to your package manager.

New Instructions

If you want to compile a new version of Frida (≥ 16.2.2) you can use my new guide.

Build Instructions

Requirements

macOS

macOS is required because you need to use Apple's proprietary software like Xcode, lipo, and codesign.

Warning
Before starting, read carefully up to the end.

Build

  1. Install the latest version of Xcode with command-line tools from the App Store. Without it, you won't have iPhoneOS SDKs.
  2. Download Xcode 11.7 directly from Apple at the following link: Xcode_11.7.xip. You will need to authenticate with your Apple ID to download it.
Tip

To better manage multiple Xcode versions, you can use a CLI tool called xcodes. Alternatively, if you prefer an equivalent GUI app, you can use XcodesApp.

  1. Once downloaded, opening the .xip archive will begin extracting it. After extraction, rename the app to avoid conflicting with your primary installation of Xcode and move it to /Applications/ (e.g., mv Xcode.app /Applications/Xcode-11.7.app).

  2. Download this script, change gdb_codesign to frida-cert, and then run it.

  3. Run brew install dpkg to install dpkg-deb.

  4. Clone the project:

    git clone --recurse-submodules https://github.com/frida/frida.git
    cd frida
  5. (Optional) Check out the latest stable release:

    git checkout "$(git describe --tags $(git rev-list --tags --max-count=1))"

    To go back to origin/main, run git switch -.

  6. (Optional) Select your preferred Xcode version:

    export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer   
    
  7. Export the identity previously created in an enviroment variable called IOS_CERTID:

    export IOS_CERTID=frida-cert
  8. Build frida-server and frida-agent.dylib for 3 different architectures:

    • rootless
      make build/frida-ios-{arm64e,arm64,arm64eoabi}/var/jb/usr/lib/pkgconfig/frida-core-1.0.pc
    • rootfull
      make build/frida-ios-{arm64e,arm64,arm64eoabi}/usr/lib/pkgconfig/frida-core-1.0.pc

    Note
    To properly instrument all applications, all necessary architectures must be in place. For instance, to instrument Safari, the frida-agent.dylib for ARM64e is required. However, for Spotify, the required architecture is ARM64. If the frida-agent.dylib does not contain both slices, you will likely encounter an Incompatible Mach-O image error when using the frida CLI tool.
    To check what I said, compare the output of the following two commands:

    file /Applications/MobileSafari.app/MobileSafari
    file /var/containers/Bundle/Application/<UUID>/Spotify.app/Spotify
  9. Make the universal frida-server and frida-agent.dylib

    • rootless
      mkdir -vp ./build/frida-ios-universal/var/jb/usr/{bin,lib/frida}/
      python ./releng/mkfatmacho.py ./build/frida-ios-{universal,arm64,arm64e,arm64eoabi}/var/jb/usr/bin/frida-server
      lipo ./build/frida-ios-{arm64,arm64e}/var/jb/usr/lib/frida/frida-agent.dylib -create -output ./build/frida-ios-universal/var/jb/usr/lib/frida/frida-agent.dylib
      install_name_tool -id 'FridaAgent' ./build/frida-ios-universal/var/jb/usr/lib/frida/frida-agent.dylib
      codesign -s "$IOS_CERTID" -fv --timestamp=none --generate-entitlement-der ./build/frida-ios-universal/var/jb/usr/lib/frida/frida-agent.dylib
    • rootfull
      mkdir -vp ./build/frida-ios-universal/usr/{bin,lib/frida}/
      python ./releng/mkfatmacho.py ./build/frida-ios-{universal,arm64,arm64e,arm64eoabi}/usr/bin/frida-server
      lipo ./build/frida-ios-{arm64,arm64e}/usr/lib/frida/frida-agent.dylib -create -output ./build/frida-ios-universal/usr/lib/frida/frida-agent.dylib
      install_name_tool -id 'FridaAgent' ./build/frida-ios-universal/usr/lib/frida/frida-agent.dylib
      codesign -s "$IOS_CERTID" -fv --timestamp=none --generate-entitlement-der ./build/frida-ios-universal/usr/lib/frida/frida-agent.dylib
  10. (Optional) Fake signing frida-server:

    ldid -S -M './build/frida-ios-universal/var/jb/usr/bin/frida-server'

    Note
    I ran this command because otherwise on Dopamine/Fugu15 Max JB frida-server was being Killed: 9.

  11. Package everything into a DEB file:

    export FRIDA_VERSION=$(releng/frida_version.py)
    • rootless
      ./frida-core/tools/package-server-fruity.sh 'iphoneos-arm64' build/frida-ios-universal/var/jb build/"frida_${FRIDA_VERSION}_iphoneos-universal.deb"
    • rootfull
      ./frida-core/tools/package-server-fruity.sh 'iphoneos-arm' build/frida-ios-universal build/"frida_${FRIDA_VERSION}_iphoneos-universal.deb"
  12. Check the build/ directory to find your DEB file. Enjoy!

Rootless

To get the rootless version of frida, you need to edit the following files:

You can find an example based on Frida 16.1.4 in this gist.

Now go to step 8.

How to upgrade

  1. Go back to origin/main
    git switch -
  2. Pull new commits
    git pull --recurse-submodules
  3. If necessary solve conflicts.
  4. Now go to step 7.

Clean up

  1. Run
     make clean distclean
  2. Go to step 8.
include config.mk
build_arch := $(shell releng/detect-arch.sh)
ios_arm64eoabi_target := $(shell test -d /Applications/Xcode-11.7.app && echo build/frida-ios-arm64eoabi/usr/lib/pkgconfig/frida-core-1.0.pc)
test_args := $(addprefix -p=,$(tests))
HELP_FUN = \
my (%help, @sections); \
while(<>) { \
if (/^([\w-]+)\s*:.*\#\#(?:@([\w-]+))?\s(.*)$$/) { \
$$section = $$2 // 'options'; \
push @sections, $$section unless exists $$help{$$section}; \
push @{$$help{$$section}}, [$$1, $$3]; \
} \
} \
$$target_color = "\033[32m"; \
$$variable_color = "\033[36m"; \
$$reset_color = "\033[0m"; \
print "\n"; \
print "\033[31mUsage:$${reset_color} make $${target_color}TARGET$${reset_color} [$${variable_color}VARIABLE$${reset_color}=value]\n\n"; \
print "Where $${target_color}TARGET$${reset_color} specifies one or more of:\n"; \
print "\n"; \
for (@sections) { \
print " /* $$_ */\n"; $$sep = " " x (23 - length $$_->[0]); \
printf(" $${target_color}%-23s$${reset_color} %s\n", $$_->[0], $$_->[1]) for @{$$help{$$_}}; \
print "\n"; \
} \
print "And optionally also $${variable_color}VARIABLE$${reset_color} values:\n"; \
print " $${variable_color}PYTHON$${reset_color} Absolute path of Python interpreter including version suffix\n"; \
print " $${variable_color}NODE$${reset_color} Absolute path of Node.js binary\n"; \
print "\n"; \
print "For example:\n"; \
print " \$$ make $${target_color}python-macos $${variable_color}PYTHON$${reset_color}=/usr/local/bin/python3.6\n"; \
print " \$$ make $${target_color}node-macos $${variable_color}NODE$${reset_color}=/usr/local/bin/node\n"; \
print "\n";
help:
@LC_ALL=C perl -e '$(HELP_FUN)' $(MAKEFILE_LIST)
include releng/frida.mk
distclean: clean-submodules
rm -rf build/
rm -rf deps/
clean: clean-submodules
rm -f build/*-clang*
rm -f build/*-pkg-config
rm -f build/*-stamp
rm -f build/*.rc
rm -f build/*.tar.bz2
rm -f build/*.txt
rm -f build/frida-version.h
rm -rf build/frida-*-*
rm -rf build/frida_thin-*-*
rm -rf build/fs-*-*
rm -rf build/ft-*-*
rm -rf build/tmp-*-*
rm -rf build/tmp_thin-*-*
rm -rf build/fs-tmp-*-*
rm -rf build/ft-tmp-*-*
clean-submodules:
cd frida-gum && git clean -xfd
cd frida-core && git clean -xfd
cd frida-python && git clean -xfd
cd frida-node && git clean -xfd
cd frida-tools && git clean -xfd
define make-ios-env-rule
build/frida-env-ios-$1.rc: releng/setup-env.sh build/frida-version.h
@if [ $1 != $$(build_machine) ]; then \
cross=yes; \
else \
cross=no; \
fi; \
for machine in $$(build_machine) ios-$1; do \
if [ ! -f build/frida-env-$$$$machine.rc ]; then \
FRIDA_HOST=$$$$machine \
FRIDA_CROSS=$$$$cross \
FRIDA_PREFIX="$$(abspath build/frida-ios-$1/var/jb/usr)" \
FRIDA_ASAN=$$(FRIDA_ASAN) \
XCODE11="$$(XCODE11)" \
./releng/setup-env.sh || exit 1; \
fi \
done
endef
$(eval $(call make-ios-env-rule,arm64))
$(eval $(call make-ios-env-rule,arm64e))
$(eval $(call make-ios-env-rule,arm64eoabi))
$(eval $(call make-ios-env-rule,x86_64-simulator))
$(eval $(call make-ios-env-rule,arm64-simulator))
build/frida-ios-%/var/jb/usr/lib/pkgconfig/frida-gum-1.0.pc: build/frida-env-ios-%.rc build/.frida-gum-submodule-stamp
. build/frida-env-ios-$*.rc; \
builddir=build/tmp-ios-$*/frida-gum; \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,ios-$*) \
--prefix /var/jb/usr \
$(frida_gum_flags) \
frida-gum $$builddir || exit 1; \
fi \
&& $(MESON) compile -C $$builddir \
&& DESTDIR="$(abspath build/frida-ios-$*)" $(MESON) install -C $$builddir
@touch $@
build/frida-ios-%/var/jb/usr/lib/pkgconfig/frida-core-1.0.pc: build/.frida-core-submodule-stamp build/frida-ios-%/var/jb/usr/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-ios-$*.rc; \
builddir=build/tmp-ios-$*/frida-core; \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,ios-$*) \
--prefix /var/jb/usr \
$(frida_core_flags) \
-Dassets=installed \
frida-core $$builddir || exit 1; \
fi \
&& $(MESON) compile -C $$builddir \
&& DESTDIR="$(abspath build/frida-ios-$*)" $(MESON) install -C $$builddir
@touch $@
gum-macos: build/frida-macos-$(build_arch)/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for macOS
gum-ios: build/frida-ios-arm64/usr/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for iOS
gum-watchos: build/frida_thin-watchos-arm64/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for watchOS
gum-tvos: build/frida_thin-tvos-arm64/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for tvOS
gum-android-x86: build/frida-android-x86/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for Android/x86
gum-android-x86_64: build/frida-android-x86_64/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for Android/x86-64
gum-android-arm: build/frida-android-arm/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for Android/arm
gum-android-arm64: build/frida-android-arm64/lib/pkgconfig/frida-gum-1.0.pc ##@gum Build for Android/arm64
define make-gum-rules
build/$1-%/lib/pkgconfig/frida-gum-1.0.pc: build/$1-env-%.rc build/.frida-gum-submodule-stamp
. build/$1-env-$$*.rc; \
builddir=build/$2-$$*/frida-gum; \
if [ ! -f $$$$builddir/build.ninja ]; then \
$$(call meson-setup-for-env,$1,$$*) \
--prefix $$(FRIDA)/build/$1-$$* \
$$(frida_gum_flags) \
frida-gum $$$$builddir || exit 1; \
fi; \
$$(MESON) install -C $$$$builddir || exit 1
@touch -c $$@
endef
$(eval $(call make-gum-rules,frida,tmp))
$(eval $(call make-gum-rules,frida_thin,tmp_thin))
ifeq ($(build_arch), arm64)
check-gum-macos: build/frida-macos-arm64/lib/pkgconfig/frida-gum-1.0.pc build/frida-macos-arm64e/lib/pkgconfig/frida-gum-1.0.pc ##@gum Run tests for macOS
build/tmp-macos-arm64/frida-gum/tests/gum-tests $(test_args)
runner=build/tmp-macos-arm64e/frida-gum/tests/gum-tests; \
if $$runner --help &>/dev/null; then \
$$runner $(test_args); \
fi
else
check-gum-macos: build/frida-macos-x86_64/lib/pkgconfig/frida-gum-1.0.pc
build/tmp-macos-x86_64/frida-gum/tests/gum-tests $(test_args)
endif
core-macos: build/frida-macos-$(build_arch)/lib/pkgconfig/frida-core-1.0.pc ##@core Build for macOS
core-ios: build/frida-ios-arm64/usr/lib/pkgconfig/frida-core-1.0.pc ##@core Build for iOS
core-watchos: build/frida_thin-watchos-arm64/lib/pkgconfig/frida-core-1.0.pc ##@core Build for watchOS
core-tvos: build/frida_thin-tvos-arm64/lib/pkgconfig/frida-core-1.0.pc ##@core Build for tvOS
core-android-x86: build/frida-android-x86/lib/pkgconfig/frida-core-1.0.pc ##@core Build for Android/x86
core-android-x86_64: build/frida-android-x86_64/lib/pkgconfig/frida-core-1.0.pc ##@core Build for Android/x86-64
core-android-arm: build/frida-android-arm/lib/pkgconfig/frida-core-1.0.pc ##@core Build for Android/arm
core-android-arm64: build/frida-android-arm64/lib/pkgconfig/frida-core-1.0.pc ##@core Build for Android/arm64
build/tmp-macos-arm64/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-macos-arm64/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-macos-arm64.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,macos-arm64) \
--prefix $(FRIDA)/build/frida-macos-arm64 \
$(frida_core_flags) \
-Dhelper_modern=$(FRIDA)/build/tmp-macos-arm64e/frida-core/src/frida-helper \
-Dhelper_legacy=$(FRIDA)/build/tmp-macos-arm64/frida-core/src/frida-helper \
-Dagent_modern=$(FRIDA)/build/tmp-macos-arm64e/frida-core/lib/agent/frida-agent.dylib \
-Dagent_legacy=$(FRIDA)/build/tmp-macos-arm64/frida-core/lib/agent/frida-agent.dylib \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-macos-arm64e/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-macos-arm64e/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-macos-arm64e.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,macos-arm64e) \
--prefix $(FRIDA)/build/frida-macos-arm64e \
$(frida_core_flags) \
-Dhelper_modern=$(FRIDA)/build/tmp-macos-arm64e/frida-core/src/frida-helper \
-Dhelper_legacy=$(FRIDA)/build/tmp-macos-arm64/frida-core/src/frida-helper \
-Dagent_modern=$(FRIDA)/build/tmp-macos-arm64e/frida-core/lib/agent/frida-agent.dylib \
-Dagent_legacy=$(FRIDA)/build/tmp-macos-arm64/frida-core/lib/agent/frida-agent.dylib \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-macos-x86_64/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-macos-x86_64/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-macos-x86_64.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,macos-x86_64) \
--prefix $(FRIDA)/build/frida-macos-x86_64 \
$(frida_core_flags) \
-Dhelper_modern=$(FRIDA)/build/tmp-macos-x86_64/frida-core/src/frida-helper \
-Dagent_modern=$(FRIDA)/build/tmp-macos-x86_64/frida-core/lib/agent/frida-agent.dylib \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-android-x86/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-android-x86/lib/pkgconfig/frida-gum-1.0.pc
if [ "$(FRIDA_AGENT_EMULATED)" == "yes" ]; then \
agent_emulated_legacy=$(FRIDA)/build/tmp-android-arm/frida-core/lib/agent/frida-agent.so; \
fi; \
. build/frida-env-android-x86.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,android-x86) \
--prefix $(FRIDA)/build/frida-android-x86 \
$(frida_core_flags) \
-Dagent_emulated_legacy=$$agent_emulated_legacy \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-android-x86_64/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-android-x86_64/lib/pkgconfig/frida-gum-1.0.pc
if [ "$(FRIDA_AGENT_EMULATED)" == "yes" ]; then \
agent_emulated_modern=$(FRIDA)/build/tmp-android-arm64/frida-core/lib/agent/frida-agent.so; \
agent_emulated_legacy=$(FRIDA)/build/tmp-android-arm/frida-core/lib/agent/frida-agent.so; \
fi; \
. build/frida-env-android-x86_64.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,android-x86_64) \
--prefix $(FRIDA)/build/frida-android-x86_64 \
$(frida_core_flags) \
-Dhelper_modern=$(FRIDA)/build/tmp-android-x86_64/frida-core/src/frida-helper \
-Dhelper_legacy=$(FRIDA)/build/tmp-android-x86/frida-core/src/frida-helper \
-Dagent_modern=$(FRIDA)/build/tmp-android-x86_64/frida-core/lib/agent/frida-agent.so \
-Dagent_legacy=$(FRIDA)/build/tmp-android-x86/frida-core/lib/agent/frida-agent.so \
-Dagent_emulated_modern=$$agent_emulated_modern \
-Dagent_emulated_legacy=$$agent_emulated_legacy \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-android-arm/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-android-arm/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-android-arm.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,android-arm) \
--prefix $(FRIDA)/build/frida-android-arm \
$(frida_core_flags) \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp-android-arm64/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida-android-arm64/lib/pkgconfig/frida-gum-1.0.pc
. build/frida-env-android-arm64.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup,android-arm64) \
--prefix $(FRIDA)/build/frida-android-arm64 \
$(frida_core_flags) \
-Dhelper_modern=$(FRIDA)/build/tmp-android-arm64/frida-core/src/frida-helper \
-Dhelper_legacy=$(FRIDA)/build/tmp-android-arm/frida-core/src/frida-helper \
-Dagent_modern=$(FRIDA)/build/tmp-android-arm64/frida-core/lib/agent/frida-agent.so \
-Dagent_legacy=$(FRIDA)/build/tmp-android-arm/frida-core/lib/agent/frida-agent.so \
frida-core $$builddir || exit 1; \
fi
@touch $@
build/tmp_thin-%/frida-core/.frida-ninja-stamp: build/.frida-core-submodule-stamp build/frida_thin-%/lib/pkgconfig/frida-gum-1.0.pc
. build/frida_thin-env-$*.rc; \
builddir=$(@D); \
if [ ! -f $$builddir/build.ninja ]; then \
$(call meson-setup-thin,$*) \
--prefix $(FRIDA)/build/frida_thin-$* \
$(frida_core_flags) \
frida-core $$builddir || exit 1; \
fi
@touch $@
ifeq ($(FRIDA_AGENT_EMULATED), yes)
legacy_agent_emulated_dep := build/tmp-android-arm/frida-core/.frida-agent-stamp
modern_agent_emulated_dep := build/tmp-android-arm64/frida-core/.frida-agent-stamp
endif
build/frida-macos-x86_64/lib/pkgconfig/frida-core-1.0.pc: build/tmp-macos-x86_64/frida-core/.frida-helper-and-agent-stamp
@rm -f build/tmp-macos-x86_64/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-macos-x86_64.rc && $(MESON) install -C build/tmp-macos-x86_64/frida-core
@touch $@
build/frida-macos-arm64/lib/pkgconfig/frida-core-1.0.pc: build/tmp-macos-arm64/frida-core/.frida-helper-and-agent-stamp build/tmp-macos-arm64e/frida-core/.frida-helper-and-agent-stamp
@rm -f build/tmp-macos-arm64/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-macos-arm64.rc && $(MESON) install -C build/tmp-macos-arm64/frida-core
@touch $@
build/frida-macos-arm64e/lib/pkgconfig/frida-core-1.0.pc: build/tmp-macos-arm64/frida-core/.frida-helper-and-agent-stamp build/tmp-macos-arm64e/frida-core/.frida-helper-and-agent-stamp
@rm -f build/tmp-macos-arm64e/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-macos-arm64e.rc && $(MESON) install -C build/tmp-macos-arm64e/frida-core
@touch $@
build/frida-android-x86/lib/pkgconfig/frida-core-1.0.pc: build/tmp-android-x86/frida-core/.frida-helper-and-agent-stamp $(legacy_agent_emulated_dep)
@rm -f build/tmp-android-x86/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-android-x86.rc && $(MESON) install -C build/tmp-android-x86/frida-core
@touch $@
build/frida-android-x86_64/lib/pkgconfig/frida-core-1.0.pc: build/tmp-android-x86/frida-core/.frida-helper-and-agent-stamp build/tmp-android-x86_64/frida-core/.frida-helper-and-agent-stamp $(legacy_agent_emulated_dep) $(modern_agent_emulated_dep)
@rm -f build/tmp-android-x86_64/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-android-x86_64.rc && $(MESON) install -C build/tmp-android-x86_64/frida-core
@touch $@
build/frida-android-arm/lib/pkgconfig/frida-core-1.0.pc: build/tmp-android-arm/frida-core/.frida-helper-and-agent-stamp
@rm -f build/tmp-android-arm/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-android-arm.rc && $(MESON) install -C build/tmp-android-arm/frida-core
@touch $@
build/frida-android-arm64/lib/pkgconfig/frida-core-1.0.pc: build/tmp-android-arm/frida-core/.frida-helper-and-agent-stamp build/tmp-android-arm64/frida-core/.frida-helper-and-agent-stamp
@rm -f build/tmp-android-arm64/frida-core/src/frida-data-{helper,agent}*
. build/frida-env-android-arm64.rc && $(MESON) install -C build/tmp-android-arm64/frida-core
@touch $@
build/frida_thin-%/lib/pkgconfig/frida-core-1.0.pc: build/tmp_thin-%/frida-core/.frida-ninja-stamp
. build/frida_thin-env-$*.rc && $(MESON) install -C build/tmp_thin-$*/frida-core
@touch $@
build/tmp-macos-%/frida-core/.frida-helper-and-agent-stamp: build/tmp-macos-%/frida-core/.frida-ninja-stamp
. build/frida-env-macos-$*.rc && ninja -C build/tmp-macos-$*/frida-core src/frida-helper lib/agent/frida-agent.dylib
@touch $@
build/tmp-macos-%/frida-core/.frida-agent-stamp: build/tmp-macos-%/frida-core/.frida-ninja-stamp
. build/frida-env-macos-$*.rc && ninja -C build/tmp-macos-$*/frida-core lib/agent/frida-agent.dylib
@touch $@
build/tmp-android-%/frida-core/.frida-helper-and-agent-stamp: build/tmp-android-%/frida-core/.frida-ninja-stamp
. build/frida-env-android-$*.rc && ninja -C build/tmp-android-$*/frida-core src/frida-helper lib/agent/frida-agent.so
@touch $@
build/tmp-android-%/frida-core/.frida-agent-stamp: build/tmp-android-%/frida-core/.frida-ninja-stamp
. build/frida-env-android-$*.rc && ninja -C build/tmp-android-$*/frida-core lib/agent/frida-agent.so
@touch $@
ifeq ($(build_arch), arm64)
check-core-macos: build/frida-macos-arm64/lib/pkgconfig/frida-core-1.0.pc build/frida-macos-arm64e/lib/pkgconfig/frida-core-1.0.pc ##@core Run tests for macOS
build/tmp-macos-arm64/frida-core/tests/frida-tests $(test_args)
runner=build/tmp-macos-arm64e/frida-core/tests/frida-tests; \
if $$runner --help &>/dev/null; then \
$$runner $(test_args); \
fi
else
check-core-macos: build/frida-macos-x86_64/lib/pkgconfig/frida-core-1.0.pc
build/tmp-macos-x86_64/frida-core/tests/frida-tests $(test_args)
endif
python-macos: build/tmp-macos-$(build_arch)/frida-$(PYTHON_NAME)/.frida-stamp ##@python Build Python bindings for macOS
define make-python-rule
build/$2-%/frida-$$(PYTHON_NAME)/.frida-stamp: build/.frida-python-submodule-stamp build/$1-%$(PYTHON_PREFIX)/lib/pkgconfig/frida-core-1.0.pc
. build/$1-env-$$*.rc; \
builddir=$$(@D); \
if [ ! -f $$$$builddir/build.ninja ]; then \
$$(call meson-setup-for-env,$1,$$*) \
--prefix $$(FRIDA)/build/$1-$$*$(PYTHON_PREFIX) \
$$(FRIDA_FLAGS_COMMON) \
-Dpython=$$(PYTHON) \
-Dpython_incdir=$$(PYTHON_INCDIR) \
frida-python $$$$builddir || exit 1; \
fi; \
$$(MESON) install -C $$$$builddir || exit 1
@touch $$@
endef
$(eval $(call make-python-rule,frida,tmp))
$(eval $(call make-python-rule,frida_thin,tmp_thin))
check-python-macos: python-macos ##@python Test Python bindings for macOS
export PYTHONPATH="$(shell pwd)/build/frida-macos-$(build_arch)/lib/$(PYTHON_NAME)/site-packages" \
&& cd frida-python \
&& $(PYTHON) -m unittest discover
node-macos: build/frida-macos-$(build_arch)/lib/node_modules/frida ##@node Build Node.js bindings for macOS
define make-node-rule
build/$1-%/lib/node_modules/frida: build/$1-%/lib/pkgconfig/frida-core-1.0.pc build/.frida-node-submodule-stamp
@$$(NPM) --version &>/dev/null || (echo -e "\033[31mOops. It appears Node.js is not installed.\nCheck PATH or set NODE to the absolute path of your Node.js binary.\033[0m"; exit 1;)
export PATH=$$(NODE_BIN_DIR):$$$$PATH FRIDA=$$(FRIDA) \
&& cd frida-node \
&& rm -rf frida-0.0.0.tgz build node_modules \
&& $$(NPM) install \
&& $$(NPM) pack \
&& rm -rf ../$$@/ ../[email protected]/ \
&& mkdir -p ../[email protected]/build/ \
&& tar -C ../[email protected]/ --strip-components 1 -x -f frida-0.0.0.tgz \
&& rm frida-0.0.0.tgz \
&& mv build/Release/frida_binding.node ../[email protected]/build/ \
&& rm -rf build \
&& mv node_modules ../[email protected]/ \
&& mv ../[email protected] ../$$@
endef
$(eval $(call make-node-rule,frida,tmp))
$(eval $(call make-node-rule,frida_thin,tmp_thin))
define run-node-tests
export PATH=$3:$$PATH FRIDA=$2 \
&& cd frida-node \
&& git clean -xfd \
&& $5 install \
&& $4 \
--expose-gc \
../build/$1/lib/node_modules/frida/node_modules/.bin/_mocha \
-r ts-node/register \
--timeout 60000 \
test/*.ts
endef
check-node-macos: node-macos ##@node Test Node.js bindings for macOS
$(call run-node-tests,frida-macos-$(build_arch),$(FRIDA),$(NODE_BIN_DIR),$(NODE),$(NPM))
tools-macos: build/tmp-macos-$(build_arch)/frida-tools-$(PYTHON_NAME)/.frida-stamp ##@tools Build CLI tools for macOS
define make-tools-rule
build/$2-%/frida-tools-$$(PYTHON_NAME)/.frida-stamp: build/.frida-tools-submodule-stamp build/$2-%/frida-$$(PYTHON_NAME)/.frida-stamp
. build/$1-env-$$*.rc; \
builddir=$$(@D); \
if [ ! -f $$$$builddir/build.ninja ]; then \
$$(call meson-setup-for-env,$1,$$*) \
--prefix $$(FRIDA)/build/$1-$$* \
-Dpython=$$(PYTHON) \
frida-tools $$$$builddir || exit 1; \
fi; \
$$(MESON) install -C $$$$builddir || exit 1
@touch $$@
endef
$(eval $(call make-tools-rule,frida,tmp))
$(eval $(call make-tools-rule,frida_thin,tmp_thin))
check-tools-macos: tools-macos ##@tools Test CLI tools for macOS
export PYTHONPATH="$(shell pwd)/build/frida-macos-$(build_arch)/lib/$(PYTHON_NAME)/site-packages" \
&& cd frida-tools \
&& $(PYTHON) -m unittest discover
.PHONY: \
distclean clean clean-submodules git-submodules git-submodule-stamps \
gum-macos \
gum-ios gum-watchos gum-tvos \
gum-android-x86 gum-android-x86_64 \
gum-android-arm gum-android-arm64 \
check-gum-macos \
frida-gum-update-submodule-stamp \
core-macos \
core-ios core-watchos core-tvos \
core-android-x86 core-android-x86_64 \
core-android-arm core-android-arm64 \
check-core-macos \
frida-core-update-submodule-stamp \
python-macos \
python-macos-universal \
check-python-macos \
frida-python-update-submodule-stamp \
node-macos \
check-node-macos \
frida-node-update-submodule-stamp \
tools-macos \
check-tools-macos \
frida-tools-update-submodule-stamp
.SECONDARY:
#!/bin/sh
if [ -z "$FRIDA_VERSION" ]; then
echo "FRIDA_VERSION must be set" > /dev/stderr
exit 2
fi
if [ $# -ne 3 ]; then
echo "Usage: $0 arch path/to/prefix output.deb" > /dev/stderr
exit 3
fi
arch=$1
prefix=$2
output_deb=$3
executable=$prefix/usr/bin/frida-server
if [ ! -f "$executable" ]; then
echo "$executable: not found" > /dev/stderr
exit 4
fi
agent=$prefix/usr/lib/frida/frida-agent.dylib
if [ ! -f "$agent" ]; then
echo "$agent: not found" > /dev/stderr
exit 5
fi
tmpdir="$(mktemp -d /tmp/package-server.XXXXXX)"
mkdir -p "$tmpdir/var/jb/usr/sbin/"
cp "$executable" "$tmpdir/var/jb/usr/sbin/frida-server"
chmod 755 "$tmpdir/var/jb/usr/sbin/frida-server"
mkdir -p "$tmpdir/var/jb/usr/lib/frida/"
cp "$agent" "$tmpdir/var/jb/usr/lib/frida/frida-agent.dylib"
chmod 755 "$tmpdir/var/jb/usr/lib/frida/frida-agent.dylib"
mkdir -p "$tmpdir/var/jb/Library/LaunchDaemons/"
cat >"$tmpdir/var/jb/Library/LaunchDaemons/re.frida.server.plist" <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>re.frida.server</string>
<key>Program</key>
<string>/var/jb/usr/sbin/frida-server</string>
<key>ProgramArguments</key>
<array>
<string>/var/jb/usr/sbin/frida-server</string>
</array>
<key>UserName</key>
<string>root</string>
<key>POSIXSpawnType</key>
<string>Interactive</string>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
<key>ThrottleInterval</key>
<integer>5</integer>
<key>ExecuteAllowed</key>
<true/>
</dict>
</plist>
EOF
chmod 644 "$tmpdir/var/jb/Library/LaunchDaemons/re.frida.server.plist"
installed_size=$(du -sk "$tmpdir" | cut -f1)
mkdir -p "$tmpdir/DEBIAN/"
cat >"$tmpdir/DEBIAN/control" <<EOF
Package: re.frida.server
Name: Frida
Version: $FRIDA_VERSION
Priority: optional
Size: 1337
Installed-Size: $installed_size
Architecture: $arch
Description: Observe and reprogram running programs.
Homepage: https://frida.re/
Maintainer: Ole André Vadla Ravnås <[email protected]>
Author: Frida Developers <[email protected]>
Section: Development
Conflicts: re.frida.server64
EOF
chmod 644 "$tmpdir/DEBIAN/control"
cat >"$tmpdir/DEBIAN/extrainst_" <<EOF
#!/bin/sh
if [ "\$1" = upgrade ]; then
launchctl unload /var/jb/Library/LaunchDaemons/re.frida.server.plist
fi
if [ "\$1" = install ] || [ "\$1" = upgrade ]; then
launchctl load /var/jb/Library/LaunchDaemons/re.frida.server.plist
fi
exit 0
EOF
chmod 755 "$tmpdir/DEBIAN/extrainst_"
cat >"$tmpdir/DEBIAN/prerm" <<EOF
#!/bin/sh
if [ "\$1" = remove ] || [ "\$1" = purge ]; then
launchctl unload /var/jb/Library/LaunchDaemons/re.frida.server.plist
fi
exit 0
EOF
chmod 755 "$tmpdir/DEBIAN/prerm"
dpkg_options="-Zxz --root-owner-group"
dpkg-deb $dpkg_options --build "$tmpdir" "$output_deb"
package_size=$(expr $(du -sk "$output_deb" | cut -f1) \* 1024)
sed \
-e "s,^Size: 1337$,Size: $package_size,g" \
"$tmpdir/DEBIAN/control" > "$tmpdir/DEBIAN/control_"
mv "$tmpdir/DEBIAN/control_" "$tmpdir/DEBIAN/control"
dpkg-deb $dpkg_options --build "$tmpdir" "$output_deb"
rm -rf "$tmpdir"
@miticollo
Copy link
Author

I updated this Gist. From version 16.1.5 Frida supports rootless and rootfull JB. So my repo it is no more necessary. You should install it from official repo. Anyway on Dopamine there is a bug: you can't spawn a process. But you can attach to it.

@k0m4h
Copy link

k0m4h commented Jul 19, 2024

I have the same bug with Serotonin: you can't spawn a process, But I can attach to it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment