Compare commits

...
66 Commits
Author SHA1 Message Date
Ole André Vadla Ravnås 8e76c7257b subprojects: Prepare for release 2025-06-06 22:11:36 +02:00
Ole André Vadla Ravnås 282927b5b6 subprojects: Bump outdated 2025-06-06 22:10:29 +02:00
Ole André Vadla Ravnås fe235491a5 compiler: Make the DeviceManager optional
It is no longer used, but we cannot drop the constructor argument
without breaking API.
2025-06-06 22:09:40 +02:00
Ole André Vadla Ravnås 46d4d1223a subprojects: Prepare for release 2025-06-06 14:11:13 +02:00
Ole André Vadla Ravnås 6f8d8cba28 linux: Fix the system-server.js build system logic 2025-06-06 13:26:51 +02:00
Ole André Vadla Ravnås 2ee3926912 subprojects: Bump outdated 2025-06-06 12:38:22 +02:00
Ole André Vadla Ravnås 11f93e20b8 compile-js-agent: Remove commented “npm link” example
As it is no longer relevant.
2025-06-06 12:37:32 +02:00
Ole André Vadla Ravnås ad15eb2b01 darwin: Switch reportcrash.js bundling to ESBuild 2025-06-06 12:36:27 +02:00
Ole André Vadla Ravnås 26c9cf3cc5 darwin: Switch osanalytics.js bundling to ESBuild 2025-06-06 12:34:21 +02:00
Ole André Vadla Ravnås 8176ea1361 linux: Switch system-server.js bundling to ESBuild 2025-06-06 12:29:35 +02:00
Ole André Vadla Ravnås ecc63e5591 barebone: Simplify the ESBuild invocation 2025-06-06 12:27:23 +02:00
Ole André Vadla Ravnås ac5898a547 barebone: Fix ESM-handling
Where we failed to await the returned Promise, so any errors would end
up being swallowed.
2025-06-06 11:38:16 +02:00
Ole André Vadla Ravnås 055360cbb6 barebone: Remove bridge globals 2025-06-06 11:37:07 +02:00
Ole André Vadla Ravnås c9b18a5f4b barebone: Switch runtime bundling to ESBuild 2025-06-06 11:36:28 +02:00
Ole André Vadla Ravnås eb55aef18e subprojects: Prepare for release 2025-06-05 22:05:20 +02:00
Ole André Vadla Ravnås 11ba9175d0 subprojects: Bump outdated 2025-06-05 21:11:15 +02:00
Ole André Vadla Ravnås 6dd7e203bf ci: Fix a stylistic inconsistency 2025-06-05 20:07:22 +02:00
Ole André Vadla Ravnås 3a312faa1e ci: Fix the Windows build step 2025-06-05 19:27:22 +02:00
Ole André Vadla Ravnås 6f97782eff meson: Warn when Compiler backend is auto-disabled 2025-06-05 19:21:48 +02:00
Ole André Vadla Ravnås 412e525210 cgo: Fix path logic when consumed as a subproject 2025-06-05 19:21:16 +02:00
Ole André Vadla Ravnås c6e8ef5a29 ci: Clean up and fix Compiler backend enable logic 2025-06-05 19:14:45 +02:00
Ole André Vadla Ravnås 0df0eefdc9 cgo: Treat arm64e as unsupported
As cgo does not yet support it.
2025-06-05 19:08:26 +02:00
Ole André Vadla Ravnås dc60f8bf10 ci: Simplify the Compiler backend enable logic 2025-06-05 19:01:31 +02:00
Ole André Vadla Ravnås 2b9f3764c5 ci: Disable Compiler backend for the emulator job 2025-06-05 18:55:35 +02:00
Ole André Vadla Ravnås 89e01be599 ci: Skip tests on macOS for now
So we can get back to a green baseline.
2025-06-05 18:49:26 +02:00
Ole André Vadla Ravnås 228a37fabf ci: Fix the compiler backend option passed in 2025-06-05 18:36:03 +02:00
Ole André Vadla Ravnås 40ec5e03cc subprojects: Bump outdated 2025-06-05 17:02:16 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 6acb6da386 ci: Explicitly enable compiler
So it's not silently disabled in cases where cgo should be available.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 9b9c91c1f2 ci: Improve naming of the Go toolchain steps
Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås c5809da386 ci: Temporarily remove the FreeBSD/arm64 job
Until we have a working runner for it.
2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 6b76a1b2d4 ci: Fix the native Windows/x86 job
Which was building for x86_64 instead of x86.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås 3da7b8bbd0 submodules: Bump releng 2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås adc93c3bf8 ci: Add native job for Windows/arm64 2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås b85397b690 ci: Install MinGW in the Windows native jobs 2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås b22326f233 ci: Add Go to the build jobs 2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås 531cfb17c0 ci: Remove trailing whitespace 2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 0a4bb7aed5 compiler: Normalize paths passed to typescript-go
So it also works on Windows.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 274898d39c compiler: Fix handling of TypeScript diagnostics
Where ESBuild Message entries without notes were incorrectly handled.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø c6c30833c8 compiler: Avoid Go alignment bug on Windows/x86_64
Where C arguments passed on the stack that are smaller than 8 bytes are
incorrectly laid out when calling into the Go runtime.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla RavnåsandHåvard Sørbø 7b30a9c516 compiler: Fix cross-platform build issues
Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-05 17:00:49 +02:00
Ole André Vadla Ravnås 32220057a8 meson: Allow compiler backend w/o local backend
Now that it no longer needs it for script execution.
2025-06-02 09:39:34 +02:00
Ole André Vadla RavnåsandHåvard Sørbø b7284691ca compiler: Move to ESBuild and typescript-go
For massively improved performance, and to reduce our maintenance burden
by no longer having to maintain a bundler.

Also add options to configure the output and bundle format, and support
disabling type checks.

Co-authored-by: Håvard Sørbø <[email protected]>
2025-06-01 23:46:10 +02:00
Ole André Vadla Ravnås 71a1b0f800 subprojects: Bump outdated 2025-06-01 11:04:52 +02:00
Ole André Vadla Ravnås b8b42a904b submodules: Bump releng 2025-06-01 11:04:51 +02:00
WorksButNotTested fdb4c5107c ci: Add jobs that test on armbe8 and arm64be (#1162) 2025-05-29 21:30:35 +02:00
Francesco Tamagni 8108d4d954 Plug Interceptor singleton leaks (#1167) 2025-05-29 21:29:15 +02:00
Ole André Vadla Ravnås 44a9757589 subprojects: Prepare for release 2025-05-29 17:32:06 +02:00
Ole André Vadla Ravnås 8c939d4954 subprojects: Bump outdated 2025-05-29 17:30:09 +02:00
Francesco Tamagni 8bb0dd14a4 device: Allow agent sessions to detach before release (#1164)
To be robust against scenarios where an out-of-order detach could lead
to indefinite hang at release time.
2025-05-29 17:22:57 +02:00
Ole André Vadla Ravnås 59619f57ca subprojects: Prepare for release 2025-05-28 23:17:01 +02:00
Ole André Vadla Ravnås 5ed7378bb0 subprojects: Bump outdated 2025-05-28 23:16:07 +02:00
londek 4d2bba4b2a darwin: Fix the launchd agent (#1166)
Which was still using an old GumJS API that is now gone.
2025-05-28 23:11:27 +02:00
Ole André Vadla Ravnås e2e2eaab82 subprojects: Prepare for release 2025-05-24 21:03:20 +02:00
Ole André Vadla Ravnås d286cbb09c subprojects: Bump outdated 2025-05-24 21:01:59 +02:00
Ole André Vadla Ravnås c910622a6a compile-js-agent: Explicitly run the build script
To ensure incremental compilation works consistently, as `npm install`
will not always run the `prepare` script.
2025-05-24 21:00:59 +02:00
Ole André Vadla Ravnås 7599500a3b compile-js-agent: Add commented “npm link” example 2025-05-24 20:59:14 +02:00
Ole André Vadla Ravnås fe4db7e37f compile-js-agent: Improve error-reporting
By capturing both stdout and stderr.
2025-05-24 20:58:33 +02:00
Ole André Vadla Ravnås 6064d0c084 Fix agents generated by latest frida-compile
We need to explicitly declare internal agents as ESM now that the
TypeScript compiler is more conformant and ends up generating CommonJS
glue code.

This fixes our Darwin and Android agents, as well as the Barebone
backend's script runtime.
2025-05-24 20:50:43 +02:00
Ole André Vadla Ravnås f970529e08 subprojects: Prepare for release 2025-05-22 21:39:32 +02:00
Ole André Vadla Ravnås 031614ddc2 compiler: Fix asset bundling logic on Windows
Where virtual paths were stored with the wrong path separator.
2025-05-22 21:20:34 +02:00
Ole André Vadla Ravnås 71d82bcebc subprojects: Bump outdated 2025-05-22 18:22:36 +02:00
Ole André Vadla Ravnås 9c7759cb53 tests: Adjust profile-compiler.sh to new layout 2025-05-22 18:20:21 +02:00
Ole André Vadla Ravnås 11b3e1415f Upgrade to frida-compile 18
Now with TypeScript 5.8.3, latest frida-fs, etc.
2025-05-22 18:17:44 +02:00
Ole André Vadla Ravnås 420370257e subprojects: Prepare for release 2025-05-20 23:12:10 +02:00
Ole André Vadla Ravnås 36948a3f22 subprojects: Bump outdated 2025-05-20 23:10:16 +02:00
Ole André Vadla Ravnås 9fd3a7e104 compiler: Bump @frida/rollup-plugin-node-polyfills
Which was depending on the old frida-fs.
2025-05-20 23:08:11 +02:00
53 changed files with 5996 additions and 4727 deletions

No files matched your search

+181 -13
View File
@@ -16,13 +16,13 @@ jobs:
strategy:
matrix:
include:
- { id: windows-x86_64, runner: '"windows-latest"' }
- { id: windows-x86, runner: '"windows-latest"' }
- { id: macos-x86_64, runner: '"macos-latest"' }
- { id: macos-arm64, runner: '"macos-latest"' }
- { id: linux-x86_64, runner: '"ubuntu-latest"' }
- { id: linux-x86, runner: '"ubuntu-latest"' }
- { id: freebsd-arm64, runner: '["self-hosted", "freebsd", "arm64"]' }
- { id: windows-arm64, runner: '"windows-11-arm"', sys: CLANGARM64, pkg: 'mingw-w64-clang-aarch64-clang' }
- { id: windows-x86_64, runner: '"windows-latest"', sys: MINGW64, pkg: 'mingw-w64-x86_64-gcc' }
- { id: windows-x86, runner: '"windows-latest"', sys: MINGW32, pkg: 'mingw-w64-i686-gcc' }
- { id: macos-x86_64, runner: '"macos-latest"' }
- { id: macos-arm64, runner: '"macos-latest"' }
- { id: linux-x86_64, runner: '"ubuntu-latest"' }
- { id: linux-x86, runner: '"ubuntu-latest"' }
fail-fast: false
runs-on: ${{ fromJSON(matrix.runner) }}
steps:
@@ -30,6 +30,18 @@ jobs:
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install MinGW toolchain for cgo support
if: ${{ startsWith(matrix.id, 'windows-') }}
id: msys2
uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
install: ${{ matrix.pkg }}
- name: Install Go toolchain
uses: actions/setup-go@v5
with:
go-version-file: 'src/compiler/go.mod'
cache-dependency-path: 'src/compiler/go.mod'
- name: Set up Apple certificates
if: ${{ startsWith(matrix.id, 'macos-') }}
uses: ./.github/actions/setup-apple-certificates
@@ -48,18 +60,29 @@ jobs:
- name: Build
if: ${{ startsWith(matrix.id, 'windows-') }}
run: |
.\configure ${{ env.FRIDA_CORE_OPTIONS }}
.\configure `
--host=${{ matrix.id }} `
--enable-compiler-backend `
${{ env.FRIDA_CORE_OPTIONS }}
.\make
env:
MSYS2_LOCATION: ${{ steps.msys2.outputs.msys2-location }}
- name: Build
if: ${{ !startsWith(matrix.id, 'windows-') && matrix.id != 'linux-x86' }}
run: |
./configure ${{ env.FRIDA_CORE_OPTIONS }}
./configure \
--enable-compiler-backend \
${{ env.FRIDA_CORE_OPTIONS }}
make
- name: Build
if: matrix.id == 'linux-x86'
run: |
CC="gcc -m32" CXX="g++ -m32" STRIP="strip" \
./configure --build=linux-x86 --host=linux-x86 ${{ env.FRIDA_CORE_OPTIONS }}
./configure \
--build=linux-x86 \
--host=linux-x86 \
--enable-compiler-backend \
${{ env.FRIDA_CORE_OPTIONS }}
make
- name: Upload devkit
if: ${{ !startsWith(matrix.id, 'linux-') }}
@@ -68,6 +91,7 @@ jobs:
name: core-devkit-${{ matrix.id }}
path: build/src/devkit/
- name: Test
if: ${{ matrix.id != 'windows-arm64' && !startsWith(matrix.id, 'macos-') }}
run: make test
cross:
@@ -91,9 +115,17 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install ${{ matrix.pkg }}
- name: Install Go toolchain
uses: actions/setup-go@v5
with:
go-version-file: 'src/compiler/go.mod'
cache-dependency-path: 'src/compiler/go.mod'
- name: Build
run: |
./configure ${{ matrix.opts }} ${{ env.FRIDA_CORE_OPTIONS }}
./configure \
${{ matrix.opts }} \
${{ !contains(matrix.id, 'mips') && '--enable-compiler-backend' || '' }} \
${{ env.FRIDA_CORE_OPTIONS }}
make
- name: Upload devkit
if: ${{ !startsWith(matrix.id, 'linux-') }}
@@ -114,9 +146,17 @@ jobs:
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Go toolchain
uses: actions/setup-go@v5
with:
go-version-file: 'src/compiler/go.mod'
cache-dependency-path: 'src/compiler/go.mod'
- name: Build
run: |
./configure --host=$XTOOLS_HOST ${{ env.FRIDA_CORE_OPTIONS }}
./configure \
--host=$XTOOLS_HOST \
${{ !startsWith(matrix.arch, 'mips') && '--enable-compiler-backend' || '' }} \
${{ env.FRIDA_CORE_OPTIONS }}
make
- name: Upload devkit
uses: actions/upload-artifact@v4
@@ -127,6 +167,126 @@ jobs:
if: matrix.arch == 'x86' || matrix.arch == 'x86_64'
run: make test
emulator:
strategy:
matrix:
arch: [armbe8, arm64be]
fail-fast: false
runs-on: ubuntu-latest
container: ghcr.io/frida/x-tools-linux-${{ matrix.arch }}:latest
steps:
- name: Check out repo
uses: actions/checkout@v4
with:
submodules: recursive
- name: Build
run: |
./configure --host=$XTOOLS_HOST --without-prebuilds=sdk:host --enable-tests
make
- name: Run custom container
uses: addnab/docker-run-action@v3
with:
image: docker:stable
options: -v ${{ github.workspace }}:/workspace:delegated
run: |
cat <<EOF > /workspace/initscript
#!/bin/sh
dmesg -n1
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs none /tmp
mount -t devtmpfs none /dev
mount -t 9p -o rw,sync,dirsync,relatime,trans=virtio,msize=131072,version=9p2000.L host0 /workspace
ip link set lo up
ip addr add 192.168.76.20/24 dev eth0
ip link set eth0 up
ip route add default via 192.168.76.2 dev eth0
export LD_LIBRARY_PATH=/lib:/lib64:/libilp32
/sbin/entropy
cat /etc/motd
export PS1='\u@frida:\w\$ '
/root/frida-tests
if [ $? -eq 0 ]; then
echo EXIT_OK
else
echo EXIT_FAIL
fi
EOF
cat <<EOF > /workspace/launch.sh
#!/bin/sh
LOGFILE=/workspace/qemu.log
: > "\$LOGFILE"
timeout 120 qemu-system-aarch64 \
-M virt \
-machine virtualization=true \
-machine type=virt \
-cpu cortex-a72 \
-smp 4 \
-kernel /root/Image.gz \
-initrd /root/initramfs.img \
-append 'earlyprintk=serial,ttyAMA0 console=ttyAMA0 coredump_filter=0x3f' \
-m 4096M \
-net nic,id=eth \
-net user,id=mynet,net=192.168.76.0/24 \
-virtfs local,path=/workspace/,mount_tag=host0,security_model=passthrough,id=host0 \
-nographic \
-no-reboot \
>> "\$LOGFILE" 2>&1 &
QEMU_PID=\$!
echo "QEMU started with PID \$QEMU_PID"
tail -n 0 -f "\$LOGFILE" | while read line; do
echo "\$line"
echo "\$line" | grep "EXIT_OK" >/dev/null 2>&1
if [ \$? -eq 0 ]; then
echo "Success signal received from guest. Killing QEMU..."
kill -9 "\$QEMU_PID"
cat -n "\$LOGFILE"
exit 0
fi
echo "\$line" | grep "EXIT_FAIL" >/dev/null 2>&1
if [ \$? -eq 0 ]; then
echo "Failure signal received from guest. Killing QEMU..."
kill -9 "\$QEMU_PID"
cat -n "\$LOGFILE"
exit 1
fi
if ! kill -0 "\$QEMU_PID" 2>/dev/null; then
echo "QEMU process has exited."
cat -n "\$LOGFILE"
exit 1
fi
done
EOF
cat <<EOF > /workspace/Dockerfile.ci
FROM ghcr.io/frida/x-tools-linux-be-target:latest
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && \
apt-get install -y \
cpio
RUN mkdir /tmp/initramfs
WORKDIR /tmp/initramfs
RUN cpio --extract < /root/initramfs.img
RUN mkdir /tmp/initramfs/workspace
COPY initscript /tmp/initramfs/init
RUN chmod +x /tmp/initramfs/init
COPY build/tests /tmp/initramfs/root/
RUN find . | cpio -o --format=newc -R root:root > /root/initramfs.img
COPY launch.sh /root/launch.sh
RUN chmod +x /root/launch.sh
ENTRYPOINT ["/root/launch.sh"]
EOF
docker build -t ci-image -f /workspace/Dockerfile.ci /workspace
docker run --rm -v /workspace:/workspace ci-image
mobile:
strategy:
matrix:
@@ -143,6 +303,11 @@ jobs:
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Go toolchain
uses: actions/setup-go@v5
with:
go-version-file: 'src/compiler/go.mod'
cache-dependency-path: 'src/compiler/go.mod'
- name: Set up Apple certificates
if: startsWith(matrix.id, 'ios-')
uses: ./.github/actions/setup-apple-certificates
@@ -160,7 +325,10 @@ jobs:
run: echo ANDROID_NDK_ROOT=${{ steps.setup-ndk.outputs.ndk-path }} >> $GITHUB_ENV
- name: Build
run: |
./configure --host=${{ matrix.id }} ${{ env.FRIDA_CORE_OPTIONS }}
./configure \
--host=${{ matrix.id }} \
--enable-compiler-backend \
${{ env.FRIDA_CORE_OPTIONS }}
make
- name: Upload devkit
uses: actions/upload-artifact@v4
+3
View File
@@ -435,6 +435,7 @@ def compile(privdir: Path, state: State):
environ={**build_env, **group.extra_environ},
allowed_prebuilds=state.allowed_prebuilds,
extra_meson_options=[
"-Dcompiler_backend=disabled",
"-Dhelper_modern=",
"-Dhelper_legacy=",
"-Dagent_modern=",
@@ -499,6 +500,8 @@ def option_should_be_forwarded(k: "OptionKey",
if k.is_project():
if is_for_us:
if k.name == "compiler_backend":
return False
tokens = k.name.split("_")
if tokens[0] in {"helper", "agent"} and tokens[-1] in {"modern", "legacy"}:
return False
+7 -7
View File
@@ -55,6 +55,7 @@ struct _FridaUnwindHookState
gpointer set_info_original;
void (* set_info) (gpointer cursor, gint is_return_address);
gpointer (* get_reg) (gpointer cursor, gint reg);
GumInterceptor * interceptor;
};
#if __has_feature (ptrauth_calls)
@@ -97,7 +98,6 @@ _frida_unwind_sitter_hook_libunwind (void)
#if GLIB_SIZEOF_VOID_P == 8
gpointer * set_info_slot;
gpointer get_reg_impl;
GumInterceptor * interceptor;
if (state != NULL)
return;
@@ -121,8 +121,9 @@ _frida_unwind_sitter_hook_libunwind (void)
state->set_info = FRIDA_RESIGN_PTR (state->set_info_original);
state->get_reg = FRIDA_RESIGN_PTR (get_reg_impl);
interceptor = gum_interceptor_obtain ();
if (gum_interceptor_replace (interceptor, state->set_info_original, frida_unwind_cursor_set_info_replacement, NULL, NULL)
state->interceptor = gum_interceptor_obtain ();
if (gum_interceptor_replace (state->interceptor, state->set_info_original, frida_unwind_cursor_set_info_replacement, NULL, NULL)
!= GUM_REPLACE_OK)
goto unsupported_version;
@@ -137,13 +138,12 @@ unsupported_version:
void
_frida_unwind_sitter_unhook_libunwind (void)
{
GumInterceptor * interceptor;
if (state == NULL)
return;
interceptor = gum_interceptor_obtain ();
gum_interceptor_revert (interceptor, state->set_info_original);
gum_interceptor_revert (state->interceptor, state->set_info_original);
g_object_unref (state->interceptor);
g_slice_free (FridaUnwindHookState, state);
state = NULL;
+78 -58
View File
@@ -6,6 +6,8 @@ project('frida-core', 'vala', 'c', 'cpp',
default_options: ['c_std=gnu99,c99', 'cpp_std=c++17'],
)
fs = import('fs')
if not meson.get_compiler('vala').version().endswith('-frida')
error('''Incompatible Vala compiler detected.
@@ -20,7 +22,7 @@ cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
releng = meson.global_source_root() / 'releng'
if not import('fs').exists(releng)
if not fs.exists(releng)
releng = meson.project_source_root() / 'releng'
endif
@@ -98,11 +100,6 @@ else
host_cpu_mode = '32'
endif
host_docks_mobile_devices = host_os in ['windows', 'macos', 'linux'] and host_cpu_mode == '64'
gumjs_archs = {
'x86': 'ia32',
'x86_64': 'x64',
}
host_arch_gumjs = gumjs_archs.get(host_arch, host_arch)
if host_os_family == 'darwin'
c_languages += ['objc', 'objcpp']
@@ -362,6 +359,42 @@ if host_os == 'android'
])
endif
if host_toolchain == 'microsoft'
lib = find_program('lib')
ar = ''
nm = ''
strip = ''
else
lib = ''
ar = find_program('ar')
nm = find_program('nm')
strip = find_program('strip')
endif
if host_os_family != 'windows'
if host_os_family == 'darwin'
readelf = ''
otool = find_program('otool')
libtool = find_program('libtool')
else
readelf = find_program('readelf')
otool = ''
libtool = ''
endif
else
readelf = ''
otool = ''
libtool = ''
endif
if host_os_family == 'darwin'
install_name_tool = find_program('install_name_tool')
lipo = find_program('lipo')
codesign = find_program('codesign')
else
install_name_tool = ''
lipo = ''
codesign = ''
endif
have_local_backend = get_option('local_backend').allowed()
have_fruity_backend = get_option('fruity_backend') \
.disable_auto_if(not host_docks_mobile_devices) \
@@ -374,15 +407,45 @@ have_barebone_backend = get_option('barebone_backend') \
.disable_if(not quickjs_dep.found()) \
.disable_auto_if(not host_docks_mobile_devices) \
.allowed()
have_compiler_backend = get_option('compiler_backend') \
.disable_if(not have_local_backend, error_message: 'compiler backend requires the local backend for script execution') \
.disable_auto_if(host_os == 'watchos') \
.allowed()
if get_option('compiler_snapshot').auto()
# Generating our snapshot with V8's CPU simulator takes a very long time.
generate_compiler_snapshot = meson.can_run_host_binaries()
else
generate_compiler_snapshot = get_option('compiler_snapshot').enabled()
compiler_backend_opt = get_option('compiler_backend') \
.disable_auto_if(host_os == 'watchos')
have_compiler_backend = false
if compiler_backend_opt.allowed()
go = find_program('go', native: true, required: false)
if go.found()
message('Detecting cgo availability')
detect_output = run_command(
[
python,
files('tools' / 'cgo' / 'detect.py'),
go,
host_os,
host_abi,
cc.get_id(),
'>>>', cc.cmd_array(), '<<<',
'>>>', ar, '<<<',
],
capture: true,
check: true
).stdout()
lines = detect_output.split('\n')
status = lines[0]
if status == 'ok'
have_compiler_backend = true
go_config = lines[1]
else
error_message = lines[1]
if compiler_backend_opt.enabled()
error(error_message)
else
warning(f'Building without Compiler backend: @error_message@')
endif
endif
elif compiler_backend_opt.enabled()
error('Need Go >= 1.24 to build the Compiler backend powered by ESBuild and typescript-go')
else
warning('Building without Compiler backend: Go >= 1.24 not found')
endif
endif
build_gadget = get_option('gadget') \
@@ -452,12 +515,6 @@ gumjs_inspector_vala_args = ['--pkg=frida-gumjs-inspector-1.0', gum_vala_args]
have_v8 = gumjs_dep.get_variable('gumjs_v8') == 'enabled'
if have_v8
vala_flags += ['--define=HAVE_V8']
v8_mksnapshot = find_program('v8-mksnapshot-@0@-@1@'.format(host_os, host_abi), required: false)
if not v8_mksnapshot.found()
v8_mksnapshot = ''
endif
else
v8_mksnapshot = ''
endif
backend_deps_private = []
@@ -579,42 +636,6 @@ if host_os in ['ios', 'tvos']
backend_libs_private += ['-Wl,-framework,CoreGraphics', '-Wl,-framework,UIKit']
endif
if host_toolchain == 'microsoft'
lib = find_program('lib')
ar = ''
nm = ''
strip = ''
else
lib = ''
ar = find_program('ar')
nm = find_program('nm')
strip = find_program('strip')
endif
if host_os_family != 'windows'
if host_os_family == 'darwin'
readelf = ''
otool = find_program('otool')
libtool = find_program('libtool')
else
readelf = find_program('readelf')
otool = ''
libtool = ''
endif
else
readelf = ''
otool = ''
libtool = ''
endif
if host_os_family == 'darwin'
install_name_tool = find_program('install_name_tool')
lipo = find_program('lipo')
codesign = find_program('codesign')
else
install_name_tool = ''
lipo = ''
codesign = ''
endif
if get_option('devkits').length() != 0
if get_option('default_library') != 'static'
error('Devkits can only be generated from static libraries')
@@ -760,7 +781,6 @@ summary(
'assets': get_option('assets'),
'mapper': have_mapper,
'connectivity': tls_provider_dep.found(),
'compiler_snapshot': generate_compiler_snapshot,
'gadget': build_gadget,
'server': build_server,
'portal': build_portal,
+1 -7
View File
@@ -37,13 +37,7 @@ option('barebone_backend',
option('compiler_backend',
type: 'feature',
value: 'auto',
description: 'Include frida-compile backend powered by GumJS',
)
option('compiler_snapshot',
type: 'feature',
value: 'auto',
description: 'Speed up compiler startup by using a snapshot'
description: 'Include frida-compile backend powered by ESBuild and typescript-go',
)
option('assets',
+1 -1
Submodule releng updated: 5d9edf166c...e10baa39a2.
+2 -1
View File
@@ -465,7 +465,8 @@ namespace Frida {
public async void load_script (AgentScriptId script_id, Cancellable? cancellable) throws Error, IOError {
check_open ();
get_script (script_id).load ();
var script = get_script (script_id);
yield script.load (cancellable);
}
public async void eternalize_script (AgentScriptId script_id, Cancellable? cancellable) throws Error, IOError {
+443 -445
View File
@@ -9,318 +9,434 @@
"version": "1.0.0",
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5",
"typescript": "^5.8.3"
}
},
"node_modules/@frida/assert": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz",
"integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==",
"dev": true
},
"node_modules/@frida/base64-js": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz",
"integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/@frida/buffer": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz",
"integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
"cpu": [
"ppc64"
],
"dependencies": {
"base64-js": "^1.5.1",
"ieee754": "^1.2.1"
}
},
"node_modules/@frida/crosspath": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz",
"integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==",
"dev": true,
"dependencies": {
"@types/node": "^17.0.36"
},
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=14.9.0"
"node": ">=18"
}
},
"node_modules/@frida/crypto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@frida/crypto/-/crypto-1.0.1.tgz",
"integrity": "sha512-WXTkVjESvX8TIVXIynJJv9BKSIdQP0Iis04StIXknkDi1ULdMlrypA9p5C4KW1H6GCkNsVnKbybpzsulYCTvag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/diagnostics_channel": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz",
"integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==",
"dev": true
},
"node_modules/@frida/events": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz",
"integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==",
"node_modules/@esbuild/android-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=0.8.x"
"node": ">=18"
}
},
"node_modules/@frida/http": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz",
"integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==",
"node_modules/@esbuild/android-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
"cpu": [
"arm64"
],
"dev": true,
"dependencies": {
"http-parser-js": "^0.5.3"
}
},
"node_modules/@frida/http-parser-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz",
"integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==",
"dev": true
},
"node_modules/@frida/https": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz",
"integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==",
"dev": true
},
"node_modules/@frida/ieee754": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz",
"integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/@frida/net": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz",
"integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==",
"dev": true
},
"node_modules/@frida/os": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz",
"integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==",
"dev": true
},
"node_modules/@frida/path": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz",
"integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==",
"dev": true
},
"node_modules/@frida/process": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz",
"integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==",
"dev": true
},
"node_modules/@frida/punycode": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz",
"integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==",
"dev": true
},
"node_modules/@frida/querystring": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz",
"integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==",
"dev": true
},
"node_modules/@frida/readable-stream": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz",
"integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==",
"dev": true
},
"node_modules/@frida/reserved-words": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz",
"integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==",
"dev": true
},
"node_modules/@frida/stream": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz",
"integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==",
"dev": true,
"dependencies": {
"@frida/readable-stream": "^4.1.3"
}
},
"node_modules/@frida/string_decoder": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz",
"integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==",
"dev": true
},
"node_modules/@frida/terser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz",
"integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==",
"dev": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=10"
"node": ">=18"
}
},
"node_modules/@frida/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true
},
"node_modules/@frida/timers": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz",
"integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==",
"dev": true
},
"node_modules/@frida/tty": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz",
"integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==",
"dev": true
},
"node_modules/@frida/url": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz",
"integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==",
"node_modules/@esbuild/android-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
"cpu": [
"x64"
],
"dev": true,
"dependencies": {
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0"
}
},
"node_modules/@frida/util": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz",
"integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==",
"dev": true
},
"node_modules/@frida/vm": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz",
"integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==",
"dev": true
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
"integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
"dev": true,
"dependencies": {
"@jridgewell/set-array": "^1.0.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.9"
},
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz",
"integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==",
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
"cpu": [
"arm64"
],
"dev": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.15",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
"integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
"dev": true
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.18",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz",
"integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==",
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
"cpu": [
"x64"
],
"dev": true,
"dependencies": {
"@jridgewell/resolve-uri": "3.1.0",
"@jridgewell/sourcemap-codec": "1.4.14"
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@jridgewell/trace-mapping/node_modules/@jridgewell/sourcemap-codec": {
"version": "1.4.14",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==",
"dev": true
"node_modules/@esbuild/linux-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/frida-gum": {
"version": "19.0.0",
@@ -329,177 +445,59 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "17.0.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==",
"dev": true
},
"node_modules/acorn": {
"version": "8.8.2",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz",
"integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"node_modules/esbuild": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/frida-compile": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-17.0.0.tgz",
"integrity": "sha512-ixJRj14qLH/Z0ckFWd5fKeDMm0W2+2WDpSGnLRgpn0nuCQAbDHRCqVCWtPnV8uzPJmA6XOX0pujsMpYe9q9RRw==",
"dev": true,
"dependencies": {
"@frida/assert": "^3.0.1",
"@frida/base64-js": "^2.0.3",
"@frida/buffer": "^7.0.4",
"@frida/crosspath": "^3.0.0",
"@frida/crypto": "^1.0.1",
"@frida/diagnostics_channel": "^1.0.0",
"@frida/events": "^4.0.4",
"@frida/http": "^4.0.2",
"@frida/http-parser-js": "^1.0.0",
"@frida/https": "^1.0.0",
"@frida/ieee754": "^2.0.2",
"@frida/net": "^4.0.1",
"@frida/os": "^1.0.0",
"@frida/path": "^2.0.3",
"@frida/process": "^1.2.1",
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0",
"@frida/readable-stream": "^4.1.3",
"@frida/reserved-words": "^1.0.0",
"@frida/stream": "^1.0.2",
"@frida/string_decoder": "^2.0.0",
"@frida/terser": "^1.0.0",
"@frida/timers": "^3.0.0",
"@frida/tty": "^1.0.0",
"@frida/url": "^1.0.2",
"@frida/util": "^1.0.3",
"@frida/vm": "^2.0.0",
"commander": "^11.1.0",
"frida-fs": "^6.0.0",
"typed-emitter": "^2.1.0"
},
"bin": {
"frida-compile": "dist/cli.js"
}
},
"node_modules/frida-fs": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-6.0.0.tgz",
"integrity": "sha512-I0fnKupZh7fU2ixwCIjJnEqNdhfm/SC1ZYBMy58EmeqOWSbjw1Dpy99mJ7BJdbk2KNXJeaBZGxDYLtn0J9S+UA==",
"dev": true,
"license": "MIT"
},
"node_modules/http-parser-js": {
"version": "0.5.8",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.8.tgz",
"integrity": "sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q==",
"dev": true
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
]
},
"node_modules/rxjs": {
"version": "7.8.1",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
"integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
"dev": true,
"optional": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/tslib": {
"version": "2.5.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.2.tgz",
"integrity": "sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA==",
"dev": true,
"optional": true
},
"node_modules/typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz",
"integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==",
"dev": true,
"node": ">=18"
},
"optionalDependencies": {
"rxjs": "*"
"@esbuild/aix-ppc64": "0.25.5",
"@esbuild/android-arm": "0.25.5",
"@esbuild/android-arm64": "0.25.5",
"@esbuild/android-x64": "0.25.5",
"@esbuild/darwin-arm64": "0.25.5",
"@esbuild/darwin-x64": "0.25.5",
"@esbuild/freebsd-arm64": "0.25.5",
"@esbuild/freebsd-x64": "0.25.5",
"@esbuild/linux-arm": "0.25.5",
"@esbuild/linux-arm64": "0.25.5",
"@esbuild/linux-ia32": "0.25.5",
"@esbuild/linux-loong64": "0.25.5",
"@esbuild/linux-mips64el": "0.25.5",
"@esbuild/linux-ppc64": "0.25.5",
"@esbuild/linux-riscv64": "0.25.5",
"@esbuild/linux-s390x": "0.25.5",
"@esbuild/linux-x64": "0.25.5",
"@esbuild/netbsd-arm64": "0.25.5",
"@esbuild/netbsd-x64": "0.25.5",
"@esbuild/openbsd-arm64": "0.25.5",
"@esbuild/openbsd-x64": "0.25.5",
"@esbuild/sunos-x64": "0.25.5",
"@esbuild/win32-arm64": "0.25.5",
"@esbuild/win32-ia32": "0.25.5",
"@esbuild/win32-x64": "0.25.5"
}
},
"node_modules/typescript": {
"version": "5.8.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
"integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
}
}
+6 -3
View File
@@ -2,12 +2,15 @@
"name": "frida-barebone-script-runtime",
"version": "1.0.0",
"description": "Script runtime used by Frida's Barebone backend",
"type": "module",
"scripts": {
"prepare": "npm run build",
"build": "frida-compile script-runtime/entrypoint.ts -o script-runtime.js -c"
"build": "esbuild script-runtime/entrypoint.ts --outfile=script-runtime.js --bundle --platform=neutral --target=es2022 --minify",
"check": "tsc",
"watch": "tsc -w"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5",
"typescript": "^5.8.3"
}
}
-18
View File
@@ -210,24 +210,6 @@ Object.defineProperties(globalThis, {
}
}
},
ObjC: {
enumerable: true,
value: {
available: false
}
},
Swift: {
enumerable: true,
value: {
available: false
}
},
Java: {
enumerable: true,
value: {
available: false
}
},
console: {
enumerable: true,
value: new Console()
+162 -38
View File
@@ -72,7 +72,7 @@ namespace Frida {
private QuickJS.Value int64_func = QuickJS.Undefined;
private QuickJS.Value uint64_func = QuickJS.Undefined;
private Gee.ArrayList<QuickJS.Value?> entrypoints = new Gee.ArrayList<QuickJS.Value?> ();
private Gee.Queue<Entrypoint> entrypoints = new Gee.ArrayQueue<Entrypoint> ();
private Gee.Map<string, Asset> assets = new Gee.HashMap<string, Asset> ();
private Cancellable io_cancellable = new Cancellable ();
@@ -328,6 +328,8 @@ namespace Frida {
foreach (var val in values)
ctx.free_value (val);
entrypoints.clear ();
QuickJS.Atom atoms[] = {
address_key,
base_key,
@@ -376,48 +378,65 @@ namespace Frida {
yield;
}
public void load () {
foreach (QuickJS.Value? entrypoint in entrypoints) {
var result = ctx.eval_function (entrypoint);
if (result.is_exception ())
public async void load (Cancellable? cancellable) throws IOError {
Entrypoint? entrypoint;
while ((entrypoint = entrypoints.poll ()) != null) {
var result = ctx.eval_function (ctx.dup_value (entrypoint.callable));
if (result.is_exception ()) {
catch_and_emit ();
ctx.free_value (result);
if (runtime_obj.is_undefined ()) {
runtime_obj = global.get_property_str (ctx, "$rt");
if (!runtime_obj.is_undefined ()) {
dispatch_exception_func = runtime_obj.get_property_str (ctx, "dispatchException");
assert (!dispatch_exception_func.is_undefined ());
dispatch_message_func = runtime_obj.get_property_str (ctx, "dispatchMessage");
assert (!dispatch_message_func.is_undefined ());
var native_pointer_instance = global.get_property_str (ctx, "NULL");
assert (!native_pointer_instance.is_undefined ());
var native_pointer_proto = native_pointer_instance.get_prototype (ctx);
var ir_proto = ctx.make_object_proto (native_pointer_proto);
add_cfunc (ir_proto, "replace", on_invocation_retval_replace, 1);
ctx.set_class_proto (invocation_retval_class, ir_proto);
ctx.free_value (native_pointer_proto);
ctx.free_value (native_pointer_instance);
ptr_func = global.get_property_str (ctx, "ptr");
assert (!ptr_func.is_undefined ());
int64_func = global.get_property_str (ctx, "int64");
assert (!int64_func.is_undefined ());
uint64_func = global.get_property_str (ctx, "uint64");
assert (!uint64_func.is_undefined ());
}
continue;
}
if (entrypoint.kind == ESM) {
var op = new PromiseWaitOperation (this, result);
var r = yield op.perform (cancellable);
if (!r.error.is_null ())
on_unhandled_exception (r.error);
} else {
ctx.free_value (result);
}
maybe_bind_runtime ();
}
perform_pending_io ();
}
private void maybe_bind_runtime () {
if (!runtime_obj.is_undefined ())
return;
runtime_obj = global.get_property_str (ctx, "$rt");
if (runtime_obj.is_undefined ())
return;
dispatch_exception_func = runtime_obj.get_property_str (ctx, "dispatchException");
assert (!dispatch_exception_func.is_undefined ());
dispatch_message_func = runtime_obj.get_property_str (ctx, "dispatchMessage");
assert (!dispatch_message_func.is_undefined ());
var native_pointer_instance = global.get_property_str (ctx, "NULL");
assert (!native_pointer_instance.is_undefined ());
var native_pointer_proto = native_pointer_instance.get_prototype (ctx);
var ir_proto = ctx.make_object_proto (native_pointer_proto);
add_cfunc (ir_proto, "replace", on_invocation_retval_replace, 1);
ctx.set_class_proto (invocation_retval_class, ir_proto);
ctx.free_value (native_pointer_proto);
ctx.free_value (native_pointer_instance);
ptr_func = global.get_property_str (ctx, "ptr");
assert (!ptr_func.is_undefined ());
int64_func = global.get_property_str (ctx, "int64");
assert (!int64_func.is_undefined ());
uint64_func = global.get_property_str (ctx, "uint64");
assert (!uint64_func.is_undefined ());
}
public void post (string json, Bytes? data) {
var json_val = ctx.make_string (json);
var data_val = (data != null) ? ctx.make_array_buffer (data.get_data ()) : QuickJS.Null;
@@ -495,7 +514,7 @@ namespace Frida {
throw_malformed_package ();
var val = compile_module (entrypoint);
entrypoints.add (val);
entrypoints.offer (new Entrypoint (this, val, ESM));
string rest = raw_assets[assets_offset:];
if (rest.has_prefix (delimiter_marker))
@@ -507,7 +526,7 @@ namespace Frida {
}
} else {
var val = compile_script (source, name);
entrypoints.add (val);
entrypoints.offer (new Entrypoint (this, val, PLAIN));
}
}
@@ -708,6 +727,111 @@ namespace Frida {
}
}
private class Entrypoint {
private weak BareboneScript script;
public QuickJS.Value callable;
public Kind kind;
public enum Kind {
PLAIN,
ESM
}
public Entrypoint (BareboneScript script, QuickJS.Value callable, Kind kind) {
this.script = script;
this.callable = callable;
this.kind = kind;
}
~Entrypoint () {
script.ctx.free_value (callable);
}
}
private class PromiseWaitOperation {
private BareboneScript script;
private QuickJS.Value promise;
private enum Magic {
ON_SUCCESS,
ON_FAILURE,
}
public PromiseWaitOperation (BareboneScript script, QuickJS.Value promise) {
this.script = script;
this.promise = promise;
}
~PromiseWaitOperation () {
script.ctx.free_value (promise);
}
public async Result perform (Cancellable? cancellable) throws IOError {
var res = new Result (script, perform.callback);
unowned QuickJS.Context ctx = script.ctx;
var data = ctx.make_object ();
data.set_opaque (res);
var on_success = ctx.make_cfunction_data (on_settled, 1, Magic.ON_SUCCESS, { data });
var on_failure = ctx.make_cfunction_data (on_settled, 1, Magic.ON_FAILURE, { data });
var then_func = promise.get_property_str (ctx, "then");
var catch_func = promise.get_property_str (ctx, "catch");
ctx.free_value (then_func.call (ctx, promise, { on_success }));
ctx.free_value (catch_func.call (ctx, promise, { on_failure }));
ctx.free_value (catch_func);
ctx.free_value (then_func);
ctx.free_value (on_failure);
ctx.free_value (on_success);
script.perform_pending_io ();
yield;
return res;
}
private static QuickJS.Value on_settled (QuickJS.Context ctx, QuickJS.Value this_val, QuickJS.Value[] argv, int magic,
QuickJS.Value[] data) {
QuickJS.ClassID cid;
unowned Result res = (Result) data[0].get_any_opaque (out cid);
if (magic == Magic.ON_SUCCESS)
res.val = ctx.dup_value (argv[0]);
else
res.error = ctx.dup_value (argv[0]);
var source = new IdleSource ();
source.set_callback ((owned) res.on_complete);
source.attach (MainContext.get_thread_default ());
return QuickJS.Undefined;
}
public class Result {
public BareboneScript script;
public SourceFunc on_complete;
public QuickJS.Value val = QuickJS.Null;
public QuickJS.Value error = QuickJS.Null;
public Result (BareboneScript script, owned SourceFunc on_complete) {
this.script = script;
this.on_complete = (owned) on_complete;
}
~Result () {
unowned QuickJS.Context ctx = script.ctx;
ctx.free_value (val);
ctx.free_value (error);
}
}
}
private class NativeCallbackHandler : Object, Barebone.CallbackHandler {
public uint arity {
get { return _arity; }
+10
View File
@@ -0,0 +1,10 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["ES2022"],
"module": "Node16",
"strict": true,
"noEmit": true
},
"include": ["script-runtime/**/*.ts"]
}
-469
View File
@@ -1,469 +0,0 @@
import * as crosspath from "@frida/crosspath";
import type * as backend from "frida-compile";
import {
makeDefaultCompilerOptions,
build as _build,
watch as _watch,
queryDefaultAssets as _queryDefaultAssets,
} from "frida-compile";
import ts from "frida-compile/ext/typescript.js";
import fridaFs from "frida-fs";
import fs from "fs";
const { DiagnosticCategory, FileWatcherEventKind } = ts;
const { S_IFDIR } = fs.constants;
export const compilerRoot = "/frida-compile";
export const compilerNodeModules = compilerRoot + "/node_modules";
export const agentDirectories = new Set<string>(__agentDirectories__);
export const agentFiles = new Map<string, string>(__agentFiles__);
const cachedSourceFiles = new Map<string, ts.SourceFile>();
declare const __agentDirectories__: string[];
declare const __agentFiles__: [string, string][];
const pendingDiagnostics: ts.Diagnostic[] = [];
const fileWatchers = new Map<WatcherId, WatcherCallback>();
let nextWatcherId: WatcherId = 1;
populateSourceFileCache();
function populateSourceFileCache() {
const config = makeDefaultCompilerOptions();
for (const [name, contents] of agentFiles) {
if (name.endsWith(".d.ts")) {
const sf = ts.createSourceFile(name, contents, config.target!);
ts.prebindSourceFile(sf, config);
cachedSourceFiles.set(name, sf);
}
}
}
export function init(): void {
function onChange(message: WatchChangeMessage): void {
const callback = fileWatchers.get(message.id);
callback?.(fileWatcherEventKindFromFileState(message.state));
recv("watch:change", onChange);
}
recv("watch:change", onChange);
const origCreateCompilerHostFromProgramHost = (ts as any).createCompilerHostFromProgramHost;
(ts as any).createCompilerHostFromProgramHost = (...args: any[]): ts.CompilerHost => {
const host = origCreateCompilerHostFromProgramHost(...args);
patchCompilerHost(host);
return host;
};
}
export function build(projectRoot: string, entrypoint: string, sourceMaps: backend.SourceMaps, compression: backend.Compression): string {
const system = new FridaSystem(projectRoot);
const assets = _queryDefaultAssets(projectRoot, system);
try {
return _build({
projectRoot,
entrypoint,
assets,
system,
sourceMaps,
compression,
onDiagnostic,
onCompilerHostCreated: patchCompilerHost,
});
} finally {
flushDiagnostics();
}
}
export function watch(projectRoot: string, entrypoint: string, sourceMaps: backend.SourceMaps, compression: backend.Compression): void {
const system = new FridaSystem(projectRoot);
const assets = _queryDefaultAssets(projectRoot, system);
_watch({
projectRoot,
entrypoint,
assets,
system,
sourceMaps,
compression,
onDiagnostic,
})
.on("compilationStarting", () => {
send(["watch:compilation-starting"]);
})
.on("compilationFinished", () => {
send(["watch:compilation-finished"]);
})
.on("bundleUpdated", bundle => {
send(["watch:bundle-updated", bundle]);
});
}
function patchCompilerHost(host: ts.CompilerHost) {
const origGetSourceFile = host.getSourceFile;
host.getSourceFile = (fileName, ...args) => {
const compilerPath = nativePathToCompilerPath(fileName);
if (compilerPath !== null) {
const sf = cachedSourceFiles.get(compilerPath);
if (sf !== undefined) {
return sf;
}
} else {
const startPos = fileName.indexOf("/node_modules/@types/");
if (startPos !== -1) {
const builtinsPath = fileName.substring(startPos);
const sf = cachedSourceFiles.get(builtinsPath);
if (sf !== undefined) {
let allowCache = true;
if (builtinsPath.startsWith("/node_modules/@types/frida-gum/")) {
try {
const hashOnDisk = Checksum.compute("sha256", File.readAllText(fileName));
const hashInCache = Checksum.compute("sha256", agentFiles.get(sf.fileName)!);
allowCache = hashOnDisk === hashInCache;
} catch (e) {
}
}
if (allowCache) {
return sf;
}
}
}
}
return origGetSourceFile(fileName, ...args);
};
}
export { _build, _watch, _queryDefaultAssets };
type DiagnosticFile = [path: string, line: number, character: number];
function onDiagnostic(diagnostic: ts.Diagnostic): void {
pendingDiagnostics.push(diagnostic);
if (pendingDiagnostics.length === 1) {
Script.nextTick(flushDiagnostics);
}
}
function flushDiagnostics(): void {
const pending = pendingDiagnostics.splice(0, pendingDiagnostics.length);
if (pending.length === 0) {
return;
}
send([
"diagnostics",
pending.map(({
category,
code,
file: tsFile,
start,
messageText
}) => {
let file: DiagnosticFile | null = null;
if (tsFile !== undefined) {
const { line, character } = ts.getLineAndCharacterOfPosition(tsFile, start!);
file = [tsFile.fileName, line, character];
}
return [
diagnosticCategoryToString(category),
code,
file,
ts.flattenDiagnosticMessageText(messageText, "\n")
];
}),
]);
}
function diagnosticCategoryToString(category: ts.DiagnosticCategory): string {
switch (category) {
case DiagnosticCategory.Warning:
return "warning";
case DiagnosticCategory.Error:
return "error";
case DiagnosticCategory.Suggestion:
return "suggestion";
case DiagnosticCategory.Message:
return "message";
}
}
class FridaSystem implements ts.System {
args = [];
newLine = "\n";
useCaseSensitiveFileNames = true;
#projectRoot: string;
#projectNodeModules: string;
constructor(projectRoot: string) {
this.#projectRoot = crosspath.ensurePosix(projectRoot);
this.#projectNodeModules = crosspath.join(this.#projectRoot, "node_modules");
}
write(s: string): void {
}
writeOutputIsTTY(): boolean {
return true;
}
readFile(path: string, encoding?: string): string | undefined {
let result: string | undefined;
if (path.startsWith(this.#projectRoot)) {
try {
result = File.readAllText(path);
} catch (e) {
}
}
if (result === undefined) {
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null) {
result = agentFiles.get(agentZipPath);
}
}
return result;
}
getFileSize(path: string): number {
throw new Error("not implemented");
}
writeFile(path: string, data: string, writeByteOrderMark?: boolean): void {
File.writeAllText(path, data);
}
watchFile(path: string, callback: ts.FileWatcherCallback, pollingInterval?: number, options?: ts.WatchOptions): ts.FileWatcher {
if (path.startsWith(compilerRoot)) {
return makeDummyWatcher();
}
return makeFileWatcher(path, "file", pollingInterval ?? 0, kind => {
callback(path, kind);
});
}
watchDirectory(path: string, callback: ts.DirectoryWatcherCallback, recursive?: boolean, options?: ts.WatchOptions): ts.FileWatcher {
if (path.startsWith(compilerRoot)) {
return makeDummyWatcher();
}
return makeFileWatcher(path, "directory", 0, kind => {
callback(path);
});
}
resolvePath(path: string): string {
return path;
}
fileExists(path: string): boolean {
if (path.startsWith(this.#projectRoot)) {
try {
const st = fs.statSync(path);
return !st.isDirectory();
} catch (e) {
}
}
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath === null) {
return false;
}
return agentFiles.has(agentZipPath);
}
directoryExists(path: string): boolean {
if (path === compilerNodeModules) {
return true;
}
if (path.startsWith(this.#projectRoot)) {
try {
const st = fs.statSync(path);
return st.isDirectory();
} catch (e) {
}
}
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath === null) {
return false;
}
return agentDirectories.has(agentZipPath);
}
createDirectory(path: string): void {
throw new Error("not implemented");
}
getExecutingFilePath(): string {
return [compilerRoot, "ext", "typescript.js"].join("/");
}
getCurrentDirectory(): string {
return this.#projectRoot;
}
getDirectories(path: string): string[] {
const result = new Set<string>();
if (path.startsWith(this.#projectRoot)) {
try {
for (const entry of fridaFs.list(path).filter(entry => entry.type === S_IFDIR)) {
result.add(entry.name);
}
} catch (e) {
}
}
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null) {
for (const dir of agentDirectories) {
const slashIndex = dir.lastIndexOf("/");
const parent = dir.substring(0, slashIndex);
if (parent === agentZipPath) {
const basename = dir.substring(slashIndex + 1);
result.add(basename);
}
}
}
return Array.from(result);
}
readDirectory(path: string, extensions?: readonly string[], exclude?: readonly string[], include?: readonly string[], depth?: number): string[] {
return [];
}
getModifiedTime(path: string): Date | undefined {
return undefined;
}
setModifiedTime(path: string, time: Date): void {
}
deleteFile(path: string): void {
}
createHash(data: string): string {
return this.createSHA256Hash(data);
}
createSHA256Hash(data: string): string {
return Checksum.compute("sha256", data);
}
getMemoryUsage(): number {
return Frida.heapSize;
}
exit(exitCode?: number): void {
}
realpath(path: string): string {
return path;
}
getEnvironmentVariable(name: string): string {
return "";
}
setTimeout(callback: (...args: any[]) => void, ms: number, ...args: any[]): any {
return setTimeout(callback);
}
clearTimeout(timeoutId: any): void {
return clearTimeout(timeoutId);
}
clearScreen(): void {
}
base64decode(input: string): string {
throw new Error("not implemented");
}
base64encode(input: string): string {
throw new Error("not implemented");
}
#nativePathToAgentZipPath(path: string): string | null {
const compilerPath = nativePathToCompilerPath(path);
if (compilerPath !== null) {
return compilerPath;
}
if (path.startsWith(this.#projectNodeModules)) {
return "/node_modules" + path.substring(this.#projectNodeModules.length);
}
return null;
}
}
function nativePathToCompilerPath(path: string): string | null {
if (!path.startsWith(compilerRoot)) {
return null;
}
const subPath = path.substring(compilerRoot.length);
if (subPath.startsWith("/node_modules")) {
return subPath;
}
return "/node_modules/frida-compile" + subPath;
}
type WatcherId = number;
type WatcherCallback = (eventKind: ts.FileWatcherEventKind) => void;
type FileState = "pristine" | "modified" | "deleted";
interface WatchChangeMessage {
id: WatcherId;
state: FileState;
}
function makeFileWatcher(path: string, type: "file" | "directory", pollingInterval: number, callback: WatcherCallback): ts.FileWatcher {
if (nextWatcherId === 0xffffffff) {
nextWatcherId = 1;
}
let id: WatcherId = nextWatcherId++;
while (fileWatchers.has(id)) {
id = nextWatcherId++;
}
fileWatchers.set(id, callback);
send(["watch:add", id, path, type, pollingInterval ?? 0]);
return {
close() {
send(["watch:remove", id]);
fileWatchers.delete(id);
}
};
}
function makeDummyWatcher(): ts.FileWatcher {
return {
close() {
}
};
}
function fileWatcherEventKindFromFileState(state: FileState): ts.FileWatcherEventKind {
switch (state) {
case "pristine": return FileWatcherEventKind.Created;
case "modified": return FileWatcherEventKind.Changed;
case "deleted": return FileWatcherEventKind.Deleted;
}
}
-5
View File
@@ -1,5 +0,0 @@
const { init, build, watch } = FridaCompilerAgentCore;
init();
rpc.exports = { build, watch };
-222
View File
@@ -1,222 +0,0 @@
const {
compilerRoot,
compilerNodeModules,
agentDirectories,
agentFiles,
_build,
_queryDefaultAssets,
} = FridaCompilerAgentCore;
const projectRoot = '/agent';
const projectNodeModules = '/agent/node_modules';
const entrypoint = 'index.ts';
const sourceMaps = 'included';
const compression = 'none';
const hashes = new Map();
let nextHashId = 1;
function main() {
const system = new StubSystem();
const assets = _queryDefaultAssets(projectRoot, system);
_build({
projectRoot,
entrypoint,
assets,
system,
sourceMaps,
compression,
onDiagnostic,
});
}
function onDiagnostic(diagnostic) {
throwNotImplemented('diagnostic', ts.flattenDiagnosticMessageText(diagnostic, '\n'));
}
class StubSystem {
args = [];
newLine = '\n';
useCaseSensitiveFileNames = true;
write(s) {
}
writeOutputIsTTY() {
return true;
}
readFile(path, encoding) {
if (path === '/agent/tsconfig.json')
return '{}';
if (path === '/agent/index.ts')
return 'Interceptor.attach(ptr(1234), { onEnter(args) {} });'
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null) {
return agentFiles.get(agentZipPath);
}
throwNotImplemented('readFile', path);
}
getFileSize(path) {
throwNotImplemented('getFileSize');
}
writeFile(path, data, writeByteOrderMark) {
throwNotImplemented('writeFile');
}
watchFile(path, callback, pollingInterval, options) {
throwNotImplemented('watchFile');
}
watchDirectory(path, callback, recursive, options) {
throwNotImplemented('watchDirectory');
}
resolvePath(path) {
throwNotImplemented('resolvePath');
}
fileExists(path) {
if (path === '/package.json' || path === '/agent/package.json')
return false;
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null)
return agentFiles.has(agentZipPath);
throwNotImplemented('fileExists', path);
}
directoryExists(path) {
if (path === '/' || path === projectRoot || path === compilerNodeModules)
return true;
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null)
return agentDirectories.has(agentZipPath);
if (path === '/node_modules/@types' || path === '/node_modules')
return false;
throwNotImplemented('directoryExists', path);
}
createDirectory(path) {
throwNotImplemented('createDirectory');
}
getExecutingFilePath() {
return [compilerRoot, 'ext', 'typescript.js'].join('/');
}
getCurrentDirectory() {
return '/';
}
getDirectories(path) {
const agentZipPath = this.#nativePathToAgentZipPath(path);
if (agentZipPath !== null) {
const result = [];
for (const dir of agentDirectories) {
const slashIndex = dir.lastIndexOf('/');
const parent = dir.substring(0, slashIndex);
if (parent === agentZipPath) {
const basename = dir.substring(slashIndex + 1);
result.push(basename);
}
}
return result;
}
throwNotImplemented('getDirectories', path);
}
readDirectory(path, extensions, exclude, include, depth) {
if (!extensions.includes('.ts'))
throwNotImplemented('readDirectory', path, extensions);
return ['index.ts'];
}
getModifiedTime(path) {
}
setModifiedTime(path, time) {
}
deleteFile(path) {
}
createHash(data) {
let hash = hashes.get(data);
if (hash === undefined) {
hash = 'hash' + nextHashId++;
hashes.set(data, hash);
}
return hash;
}
createSHA256Hash(data) {
throwNotImplemented('createSHA256Hash');
}
getMemoryUsage() {
throwNotImplemented('getMemoryUsage');
}
exit(exitCode) {
}
realpath(path) {
return path;
}
getEnvironmentVariable(name) {
return '';
}
setTimeout(callback, ms, ...args) {
throwNotImplemented('setTimeout');
}
clearTimeout(timeoutId) {
throwNotImplemented('clearTimeout');
}
clearScreen() {
}
base64decode(input) {
throwNotImplemented('base64decode');
}
base64encode(input) {
throwNotImplemented('base64encode');
}
#nativePathToAgentZipPath(path) {
if (path.startsWith(compilerRoot)) {
const subPath = path.substring(compilerRoot.length);
if (subPath.startsWith('/node_modules')) {
return subPath;
}
return '/node_modules/frida-compile' + subPath;
}
if (path.startsWith(projectNodeModules)) {
return '/node_modules' + path.substring(projectNodeModules.length);
}
return null;
}
}
function throwNotImplemented(operation, ...details) {
throw new Error('not implemented: ' + operation + ((details.length > 0) ? ` (${details.join(' ')})` : ''));
}
main();
+28
View File
@@ -0,0 +1,28 @@
#ifdef _MSC_VER
#include <glib.h>
#ifdef HAVE_ARM64
# define FRIDA_CGO_INIT_FUNC _rt0_arm64_windows_lib
#elif GLIB_SIZEOF_VOID_P == 8
# define FRIDA_CGO_INIT_FUNC _rt0_amd64_windows_lib
#else
# define FRIDA_CGO_INIT_FUNC rt0_386_windows_lib
#endif
extern void FRIDA_CGO_INIT_FUNC ();
void
frida_compiler_backend_init (void)
{
FRIDA_CGO_INIT_FUNC ();
}
#else
void
frida_compiler_backend_init (void)
{
}
#endif
+816
View File
@@ -0,0 +1,816 @@
package main
/*
#include <stdint.h>
typedef enum {
FRIDA_OUTPUT_UNESCAPED,
FRIDA_OUTPUT_HEX_BYTES,
FRIDA_OUTPUT_C_STRING,
} FridaOutputFormat;
typedef enum {
FRIDA_BUNDLE_ESM,
FRIDA_BUNDLE_IIFE,
} FridaBundleFormat;
typedef void (* FridaBuildCompleteFunc) (char * bundle, char * error_message, void * user_data);
typedef void (* FridaWatchReadyFunc) (uintptr_t session_handle, char * error_message, void * user_data);
typedef void (* FridaStartingFunc) (void * user_data);
typedef void (* FridaFinishedFunc) (void * user_data);
typedef void (* FridaOutputFunc) (char * bundle, void * user_data);
typedef void (* FridaDiagnosticFunc) (char * category, int code, char * path, int line, int character, char * text,
void * user_data);
typedef void (* FridaDestroyFunc) (void * user_data);
static inline void
invoke_build_complete_func (FridaBuildCompleteFunc fn,
char * bundle,
char * error_message,
void * user_data)
{
fn (bundle, error_message, user_data);
}
static inline void
invoke_watch_ready_func (FridaWatchReadyFunc fn,
uintptr_t session_handle,
char * error_message,
void * user_data)
{
fn (session_handle, error_message, user_data);
}
static inline void
invoke_starting_func (FridaStartingFunc fn,
void * user_data)
{
fn (user_data);
}
static inline void
invoke_finished_func (FridaFinishedFunc fn,
void * user_data)
{
fn (user_data);
}
static inline void
invoke_output_func (FridaOutputFunc fn,
char * bundle,
void * user_data)
{
fn (bundle, user_data);
}
static inline void
invoke_diagnostic_func (FridaDiagnosticFunc fn,
char * category,
int code,
char * path,
int line,
int character,
char * text,
void * user_data)
{
fn (category, code, path, line, character, text, user_data);
}
static inline void
invoke_destroy_func (FridaDestroyFunc fn,
void * user_data)
{
fn (user_data);
}
*/
import "C"
import (
"fmt"
"path"
"path/filepath"
"runtime/cgo"
"strings"
"sync"
"unsafe"
esbuild "github.com/evanw/esbuild/pkg/api"
tsscanner "github.com/frida/typescript-go/pkg/scanner"
)
type BuildOptions struct {
ProjectRoot string
Entrypoint string
OutputFormat OutputFormat
BundleFormat BundleFormat
DisableTypeCheck bool
SourceMap bool
Compress bool
}
type OutputFormat C.FridaOutputFormat
const (
OutputFormatUnescaped OutputFormat = OutputFormat(C.FRIDA_OUTPUT_UNESCAPED)
OutputFormatHexBytes OutputFormat = OutputFormat(C.FRIDA_OUTPUT_HEX_BYTES)
OutputFormatCString OutputFormat = OutputFormat(C.FRIDA_OUTPUT_C_STRING)
)
type BundleFormat C.FridaBundleFormat
const (
BundleFormatESM BundleFormat = BundleFormat(C.FRIDA_BUNDLE_ESM)
BundleFormatIIFE BundleFormat = BundleFormat(C.FRIDA_BUNDLE_IIFE)
)
type Diagnostic struct {
category string
code int
path string
line, character int
text string
}
type BuildEventCallbacks struct {
OnStart BuildStartCallback
OnEnd BuildEndCallback
OnOutput BuildOutputCallback
OnDiagnostic BuildDiagnosticCallback
OnConfigChange ConfigChangeCallback
}
type BuildStartCallback func()
type BuildEndCallback func()
type BuildOutputCallback func(bundle string)
type BuildDiagnosticCallback func(d Diagnostic)
//export frida_compiler_backend_build
func frida_compiler_backend_build(cProjectRoot, cEntrypoint *C.char, outputFormat C.FridaOutputFormat, bundleFormat C.FridaBundleFormat,
disableTypeCheck, sourceMap, compress uintptr,
onCompleteFn C.FridaBuildCompleteFunc, onCompleteData unsafe.Pointer, onCompleteDataDestroy C.FridaDestroyFunc,
onDiagnosticFn C.FridaDiagnosticFunc, onDiagnosticData unsafe.Pointer) {
options := BuildOptions{
ProjectRoot: C.GoString(cProjectRoot),
Entrypoint: C.GoString(cEntrypoint),
OutputFormat: OutputFormat(outputFormat),
BundleFormat: BundleFormat(bundleFormat),
DisableTypeCheck: disableTypeCheck != 0,
SourceMap: sourceMap != 0,
Compress: compress != 0,
}
onComplete := NewCDelegate(onCompleteFn, onCompleteData, onCompleteDataDestroy)
onDiagnostic := NewCDelegate(onDiagnosticFn, onDiagnosticData, nil)
go func() {
defer onComplete.Dispose()
defer onDiagnostic.Dispose()
onDiagnostic := makeCBuildDiagnosticCallback(onDiagnostic)
bundle, err := build(options, onDiagnostic)
var cBundle, cErrorMessage *C.char
if err == nil {
cBundle = C.CString(bundle)
} else {
cErrorMessage = C.CString(err.Error())
}
C.invoke_build_complete_func(onComplete.Func, cBundle, cErrorMessage, onComplete.Data)
}()
}
//export frida_compiler_backend_watch
func frida_compiler_backend_watch(cProjectRoot, cEntrypoint *C.char, outputFormat C.FridaOutputFormat, bundleFormat C.FridaBundleFormat,
disableTypeCheck, sourceMap, compress uintptr,
onReadyFn C.FridaWatchReadyFunc, onReadyData unsafe.Pointer, onReadyDataDestroy C.FridaDestroyFunc,
onStartingFn C.FridaStartingFunc, onStartingData unsafe.Pointer,
onFinishedFn C.FridaFinishedFunc, onFinishedData unsafe.Pointer,
onOutputFn C.FridaOutputFunc, onOutputData unsafe.Pointer,
onDiagnosticFn C.FridaDiagnosticFunc, onDiagnosticData unsafe.Pointer) {
options := BuildOptions{
ProjectRoot: C.GoString(cProjectRoot),
Entrypoint: C.GoString(cEntrypoint),
OutputFormat: OutputFormat(outputFormat),
BundleFormat: BundleFormat(bundleFormat),
DisableTypeCheck: disableTypeCheck != 0,
SourceMap: sourceMap != 0,
Compress: compress != 0,
}
onReady := NewCDelegate(onReadyFn, onReadyData, onReadyDataDestroy)
onStarting := NewCDelegate(onStartingFn, onStartingData, nil)
onFinished := NewCDelegate(onFinishedFn, onFinishedData, nil)
onOutput := NewCDelegate(onOutputFn, onOutputData, nil)
onDiagnostic := NewCDelegate(onDiagnosticFn, onDiagnosticData, nil)
go func() {
defer onReady.Dispose()
onDispose := func() {
onStarting.Dispose()
onFinished.Dispose()
onOutput.Dispose()
onDiagnostic.Dispose()
}
callbacks := BuildEventCallbacks{
OnStart: func() {
C.invoke_starting_func(onStarting.Func, onStarting.Data)
},
OnEnd: func() {
C.invoke_starting_func(onFinished.Func, onFinished.Data)
},
OnOutput: func(bundle string) {
C.invoke_output_func(onOutput.Func, C.CString(bundle), onOutput.Data)
},
OnDiagnostic: makeCBuildDiagnosticCallback(onDiagnostic),
}
session, err := NewWatchSession(options, onDispose, callbacks)
var cSession C.uintptr_t
var cErrorMessage *C.char
if err == nil {
cSession = C.uintptr_t(cgo.NewHandle(session))
} else {
cErrorMessage = C.CString(err.Error())
}
C.invoke_watch_ready_func(onReady.Func, cSession, cErrorMessage, onReady.Data)
}()
}
//export frida_compiler_backend_watch_session_dispose
func frida_compiler_backend_watch_session_dispose(h uintptr) {
handle := cgo.Handle(h)
session := handle.Value().(*WatchSession)
session.Dispose()
handle.Delete()
}
func makeCBuildDiagnosticCallback(onDiagnostic *CDelegate[C.FridaDiagnosticFunc]) BuildDiagnosticCallback {
return func(d Diagnostic) {
var cPath *C.char
if d.path != "" {
cPath = C.CString(d.path)
}
C.invoke_diagnostic_func(onDiagnostic.Func, C.CString(d.category), C.int(d.code), cPath, C.int(d.line),
C.int(d.character), C.CString(d.text), onDiagnostic.Data)
}
}
func build(options BuildOptions, onDiagnostic BuildDiagnosticCallback) (bundle string, err error) {
callbacks := BuildEventCallbacks{
OnOutput: func(b string) {
bundle = b
},
OnDiagnostic: onDiagnostic,
}
ctx, err := makeContext(options, callbacks)
if err != nil {
return
}
defer ctx.Dispose()
result := ctx.Rebuild()
if len(result.Errors) != 0 {
err = fmt.Errorf("Compilation failed")
}
return
}
type WatchSession struct {
mu sync.Mutex
options BuildOptions
callbacks BuildEventCallbacks
ctx esbuild.BuildContext
onDispose SessionDisposeHandler
}
type SessionDisposeHandler func()
func NewWatchSession(opts BuildOptions, onDispose SessionDisposeHandler, callbacks BuildEventCallbacks) (session *WatchSession, err error) {
cbs := BuildEventCallbacks{
OnStart: callbacks.OnStart,
OnEnd: callbacks.OnEnd,
OnOutput: callbacks.OnOutput,
OnDiagnostic: callbacks.OnDiagnostic,
OnConfigChange: func() {
if callbacks.OnConfigChange != nil {
callbacks.OnConfigChange()
}
session.onConfigChange()
},
}
ctx, err := makeContext(opts, cbs)
if err != nil {
return
}
ctx.Watch(esbuild.WatchOptions{})
session = &WatchSession{
options: opts,
callbacks: cbs,
ctx: ctx,
onDispose: onDispose,
}
return
}
func (s *WatchSession) Dispose() {
s.mu.Lock()
defer s.mu.Unlock()
if s.ctx != nil {
s.ctx.Dispose()
s.ctx = nil
}
s.onDispose()
}
func (s *WatchSession) onConfigChange() {
go func() {
s.mu.Lock()
defer s.mu.Unlock()
if s.ctx != nil {
s.ctx.Dispose()
s.ctx = nil
}
ctx, err := makeContext(s.options, s.callbacks)
if err != nil {
return
}
s.ctx = ctx
ctx.Watch(esbuild.WatchOptions{})
}()
}
func makeContext(options BuildOptions, callbacks BuildEventCallbacks) (ctx esbuild.BuildContext, err error) {
var e error
var projectRoot string
if projectRoot, e = filepath.EvalSymlinks(options.ProjectRoot); e != nil {
err = fmt.Errorf("Failed to resolve project root: %w", e)
return
}
var entrypoint string
if filepath.IsAbs(options.Entrypoint) {
entrypoint = options.Entrypoint
} else {
entrypoint = filepath.Join(projectRoot, options.Entrypoint)
}
if entrypoint, e = filepath.EvalSymlinks(entrypoint); e != nil {
err = fmt.Errorf("Failed to resolve entrypoint: %w", e)
return
}
rel, e := filepath.Rel(projectRoot, entrypoint)
if e != nil {
err = fmt.Errorf("Could not compute entrypoint path relative to project root: %w", e)
return
}
if strings.HasPrefix(rel, "..") {
err = fmt.Errorf("Entrypoint must be inside the project root")
return
}
isTS := strings.HasSuffix(entrypoint, ".ts")
var tsconfigCache *TSConfigCache
var tsconfigText string
var tsCompiler *TSCompiler
if isTS {
tsconfigCache = NewTSConfigCache(projectRoot, options.SourceMap, callbacks.OnConfigChange)
tsCompiler = NewTSCompiler(projectRoot, entrypoint, tsconfigCache.GetCompilerOptions)
_, tsconfigText, err = tsconfigCache.GetCompilerOptions(tsCompiler)
if err != nil {
err = fmt.Errorf("Failed to load tsconfig options: %w", err)
return
}
}
sourcemapOption := esbuild.SourceMapNone
if options.SourceMap {
if options.BundleFormat == BundleFormatESM {
sourcemapOption = esbuild.SourceMapExternal
} else {
sourcemapOption = esbuild.SourceMapInline
}
}
minifyWhitespace := false
minifyIdentifiers := false
minifySyntax := false
if options.Compress {
minifyWhitespace = true
minifyIdentifiers = true
minifySyntax = true
}
var format esbuild.Format
if options.BundleFormat == BundleFormatESM {
format = esbuild.FormatESModule
} else {
format = esbuild.FormatIIFE
}
plugins := []esbuild.Plugin{
makeBuildObserverPlugin(projectRoot, entrypoint, options, callbacks),
}
if isTS && !options.DisableTypeCheck {
plugins = append(plugins, makeTypeScriptPlugin(tsCompiler))
}
plugins = append(plugins, makeFridaShimsPlugin())
buildOpts := esbuild.BuildOptions{
Sourcemap: sourcemapOption,
SourcesContent: esbuild.SourcesContentExclude,
Target: esbuild.ES2022,
MinifyWhitespace: minifyWhitespace,
MinifyIdentifiers: minifyIdentifiers,
MinifySyntax: minifySyntax,
LegalComments: esbuild.LegalCommentsNone,
Bundle: true,
Outdir: projectRoot,
AbsWorkingDir: projectRoot,
Platform: esbuild.PlatformNeutral,
Format: format,
Inject: []string{"frida-builtins:///node-globals.js"},
EntryPoints: []string{entrypoint},
Write: false,
Plugins: plugins,
}
if isTS {
buildOpts.TsconfigRaw = tsconfigText
}
if buildCtx, ctxErr := esbuild.Context(buildOpts); ctxErr == nil {
ctx = buildCtx
} else {
for _, e := range ctxErr.Errors {
emitDiagnostic("error", e, callbacks.OnDiagnostic)
}
err = fmt.Errorf("Failed to create ESBuild context")
}
return
}
func emitDiagnostic(category string, message esbuild.Message, onDiagnostic BuildDiagnosticCallback) {
d := Diagnostic{
category: category,
code: -1,
text: message.Text,
}
l := message.Location
if l != nil {
d.path = l.File
d.line = l.Line
d.character = l.Column
}
if message.PluginName == "frida-custom-ts" && len(message.Notes) == 2 {
d.category = message.Notes[0].Text
fmt.Sscan(message.Notes[1].Text, &d.code)
}
onDiagnostic(d)
}
func changeToJS(p string) string {
ext := path.Ext(p)
base := p[:len(p)-len(ext)]
return base + ".js"
}
func makeBuildObserverPlugin(projectRoot, entrypoint string, options BuildOptions, callbacks BuildEventCallbacks) esbuild.Plugin {
return esbuild.Plugin{
Name: "frida-build-observer",
Setup: func(build esbuild.PluginBuild) {
if callbacks.OnStart != nil {
build.OnStart(func() (esbuild.OnStartResult, error) {
callbacks.OnStart()
return esbuild.OnStartResult{}, nil
})
}
build.OnEnd(func(result *esbuild.BuildResult) (esbuild.OnEndResult, error) {
if len(result.Errors) == 0 {
var output string
if options.BundleFormat == BundleFormatESM {
output = makeESMBundle(result.OutputFiles, projectRoot, entrypoint)
} else {
output = string(result.OutputFiles[0].Contents)
}
switch options.OutputFormat {
case OutputFormatHexBytes:
output = encodeStringToHexBytes(output)
case OutputFormatCString:
output = encodeStringToCString(output)
}
callbacks.OnOutput(output)
} else {
for _, e := range result.Errors {
emitDiagnostic("error", e, callbacks.OnDiagnostic)
}
for _, e := range result.Warnings {
emitDiagnostic("warning", e, callbacks.OnDiagnostic)
}
}
if callbacks.OnEnd != nil {
callbacks.OnEnd()
}
return esbuild.OnEndResult{}, nil
})
},
}
}
func makeESMBundle(files []esbuild.OutputFile, projectRoot, entrypoint string) string {
entrypointJS, entrypointMap := outputForEntrypoint(projectRoot, entrypoint)
relEntryp, err := filepath.Rel(projectRoot, entrypoint)
if err != nil {
panic(fmt.Sprintf("Cannot compute entrypoint relative path: %v", err))
}
entrySubDir := filepath.Dir(relEntryp)
entryIndexJS := -1
entryIndexMap := -1
for i, of := range files {
if of.Path == entrypointJS {
entryIndexJS = i
}
if of.Path == entrypointMap {
entryIndexMap = i
}
}
if entryIndexJS < 0 {
panic(fmt.Sprintf("Entrypoint JS %q not found in files", entrypointJS))
}
orderedFiles := make([]esbuild.OutputFile, 0, len(files))
orderedFiles = append(orderedFiles, files[entryIndexJS])
if entryIndexMap >= 0 {
orderedFiles = append(orderedFiles, files[entryIndexMap])
}
for i, of := range files {
if i == entryIndexJS || i == entryIndexMap {
continue
}
orderedFiles = append(orderedFiles, of)
}
var sb strings.Builder
sb.WriteString("📦\n")
for _, of := range orderedFiles {
size := len(of.Contents)
relPath, _ := filepath.Rel(projectRoot, of.Path)
withSub := filepath.Join(entrySubDir, relPath)
sb.WriteString(fmt.Sprintf("%d /%s\n", size, filepath.ToSlash(withSub)))
}
sb.WriteString("✄\n")
for i, of := range orderedFiles {
sb.Write(of.Contents)
if i < len(orderedFiles)-1 {
sb.WriteString("\n✄\n")
}
}
return sb.String()
}
func outputForEntrypoint(projectRoot, entrypoint string) (jsOut, mapOut string) {
jsOut = filepath.Join(projectRoot, changeToJS(filepath.Base(entrypoint)))
mapOut = jsOut + ".map"
return
}
func encodeStringToHexBytes(s string) string {
n := len(s)
if n == 0 {
return ""
}
totalLen := n*4 + (n-1)*2 + 1
buf := make([]byte, 0, totalLen)
hexDigits := "0123456789abcdef"
for i := 0; i < n; i++ {
b := s[i]
buf = append(buf, '0', 'x')
buf = append(buf,
hexDigits[b>>4],
hexDigits[b&0xF],
)
if i < n-1 {
if (i+1)%12 == 0 {
buf = append(buf, ',', '\n')
} else {
buf = append(buf, ',', ' ')
}
}
}
buf = append(buf, '\n')
return string(buf)
}
func encodeStringToCString(s string) string {
n := len(s)
if n == 0 {
return `""`
}
hexDigits := "0123456789abcdef"
var bldr strings.Builder
openLiteral := func() {
bldr.WriteByte('"')
}
closeLiteral := func() {
bldr.WriteByte('"')
}
inLiteral := false
for i := 0; i < n; i++ {
c := s[i]
if !inLiteral {
openLiteral()
inLiteral = true
}
if c == '\n' {
bldr.WriteByte('\\')
bldr.WriteByte('n')
closeLiteral()
inLiteral = false
if i < n-1 {
bldr.WriteByte('\n')
openLiteral()
inLiteral = true
}
continue
}
switch c {
case '"':
bldr.WriteByte('\\')
bldr.WriteByte('"')
case '\\':
bldr.WriteByte('\\')
bldr.WriteByte('\\')
case '\a':
bldr.WriteByte('\\')
bldr.WriteByte('a')
case '\b':
bldr.WriteByte('\\')
bldr.WriteByte('b')
case '\t':
bldr.WriteByte('\\')
bldr.WriteByte('t')
case '\v':
bldr.WriteByte('\\')
bldr.WriteByte('v')
case '\f':
bldr.WriteByte('\\')
bldr.WriteByte('f')
case '\r':
bldr.WriteByte('\\')
bldr.WriteByte('r')
default:
isPrintableExceptQuoteAndBackslash := c >= 0x20 && c <= 0x7E
if isPrintableExceptQuoteAndBackslash {
bldr.WriteByte(c)
} else {
bldr.WriteByte('\\')
bldr.WriteByte('x')
bldr.WriteByte(hexDigits[c>>4])
bldr.WriteByte(hexDigits[c&0xF])
}
}
}
if inLiteral {
closeLiteral()
}
bldr.WriteByte('\n')
return bldr.String()
}
func makeTypeScriptPlugin(compiler *TSCompiler) esbuild.Plugin {
return esbuild.Plugin{
Name: "frida-custom-ts",
Setup: func(build esbuild.PluginBuild) {
build.OnStart(func() (esbuild.OnStartResult, error) {
compiler.EnsureProgramUpToDate()
return esbuild.OnStartResult{}, nil
})
build.OnEnd(func(result *esbuild.BuildResult) (esbuild.OnEndResult, error) {
if len(result.Errors) == 0 {
compiler.CommitPendingInputs()
} else {
compiler.DropPendingInputs()
}
return esbuild.OnEndResult{}, nil
})
build.OnLoad(esbuild.OnLoadOptions{Filter: "\\.ts$"}, func(args esbuild.OnLoadArgs) (esbuild.OnLoadResult, error) {
compiledJS, tsDiagnostics, err := compiler.Compile(args.Path)
result := esbuild.OnLoadResult{
WatchFiles: compiler.WatchFiles(),
WatchDirs: compiler.WatchDirs(),
}
var esbuildMessages []esbuild.Message
for _, d := range tsDiagnostics {
f := d.File()
pos := d.Pos()
line, column := tsscanner.GetLineAndCharacterOfPosition(f, pos)
esbuildMessages = append(esbuildMessages, esbuild.Message{
Text: d.Message(),
Location: &esbuild.Location{
File: f.FileName(),
Line: line,
Column: column,
Length: d.Len(),
LineText: f.Text()[pos:d.End()],
},
Notes: []esbuild.Note{
{Text: d.Category().Name()},
{Text: fmt.Sprintf("%d", d.Code())},
},
})
}
if err != nil {
mainErr := esbuild.Message{Text: err.Error()}
result.Errors = append([]esbuild.Message{mainErr}, esbuildMessages...)
return result, nil
}
if len(esbuildMessages) > 0 {
result.Errors = esbuildMessages
return result, nil
}
result.Contents = &compiledJS
result.Loader = esbuild.LoaderJS
return result, nil
})
},
}
}
type CDelegate[F any] struct {
Func F
null F
Data unsafe.Pointer
dataDestroy C.FridaDestroyFunc
}
func NewCDelegate[F any](function F, data unsafe.Pointer, dataDestroy C.FridaDestroyFunc) *CDelegate[F] {
return &CDelegate[F]{Func: function, Data: data, dataDestroy: dataDestroy}
}
func (d *CDelegate[F]) Dispose() {
if d.dataDestroy != nil {
C.invoke_destroy_func(d.dataDestroy, d.Data)
}
d.Func = d.null
d.Data = nil
d.dataDestroy = nil
}
func main() {}
+312
View File
@@ -0,0 +1,312 @@
import base64
import json
import os
import shutil
import struct
import subprocess
import sys
from pathlib import Path
from typing import List
def main(argv):
go_config = json.loads(base64.b64decode(argv[1]).decode("utf-8"))
output_dir, priv_dir, go, npm, *inputs = [Path(d).resolve() for d in argv[2:]]
try:
build_backend(go_config, inputs, output_dir, priv_dir, go, npm)
except subprocess.CalledProcessError as e:
print(e, file=sys.stderr)
print(
"Output:\n\t| " + "\n\t| ".join(e.output.strip().split("\n")),
file=sys.stderr,
)
sys.exit(2)
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)
def build_backend(
config: dict,
inputs: List[Path],
output_dir: Path,
priv_dir: Path,
go: Path,
npm: Path,
):
base_dir = min(inputs, key=lambda p: len(p.parts)).parent
for f in inputs:
dest = priv_dir / f.relative_to(base_dir)
dest.parent.mkdir(exist_ok=True)
shutil.copy(f, dest)
go_sources = [str(f.relative_to(base_dir)) for f in inputs if f.suffix == ".go"]
def run(*args):
return subprocess.run(
args,
cwd=priv_dir,
env=config["env"],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding="utf-8",
check=True,
)
run(npm, "install")
# run(npm, "link", "/home/oleavr/src/frida-fs")
backend_a = "frida-compiler-backend.a"
backend_h = "frida-compiler-backend.h"
run(
go,
"build",
"-buildmode=c-archive",
"-o",
backend_a,
"-buildvcs=false",
*config["extra_go_args"],
*go_sources,
)
if (mingw := config.get("mingw")) is not None and (abi := config["abi"]) in {
"x86",
"x86_64",
}:
prefix = Path(mingw["prefix"])
ar = Path(mingw["ar"])
libmingwex_a = prefix / "lib" / "libmingwex.a"
if not libmingwex_a.exists():
libmingwex_a = prefix / mingw["triplet"] / "lib" / "libmingwex.a"
libgcc_objects = [
"_chkstk_ms.o",
]
run(ar, "x", mingw["libcc"], *libgcc_objects)
gwex_objflavor = "64" if abi == "x86_64" else "32"
gwex_objects = [
f"lib{gwex_objflavor}_libmingwex_a-{name}.o"
for name in [
"dmisc",
"gdtoa",
"gmisc",
"mingw_fprintf",
"mingw_pformat",
"misc",
]
]
run(ar, "x", libmingwex_a, *gwex_objects)
extra_objects = []
if abi == "x86_64":
run(ar, "x", backend_a, "go.o")
sort_pdata_in_object(Path(priv_dir) / "go.o")
extra_objects.append("go.o")
run(ar, "rs", backend_a, *libgcc_objects, *gwex_objects, *extra_objects)
shutil.copy(priv_dir / backend_a, output_dir / backend_a)
shutil.copy(priv_dir / backend_h, output_dir / backend_h)
# Work around the Go toolchain's almost-MSVC-compatible object files
# until our patch is merged upstream:
# https://go-review.googlesource.com/c/go/+/678795
def sort_pdata_in_object(object_file: Path):
data = bytearray(object_file.read_bytes())
# --- Parse COFF File Header (IMAGE_FILE_HEADER) ---
# Format: WORD Machine; WORD NumberOfSections;
# DWORD TimeDateStamp; DWORD PointerToSymbolTable;
# DWORD NumberOfSymbols; WORD SizeOfOptionalHeader;
# WORD Characteristics;
IMAGE_FILE_HEADER_FMT = "<HHLLLHH"
IMAGE_FILE_HEADER_SIZE = struct.calcsize(IMAGE_FILE_HEADER_FMT)
if len(data) < IMAGE_FILE_HEADER_SIZE:
print("Error: File too small to be a valid COFF object", file=sys.stderr)
return
(
machine,
number_of_sections,
time_date_stamp,
pointer_to_symbol_table,
number_of_symbols,
size_of_optional_header,
characteristics,
) = struct.unpack(IMAGE_FILE_HEADER_FMT, data[0:IMAGE_FILE_HEADER_SIZE])
# --- Parse Section Headers to find .pdata ---
# Each IMAGE_SECTION_HEADER is 40 bytes: Name[8], Misc(VirtualSize), VirtualAddress,
# SizeOfRawData, PointerToRawData, PointerToRelocations, PointerToLinenumbers,
# NumberOfRelocations, NumberOfLinenumbers, Characteristics
SECTION_HEADER_FMT = "<8sLLLLLLHHI"
SECTION_HEADER_SIZE = struct.calcsize(SECTION_HEADER_FMT)
section_table_offset = IMAGE_FILE_HEADER_SIZE + size_of_optional_header
pdata_section_index = None
pdata_pointer_to_raw = None
pdata_size_of_raw = None
pdata_pointer_to_relocs = None
pdata_number_of_relocs = None
# Keep all section headers for rewriting relocation entries later if needed
section_headers = []
for i in range(number_of_sections):
offset = section_table_offset + i * SECTION_HEADER_SIZE
section_data = data[offset : offset + SECTION_HEADER_SIZE]
(
name,
virtual_size,
virtual_address,
size_of_raw_data,
pointer_to_raw_data,
pointer_to_relocations,
pointer_to_linenumbers,
number_of_relocations,
number_of_linenumbers,
sec_characteristics,
) = struct.unpack(SECTION_HEADER_FMT, section_data)
section_name = name.rstrip(b"\x00").decode("utf-8")
section_headers.append(
{
"name": section_name,
"offset": offset,
"virtual_size": virtual_size,
"virtual_address": virtual_address,
"size_of_raw_data": size_of_raw_data,
"pointer_to_raw_data": pointer_to_raw_data,
"pointer_to_relocations": pointer_to_relocations,
"number_of_relocations": number_of_relocations,
}
)
if section_name == ".pdata":
pdata_section_index = i
pdata_pointer_to_raw = pointer_to_raw_data
pdata_size_of_raw = size_of_raw_data
pdata_pointer_to_relocs = pointer_to_relocations
pdata_number_of_relocs = number_of_relocations
if pdata_section_index is None:
print("Error: No .pdata section found in the object file", file=sys.stderr)
return
# --- Parse Symbol Table ---
# Each IMAGE_SYMBOL is 18 bytes: Name[8], Value (4 bytes), SectionNumber (2 bytes),
# Type (2 bytes), StorageClass (1 byte), NumberOfAuxSymbols (1 byte)
SYMBOL_TABLE_ENTRY_SIZE = 18
symbols = []
for sym_index in range(number_of_symbols):
sym_offset = pointer_to_symbol_table + sym_index * SYMBOL_TABLE_ENTRY_SIZE
entry = data[sym_offset : sym_offset + SYMBOL_TABLE_ENTRY_SIZE]
if len(entry) < SYMBOL_TABLE_ENTRY_SIZE:
print("Error: Truncated symbol table entry", file=sys.stderr)
return
# Unpack: Name (8s), Value (L), SectionNumber (h), Type (H), StorageClass (B), NumberOfAuxSymbols (B)
name_bytes, value, section_number, sym_type, storage_class, num_aux = (
struct.unpack("<8sLhHBB", entry)
)
# Decode name: if name_bytes[0:4] are zeros, use string from offset in string table
if name_bytes[:4] == b"\x00\x00\x00\x00":
str_table_offset = struct.unpack("<L", name_bytes[4:])[0]
# String table starts immediately after symbol table: size (4 bytes) + NUL-terminated strings
str_tab_start = (
pointer_to_symbol_table + number_of_symbols * SYMBOL_TABLE_ENTRY_SIZE
)
# Fetch the name from string table
str_offset = str_tab_start + str_table_offset
name_end = data.find(b"\x00", str_offset)
symbol_name = data[str_offset:name_end].decode("utf-8")
else:
symbol_name = name_bytes.partition(b"\x00")[0].decode("utf-8")
symbols.append(
{"name": symbol_name, "value": value, "section_number": section_number}
)
# --- Read original .pdata section raw data ---
pdata_data = data[pdata_pointer_to_raw : pdata_pointer_to_raw + pdata_size_of_raw]
if len(pdata_data) % 12 != 0:
print("Error: .pdata size is not a multiple of 12 bytes", file=sys.stderr)
return
num_entries = len(pdata_data) // 12
# --- Read relocation entries for .pdata ---
# Each IMAGE_RELOCATION is 10 bytes: VirtualAddress (4), SymbolTableIndex (4), Type (2)
RELOC_ENTRY_SIZE = 10
reloc_entries = []
reloc_table_start = pdata_pointer_to_relocs
for rindex in range(pdata_number_of_relocs):
reloff = reloc_table_start + rindex * RELOC_ENTRY_SIZE
entry = data[reloff : reloff + RELOC_ENTRY_SIZE]
if len(entry) < RELOC_ENTRY_SIZE:
print("Error: Truncated relocation entry", file=sys.stderr)
return
va, sym_index, rtype = struct.unpack("<LLH", entry)
reloc_entries.append(
{"virtual_address": va, "symbol_index": sym_index, "type": rtype}
)
# There should be 3 relocations per .pdata entry
if len(reloc_entries) != num_entries * 3:
print(
"Warning: Expected {} relocations but found {}".format(
num_entries * 3, len(reloc_entries)
),
file=sys.stderr,
)
# --- Associate each entry with its relocations and sorting key ---
entries = []
for i in range(num_entries):
entry_bytes = pdata_data[i * 12 : (i + 1) * 12]
entry_relocs = reloc_entries[i * 3 : i * 3 + 3]
# Sorting key: use symbol.Value of first relocation"s symbol index
sym_idx = entry_relocs[0]["symbol_index"]
if sym_idx < 0 or sym_idx >= number_of_symbols:
key = 0
else:
key = symbols[sym_idx]["value"]
entries.append({"entry_bytes": entry_bytes, "relocs": entry_relocs, "key": key})
# --- Sort entries by computed key ---
entries.sort(key=lambda x: x["key"])
# --- Build new .pdata data buffer ---
sorted_pdata = bytearray()
for e in entries:
sorted_pdata.extend(e["entry_bytes"])
# --- Build new relocation table buffer ---
new_reloc_buf = bytearray()
for new_i, e in enumerate(entries):
for reloc in e["relocs"]:
field_offset = reloc["virtual_address"] % 12
new_va = new_i * 12 + field_offset
packed = struct.pack("<LLH", new_va, reloc["symbol_index"], reloc["type"])
new_reloc_buf.extend(packed)
# --- Write back sorted .pdata and new relocations into data buffer ---
# Replace .pdata raw data
data[pdata_pointer_to_raw : pdata_pointer_to_raw + pdata_size_of_raw] = sorted_pdata
# Replace relocation entries
data[pdata_pointer_to_relocs : pdata_pointer_to_relocs + len(new_reloc_buf)] = (
new_reloc_buf
)
# --- Emit the fixed object file ---
object_file.write_bytes(data)
if __name__ == "__main__":
main(sys.argv)
-3
View File
@@ -1,3 +0,0 @@
[resource-compiler]
namespace = Frida.Data.Compiler
compress = *.js:text:7; *.bin:generic:7
-3
View File
@@ -1,3 +0,0 @@
[resource-compiler]
namespace = Frida.Data.Compiler
compress = *.js:text:11; *.bin:generic:11
+239 -344
View File
@@ -5,59 +5,50 @@ namespace Frida {
public signal void output (string bundle);
public signal void diagnostics (Variant diagnostics);
public DeviceManager manager {
get;
construct;
private size_t watch_session_handle = 0;
private Gee.Queue<Diagnostic> pending_diagnostics = new Gee.ArrayQueue<Diagnostic> ();
private MainContext main_context;
// TODO: Remove the DeviceManager parameter.
public Compiler (DeviceManager? manager = null) {
Object ();
}
#if HAVE_COMPILER_BACKEND
private Promise<Agent>? load_request;
private Gee.Map<uint, MonitorEntry> monitors = new Gee.HashMap<uint, MonitorEntry> ();
private Gee.Set<MonitorEntry> dirty_monitors = new Gee.HashSet<MonitorEntry> ();
private TimeoutSource? monitor_flush_timer;
private Cancellable io_cancellable = new Cancellable ();
#endif
public Compiler (DeviceManager manager) {
Object (manager: manager);
static construct {
CompilerBackend.init ();
}
#if HAVE_COMPILER_BACKEND
public override void dispose () {
if (load_request != null)
close.begin ();
base.dispose ();
construct {
main_context = Frida.get_main_context ();
}
private async void close () {
try {
var agent = yield get_agent (null);
yield agent.close (null);
} catch (GLib.Error e) {
}
load_request = null;
if (monitor_flush_timer != null) {
monitor_flush_timer.destroy ();
monitor_flush_timer = null;
}
foreach (var entry in monitors.values)
detach_monitor_entry (entry);
monitors.clear ();
~Compiler () {
cancel_watch ();
}
#endif
public async string build (string entrypoint, BuildOptions? options = null, Cancellable? cancellable = null)
throws Error, IOError {
#if HAVE_COMPILER_BACKEND
var agent = yield get_agent (cancellable);
BuildOptions opts = (options != null) ? options : new BuildOptions ();
string project_root = compute_project_root (entrypoint, opts);
starting ();
try {
string bundle = yield agent.build (entrypoint, options, cancellable);
string? bundle = null;
string? error_message = null;
CompilerBackend.BuildCompleteFunc on_complete = (b, e) => {
bundle = b;
error_message = e;
schedule_on_frida_thread (build.callback);
};
CompilerBackend.build (project_root, entrypoint, opts.output_format, opts.bundle_format,
(size_t) (opts.type_check == NONE), (size_t) (opts.source_maps == INCLUDED),
(size_t) (opts.compression == TERSER), (owned) on_complete, on_diagnostic);
yield;
if (error_message != null)
throw new Error.INVALID_ARGUMENT ("%s", error_message);
output (bundle);
@@ -65,9 +56,6 @@ namespace Frida {
} finally {
finished ();
}
#else
throw_not_supported ();
#endif
}
public string build_sync (string entrypoint, BuildOptions? options = null, Cancellable? cancellable = null)
@@ -89,13 +77,36 @@ namespace Frida {
public async void watch (string entrypoint, WatchOptions? options = null, Cancellable? cancellable = null)
throws Error, IOError {
#if HAVE_COMPILER_BACKEND
var agent = yield get_agent (cancellable);
WatchOptions opts = (options != null) ? options : new WatchOptions ();
string project_root = compute_project_root (entrypoint, opts);
yield agent.watch (entrypoint, options, cancellable);
#else
throw_not_supported ();
#endif
cancel_watch ();
size_t session_handle = 0;
string? error_message = null;
CompilerBackend.WatchReadyFunc on_ready = (h, e) => {
session_handle = h;
error_message = e;
schedule_on_frida_thread (watch.callback);
};
CompilerBackend.watch (project_root, entrypoint, opts.output_format, opts.bundle_format,
(size_t) (opts.type_check == NONE), (size_t) (opts.source_maps == INCLUDED),
(size_t) (opts.compression == TERSER), (owned) on_ready, on_starting, on_finished,
on_output, on_diagnostic);
yield;
if (error_message != null)
throw new Error.INVALID_ARGUMENT ("%s", error_message);
watch_session_handle = session_handle;
}
private void cancel_watch () {
if (watch_session_handle != 0) {
CompilerBackend.WatchSession.dispose (watch_session_handle);
watch_session_handle = 0;
}
}
public void watch_sync (string entrypoint, WatchOptions? options = null, Cancellable? cancellable = null)
@@ -115,335 +126,161 @@ namespace Frida {
}
}
#if HAVE_COMPILER_BACKEND
private void on_watch_add (uint id, string path, string type, int64 polling_interval) {
var file = File.parse_name (path);
private void on_starting () {
schedule_on_frida_thread (() => {
starting ();
return Source.REMOVE;
});
}
GLib.FileMonitor monitor;
try {
if (type == "file")
monitor = file.monitor_file (FileMonitorFlags.SEND_MOVED, io_cancellable);
else if (type == "directory")
monitor = file.monitor_directory (FileMonitorFlags.NONE, io_cancellable);
else
assert_not_reached ();
} catch (GLib.Error e) {
return;
private void on_finished () {
schedule_on_frida_thread (() => {
finished ();
return Source.REMOVE;
});
}
private void on_output (owned string bundle) {
schedule_on_frida_thread (() => {
output (bundle);
return Source.REMOVE;
});
}
private void on_diagnostic (owned string category, int code, owned string? path, int line, int character,
owned string text) {
var diag = new Diagnostic () {
category = category,
code = code,
path = path,
line = line,
character = character,
text = text,
};
bool schedule_emit = false;
lock (pending_diagnostics) {
schedule_emit = pending_diagnostics.is_empty;
pending_diagnostics.add (diag);
}
if (polling_interval != 0)
monitor.rate_limit = (int) polling_interval;
var entry = new MonitorEntry (id, monitor);
entry.file_changed.connect (on_file_changed);
monitors[id] = entry;
}
private void on_watch_remove (uint id) {
MonitorEntry? entry;
if (monitors.unset (id, out entry))
detach_monitor_entry (entry);
}
private void detach_monitor_entry (MonitorEntry entry) {
dirty_monitors.remove (entry);
entry.file_changed.disconnect (on_file_changed);
entry.destroy ();
}
private void on_file_changed (MonitorEntry entry) {
dirty_monitors.add (entry);
if (monitor_flush_timer == null) {
var source = new TimeoutSource (50);
source.set_callback (on_monitor_flush_tick);
source.attach (MainContext.get_thread_default ());
monitor_flush_timer = source;
if (schedule_emit) {
schedule_on_frida_thread (() => {
emit_pending_diagnostics ();
return Source.REMOVE;
});
}
}
private bool on_monitor_flush_tick () {
var settled = new Gee.ArrayList<MonitorEntry> ();
var now = get_monotonic_time ();
settled.add_all_iterator (dirty_monitors.filter (m => now - m.last_change >= 50000));
Agent agent = load_request.future.value;
foreach (var entry in settled) {
agent.notify_file_changed (entry.id, entry.state, io_cancellable);
dirty_monitors.remove (entry);
private void emit_pending_diagnostics () {
var batch = new Gee.ArrayList<Diagnostic> ();
lock (pending_diagnostics) {
batch.add_all (pending_diagnostics);
pending_diagnostics.clear ();
}
if (!dirty_monitors.is_empty)
return Source.CONTINUE;
var builder = new VariantBuilder (new VariantType.array (VariantType.VARDICT));
monitor_flush_timer = null;
return Source.REMOVE;
}
private async Agent get_agent (Cancellable? cancellable) throws Error, IOError {
Future<Agent> future;
if (load_request != null) {
future = load_request.future;
} else {
load_request = new Promise<Agent> ();
future = load_request.future;
load_agent.begin ();
foreach (var d in batch) {
builder.open (VariantType.VARDICT);
builder.add ("{sv}", "category", new Variant.string (d.category));
builder.add ("{sv}", "code", new Variant.int64 (d.code));
if (d.path != null) {
var b = new VariantBuilder (VariantType.VARDICT);
b.add ("{sv}", "path", new Variant.string (d.path));
b.add ("{sv}", "line", new Variant.int64 (d.line));
b.add ("{sv}", "character", new Variant.int64 (d.character));
builder.add ("{sv}", "file", b.end ());
}
builder.add ("{sv}", "text", new Variant.string (d.text));
builder.close ();
}
return yield future.wait_async (cancellable);
diagnostics (builder.end ());
}
private async void load_agent () {
try {
var device = yield manager.get_device_by_type (LOCAL, 0, io_cancellable);
var session = yield device.get_host_session (io_cancellable);
var agent = new Agent (this, (LocalHostSession) session);
load_request.resolve (agent);
} catch (GLib.Error e) {
if ((e is Error || e is IOError.CANCELLED))
e = new Error.NOT_SUPPORTED ("%s", e.message);
load_request.reject (e);
load_request = null;
}
}
#else
[NoReturn]
private void throw_not_supported () throws Error {
throw new Error.NOT_SUPPORTED ("Compiler backend disabled at build-time");
}
#endif
private T create<T> () {
return Object.new (typeof (T), parent: this);
}
protected void schedule_on_frida_thread (owned SourceFunc function) {
var source = new IdleSource ();
source.set_callback ((owned) function);
source.attach (main_context);
}
private class Diagnostic {
public string category;
public int code;
public string? path;
public int line;
public int character;
public string text;
}
private abstract class CompilerTask<T> : AsyncTask<T> {
public weak Compiler parent {
get;
construct;
}
}
}
namespace CompilerBackend {
private extern void init ();
#if HAVE_COMPILER_BACKEND
private class Agent : InternalAgent {
public weak Compiler parent {
get;
construct;
}
private extern void build (string project_root, string entrypoint, OutputFormat output_format, BundleFormat bundle_format,
size_t disable_type_check, size_t source_map, size_t compress, owned BuildCompleteFunc on_complete,
DiagnosticFunc on_diagnostic);
private extern void watch (string project_root, string entrypoint, OutputFormat output_format, BundleFormat bundle_format,
size_t disable_type_check, size_t source_map, size_t compress, owned WatchReadyFunc on_ready,
StartingFunc on_starting, FinishedFunc on_finished, OutputFunc on_output, DiagnosticFunc on_diagnostic);
private Promise<string> source_request = new Promise<string> ();
private Promise<Bytes?> snapshot_request = new Promise<Bytes?> ();
public Agent (Compiler parent, LocalHostSession host_session) {
Object (
parent: parent,
host_session: host_session,
#if HAVE_V8
script_runtime: ScriptRuntime.V8
namespace WatchSession {
private extern void dispose (size_t handle);
}
#else
script_runtime: ScriptRuntime.DEFAULT
#endif
);
}
private const string DISABLED_MESSAGE = "Compiler backend disabled at build-time";
construct {
load_resources ();
}
private void load_resources () {
new Thread<void> ("compiler-agent-loader", () => {
var agent_js_blob = Data.Compiler.get_agent_js_blob ();
Bytes agent_js_bytes = decompress (agent_js_blob.data, agent_js_blob.uncompressed_size);
source_request.resolve ((string) agent_js_bytes.get_data ());
var snapshot_blob = Data.Compiler.get_snapshot_bin_blob ();
Bytes snapshot = decompress (snapshot_blob.data, snapshot_blob.uncompressed_size);
snapshot_request.resolve ((snapshot.get_size () != 0) ? snapshot : null);
});
}
public async string build (string entrypoint, BuildOptions? options, Cancellable? cancellable)
throws Error, IOError {
BuildOptions opts = (options != null) ? options : new BuildOptions ();
Json.Node bundle = yield call ("build", new Json.Node[] {
new Json.Node.alloc ().init_string (compute_project_root (entrypoint, opts)),
new Json.Node.alloc ().init_string (entrypoint),
new Json.Node.alloc ().init_string (opts.source_maps.to_nick ()),
new Json.Node.alloc ().init_string (opts.compression.to_nick ()),
}, null, cancellable);
return bundle.get_string ();
}
public async void watch (string entrypoint, WatchOptions? options, Cancellable? cancellable)
throws Error, IOError {
WatchOptions opts = (options != null) ? options : new WatchOptions ();
yield call ("watch", new Json.Node[] {
new Json.Node.alloc ().init_string (compute_project_root (entrypoint, opts)),
new Json.Node.alloc ().init_string (entrypoint),
new Json.Node.alloc ().init_string (opts.source_maps.to_nick ()),
new Json.Node.alloc ().init_string (opts.compression.to_nick ()),
}, null, cancellable);
}
private static string compute_project_root (string entrypoint, CompilerOptions options) {
string? project_root = options.project_root;
if (project_root != null)
return project_root;
if (Path.is_absolute (entrypoint))
return Path.get_dirname (entrypoint);
return Environment.get_current_dir ();
}
public void notify_file_changed (uint id, FileState state, Cancellable? cancellable) {
var notification = new Json.Builder ();
notification
.begin_object ()
.set_member_name ("type")
.add_string_value ("watch:change")
.set_member_name ("id")
.add_int_value (id)
.set_member_name ("state")
.add_string_value (Marshal.enum_to_nick<FileState> (state))
.end_object ();
post.begin (notification.get_root (), cancellable);
}
protected override async uint get_target_pid (Cancellable? cancellable) throws Error, IOError {
return 0;
}
protected override async string? load_source (Cancellable? cancellable) throws Error, IOError {
return yield source_request.future.wait_async (cancellable);
}
protected override async Bytes? load_snapshot (Cancellable? cancellable, out SnapshotTransport transport)
throws Error, IOError {
transport = SHARED_MEMORY;
return yield snapshot_request.future.wait_async (cancellable);
}
protected override void on_event (string type, Json.Array event) {
if (type == "diagnostics") {
on_build_diagnostics (event.get_array_element (1));
} else if (type == "watch:compilation-starting") {
parent.starting ();
} else if (type == "watch:compilation-finished") {
parent.finished ();
} else if (type == "watch:bundle-updated") {
on_watch_bundle_updated (event.get_string_element (1));
} else if (type == "watch:add") {
parent.on_watch_add ((uint) event.get_int_element (1), event.get_string_element (2),
event.get_string_element (3), event.get_int_element (4));
} else if (type == "watch:remove") {
parent.on_watch_remove ((uint) event.get_int_element (1));
} else {
assert_not_reached ();
}
}
private void on_build_diagnostics (Json.Array diagnostics) {
uint n = diagnostics.get_length ();
var builder = new VariantBuilder (new VariantType.array (VariantType.VARDICT));
for (uint i = 0; i != n; i++) {
var diag = diagnostics.get_array_element (i);
builder.open (VariantType.VARDICT);
builder.add ("{sv}", "category", new Variant.string (diag.get_string_element (0)));
builder.add ("{sv}", "code", new Variant.int64 (diag.get_int_element (1)));
if (!diag.get_null_element (2)) {
var file = diag.get_array_element (2);
var b = new VariantBuilder (VariantType.VARDICT);
b.add ("{sv}", "path", new Variant.string (file.get_string_element (0)));
b.add ("{sv}", "line", new Variant.int64 (file.get_int_element (1)));
b.add ("{sv}", "character", new Variant.int64 (file.get_int_element (2)));
builder.add ("{sv}", "file", b.end ());
}
builder.add ("{sv}", "text", new Variant.string (diag.get_string_element (3)));
builder.close ();
}
parent.diagnostics (builder.end ());
}
private void on_watch_bundle_updated (string bundle) {
parent.output (bundle);
}
private static Bytes decompress (uint8[] data, uint uncompressed_size) {
var decoder = new Brotli.Decoder ();
decoder.set_parameter (LARGE_WINDOW, 1);
uint8[] uncompressed_data = new uint8[uncompressed_size + 1];
size_t available_in = data.length;
size_t available_out = uncompressed_size;
uint8 * next_in = data;
uint8 * next_out = uncompressed_data;
decoder.decompress_stream (&available_in, &next_in, &available_out, &next_out);
uncompressed_data.length = (int) (next_out - (uint8 *) uncompressed_data);
return new Bytes.take ((owned) uncompressed_data);
}
private void build (string project_root, string entrypoint, OutputFormat output_format, BundleFormat bundle_format,
size_t disable_type_check, size_t source_map, size_t compress, owned BuildCompleteFunc on_complete,
DiagnosticFunc on_diagnostic) {
on_complete (null, DISABLED_MESSAGE);
}
private class MonitorEntry : Object {
public signal void file_changed ();
public uint id;
public GLib.FileMonitor monitor;
public FileState state = PRISTINE;
public int64 last_change = -1;
public MonitorEntry (uint id, GLib.FileMonitor monitor) {
this.id = id;
this.monitor = monitor;
monitor.changed.connect (on_file_changed);
}
public void destroy () {
monitor.changed.disconnect (on_file_changed);
monitor.cancel ();
}
private void on_file_changed (File file, File? other_file, FileMonitorEvent event) {
switch (event) {
case CREATED:
state = PRISTINE;
break;
case CHANGED:
if (state != PRISTINE)
state = MODIFIED;
break;
case DELETED:
case MOVED:
state = DELETED;
break;
default:
return;
}
last_change = get_monotonic_time ();
file_changed ();
}
private void watch (string project_root, string entrypoint, OutputFormat output_format, BundleFormat bundle_format,
size_t disable_type_check, size_t source_map, size_t compress, owned WatchReadyFunc on_ready,
StartingFunc on_starting, FinishedFunc on_finished, OutputFunc on_output, DiagnosticFunc on_diagnostic) {
on_ready (0, DISABLED_MESSAGE);
}
private enum FileState {
PRISTINE,
MODIFIED,
DELETED,
namespace WatchSession {
private void dispose (size_t handle) {
assert_not_reached ();
}
}
#endif
private delegate void BuildCompleteFunc (owned string? bundle, owned string? error_message);
private delegate void WatchReadyFunc (size_t session_handle, owned string? error_message);
private delegate void StartingFunc ();
private delegate void FinishedFunc ();
private delegate void OutputFunc (owned string bundle);
private delegate void DiagnosticFunc (owned string category, int code, owned string? path, int line, int character,
owned string text);
}
private string compute_project_root (string entrypoint, CompilerOptions options) {
string? project_root = options.project_root;
if (project_root != null)
return project_root;
if (Path.is_absolute (entrypoint))
return Path.get_dirname (entrypoint);
return Environment.get_current_dir ();
}
public class CompilerOptions : Object {
@@ -452,6 +289,24 @@ namespace Frida {
set;
}
public OutputFormat output_format {
get;
set;
default = UNESCAPED;
}
public BundleFormat bundle_format {
get;
set;
default = ESM;
}
public TypeCheckMode type_check {
get;
set;
default = FULL;
}
public SourceMaps source_maps {
get;
set;
@@ -471,6 +326,46 @@ namespace Frida {
public sealed class WatchOptions : CompilerOptions {
}
public enum OutputFormat {
UNESCAPED,
HEX_BYTES,
C_STRING;
public static OutputFormat from_nick (string nick) throws Error {
return Marshal.enum_from_nick<OutputFormat> (nick);
}
public string to_nick () {
return Marshal.enum_to_nick<OutputFormat> (this);
}
}
public enum BundleFormat {
ESM,
IIFE;
public static BundleFormat from_nick (string nick) throws Error {
return Marshal.enum_from_nick<BundleFormat> (nick);
}
public string to_nick () {
return Marshal.enum_to_nick<BundleFormat> (this);
}
}
public enum TypeCheckMode {
FULL,
NONE;
public static TypeCheckMode from_nick (string nick) throws Error {
return Marshal.enum_from_nick<TypeCheckMode> (nick);
}
public string to_nick () {
return Marshal.enum_to_nick<TypeCheckMode> (this);
}
}
public enum SourceMaps {
INCLUDED,
OMITTED;
-91
View File
@@ -1,91 +0,0 @@
from pathlib import Path
import shutil
import subprocess
import sys
INPUTS = [
"agent-entrypoint.js",
"agent-core.ts",
"agent-warmup.js",
"package.json",
"package-lock.json",
"tsconfig.json",
"rollup.config.agent-core.ts",
"rollup.config.typescript.ts",
]
def main(argv):
output_dir, priv_dir, input_dir, npm, v8_mksnapshot = [Path(d).resolve() if d else None for d in argv[1:6]]
host_os_family, host_arch, host_cpu_mode = argv[6:9]
try:
generate_agent(output_dir, priv_dir, input_dir, npm, v8_mksnapshot, host_os_family, host_arch, host_cpu_mode)
except subprocess.CalledProcessError as e:
print(e, file=sys.stderr)
print("Output:\n\t| " + "\n\t| ".join(e.output.strip().split("\n")), file=sys.stderr)
sys.exit(2)
except Exception as e:
print(e, file=sys.stderr)
sys.exit(1)
def generate_agent(output_dir, priv_dir, input_dir, npm, v8_mksnapshot, host_os_family, host_arch, host_cpu_mode):
entrypoint = input_dir / "agent-entrypoint.js"
priv_dir.mkdir(exist_ok=True)
for name in INPUTS:
if name == "agent-entrypoint.js":
continue
shutil.copy(input_dir / name, priv_dir / name)
run_kwargs = {
"cwd": priv_dir,
"stdout": subprocess.PIPE,
"stderr": subprocess.STDOUT,
"encoding": "utf-8",
"check": True,
}
subprocess.run([npm, "install"], **run_kwargs)
#subprocess.run([npm, "link", "/Users/oleavr/src/frida-compile"], **run_kwargs)
components = ["typescript", "agent-core"]
for component in components:
subprocess.run([
npm, "run", "build:" + component,
"--",
"--environment", f"FRIDA_HOST_OS_FAMILY:{host_os_family},FRIDA_HOST_ARCH:{host_arch},FRIDA_HOST_CPU_MODE:{host_cpu_mode}",
"--silent",
],
**run_kwargs)
chunks = []
for component in components:
script = (priv_dir / f"{component}.js").read_text(encoding="utf-8")
chunks.append(script)
components_source = "\n".join(chunks)
agent = output_dir / "agent.js"
snapshot = output_dir / "snapshot.bin"
if v8_mksnapshot is not None:
shutil.copy(entrypoint, agent)
(priv_dir / "embed.js").write_text(components_source, encoding="utf-8")
subprocess.run([
v8_mksnapshot,
"--turbo-instruction-scheduling",
f"--startup-blob={snapshot}",
"embed.js",
input_dir / "agent-warmup.js",
],
**run_kwargs)
else:
agent.write_text("\n".join([
components_source,
entrypoint.read_text(encoding="utf-8"),
]), encoding="utf-8")
snapshot.write_bytes(b"")
if __name__ == "__main__":
main(sys.argv)
+14
View File
@@ -0,0 +1,14 @@
module github.com/frida/frida-core-compiler
go 1.24.3
require (
github.com/evanw/esbuild v0.25.5
github.com/frida/typescript-go v0.0.0-20250601212135-a4721f45f19c
)
require (
github.com/dlclark/regexp2 v1.11.5 // indirect
github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 // indirect
golang.org/x/sys v0.33.0 // indirect
)
+17
View File
@@ -0,0 +1,17 @@
github.com/dlclark/regexp2 v1.11.5 h1:Q/sSnsKerHeCkc/jSTNq1oCm7KiVgUMZRDUoRu0JQZQ=
github.com/dlclark/regexp2 v1.11.5/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/evanw/esbuild v0.25.5 h1:E+JpeY5S/1LFmnX1vtuZqUKT7qDVcfXdhzMhM3uIKFs=
github.com/evanw/esbuild v0.25.5/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/frida/typescript-go v0.0.0-20250601212135-a4721f45f19c h1:IWBI9AwSFLWymI4enx1jrAw0E4H2E+qHwsihv+AxSoE=
github.com/frida/typescript-go v0.0.0-20250601212135-a4721f45f19c/go.mod h1:L4RMzD/pFBl7CqIf9XTrX41RO2xcok3OOVVcowv0H4k=
github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8 h1:o8UqXPI6SVwQt04RGsqKp3qqmbOfTNMqDrWsc4O47kk=
github.com/go-json-experiment/json v0.0.0-20250517221953-25912455fbc8/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/peter-evans/patience v0.3.0 h1:rX0JdJeepqdQl1Sk9c9uvorjYYzL2TfgLX1adqYm9cA=
github.com/peter-evans/patience v0.3.0/go.mod h1:Kmxu5sY1NmBLFSStvXjX1wS9mIv7wMcP/ubucyMOAu0=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
+15 -42
View File
@@ -1,61 +1,34 @@
compiler_sources = files(
'compiler.vala',
'backend-glue.c',
)
if have_compiler_backend
compiler_mksnapshot = generate_compiler_snapshot ? v8_mksnapshot : ''
compiler_agent = custom_target('frida-compiler-agent',
compiler_backend = custom_target('frida-compiler-backend',
input: [
'agent-entrypoint.js',
'agent-core.ts',
'agent-warmup.js',
'go.mod',
'go.sum',
'backend.go',
'tscompiler.go',
'tsconfig.go',
'shims.go',
'package.json',
'package-lock.json',
'tsconfig.json',
'rollup.config.agent-core.ts',
'rollup.config.typescript.ts',
],
output: [
'agent.js',
'snapshot.bin',
'frida-compiler-backend.a',
'frida-compiler-backend.h',
],
command: [
python,
files('generate-agent.py'),
files('build-backend.py'),
go_config,
meson.current_build_dir(),
'@PRIVATE_DIR@',
meson.current_source_dir(),
go,
npm,
compiler_mksnapshot,
host_os_family,
host_arch_gumjs,
host_cpu_mode,
'@INPUT@',
],
)
compiler_data = custom_target('frida-data-compiler',
input: [
'compiler.resources.' + frida_profile,
compiler_agent,
],
output: [
'frida-data-compiler.vapi',
'frida-data-compiler.h',
'frida-data-compiler.c',
'frida-data-compiler-blob' + resource_blob_extension,
'frida-data-compiler-agent.js.br',
'frida-data-compiler-snapshot.bin.br',
],
command: [
resource_compiler_cmd_array,
'-c', '@INPUT0@',
'-o', meson.current_build_dir() / 'frida-data-compiler',
'@INPUT1@',
'@INPUT2@',
],
)
compiler_sources += compiler_data
backend_vala_args_private += '--pkg=libbrotlidec'
backend_deps_private += brotlidec_dep
backend_libs += compiler_backend[0]
endif
+1083 -1277
View File
File diff suppressed because it is too large. Load diff
+30 -21
View File
@@ -1,27 +1,36 @@
{
"name": "frida-compiler-agent",
"name": "frida-compiler-shims",
"version": "1.0.0",
"description": "Agent used by Frida's compiler",
"main": "agent.ts",
"scripts": {
"build:typescript": "rollup --config rollup.config.typescript.ts --configPlugin typescript",
"build:agent-core": "rollup --config rollup.config.agent-core.ts --configPlugin typescript"
},
"description": "Shims used by Frida's compiler",
"private": true,
"dependencies": {
"@frida/crosspath": "3.0.0",
"frida-compile": "17.0.0",
"frida-fs": "6.0.0"
},
"devDependencies": {
"@frida/rollup-plugin-node-polyfills": "^1.0.3",
"@rollup/plugin-node-resolve": "^14.1.0",
"@rollup/plugin-replace": "^4.0.0",
"@rollup/plugin-typescript": "^8.3.4",
"@frida/assert": "^3.0.2",
"@frida/base64-js": "^2.0.3",
"@frida/buffer": "^7.0.4",
"@frida/crypto": "^1.0.1",
"@frida/diagnostics_channel": "^1.0.0",
"@frida/events": "^4.0.4",
"@frida/http": "^4.0.2",
"@frida/http-parser-js": "^1.0.0",
"@frida/https": "^1.0.0",
"@frida/ieee754": "^2.0.2",
"@frida/net": "^4.0.2",
"@frida/os": "^1.0.2",
"@frida/path": "^2.0.3",
"@frida/process": "^1.2.1",
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0",
"@frida/readable-stream": "^4.1.3",
"@frida/reserved-words": "^1.0.0",
"@frida/stream": "^1.0.2",
"@frida/string_decoder": "^2.0.0",
"@frida/timers": "^3.0.0",
"@frida/tty": "^1.0.0",
"@frida/url": "^1.0.2",
"@frida/util": "^1.0.3",
"@frida/vm": "^2.0.0",
"@types/frida-gum": "19.0.0",
"@types/glob": "^8.0.0",
"@types/node": "18.7.23",
"glob": "^8.0.3",
"rollup": "^2.79.1",
"rollup-plugin-terser": "^7.0.2"
"@types/node": "18.19.103",
"frida-fs": "7.0.0"
}
}
-184
View File
@@ -1,184 +0,0 @@
import crosspath from "@frida/crosspath";
import fs from "fs";
import { sync as glob } from "glob";
import replace from "@rollup/plugin-replace";
import resolve from "@rollup/plugin-node-resolve";
import typescript from "@rollup/plugin-typescript";
import polyfills from "@frida/rollup-plugin-node-polyfills";
import { terser } from "rollup-plugin-terser";
import { defineConfig } from "rollup";
import type rollup from "rollup";
export default defineConfig({
input: "agent-core.ts",
output: {
file: "agent-core.js",
format: "umd",
name: "FridaCompilerAgentCore",
generatedCode: {
preset: "es2015",
},
strict: false,
interop: "default",
globals: {
"typescript": "ts",
},
},
plugins: [
typescript(),
replace({
preventAssignment: true,
values: computeSubstitutionValues(),
}),
stubTsImportPlugin(),
polyfills(),
resolve(),
/*
terser({
ecma: 2020,
compress: {
module: true,
global_defs: {
"process.env.FRIDA_COMPILE": true
},
},
mangle: {
module: true,
},
}),
*/
],
});
function computeSubstitutionValues() {
const hostOsFamily = process.env.FRIDA_HOST_OS_FAMILY;
if (hostOsFamily === undefined) {
throw new Error("missing FRIDA_HOST_OS_FAMILY");
}
const hostArch = process.env.FRIDA_HOST_ARCH;
if (hostArch === undefined) {
throw new Error("missing FRIDA_HOST_ARCH");
}
const hostCpuMode = process.env.FRIDA_HOST_CPU_MODE;
if (hostCpuMode === undefined) {
throw new Error("missing FRIDA_HOST_CPU_MODE");
}
const outputDir = __dirname;
const compilerDir = crosspath.join(__dirname, "node_modules", "frida-compile");
let usingLinkedCompiler = false;
try {
usingLinkedCompiler = fs.statSync(crosspath.join(compilerDir, "node_modules")).isDirectory();
} catch (e) {
}
const assetParentDir = usingLinkedCompiler ? compilerDir : outputDir;
const assetModulesDir = crosspath.join(assetParentDir, "node_modules");
const shimDirs = [
["@frida", "assert"],
["@frida", "base64-js"],
["@frida", "buffer"],
["@frida", "crypto"],
["@frida", "diagnostics_channel"],
["@frida", "events"],
["@frida", "http"],
["@frida", "http-parser-js"],
["@frida", "https"],
["@frida", "ieee754"],
["@frida", "net"],
["@frida", "os"],
["@frida", "path"],
["@frida", "process"],
["@frida", "punycode"],
["@frida", "querystring"],
["@frida", "readable-stream"],
["@frida", "stream"],
["@frida", "string_decoder"],
["@frida", "timers"],
["@frida", "tty"],
["@frida", "url"],
["@frida", "util"],
["@frida", "vm"],
["frida-fs"],
];
const typeDirs = [
["@types", "node"],
["@types", "frida-gum"],
];
const assets: string[] = [];
for (const shimDir of shimDirs) {
assets.push(...glob(crosspath.join(assetModulesDir, ...shimDir, "package.json")));
assets.push(...glob(crosspath.join(assetModulesDir, ...shimDir, "**", "*.js")));
}
for (const typeDir of typeDirs) {
assets.push(...glob(crosspath.join(assetModulesDir, ...typeDir, "package.json")));
assets.push(...glob(crosspath.join(assetModulesDir, ...typeDir, "**", "*.d.ts")));
}
assets.push(...glob(crosspath.join(compilerDir, "ext", "lib.es*.d.ts")));
assets.push(...glob(crosspath.join(compilerDir, "ext", "lib.decorators*.d.ts")));
const ignoredAssetFiles = new Set([
"@frida/process/browser.js",
]);
const agentDirectories = new Set<string>();
const agentFiles = new Map<string, string>();
for (const assetPath of assets) {
let assetRelpath = assetPath.substring(assetParentDir.length);
if (usingLinkedCompiler && assetRelpath.startsWith("/ext/")) {
assetRelpath = crosspath.join("/", "node_modules", "frida-compile", assetRelpath.substring(1));
}
const identifier = assetRelpath.split("/").slice(2).join("/");
if (ignoredAssetFiles.has(identifier)) {
continue;
}
let currentDir = crosspath.dirname(assetRelpath);
do {
agentDirectories.add(currentDir);
currentDir = crosspath.dirname(currentDir);
} while (currentDir !== "/");
agentFiles.set(assetRelpath, fs.readFileSync(assetPath, "utf-8"));
}
const orderedAgentDirectories = Array.from(agentDirectories);
orderedAgentDirectories.sort();
const orderedAgentFiles = Array.from(agentFiles);
orderedAgentFiles.sort((a, b) => a[0].localeCompare(b[0]));
return {
"Frida.version": "'0.0.0'",
"Process.id": "1",
"Process.platform": `'${hostOsFamily}'`,
"Process.arch": `'${hostArch}'`,
"Process.pointerSize": (hostCpuMode === "64") ? "8" : "4",
"__agentDirectories__": JSON.stringify(orderedAgentDirectories, null, 4),
"__agentFiles__": JSON.stringify(orderedAgentFiles, null, 4),
};
}
function stubTsImportPlugin(): rollup.Plugin {
return {
name: "stub-ts-import",
async resolveId(source, importer, options) {
if (crosspath.basename(source) === "typescript.js") {
return {
id: "typescript",
external: true,
meta: {},
moduleSideEffects: false,
syntheticNamedExports: false
};
}
return this.resolve(source, importer, { skipSelf: true, ...options });
}
};
}
-15
View File
@@ -1,15 +0,0 @@
import path from "path";
import { defineConfig } from "rollup";
export default defineConfig({
input: path.join("node_modules", "frida-compile", "ext", "typescript.js"),
output: {
file: "typescript.js",
format: "umd",
name: "ts",
generatedCode: {
preset: "es2015",
},
strict: false,
},
});
+195
View File
@@ -0,0 +1,195 @@
package main
import (
"embed"
"encoding/json"
"fmt"
"path/filepath"
"strings"
esbuild "github.com/evanw/esbuild/pkg/api"
)
var nodeGlobals = `
export { Buffer } from 'node:buffer';
export { default as process } from 'node:process';
`
//go:embed node_modules/@frida/*/package.json
//go:embed node_modules/@frida/*/*.js
//go:embed node_modules/@frida/*/*/*.js
//go:embed node_modules/frida-fs/package.json
//go:embed node_modules/frida-fs/*/*.js
var embeddedShims embed.FS
func makeFridaShimsPlugin() esbuild.Plugin {
const (
nsBuiltins = "frida-builtins"
nsShim = "frida-shim"
)
const (
builtinFilter = `^frida-builtins://(.+)$`
shimFilter = `^(assert|base64-js|buffer|crypto|diagnostics_channel|events|fs|http|https|http-parser-js|ieee754|net|os|path|process|punycode|querystring|readable-stream|stream|string_decoder|timers|tty|url|util|vm)$`
shimNodePrefixFilter = `^node:(assert|buffer|crypto|diagnostics_channel|events|fs|http|https|net|os|path|process|punycode|querystring|stream|string_decoder|timers|tty|url|util|vm)$`
)
return esbuild.Plugin{
Name: "frida-custom-shims",
Setup: func(build esbuild.PluginBuild) {
build.OnResolve(esbuild.OnResolveOptions{Filter: builtinFilter},
func(args esbuild.OnResolveArgs) (esbuild.OnResolveResult, error) {
return esbuild.OnResolveResult{
Path: strings.TrimPrefix(args.Path, "frida-builtins://"),
Namespace: nsBuiltins,
SideEffects: esbuild.SideEffectsFalse,
}, nil
})
build.OnLoad(esbuild.OnLoadOptions{Filter: ".*", Namespace: nsBuiltins},
func(args esbuild.OnLoadArgs) (esbuild.OnLoadResult, error) {
if args.Path != "/node-globals.js" {
return esbuild.OnLoadResult{
Errors: []esbuild.Message{{Text: "Unexpected path: " + args.Path}},
}, nil
}
return esbuild.OnLoadResult{
Contents: &nodeGlobals,
Loader: esbuild.LoaderJS,
}, nil
})
registerShimResolve := func(pattern string) {
build.OnResolve(esbuild.OnResolveOptions{Filter: pattern},
func(args esbuild.OnResolveArgs) (esbuild.OnResolveResult, error) {
return makeResolveResult(nsShim, args.Path)
})
}
registerShimResolve(shimFilter)
registerShimResolve(shimNodePrefixFilter)
build.OnResolve(esbuild.OnResolveOptions{Filter: ".*", Namespace: nsShim},
func(args esbuild.OnResolveArgs) (esbuild.OnResolveResult, error) {
if strings.HasPrefix(args.Path, ".") {
abs := filepath.ToSlash(filepath.Join(filepath.Dir(args.Importer), args.Path))
return esbuild.OnResolveResult{
Path: abs,
Namespace: nsShim,
SideEffects: esbuild.SideEffectsFalse,
}, nil
}
return makeResolveResult(nsShim, args.Path)
})
build.OnLoad(esbuild.OnLoadOptions{Filter: ".*", Namespace: nsShim},
func(args esbuild.OnLoadArgs) (esbuild.OnLoadResult, error) {
data, err := embeddedShims.ReadFile(filepath.ToSlash(args.Path))
if err != nil {
return esbuild.OnLoadResult{
Errors: []esbuild.Message{{
Text: fmt.Sprintf("Error reading shim file %q: %v", args.Path, err),
}},
}, nil
}
content := string(data)
return esbuild.OnLoadResult{
Contents: &content,
Loader: loaderFor(args.Path),
}, nil
})
},
}
}
func makeResolveResult(ns string, module string) (esbuild.OnResolveResult, error) {
path, errs := resolveShim(module)
if len(errs) > 0 {
return esbuild.OnResolveResult{Errors: errs}, nil
}
return esbuild.OnResolveResult{
Path: path,
Namespace: ns,
SideEffects: esbuild.SideEffectsFalse,
}, nil
}
func loaderFor(path string) esbuild.Loader {
switch ext := filepath.Ext(path); ext {
case ".js", ".mjs", ".cjs":
return esbuild.LoaderJS
case ".json":
return esbuild.LoaderJSON
default:
panic(fmt.Sprintf("frida-shims: unsupported file type %q", ext))
}
}
var shimMap = map[string]string{
"assert": "@frida/assert",
"base64-js": "@frida/base64-js",
"buffer": "@frida/buffer",
"crypto": "@frida/crypto",
"diagnostics_channel": "@frida/diagnostics_channel",
"events": "@frida/events",
"fs": "frida-fs",
"http": "@frida/http",
"https": "@frida/https",
"http-parser-js": "@frida/http-parser-js",
"ieee754": "@frida/ieee754",
"net": "@frida/net",
"os": "@frida/os",
"path": "@frida/path",
"process": "@frida/process",
"punycode": "@frida/punycode",
"querystring": "@frida/querystring",
"readable-stream": "@frida/readable-stream",
"stream": "@frida/stream",
"string_decoder": "@frida/string_decoder",
"timers": "@frida/timers",
"tty": "@frida/tty",
"url": "@frida/url",
"util": "@frida/util",
"vm": "@frida/vm",
}
type PackageJSON struct {
Main string `json:"main"`
Module string `json:"module"`
}
func resolveShim(shimName string) (string, []esbuild.Message) {
var subDir string
if strings.HasPrefix(shimName, "@frida/") {
subDir = shimName
} else {
actualShimName := strings.TrimPrefix(shimName, "node:")
var ok bool
subDir, ok = shimMap[actualShimName]
if !ok {
return "", []esbuild.Message{{Text: "Unknown shim: " + actualShimName}}
}
}
shimPackageDir := filepath.Join("node_modules", subDir)
packageJSONPath := filepath.Join(shimPackageDir, "package.json")
pkgJSONBytes, _ := embeddedShims.ReadFile(filepath.ToSlash(packageJSONPath))
var pkg PackageJSON
json.Unmarshal(pkgJSONBytes, &pkg)
entryFile := ""
if pkg.Module != "" {
entryFile = pkg.Module
} else if pkg.Main != "" {
entryFile = pkg.Main
} else {
entryFile = "index.js"
}
resolvedEntryPath := filepath.Join(shimPackageDir, entryFile)
return filepath.ToSlash(resolvedEntryPath), nil
}
+448
View File
@@ -0,0 +1,448 @@
package main
import (
"context"
"embed"
"fmt"
"maps"
"os"
"path/filepath"
"slices"
"sort"
"strings"
"sync"
"time"
"github.com/frida/typescript-go/pkg/ast"
"github.com/frida/typescript-go/pkg/bundled"
"github.com/frida/typescript-go/pkg/compiler"
"github.com/frida/typescript-go/pkg/core"
"github.com/frida/typescript-go/pkg/tsoptions"
"github.com/frida/typescript-go/pkg/tspath"
"github.com/frida/typescript-go/pkg/vfs"
"github.com/frida/typescript-go/pkg/vfs/iovfs"
"github.com/frida/typescript-go/pkg/vfs/osvfs"
)
//go:embed node_modules/@types/*/package.json
//go:embed node_modules/@types/*/*.d.ts
//go:embed node_modules/@types/*/*/*.d.ts
var embeddedTypes embed.FS
type TSCompiler struct {
projectRoot string
entrypoint string
loadCompilerOptions LoadCompilerOptionsHandler
fs vfs.FS
captureFs *captureFS
mu sync.Mutex
options *core.CompilerOptions
program *compiler.Program
programErr error
forceFreshProgram bool
mtimes map[tspath.Path]time.Time
inputDirs, inputFiles []string
pendingDirs, pendingFiles []string
}
type LoadCompilerOptionsHandler func(host tsoptions.ParseConfigHost) (*core.CompilerOptions, string, error)
func NewTSCompiler(projectRoot, entrypoint string, loadCompilerOptions LoadCompilerOptionsHandler) *TSCompiler {
captureFs := newCaptureFS(osvfs.FS())
fs := newTypesFS(bundled.WrapFS(captureFs), projectRoot)
return &TSCompiler{
projectRoot: projectRoot,
entrypoint: tspath.NormalizePath(entrypoint),
loadCompilerOptions: loadCompilerOptions,
fs: fs,
captureFs: captureFs,
}
}
func (c *TSCompiler) resetProgramState() {
c.options = nil
c.program = nil
c.programErr = nil
c.forceFreshProgram = false
c.mtimes = nil
}
func (c *TSCompiler) EnsureProgramUpToDate() error {
opts, _, err := c.loadCompilerOptions(c)
if err != nil {
c.resetProgramState()
c.recomputeInputs()
return err
}
var prog *compiler.Program
var progErr error
if c.forceFreshProgram || c.program == nil || opts != c.options {
c.forceFreshProgram = false
prog, progErr = c.createProgram(opts)
} else {
prog, progErr = c.updateProgram(c.program, opts)
}
c.program = prog
c.programErr = progErr
c.options = opts
c.recomputeInputs()
return progErr
}
func (c *TSCompiler) createProgram(options *core.CompilerOptions) (*compiler.Program, error) {
host := compiler.NewCompilerHost(options, c.projectRoot, c.fs, bundled.LibPath())
program := compiler.NewProgram(compiler.ProgramOptions{
RootFiles: []string{c.entrypoint},
Host: host,
Options: options,
})
c.updateMtimes(program)
return program, nil
}
func (c *TSCompiler) updateProgram(old *compiler.Program, options *core.CompilerOptions) (*compiler.Program, error) {
newMtimes, err := c.collectMtimes(old)
if err != nil {
return c.createProgram(options)
}
updated := []tspath.Path{}
newProg := old
for path, mtime := range newMtimes {
if !mtime.Equal(c.mtimes[path]) {
var reused bool
newProg, reused = newProg.UpdateProgram(path)
updated = append(updated, path)
if !reused {
c.updateMtimes(newProg)
return newProg, nil
}
}
}
c.mtimes = newMtimes
return newProg, nil
}
func (c *TSCompiler) updateMtimes(p *compiler.Program) {
mt, _ := c.collectMtimes(p)
c.mtimes = mt
}
func (c *TSCompiler) collectMtimes(p *compiler.Program) (map[tspath.Path]time.Time, error) {
mt := make(map[tspath.Path]time.Time, len(p.SourceFiles()))
for _, sf := range p.SourceFiles() {
name := sf.FileName()
if isBundled(name) {
continue
}
info := c.fs.Stat(name)
if info == nil {
return nil, fmt.Errorf("File %q disappeared", name)
}
mt[sf.Path()] = info.ModTime()
}
return mt, nil
}
func isBundled(name string) bool {
return strings.HasPrefix(name, "bundled://")
}
func (c *TSCompiler) WatchDirs() []string {
if c.inputDirs != nil {
return c.inputDirs
}
return c.pendingDirs
}
func (c *TSCompiler) WatchFiles() []string {
if c.inputFiles != nil {
return c.inputFiles
}
return c.pendingFiles
}
func (c *TSCompiler) CommitPendingInputs() {
c.inputDirs, c.pendingDirs = c.pendingDirs, nil
c.inputFiles, c.pendingFiles = c.pendingFiles, nil
}
func (c *TSCompiler) DropPendingInputs() {
c.pendingDirs, c.pendingFiles = nil, nil
}
func (c *TSCompiler) recomputeInputs() {
var capHint int
if c.program != nil {
capHint = 1 + len(c.program.GetSourceFiles())
} else {
capHint = 1
}
files := make([]string, 0, capHint)
files = append(files, filepath.Join(c.projectRoot, "tsconfig.json"))
if c.program != nil {
for _, sf := range c.program.GetSourceFiles() {
name := sf.FileName()
if !isBundled(name) {
files = append(files, name)
}
}
}
sort.Strings(files)
c.pendingDirs = uniqueDirs(files)
c.pendingFiles = files
}
func (c *TSCompiler) Compile(filePathToCompile string) (string, []*ast.Diagnostic, error) {
c.mu.Lock()
defer c.mu.Unlock()
if c.programErr != nil {
return "", nil, c.programErr
}
program := c.program
var targetSourceFile *ast.SourceFile
normalizedFilePathToCompile := tspath.NormalizePath(filePathToCompile)
for _, sf := range program.GetSourceFiles() {
if sf.FileName() == normalizedFilePathToCompile {
targetSourceFile = sf
break
}
}
if targetSourceFile == nil {
return "", nil, fmt.Errorf("TypeScript source file not found in program: %s", filePathToCompile)
}
c.captureFs.ClearOutputs()
res := program.Emit(compiler.EmitOptions{
TargetSourceFile: targetSourceFile,
})
ctx := context.Background()
diagnostics := program.GetSyntacticDiagnostics(ctx, targetSourceFile)
if len(diagnostics) == 0 {
diagnostics = append(diagnostics, program.GetBindDiagnostics(ctx, targetSourceFile)...)
}
if len(diagnostics) == 0 {
diagnostics = append(diagnostics, program.GetOptionsDiagnostics(ctx)...)
}
if len(diagnostics) == 0 {
diagnostics = append(diagnostics, program.GetGlobalDiagnostics(ctx)...)
}
if len(diagnostics) == 0 {
semanticDiags := program.GetSemanticDiagnostics(ctx, targetSourceFile)
for _, d := range semanticDiags {
switch d.Code() {
case
2305, // Module '{0}' has no exported member '{1}'.
2306, // File '{0}' is not a module.
2307: // Cannot find module '{0}' or its corresponding type declarations.
c.forceFreshProgram = true
}
}
diagnostics = append(diagnostics, semanticDiags...)
}
if res.EmitSkipped {
errMsg := "TypeScript compilation failed and was skipped"
if len(diagnostics) == 0 {
errMsg = fmt.Sprintf("TypeScript compilation failed and was skipped for %s, but no diagnostics reported", filePathToCompile)
}
return "", diagnostics, fmt.Errorf(errMsg)
}
var compiledJS string
var foundJSOutput bool
for path, content := range c.captureFs.GetOutputs() {
ext := filepath.Ext(path)
if ext == ".js" {
compiledJS = content
foundJSOutput = true
break
}
}
if !foundJSOutput {
if len(diagnostics) == 0 {
return "", nil, fmt.Errorf("TypeScript compilation for %s seemed to succeed (emit not skipped, no diagnostics) but no .js output file was captured. Captured outputs: %v", filePathToCompile, c.captureFs.GetOutputs())
}
return "", diagnostics, fmt.Errorf("No .js output file was captured for %s. Captured outputs: %v", filePathToCompile, c.captureFs.GetOutputs())
}
return compiledJS, diagnostics, nil
}
func uniqueDirs(files []string) []string {
m := make(map[string]struct{}, len(files))
for _, f := range files {
m[filepath.Dir(f)] = struct{}{}
}
out := make([]string, 0, len(m))
for d := range m {
out = append(out, d)
}
sort.Strings(out)
return out
}
// FS implements ParseConfigHost.
func (c *TSCompiler) FS() vfs.FS {
return c.fs
}
// GetCurrentDirectory implements ParseConfigHost.
func (c *TSCompiler) GetCurrentDirectory() string {
return c.projectRoot
}
type captureFS struct {
vfs.FS
outputs map[string]string
mutex sync.Mutex
}
var _ vfs.FS = (*captureFS)(nil)
func newCaptureFS(inner vfs.FS) *captureFS {
return &captureFS{
FS: inner,
outputs: make(map[string]string),
}
}
func (c *captureFS) ClearOutputs() {
c.mutex.Lock()
defer c.mutex.Unlock()
c.outputs = make(map[string]string)
}
func (c *captureFS) GetOutputs() map[string]string {
c.mutex.Lock()
defer c.mutex.Unlock()
snap := make(map[string]string, len(c.outputs))
for k, v := range c.outputs {
snap[k] = v
}
return snap
}
func (c *captureFS) WriteFile(path string, data string, writeByteOrderMark bool) error {
c.mutex.Lock()
defer c.mutex.Unlock()
c.outputs[path] = data
return nil
}
func (c *captureFS) Remove(path string) error {
c.mutex.Lock()
defer c.mutex.Unlock()
delete(c.outputs, path)
return nil
}
type typesFS struct {
vfs.FS
projectRoot string
types vfs.FS
}
var _ vfs.FS = (*typesFS)(nil)
func newTypesFS(inner vfs.FS, projectRoot string) *typesFS {
return &typesFS{
FS: inner,
projectRoot: projectRoot,
types: iovfs.From(embeddedTypes, true),
}
}
func (t *typesFS) DirectoryExists(path string) bool {
embeddedPath := t.resolveEmbeddedPath(path)
if embeddedPath != "" {
if t.types.DirectoryExists(embeddedPath) {
return true
}
}
return t.FS.DirectoryExists(path)
}
func (t *typesFS) GetAccessibleEntries(path string) vfs.Entries {
embeddedPath := t.resolveEmbeddedPath(path)
var embeddedEntries vfs.Entries
if embeddedPath != "" {
embeddedEntries = t.types.GetAccessibleEntries(embeddedPath)
}
otherEntries := t.FS.GetAccessibleEntries(path)
return vfs.Entries{
Files: mergeAndSort(embeddedEntries.Files, otherEntries.Files),
Directories: mergeAndSort(embeddedEntries.Directories, otherEntries.Directories),
}
}
func (t *typesFS) FileExists(path string) bool {
embeddedPath := t.resolveEmbeddedPath(path)
if embeddedPath != "" {
if t.types.FileExists(embeddedPath) {
return true
}
}
return t.FS.FileExists(path)
}
func (t *typesFS) ReadFile(path string) (contents string, ok bool) {
contents, ok = t.FS.ReadFile(path)
if ok {
return contents, ok
}
embeddedPath := t.resolveEmbeddedPath(path)
if embeddedPath != "" {
contents, ok = t.types.ReadFile(embeddedPath)
}
return contents, ok
}
func (c *typesFS) resolveEmbeddedPath(path string) string {
rel, err := filepath.Rel(c.projectRoot, path)
if err != nil {
return ""
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(os.PathSeparator)) {
return ""
}
return "/" + filepath.ToSlash(rel)
}
func mergeAndSort(a, b []string) []string {
m := make(map[string]struct{}, len(a)+len(b))
for _, v := range append(a, b...) {
m[v] = struct{}{}
}
return slices.Sorted(maps.Keys(m))
}
+158
View File
@@ -0,0 +1,158 @@
package main
import (
"encoding/json"
"fmt"
"path/filepath"
"reflect"
"strings"
"sync"
"time"
tscore "github.com/frida/typescript-go/pkg/core"
"github.com/frida/typescript-go/pkg/tsoptions"
"github.com/frida/typescript-go/pkg/tspath"
)
type TSConfigCache struct {
projectRoot string
sourceMap bool
tsconfigPath string
onChange ConfigChangeCallback
mu sync.Mutex
lastModTime time.Time
cachedOpts *tscore.CompilerOptions
lastText string
}
type ConfigChangeCallback func()
func NewTSConfigCache(
projectRoot string,
sourceMap bool,
callback ConfigChangeCallback,
) *TSConfigCache {
return &TSConfigCache{
projectRoot: projectRoot,
sourceMap: sourceMap,
tsconfigPath: filepath.Join(projectRoot, "tsconfig.json"),
lastModTime: time.Time{},
cachedOpts: nil,
lastText: "",
onChange: callback,
}
}
func (c *TSConfigCache) GetCompilerOptions(
host tsoptions.ParseConfigHost,
) (*tscore.CompilerOptions, string, error) {
c.mu.Lock()
defer c.mu.Unlock()
fs := host.FS()
info := fs.Stat(c.tsconfigPath)
var currentModTime time.Time
if info != nil {
currentModTime = info.ModTime()
} else {
currentModTime = time.Time{}
}
if c.cachedOpts != nil && currentModTime.Equal(c.lastModTime) {
return c.cachedOpts, c.lastText, nil
}
var tsconfigText string
if info != nil {
data, ok := fs.ReadFile(c.tsconfigPath)
if !ok {
return nil, "", fmt.Errorf("Unable to read %q", c.tsconfigPath)
}
tsconfigText = string(data)
} else {
tsconfigText = "{}"
}
parsedSource := tsoptions.NewTsconfigSourceFileFromFilePath(
tspath.NormalizePath(c.tsconfigPath),
tspath.ToPath(c.tsconfigPath, "", fs.UseCaseSensitiveFileNames()),
tsconfigText,
)
parsedCommandLine := tsoptions.ParseJsonSourceFileConfigFileContent(
parsedSource,
host,
c.projectRoot,
nil,
c.tsconfigPath,
nil, nil, nil,
)
if len(parsedCommandLine.Errors) > 0 {
var msgs []string
for _, diag := range parsedCommandLine.Errors {
msgs = append(msgs, diag.Message())
}
return nil, "", fmt.Errorf(
"Failed to parse %s: %s",
c.tsconfigPath,
strings.Join(msgs, "; "),
)
}
newOpts := parsedCommandLine.CompilerOptions()
newOpts.Module = tscore.ModuleKindNode16
newOpts.ModuleResolution = tscore.ModuleResolutionKindNode16
newOpts.NoEmit = tscore.TSFalse
sourceMapOptVal := boolToTristate(c.sourceMap)
newOpts.SourceMap = sourceMapOptVal
newOpts.InlineSourceMap = sourceMapOptVal
if newOpts.Target == tscore.ScriptTargetNone {
newOpts.Target = tscore.ScriptTargetES2022
}
if newOpts.Lib == nil {
newOpts.Lib = []string{"lib.es2022.d.ts"}
}
if newOpts.SkipLibCheck == tscore.TSUnknown {
newOpts.SkipLibCheck = tscore.TSTrue
}
if newOpts.Strict == tscore.TSUnknown {
newOpts.Strict = tscore.TSTrue
}
tsconfigData, _ := json.Marshal(parsedCommandLine.ParsedConfig)
tsconfigText = string(tsconfigData)
hadPreviousOpts := c.cachedOpts != nil
optsChanged := true
if c.cachedOpts != nil && reflect.DeepEqual(newOpts, c.cachedOpts) {
optsChanged = false
}
if optsChanged {
c.cachedOpts = newOpts
c.lastText = tsconfigText
}
c.lastModTime = currentModTime
c.mu.Unlock()
defer c.mu.Lock()
if hadPreviousOpts && optsChanged {
if c.onChange != nil {
c.onChange()
}
}
return newOpts, tsconfigText, nil
}
func boolToTristate(val bool) tscore.Tristate {
if val {
return tscore.TSTrue
}
return tscore.TSFalse
}
-11
View File
@@ -1,11 +0,0 @@
{
"compilerOptions": {
"target": "es2020",
"lib": ["es2020"],
"module": "ES2020",
"moduleResolution": "node",
"allowSyntheticDefaultImports": true,
"strict": true,
"noEmit": true
}
}
+1 -1
View File
@@ -257,7 +257,7 @@ function findSubstrateLauncher() {
if (Process.arch !== 'arm64')
return null;
const imp = Module.enumerateImports('/sbin/launchd').filter(imp => imp.name === 'posix_spawn')[0];
const imp = Process.mainModule.enumerateImports().find(imp => imp.name === 'posix_spawn');
if (imp === undefined)
return null;
const impl = imp.slot.readPointer().strip();
+420 -483
View File
@@ -11,543 +11,480 @@
"frida-objc-bridge": "^8.0.4"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5"
}
},
"node_modules/@frida/assert": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz",
"integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/base64-js": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz",
"integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
"cpu": [
"ppc64"
],
"license": "MIT"
},
"node_modules/@frida/buffer": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz",
"integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.5.1",
"ieee754": "^1.2.1"
}
},
"node_modules/@frida/crosspath": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz",
"integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "^17.0.36"
},
"engines": {
"node": ">=14.9.0"
"node": ">=18"
}
},
"node_modules/@frida/crypto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@frida/crypto/-/crypto-1.0.1.tgz",
"integrity": "sha512-WXTkVjESvX8TIVXIynJJv9BKSIdQP0Iis04StIXknkDi1ULdMlrypA9p5C4KW1H6GCkNsVnKbybpzsulYCTvag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/diagnostics_channel": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz",
"integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/events": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz",
"integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/@frida/http": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz",
"integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"http-parser-js": "^0.5.3"
}
},
"node_modules/@frida/http-parser-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz",
"integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/https": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz",
"integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/ieee754": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz",
"integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/android-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
"cpu": [
"arm"
],
"license": "BSD-3-Clause"
},
"node_modules/@frida/net": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz",
"integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/os": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz",
"integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/path": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz",
"integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/process": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz",
"integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/punycode": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz",
"integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/querystring": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz",
"integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/readable-stream": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz",
"integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/reserved-words": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz",
"integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/stream": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz",
"integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/readable-stream": "^4.1.3"
}
},
"node_modules/@frida/string_decoder": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz",
"integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/terser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz",
"integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=10"
"node": ">=18"
}
},
"node_modules/@frida/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/timers": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz",
"integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/tty": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz",
"integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/url": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz",
"integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==",
"node_modules/@esbuild/android-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0"
}
},
"node_modules/@frida/util": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz",
"integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/vm": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz",
"integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"node_modules/@esbuild/android-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/frida-gum": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.0.tgz",
"integrity": "sha512-qViK1KwvPEAkajwSUv0wpZvZLiX8xO4JFFCh8dfYZfzSyOEfoE0KliCP/nJSKIKG6N3hXnPowrvPufjs5fLKAA==",
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT"
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/node": {
"version": "17.0.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==",
"node_modules/@esbuild/linux-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT"
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/frida-compile": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-17.0.0.tgz",
"integrity": "sha512-ixJRj14qLH/Z0ckFWd5fKeDMm0W2+2WDpSGnLRgpn0nuCQAbDHRCqVCWtPnV8uzPJmA6XOX0pujsMpYe9q9RRw==",
"dev": true,
"dependencies": {
"@frida/assert": "^3.0.1",
"@frida/base64-js": "^2.0.3",
"@frida/buffer": "^7.0.4",
"@frida/crosspath": "^3.0.0",
"@frida/crypto": "^1.0.1",
"@frida/diagnostics_channel": "^1.0.0",
"@frida/events": "^4.0.4",
"@frida/http": "^4.0.2",
"@frida/http-parser-js": "^1.0.0",
"@frida/https": "^1.0.0",
"@frida/ieee754": "^2.0.2",
"@frida/net": "^4.0.1",
"@frida/os": "^1.0.0",
"@frida/path": "^2.0.3",
"@frida/process": "^1.2.1",
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0",
"@frida/readable-stream": "^4.1.3",
"@frida/reserved-words": "^1.0.0",
"@frida/stream": "^1.0.2",
"@frida/string_decoder": "^2.0.0",
"@frida/terser": "^1.0.0",
"@frida/timers": "^3.0.0",
"@frida/tty": "^1.0.0",
"@frida/url": "^1.0.2",
"@frida/util": "^1.0.3",
"@frida/vm": "^2.0.0",
"commander": "^11.1.0",
"frida-fs": "^6.0.0",
"typed-emitter": "^2.1.0"
"node": ">=18"
},
"bin": {
"frida-compile": "dist/cli.js"
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.5",
"@esbuild/android-arm": "0.25.5",
"@esbuild/android-arm64": "0.25.5",
"@esbuild/android-x64": "0.25.5",
"@esbuild/darwin-arm64": "0.25.5",
"@esbuild/darwin-x64": "0.25.5",
"@esbuild/freebsd-arm64": "0.25.5",
"@esbuild/freebsd-x64": "0.25.5",
"@esbuild/linux-arm": "0.25.5",
"@esbuild/linux-arm64": "0.25.5",
"@esbuild/linux-ia32": "0.25.5",
"@esbuild/linux-loong64": "0.25.5",
"@esbuild/linux-mips64el": "0.25.5",
"@esbuild/linux-ppc64": "0.25.5",
"@esbuild/linux-riscv64": "0.25.5",
"@esbuild/linux-s390x": "0.25.5",
"@esbuild/linux-x64": "0.25.5",
"@esbuild/netbsd-arm64": "0.25.5",
"@esbuild/netbsd-x64": "0.25.5",
"@esbuild/openbsd-arm64": "0.25.5",
"@esbuild/openbsd-x64": "0.25.5",
"@esbuild/sunos-x64": "0.25.5",
"@esbuild/win32-arm64": "0.25.5",
"@esbuild/win32-ia32": "0.25.5",
"@esbuild/win32-x64": "0.25.5"
}
},
"node_modules/frida-fs": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-6.0.0.tgz",
"integrity": "sha512-I0fnKupZh7fU2ixwCIjJnEqNdhfm/SC1ZYBMy58EmeqOWSbjw1Dpy99mJ7BJdbk2KNXJeaBZGxDYLtn0J9S+UA==",
"dev": true,
"license": "MIT"
},
"node_modules/frida-objc-bridge": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/frida-objc-bridge/-/frida-objc-bridge-8.0.4.tgz",
"integrity": "sha512-AUzwq/+TFtblQLTI97UPX22pBcvyG2oUde9380DXbcJ0zXts4n9JDVONHUr03aBowa0Le+bdBoVdCs7jyyjvlg==",
"license": "LGPL-2.0 WITH WxWindows-exception-3.1"
},
"node_modules/http-parser-js": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
"integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
"dev": true,
"license": "MIT"
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
},
"node_modules/typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz",
"integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==",
"dev": true,
"license": "MIT",
"optionalDependencies": {
"rxjs": "*"
}
}
}
}
+3 -4
View File
@@ -2,13 +2,12 @@
"name": "frida-osanalytics-agent",
"version": "1.0.0",
"description": "Agent used by Frida's Darwin backend on iOS/iPadOS/tvOS",
"type": "module",
"scripts": {
"prepare": "npm run build",
"build": "frida-compile index.js -o osanalytics.js -S -c"
"build": "esbuild index.js --outfile=osanalytics.js --bundle --platform=neutral --target=es2022 --minify"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5"
},
"dependencies": {
"frida-objc-bridge": "^8.0.4"
+420 -483
View File
@@ -11,543 +11,480 @@
"frida-objc-bridge": "^8.0.4"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5"
}
},
"node_modules/@frida/assert": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz",
"integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/base64-js": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz",
"integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
"cpu": [
"ppc64"
],
"license": "MIT"
},
"node_modules/@frida/buffer": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz",
"integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.5.1",
"ieee754": "^1.2.1"
}
},
"node_modules/@frida/crosspath": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz",
"integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "^17.0.36"
},
"engines": {
"node": ">=14.9.0"
"node": ">=18"
}
},
"node_modules/@frida/crypto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@frida/crypto/-/crypto-1.0.1.tgz",
"integrity": "sha512-WXTkVjESvX8TIVXIynJJv9BKSIdQP0Iis04StIXknkDi1ULdMlrypA9p5C4KW1H6GCkNsVnKbybpzsulYCTvag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/diagnostics_channel": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz",
"integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/events": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz",
"integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/@frida/http": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz",
"integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"http-parser-js": "^0.5.3"
}
},
"node_modules/@frida/http-parser-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz",
"integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/https": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz",
"integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/ieee754": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz",
"integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/android-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
"cpu": [
"arm"
],
"license": "BSD-3-Clause"
},
"node_modules/@frida/net": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz",
"integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/os": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz",
"integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/path": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz",
"integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/process": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz",
"integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/punycode": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz",
"integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/querystring": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz",
"integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/readable-stream": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz",
"integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/reserved-words": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz",
"integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/stream": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz",
"integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/readable-stream": "^4.1.3"
}
},
"node_modules/@frida/string_decoder": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz",
"integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/terser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz",
"integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=10"
"node": ">=18"
}
},
"node_modules/@frida/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/timers": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz",
"integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/tty": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz",
"integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/url": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz",
"integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==",
"node_modules/@esbuild/android-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0"
}
},
"node_modules/@frida/util": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz",
"integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/vm": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz",
"integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"node_modules/@esbuild/android-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=6.0.0"
"node": ">=18"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/frida-gum": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.0.tgz",
"integrity": "sha512-qViK1KwvPEAkajwSUv0wpZvZLiX8xO4JFFCh8dfYZfzSyOEfoE0KliCP/nJSKIKG6N3hXnPowrvPufjs5fLKAA==",
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT"
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@types/node": {
"version": "17.0.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==",
"node_modules/@esbuild/linux-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT"
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/esbuild": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/frida-compile": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-17.0.0.tgz",
"integrity": "sha512-ixJRj14qLH/Z0ckFWd5fKeDMm0W2+2WDpSGnLRgpn0nuCQAbDHRCqVCWtPnV8uzPJmA6XOX0pujsMpYe9q9RRw==",
"dev": true,
"dependencies": {
"@frida/assert": "^3.0.1",
"@frida/base64-js": "^2.0.3",
"@frida/buffer": "^7.0.4",
"@frida/crosspath": "^3.0.0",
"@frida/crypto": "^1.0.1",
"@frida/diagnostics_channel": "^1.0.0",
"@frida/events": "^4.0.4",
"@frida/http": "^4.0.2",
"@frida/http-parser-js": "^1.0.0",
"@frida/https": "^1.0.0",
"@frida/ieee754": "^2.0.2",
"@frida/net": "^4.0.1",
"@frida/os": "^1.0.0",
"@frida/path": "^2.0.3",
"@frida/process": "^1.2.1",
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0",
"@frida/readable-stream": "^4.1.3",
"@frida/reserved-words": "^1.0.0",
"@frida/stream": "^1.0.2",
"@frida/string_decoder": "^2.0.0",
"@frida/terser": "^1.0.0",
"@frida/timers": "^3.0.0",
"@frida/tty": "^1.0.0",
"@frida/url": "^1.0.2",
"@frida/util": "^1.0.3",
"@frida/vm": "^2.0.0",
"commander": "^11.1.0",
"frida-fs": "^6.0.0",
"typed-emitter": "^2.1.0"
"node": ">=18"
},
"bin": {
"frida-compile": "dist/cli.js"
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.5",
"@esbuild/android-arm": "0.25.5",
"@esbuild/android-arm64": "0.25.5",
"@esbuild/android-x64": "0.25.5",
"@esbuild/darwin-arm64": "0.25.5",
"@esbuild/darwin-x64": "0.25.5",
"@esbuild/freebsd-arm64": "0.25.5",
"@esbuild/freebsd-x64": "0.25.5",
"@esbuild/linux-arm": "0.25.5",
"@esbuild/linux-arm64": "0.25.5",
"@esbuild/linux-ia32": "0.25.5",
"@esbuild/linux-loong64": "0.25.5",
"@esbuild/linux-mips64el": "0.25.5",
"@esbuild/linux-ppc64": "0.25.5",
"@esbuild/linux-riscv64": "0.25.5",
"@esbuild/linux-s390x": "0.25.5",
"@esbuild/linux-x64": "0.25.5",
"@esbuild/netbsd-arm64": "0.25.5",
"@esbuild/netbsd-x64": "0.25.5",
"@esbuild/openbsd-arm64": "0.25.5",
"@esbuild/openbsd-x64": "0.25.5",
"@esbuild/sunos-x64": "0.25.5",
"@esbuild/win32-arm64": "0.25.5",
"@esbuild/win32-ia32": "0.25.5",
"@esbuild/win32-x64": "0.25.5"
}
},
"node_modules/frida-fs": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-6.0.0.tgz",
"integrity": "sha512-I0fnKupZh7fU2ixwCIjJnEqNdhfm/SC1ZYBMy58EmeqOWSbjw1Dpy99mJ7BJdbk2KNXJeaBZGxDYLtn0J9S+UA==",
"dev": true,
"license": "MIT"
},
"node_modules/frida-objc-bridge": {
"version": "8.0.4",
"resolved": "https://registry.npmjs.org/frida-objc-bridge/-/frida-objc-bridge-8.0.4.tgz",
"integrity": "sha512-AUzwq/+TFtblQLTI97UPX22pBcvyG2oUde9380DXbcJ0zXts4n9JDVONHUr03aBowa0Le+bdBoVdCs7jyyjvlg==",
"license": "LGPL-2.0 WITH WxWindows-exception-3.1"
},
"node_modules/http-parser-js": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
"integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
"dev": true,
"license": "MIT"
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
},
"node_modules/typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz",
"integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==",
"dev": true,
"license": "MIT",
"optionalDependencies": {
"rxjs": "*"
}
}
}
}
+3 -4
View File
@@ -2,13 +2,12 @@
"name": "frida-reportcrash-agent",
"version": "1.0.0",
"description": "Agent used by Frida's Darwin backend on iOS/iPadOS/tvOS",
"type": "module",
"scripts": {
"prepare": "npm run build",
"build": "frida-compile index.js -o reportcrash.js -S -c"
"build": "esbuild index.js --outfile=reportcrash.js --bundle --platform=neutral --target=es2022 --minify"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5"
},
"dependencies": {
"frida-objc-bridge": "^8.0.4"
+2
View File
@@ -109,6 +109,8 @@ _frida_get_springboard_api (void)
gum_interceptor_replace (interceptor, frida_xpc_look_up_endpoint, frida_replacement_xpc_look_up_endpoint, NULL, NULL);
else
g_error ("Unable to locate _xpc_look_up_endpoint(); please file a bug");
g_object_unref (interceptor);
}
#endif
+5 -1
View File
@@ -1459,7 +1459,9 @@ namespace Frida {
break;
}
}
assert (session_id != null);
if (session_id == null)
return;
agent_sessions.unset (session_id);
if (may_block) {
@@ -1483,6 +1485,8 @@ namespace Frida {
Promise<bool> detach_request;
if (pending_detach_requests.unset (id, out detach_request))
detach_request.resolve (true);
else if (session != null)
agent_sessions.unset (id);
}
private void on_spawn_added (HostSpawnInfo info) {
+22
View File
@@ -0,0 +1,22 @@
import esbuild from 'esbuild';
import alias from 'esbuild-plugin-alias';
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
const BUFFER_SHIM = require.resolve('@frida/buffer');
esbuild.build({
entryPoints: ['index.js'],
outfile: 'system-server.js',
bundle: true,
platform: 'neutral',
target: ['es2022'],
legalComments: 'none',
minify: true,
plugins: [
alias({
'buffer': BUFFER_SHIM,
'node:buffer': BUFFER_SHIM,
}),
],
}).catch(() => process.exit(1));
@@ -2,6 +2,7 @@ system_server_js = custom_target('system-server.js',
input: [
'package.json',
'package-lock.json',
'build.js',
'index.js',
],
output: [
+466 -456
View File
@@ -8,46 +8,443 @@
"name": "frida-system-server-agent",
"version": "1.0.0",
"dependencies": {
"@frida/buffer": "^7.0.4",
"frida-java-bridge": "^7.0.1"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5",
"esbuild-plugin-alias": "^0.2.1"
}
},
"node_modules/@frida/assert": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/@frida/assert/-/assert-3.0.2.tgz",
"integrity": "sha512-JXJq5SbXGrM5EkjrZKfRmB29zOoEOix02NC6A5TSJ+C1GE/X051EinJJsuOO2pEOx7KZwpvAHvS0WXW0+levKg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/base64-js": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/base64-js/-/base64-js-2.0.3.tgz",
"integrity": "sha512-2w0F+1TynOTCZ/v7du9LdHPWwq0lJhazjo2fF9upMyQmA1zHetT14fLuQ1v/6T0qPgyeEGkiSrybstU8EsgeUA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
"integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
"cpu": [
"ppc64"
],
"license": "MIT"
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"aix"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
"integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
"integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/android-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
"integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
"integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/darwin-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
"integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
"integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/freebsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
"integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
"integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
"cpu": [
"arm"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
"integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
"integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-loong64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
"integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
"cpu": [
"loong64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-mips64el": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
"integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
"cpu": [
"mips64el"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-ppc64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
"integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
"cpu": [
"ppc64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-riscv64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
"integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
"cpu": [
"riscv64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-s390x": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
"integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
"cpu": [
"s390x"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/linux-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
"integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
"integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/netbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
"integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"netbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
"integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/openbsd-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
"integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"openbsd"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/sunos-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
"integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"sunos"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-arm64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
"integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-ia32": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
"integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
"cpu": [
"ia32"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@esbuild/win32-x64": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
"integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=18"
}
},
"node_modules/@frida/buffer": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/@frida/buffer/-/buffer-7.0.4.tgz",
"integrity": "sha512-RxQ1lZRRiCJj7nhcCiD8xeJx0NsLpGGnjqsmTg7jShGmbnVFMN5W7+J+3gqdPSQhc/IxNBIWc6zRXVp4+qnYHg==",
"dev": true,
"funding": [
{
"type": "github",
@@ -68,322 +465,10 @@
"ieee754": "^1.2.1"
}
},
"node_modules/@frida/crosspath": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/crosspath/-/crosspath-3.0.0.tgz",
"integrity": "sha512-bNdO1spIPD2P40XtK89N49oZpJhstdlnkJZcD4yJ17jrdkm9Ctu0sd9MIEX6Z8Tm8ydhVJBAOMEKl9/R27onAQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "^17.0.36"
},
"engines": {
"node": ">=14.9.0"
}
},
"node_modules/@frida/crypto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@frida/crypto/-/crypto-1.0.1.tgz",
"integrity": "sha512-WXTkVjESvX8TIVXIynJJv9BKSIdQP0Iis04StIXknkDi1ULdMlrypA9p5C4KW1H6GCkNsVnKbybpzsulYCTvag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/diagnostics_channel": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/diagnostics_channel/-/diagnostics_channel-1.0.0.tgz",
"integrity": "sha512-mYX1jp/5Bpk24tHArJNx65iCk7qSuV8YJkdU0gFNVtJUXxfV8BG5WuPa4mL+ynxsbWWpsg/cwKZbLAepYKTdQQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/events": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/@frida/events/-/events-4.0.4.tgz",
"integrity": "sha512-qJVQ6VWHf9sjUKuiJzoCAC00frbpcwxeYfvQ+PP9LU/d70j+QvjWgYe98Qa3ekLaBU6r/AvWm8ThKCDUCLWrQQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8.x"
}
},
"node_modules/@frida/http": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/http/-/http-4.0.2.tgz",
"integrity": "sha512-cvkc7ex7GmVXVOWqtjXKBWUUbYEBgpNRKZbEEoMeI8KiIs8zejKwg+N7rx7296Ao+EP3+xcUr4wBVr3xLaUVfQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"http-parser-js": "^0.5.3"
}
},
"node_modules/@frida/http-parser-js": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/http-parser-js/-/http-parser-js-1.0.0.tgz",
"integrity": "sha512-2nMrNXt/OeTlWbqnE8AH4Sfz4I2+BGoN206dzKEyC/g2svtn83Xu+zuv/V3TkwrA27s26Mcy84ZwsXeNlqNxUQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/https": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/https/-/https-1.0.0.tgz",
"integrity": "sha512-OiqQ6qsALcWOktRLq07oJ0i6sH8eX6MXb/MdZS1qVKDRf6wchH4Pjn6fiLB+pt/OlYbggk+DOfpHwSdjTwuHMQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/ieee754": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@frida/ieee754/-/ieee754-2.0.2.tgz",
"integrity": "sha512-wlcUebnne4ENN7GDr5pTH598ZDLMVOsh0FjenxeVOe6u7ewZkz9gGRnLnZKJAm9kl5G6XhdxhI0cSXVQK/rQUw==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/@frida/net": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@frida/net/-/net-4.0.2.tgz",
"integrity": "sha512-qQRe7hQ+ZfCcG/SE3P1TRqQ9bmuK/T7wPCYaT4z56rBPWAxsaQbQHpX4fR6OrFaSDr7X0xJLsTbdIp9hGhhLZg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/os": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/os/-/os-1.0.2.tgz",
"integrity": "sha512-3ISAiGNiyIya3QN2EHBCz1wqP0enTdSxP99wUeroeh8+AQRmgoOr/5TRnrVry8pe378anay3fmV/tdUMMSkehQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/path": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@frida/path/-/path-2.0.3.tgz",
"integrity": "sha512-2RQy36QatoC846fzBhBhV8sXMsSOBGoYvwTHeaE1zUdz7F4RNScP4QEekTTooBYWYX/XjiF36KQpYAzc9OYFtg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/process": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@frida/process/-/process-1.2.1.tgz",
"integrity": "sha512-nvCu22DstFW2ttGFtOKekHM7vnjbZm+XgtvavOt427GNT6uV7k0JYK9tnMbcLMRWv57DG6udAmuJlWs8Paq1ag==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/punycode": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/punycode/-/punycode-3.0.0.tgz",
"integrity": "sha512-XVSDY2KamDs1D5/fTVgHcOSNxdU4kTboxzqJMBbTjcQC7XScIT9c0EfbwKCq7Kci6gWQdsHSCr7lU+9Oc4KAdg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/querystring": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/querystring/-/querystring-1.0.0.tgz",
"integrity": "sha512-15m1fOZPmoO/vWlgPJrG/J9/BJDz6a2/JpVGpS8ynNzo+fBhTznaStX5nHxUs24mVTqh/OqLo0EiYJM5WWHXxg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/readable-stream": {
"version": "4.1.3",
"resolved": "https://registry.npmjs.org/@frida/readable-stream/-/readable-stream-4.1.3.tgz",
"integrity": "sha512-ntGUFmi+CryRGRJIK13a/VST2Ad19uivbln8Xd92vKPAARq+6vMIASDyZIqyl5BLRccfiyCHdYgrgQ6RI5rUig==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/reserved-words": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/reserved-words/-/reserved-words-1.0.0.tgz",
"integrity": "sha512-2yG/XxJlsGlk/mm6eZTb4OAaQEhkTI2qaFfZFtAsrA/XuCpuMWkS4y/guyBlsRu4hAuhK2HPmNM8+OLLK1zM9Q==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/stream": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/stream/-/stream-1.0.2.tgz",
"integrity": "sha512-4OuaC1ztmEKgTq3WeBhsy8Oq+AwW9n9cYnvLklcC9jwD93AEwgbWpecLlxJCVuALvTMdhKPg0nQVfyGYP/i9Bw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/readable-stream": "^4.1.3"
}
},
"node_modules/@frida/string_decoder": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/string_decoder/-/string_decoder-2.0.0.tgz",
"integrity": "sha512-in371tYZMHQiW9HF5MS3JDw6Ao6tyBoq34UWy2rzOswYyMG1rpizh85ofi/yVkxDiaqybEZefxzkVittpPGT6g==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/terser": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/terser/-/terser-1.0.0.tgz",
"integrity": "sha512-59h9WuNzD1Rx/zwoWqQ/FW/4Y/Q3R91Eng2hEwdHapqiTDvtKbZ08F6CynCR7ZVinrh4tLYsF46AtVPTz1ys9g==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
"commander": "^2.20.0",
"source-map-support": "~0.5.20"
},
"bin": {
"terser": "bin/terser"
},
"engines": {
"node": ">=10"
}
},
"node_modules/@frida/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/timers": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@frida/timers/-/timers-3.0.0.tgz",
"integrity": "sha512-3b+0igv10aT8TMxefrTAd06rActqbxJLY2Xkkq9vYcPBffB/yHszl0NYIp/5ko8WC3ecDYPU6bQiY6fjs72zTA==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/tty": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@frida/tty/-/tty-1.0.0.tgz",
"integrity": "sha512-p/kjLnKYxEAB1MdYP8+5rKv9CsHzyA+0jg9BcGETzjQVKHHcroHDULRxDYUh+DC7qs6cpX8QdDQh9E+a6ydgsQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/url": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/@frida/url/-/url-1.0.2.tgz",
"integrity": "sha512-ZKunbKJHMr8w2Eb/5K1avy0MzK1B998S17wYXNv3RmzBGxMm8S5T0F3qEpRxkU7/72P8m4izyQU87fWl+FjQsQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0"
}
},
"node_modules/@frida/util": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/@frida/util/-/util-1.0.3.tgz",
"integrity": "sha512-htcG3uDiRXv89ERVNNYhfase39kJ2X75ZARfrYcYEtJLFEsSk0nemM1YnEIR4CjrHvdvkWHrwgKkS+acOyoNEg==",
"dev": true,
"license": "MIT"
},
"node_modules/@frida/vm": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@frida/vm/-/vm-2.0.0.tgz",
"integrity": "sha512-7fsjLWscZT5odNIBtg6qbLNI+vAk1xmii6H5W2kaYkMYt0vRohQEcDSUWacA+eaWlu5SvMjZI82Yibj/3G9pJw==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/gen-mapping": {
"version": "0.3.8",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz",
"integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/set-array": "^1.2.1",
"@jridgewell/sourcemap-codec": "^1.4.10",
"@jridgewell/trace-mapping": "^0.3.24"
},
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/resolve-uri": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/set-array": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz",
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/@jridgewell/source-map": {
"version": "0.3.6",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.6.tgz",
"integrity": "sha512-1ZJTZebgqllO79ue2bm3rIGud/bOe0pP5BjSRCRxxYkEZS8STV7zN84UBbiYu7jy+eCKSnVIUgoWWE/tt+shMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
}
},
"node_modules/@jridgewell/sourcemap-codec": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.25",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz",
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
"@jridgewell/sourcemap-codec": "^1.4.14"
}
},
"node_modules/@types/frida-gum": {
"version": "19.0.0",
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.0.0.tgz",
"integrity": "sha512-qViK1KwvPEAkajwSUv0wpZvZLiX8xO4JFFCh8dfYZfzSyOEfoE0KliCP/nJSKIKG6N3hXnPowrvPufjs5fLKAA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
"version": "17.0.45",
"resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.45.tgz",
"integrity": "sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==",
"dev": true,
"license": "MIT"
},
"node_modules/acorn": {
"version": "8.14.1",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz",
"integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==",
"dev": true,
"license": "MIT",
"bin": {
"acorn": "bin/acorn"
},
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/base64-js": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
"integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
"dev": true,
"funding": [
{
"type": "github",
@@ -400,68 +485,51 @@
],
"license": "MIT"
},
"node_modules/buffer-from": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
"dev": true,
"license": "MIT"
},
"node_modules/commander": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz",
"integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==",
"node_modules/esbuild": {
"version": "0.25.5",
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
"integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
"dev": true,
"hasInstallScript": true,
"license": "MIT",
"engines": {
"node": ">=16"
}
},
"node_modules/frida-compile": {
"version": "17.0.0",
"resolved": "https://registry.npmjs.org/frida-compile/-/frida-compile-17.0.0.tgz",
"integrity": "sha512-ixJRj14qLH/Z0ckFWd5fKeDMm0W2+2WDpSGnLRgpn0nuCQAbDHRCqVCWtPnV8uzPJmA6XOX0pujsMpYe9q9RRw==",
"dev": true,
"dependencies": {
"@frida/assert": "^3.0.1",
"@frida/base64-js": "^2.0.3",
"@frida/buffer": "^7.0.4",
"@frida/crosspath": "^3.0.0",
"@frida/crypto": "^1.0.1",
"@frida/diagnostics_channel": "^1.0.0",
"@frida/events": "^4.0.4",
"@frida/http": "^4.0.2",
"@frida/http-parser-js": "^1.0.0",
"@frida/https": "^1.0.0",
"@frida/ieee754": "^2.0.2",
"@frida/net": "^4.0.1",
"@frida/os": "^1.0.0",
"@frida/path": "^2.0.3",
"@frida/process": "^1.2.1",
"@frida/punycode": "^3.0.0",
"@frida/querystring": "^1.0.0",
"@frida/readable-stream": "^4.1.3",
"@frida/reserved-words": "^1.0.0",
"@frida/stream": "^1.0.2",
"@frida/string_decoder": "^2.0.0",
"@frida/terser": "^1.0.0",
"@frida/timers": "^3.0.0",
"@frida/tty": "^1.0.0",
"@frida/url": "^1.0.2",
"@frida/util": "^1.0.3",
"@frida/vm": "^2.0.0",
"commander": "^11.1.0",
"frida-fs": "^6.0.0",
"typed-emitter": "^2.1.0"
},
"bin": {
"frida-compile": "dist/cli.js"
"esbuild": "bin/esbuild"
},
"engines": {
"node": ">=18"
},
"optionalDependencies": {
"@esbuild/aix-ppc64": "0.25.5",
"@esbuild/android-arm": "0.25.5",
"@esbuild/android-arm64": "0.25.5",
"@esbuild/android-x64": "0.25.5",
"@esbuild/darwin-arm64": "0.25.5",
"@esbuild/darwin-x64": "0.25.5",
"@esbuild/freebsd-arm64": "0.25.5",
"@esbuild/freebsd-x64": "0.25.5",
"@esbuild/linux-arm": "0.25.5",
"@esbuild/linux-arm64": "0.25.5",
"@esbuild/linux-ia32": "0.25.5",
"@esbuild/linux-loong64": "0.25.5",
"@esbuild/linux-mips64el": "0.25.5",
"@esbuild/linux-ppc64": "0.25.5",
"@esbuild/linux-riscv64": "0.25.5",
"@esbuild/linux-s390x": "0.25.5",
"@esbuild/linux-x64": "0.25.5",
"@esbuild/netbsd-arm64": "0.25.5",
"@esbuild/netbsd-x64": "0.25.5",
"@esbuild/openbsd-arm64": "0.25.5",
"@esbuild/openbsd-x64": "0.25.5",
"@esbuild/sunos-x64": "0.25.5",
"@esbuild/win32-arm64": "0.25.5",
"@esbuild/win32-ia32": "0.25.5",
"@esbuild/win32-x64": "0.25.5"
}
},
"node_modules/frida-fs": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/frida-fs/-/frida-fs-6.0.0.tgz",
"integrity": "sha512-I0fnKupZh7fU2ixwCIjJnEqNdhfm/SC1ZYBMy58EmeqOWSbjw1Dpy99mJ7BJdbk2KNXJeaBZGxDYLtn0J9S+UA==",
"node_modules/esbuild-plugin-alias": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/esbuild-plugin-alias/-/esbuild-plugin-alias-0.2.1.tgz",
"integrity": "sha512-jyfL/pwPqaFXyKnj8lP8iLk6Z0m099uXR45aSN8Av1XD4vhvQutxxPzgA2bTcAwQpa1zCXDcWOlhFgyP3GKqhQ==",
"dev": true,
"license": "MIT"
},
@@ -471,18 +539,10 @@
"integrity": "sha512-pyNv12Y+erFgqdbFMsECh1OfqS77E62GeKHtxaBOZUPSpqcEkL0T2/6q/XD2161S4eGYBn6V7zumH2gbxtXK/Q==",
"license": "LGPL-2.0 WITH WxWindows-exception-3.1"
},
"node_modules/http-parser-js": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz",
"integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==",
"dev": true,
"license": "MIT"
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
@@ -498,56 +558,6 @@
}
],
"license": "BSD-3-Clause"
},
"node_modules/rxjs": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
"dev": true,
"license": "Apache-2.0",
"optional": true,
"dependencies": {
"tslib": "^2.1.0"
}
},
"node_modules/source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/source-map-support": {
"version": "0.5.21",
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer-from": "^1.0.0",
"source-map": "^0.6.0"
}
},
"node_modules/tslib": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"dev": true,
"license": "0BSD",
"optional": true
},
"node_modules/typed-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/typed-emitter/-/typed-emitter-2.1.0.tgz",
"integrity": "sha512-g/KzbYKbH5C2vPkaXGu8DJlHrGKHLsM25Zg9WuC9pMGfuvT+X25tZQWo5fK1BjBm8+UrVE9LDCvaY0CQk+fXDA==",
"dev": true,
"license": "MIT",
"optionalDependencies": {
"rxjs": "*"
}
}
}
}
+5 -4
View File
@@ -2,15 +2,16 @@
"name": "frida-system-server-agent",
"version": "1.0.0",
"description": "Agent used by Frida's Linux backend on Android",
"type": "module",
"scripts": {
"prepare": "npm run build",
"build": "frida-compile index.js -o system-server.js -S -c"
"build": "node build.js"
},
"devDependencies": {
"@types/frida-gum": "^19.0.0",
"frida-compile": "^17.0.0"
"esbuild": "^0.25.5",
"esbuild-plugin-alias": "^0.2.1"
},
"dependencies": {
"@frida/buffer": "^7.0.4",
"frida-java-bridge": "^7.0.1"
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/frida-gum.git
revision = 17.0.2
revision = 17.1.2
depth = 1
[provide]
+1 -1
View File
@@ -1,6 +1,6 @@
[wrap-git]
url = https://github.com/frida/ngtcp2.git
revision = cc5cf523615b7fa7a9340234c7eec3c3645ae969
revision = 828dcaed498b40954e1b496664a3309796968db6
depth = 1
[provide]
+1 -1
View File
@@ -2,7 +2,7 @@
tests=$(dirname "$0")
repo=$(dirname "$tests")
builddir=../build/tmp_thin-macos-arm64/frida-core
builddir=build
flamegraph=/Users/oleavr/src/FlameGraph
set -ex
+20 -3
View File
@@ -25,14 +25,31 @@ namespace Frida.CompilerTest {
string project_dir = DirUtils.make_tmp ("compiler-test.XXXXXX");
string agent_ts_path = Path.build_filename (project_dir, "agent.ts");
FileUtils.set_contents (agent_ts_path, "console.log(\"Hello World\");");
FileUtils.set_contents (agent_ts_path, """
import { log } from "./logger.js";
const woot = Buffer.from("w00t").toString("base64");
log("Hello World: " + woot);
log(hexdump(Process.mainModule.base, { ansi: true }));
""");
string logger_ts_path = Path.build_filename (project_dir, "logger.ts");
FileUtils.set_contents (logger_ts_path, """
export function log(...items: any[]) {
const message = items.join("\n");
console.log(`[LOG] ${message}`);
}
""");
var timer = new Timer ();
yield compiler.build (agent_ts_path);
var code = yield compiler.build (agent_ts_path);
uint elapsed_msec = (uint) (timer.elapsed () * 1000.0);
if (GLib.Test.verbose ())
if (GLib.Test.verbose ()) {
print ("Output:\nvvv\n%s^^^\n", code);
print ("Built in %u ms\n", elapsed_msec);
}
unowned string? test_log_path = Environment.get_variable ("FRIDA_TEST_LOG");
if (test_log_path != null) {
+340
View File
@@ -0,0 +1,340 @@
from __future__ import annotations
import base64
import json
import os
import platform
import re
import shlex
import shutil
import subprocess
import sys
from dataclasses import dataclass
from pathlib import Path
from typing import List, Optional, Tuple
if platform.system() == "Windows":
import winreg
FRIDA_OS_TO_GO_OS = {
"android": "linux", # XXX: Work around lack of support for -buildmode=c-archive
"macos": "darwin",
}
FRIDA_ABI_TO_GO_ARCH = {
"armbe8": "armbe",
"armhf": "arm",
"mips64el": "mips64le",
"mipsel": "mipsle",
"x86": "386",
"x86_64": "amd64",
}
FRIDA_ABI_TO_MINGW_FLAVOR = {
"arm64": "clangarm64",
"x86": "mingw32",
"x86_64": "mingw64",
}
FRIDA_ABI_TO_MINGW_ARCH = {
"arm64": "aarch64",
"x86": "i686",
"x86_64": "x86_64",
}
MACHINE_FLAG_PATTERN = re.compile(
r"^-m(?:arch|float-abi|fpu|thumb|fpmath|stackrealign|cpu|tune|fp32|abi)(?:=.*)?$"
)
def main(argv: List[str]):
args = argv[1:]
go = Path(args.pop(0))
host_os = args.pop(0)
host_abi = args.pop(0)
cc_id = args.pop(0)
cc_cmd_array = pop_cmd_array_arg(args)
ar_cmd_array = pop_cmd_array_arg(args)
try:
config = detect_config(go, host_os, host_abi, cc_id, cc_cmd_array, ar_cmd_array)
print("ok")
print(base64.b64encode(json.dumps(config).encode("utf-8")).decode("ascii"))
except Exception as e:
print("error")
print(str(e).replace("\n", "\\n"))
def pop_cmd_array_arg(args: List[str]) -> List[str]:
result = []
first = args.pop(0)
assert first == ">>>"
while True:
cur = args.pop(0)
if cur == "<<<":
break
result.append(cur)
if len(result) == 1 and not result[0]:
return None
return result
def detect_config(
go: Path,
host_os: str,
host_abi: str,
cc_id: str,
cc_cmd_array: List[str],
ar_cmd_array: Optional[List[str]],
) -> dict:
source_root = Path(os.environ["MESON_SOURCE_ROOT"])
build_root = Path(os.environ["MESON_BUILD_ROOT"])
subdir = Path(os.environ["MESON_SUBDIR"])
work_dir = build_root / subdir / "tools" / "cgo"
work_dir.mkdir(parents=True, exist_ok=True)
for f in ("go.mod", "main.go"):
shutil.copyfile(source_root / subdir / "tools" / "cgo" / f, work_dir / f)
extra_go_args = []
mingw = None
env = {
**os.environ,
"CGO_ENABLED": "1",
}
if cc_id == "msvc":
toolchain = MinGWToolchain.detect(host_abi)
mingw = {
"triplet": toolchain.triplet,
"prefix": str(toolchain.prefix),
"bindir": str(toolchain.bindir),
"cc": str(toolchain.cc),
"ar": str(toolchain.ar),
"libcc": str(toolchain.libcc),
}
env["CC"] = str(toolchain.cc)
env["PATH"] = str(toolchain.cc.parent) + ";" + env["PATH"]
ar = str(toolchain.ar)
else:
env["CC"] = shlex.join(
[arg for arg in cc_cmd_array if MACHINE_FLAG_PATTERN.fullmatch(arg) is None]
)
ar = ar_cmd_array[0]
extra_go_args.append(f"-ldflags=-extar={ar}")
if host_os == "macos":
extra_go_args.append("-ldflags=-extldflags=-mmacosx-version-min=11.0")
env["MACOSX_DEPLOYMENT_TARGET"] = "11.0"
if host_os == "android":
# XXX: Avoid socklen_t compatibility issue caused by us using GOOS=linux for Android
extra_go_args += ["-tags", "netgo"]
def run(*args):
return subprocess.run(
args,
cwd=work_dir,
env=env,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding="utf-8",
check=True,
)
goos = FRIDA_OS_TO_GO_OS.get(host_os, host_os)
goarch = FRIDA_ABI_TO_GO_ARCH.get(host_abi, host_abi)
needed = f"{goos}/{goarch}"
supported = run("go", "tool", "dist", "list").stdout.splitlines()
if needed not in supported:
raise NotSupportedError(f"Go does not support {needed}")
env["GOOS"] = goos
env["GOARCH"] = goarch
try:
run(go, "build", "-buildmode=c-archive", "-o", "cgotest.a", "-buildvcs=false")
except subprocess.CalledProcessError as e:
raise BuildError(e.output.strip())
config = {
"os": host_os,
"abi": host_abi,
"extra_go_args": extra_go_args,
"env": env,
}
if mingw is not None:
config["mingw"] = mingw
return config
class BuildError(Exception):
pass
class NotSupportedError(Exception):
pass
@dataclass
class MinGWToolchain:
triplet: str
prefix: Path
bindir: Path
cc: Path
ar: Path
libcc: Path
@staticmethod
def detect(host_abi: str) -> MinGWToolchain:
msys_prefix = find_msys2_prefix_from_environment()
if msys_prefix is None:
msys_prefix = find_msys2_prefix_from_registry()
if msys_prefix is None:
msys_prefix = Path(os.environ["SystemDrive"] + r"\msys64")
if not msys_prefix.exists():
msys_prefix = None
if msys_prefix is not None:
flavor = host_abi_to_mingw_flavor(host_abi)
mingw_prefix = msys_prefix / flavor
if not mingw_prefix.exists():
mingw_prefix = None
else:
mingw_prefix = None
mingw_cc = host_abi_to_mingw_cc(host_abi)
if mingw_prefix is not None:
mingw_bindir = mingw_prefix / "bin"
cc_path = mingw_bindir / f"{mingw_cc}.exe"
if not cc_path.exists():
cc_path = None
else:
raw_cc_path = shutil.which(mingw_cc)
cc_path = Path(raw_cc_path) if raw_cc_path is not None else None
if cc_path is not None:
mingw_bindir = cc_path.parent
mingw_prefix = mingw_bindir.parent
if cc_path is None:
raise MinGWNotFoundError(
"could not find an MSYS2/MinGW toolchain under msys64, "
"nor a MinGW-based GCC/Clang on PATH matching the requested host_abi"
)
def query_cc(*args):
return subprocess.run(
[cc_path, *args],
cwd=cc_path.parent,
capture_output=True,
encoding="utf-8",
check=True,
).stdout.rstrip()
try:
triplet = query_cc("-dumpmachine")
except subprocess.CalledProcessError:
raise MinGWNotFoundError(
f"unable to detect the machine triplet of {cc_path}"
)
actual_mingw_arch = triplet.split("-", 1)[0]
expected_mingw_arch = FRIDA_ABI_TO_MINGW_ARCH[host_abi]
if actual_mingw_arch != expected_mingw_arch:
raise MinGWNotFoundError(
f"compiler at {cc_path} is for {actual_mingw_arch}, expected {expected_mingw_arch}"
)
if host_abi != "arm64" and "mingw" not in triplet:
raise MinGWNotFoundError(
f"compiler at {cc_path} does not target MinGW, its triplet is {triplet}"
)
ar_path = cc_path.parent / "ar.exe"
try:
libcc_name = query_cc("-print-libgcc-file-name")
except subprocess.CalledProcessError:
raise MinGWNotFoundError(
f"unable to detect the libgcc file name of {cc_path}"
)
libcc_path = Path(libcc_name).resolve()
return MinGWToolchain(
triplet, mingw_prefix, mingw_bindir, cc_path, ar_path, libcc_path
)
class MinGWNotFoundError(Exception):
pass
def host_abi_to_mingw_flavor(abi: str) -> str:
try:
return FRIDA_ABI_TO_MINGW_FLAVOR[abi]
except KeyError:
raise MinGWNotFoundError(f"unsupported host_abi: {abi}")
def host_abi_to_mingw_cc(abi: str) -> str:
return "clang" if abi == "arm64" else "gcc"
def find_msys2_prefix_from_environment() -> Optional[Path]:
location = os.environ.get("MSYS2_LOCATION")
if location is None:
return None
return Path(location)
def find_msys2_prefix_from_registry() -> Optional[Path]:
UNINSTALL_PATHS = [
(
winreg.HKEY_CURRENT_USER,
r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
),
(
winreg.HKEY_CURRENT_USER,
r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
),
(
winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
),
(
winreg.HKEY_LOCAL_MACHINE,
r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall",
),
]
for hive, subkey_path in UNINSTALL_PATHS:
try:
with winreg.OpenKey(hive, subkey_path) as uninstall_root:
num_subkeys, _, _ = winreg.QueryInfoKey(uninstall_root)
for i in range(num_subkeys):
try:
subkey_name = winreg.EnumKey(uninstall_root, i)
with winreg.OpenKey(uninstall_root, subkey_name) as app_key:
disp_name, _ = winreg.QueryValueEx(app_key, "DisplayName")
if disp_name.startswith("MSYS2"):
install_loc, _ = winreg.QueryValueEx(
app_key, "InstallLocation"
)
return Path(install_loc)
except FileNotFoundError:
continue
except OSError:
continue
except FileNotFoundError:
continue
except OSError:
continue
return None
if __name__ == "__main__":
main(sys.argv)
+3
View File
@@ -0,0 +1,3 @@
module frida.re/cgotest
go 1.24.3
+13
View File
@@ -0,0 +1,13 @@
package main
/*
#include <stdlib.h>
*/
import "C"
//export frobnicate
func frobnicate() int {
return 42
}
func main() {}
+10 -7
View File
@@ -22,14 +22,17 @@ def compile_js_agent(output_js: Path, inputs: List[Path], priv_dir: Path, npm: P
dest.parent.mkdir(exist_ok=True)
shutil.copy(f, dest)
run_kwargs = {
"cwd": priv_dir,
"stdout": subprocess.PIPE,
"stderr": subprocess.STDOUT,
"encoding": "utf-8",
"check": True,
}
try:
subprocess.run(
[npm, "install"],
capture_output=True,
cwd=priv_dir,
encoding="utf-8",
check=True,
)
subprocess.run([npm, "install"], **run_kwargs)
subprocess.run([npm, "run", "build"], **run_kwargs)
except subprocess.CalledProcessError as e:
print(e, file=sys.stderr)
print(
+10
View File
@@ -163,6 +163,9 @@ namespace QuickJS {
[CCode (cname = "JS_NewCFunction2")]
public Value make_cfunction2 (CFunction func, string name, int length, CFunctionEnum cproto, int magic);
[CCode (cname = "JS_NewCFunctionData")]
public Value make_cfunction_data (CFunctionData func, int length, int magic, [CCode (array_length_pos = 3.1)] Value[] data);
[CCode (cname = "JS_NewPromiseCapability")]
public Value make_promise ([CCode (array_length = false, array_null_terminated = false)] Value[] resolving_funcs);
@@ -201,6 +204,10 @@ namespace QuickJS {
[CCode (has_target = false)]
public delegate Value CFunction (Context ctx, Value this_val, [CCode (array_length_pos = 2.1)] Value[] argv);
[CCode (has_target = false)]
public delegate Value CFunctionData (Context ctx, Value this_val, [CCode (array_length_pos = 2.1)] Value[] argv, int magic,
[CCode (array_length = false, array_null_terminated = false)] Value[] data);
[CCode (cprefix = "JS_CFUNC_", has_type_id = false)]
public enum CFunctionEnum {
generic,
@@ -314,6 +321,9 @@ namespace QuickJS {
[CCode (cname = "JS_GetOpaque")]
public void * get_opaque (ClassID class_id);
[CCode (cname = "JS_GetAnyOpaque")]
public void * get_any_opaque (out ClassID class_id);
[CCode (cname = "JS_SetOpaque")]
public void set_opaque (void * opaque);
}