mirror of
https://github.com/frida/frida-core.git
synced 2026-11-09 17:12:24 -10:00
Compare commits
No files matched your search
+145
-6
@@ -2,11 +2,15 @@ name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
tag:
|
||||
description: "Tag to build/test"
|
||||
required: false
|
||||
type: string
|
||||
|
||||
env:
|
||||
FRIDA_CORE_OPTIONS: '--with-devkits=core --enable-tests'
|
||||
@@ -71,6 +75,7 @@ jobs:
|
||||
if: ${{ !startsWith(matrix.id, 'windows-') && matrix.id != 'linux-x86' }}
|
||||
run: |
|
||||
./configure \
|
||||
--host=${{ matrix.id }} \
|
||||
--enable-compiler-backend \
|
||||
${{ env.FRIDA_CORE_OPTIONS }}
|
||||
make
|
||||
@@ -205,7 +210,7 @@ jobs:
|
||||
/sbin/entropy
|
||||
cat /etc/motd
|
||||
export PS1='\u@frida:\w\$ '
|
||||
/root/frida-tests
|
||||
/root/tests/frida-tests
|
||||
status=\$?
|
||||
echo "exit status: \$status"
|
||||
if [ \$status -eq 0 ]; then
|
||||
@@ -281,7 +286,8 @@ jobs:
|
||||
COPY initscript /tmp/initramfs/init
|
||||
RUN chmod +x /tmp/initramfs/init
|
||||
|
||||
COPY build/tests /tmp/initramfs/root/
|
||||
COPY build/tests /tmp/initramfs/root/tests/
|
||||
COPY build/lib/agent/frida-agent.so /tmp/initramfs/root/lib/agent/
|
||||
RUN find . | cpio -o --format=newc -R root:root > /root/initramfs.img
|
||||
|
||||
COPY launch.sh /root/launch.sh
|
||||
@@ -297,6 +303,7 @@ jobs:
|
||||
matrix:
|
||||
id:
|
||||
- ios-arm64
|
||||
- ios-arm64-simulator
|
||||
- android-x86
|
||||
- android-x86_64
|
||||
- android-arm
|
||||
@@ -341,6 +348,7 @@ jobs:
|
||||
name: core-devkit-${{ matrix.id }}
|
||||
path: build/src/devkit/
|
||||
- name: Package tests
|
||||
if: false
|
||||
run: |
|
||||
mkdir -p /tmp/pkg
|
||||
cd build
|
||||
@@ -360,7 +368,7 @@ jobs:
|
||||
esac
|
||||
tar -C /tmp/pkg -czf /tmp/runner.tar.gz .
|
||||
- name: Test on Corellium iOS device
|
||||
if: matrix.id == 'ios-arm64'
|
||||
if: false
|
||||
continue-on-error: true
|
||||
uses: frida/corellium-action@v4
|
||||
with:
|
||||
@@ -376,7 +384,7 @@ jobs:
|
||||
tar xf $ASSET_PATH
|
||||
./frida-tests
|
||||
- name: Test on Corellium Android device
|
||||
if: matrix.id == 'android-arm64'
|
||||
if: false
|
||||
continue-on-error: true
|
||||
uses: frida/corellium-action@v4
|
||||
with:
|
||||
@@ -480,3 +488,134 @@ jobs:
|
||||
else
|
||||
echo "No unexpected changes detected."
|
||||
fi
|
||||
|
||||
xcframework:
|
||||
name: Build FridaCore.xcframework
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- native
|
||||
- mobile
|
||||
steps:
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v4
|
||||
- name: Download macOS/x86_64 devkit
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: core-devkit-macos-x86_64
|
||||
path: devkits/macos-x86_64
|
||||
- name: Download macOS/arm64 devkit
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: core-devkit-macos-arm64
|
||||
path: devkits/macos-arm64
|
||||
- name: Download iOS/arm64 devkit
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: core-devkit-ios-arm64
|
||||
path: devkits/ios-arm64
|
||||
- name: Download iOS/arm64-simulator devkit
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: core-devkit-ios-arm64-simulator
|
||||
path: devkits/ios-arm64-simulator
|
||||
- name: Create FridaCore.xcframework
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
|
||||
mkdir -p devkits/macos-universal
|
||||
lipo -create \
|
||||
devkits/macos-x86_64/libfrida-core.a \
|
||||
devkits/macos-arm64/libfrida-core.a \
|
||||
-output devkits/macos-universal/libfrida-core.a
|
||||
|
||||
platforms=(
|
||||
"macos-universal"
|
||||
"ios-arm64"
|
||||
"ios-arm64-simulator"
|
||||
)
|
||||
|
||||
for platform in "${platforms[@]}"; do
|
||||
mkdir -p "xcframework_headers/${platform}/FridaCore"
|
||||
done
|
||||
|
||||
cp devkits/macos-x86_64/frida-core.h \
|
||||
xcframework_headers/macos-universal/frida-core-x86_64.h
|
||||
cp devkits/macos-arm64/frida-core.h \
|
||||
xcframework_headers/macos-universal/frida-core-arm64.h
|
||||
|
||||
cat > xcframework_headers/macos-universal/frida-core.h <<'EOF'
|
||||
#if defined (__x86_64__)
|
||||
# include "frida-core-x86_64.h"
|
||||
#elif defined (__arm64__)
|
||||
# include "frida-core-arm64.h"
|
||||
#else
|
||||
# error "Unsupported macOS architecture for FridaCore"
|
||||
#endif
|
||||
EOF
|
||||
|
||||
cp devkits/ios-arm64/frida-core.h \
|
||||
xcframework_headers/ios-arm64/frida-core.h
|
||||
cp devkits/ios-arm64-simulator/frida-core.h \
|
||||
xcframework_headers/ios-arm64-simulator/frida-core.h
|
||||
|
||||
for platform in "${platforms[@]}"; do
|
||||
cat > "xcframework_headers/${platform}/FridaCore/module.modulemap" <<'EOF'
|
||||
module FridaCore [extern_c] {
|
||||
header "../frida-core.h"
|
||||
export *
|
||||
}
|
||||
EOF
|
||||
done
|
||||
|
||||
xcodebuild -create-xcframework \
|
||||
-library devkits/macos-universal/libfrida-core.a \
|
||||
-headers xcframework_headers/macos-universal \
|
||||
-library devkits/ios-arm64/libfrida-core.a \
|
||||
-headers xcframework_headers/ios-arm64 \
|
||||
-library devkits/ios-arm64-simulator/libfrida-core.a \
|
||||
-headers xcframework_headers/ios-arm64-simulator \
|
||||
-output FridaCore.xcframework
|
||||
- name: Upload FridaCore.xcframework
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: FridaCore.xcframework
|
||||
path: FridaCore.xcframework
|
||||
|
||||
publish-xcframework:
|
||||
if: github.ref_type == 'tag'
|
||||
runs-on: macos-latest
|
||||
needs:
|
||||
- xcframework
|
||||
steps:
|
||||
- name: Download FridaCore.xcframework artifact
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: FridaCore.xcframework
|
||||
path: dist
|
||||
- name: Rewrap into FridaCore.xcframework directory
|
||||
shell: bash
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd dist
|
||||
|
||||
mkdir -p FridaCore.xcframework
|
||||
|
||||
shopt -s dotglob
|
||||
for f in *; do
|
||||
if [[ "$f" != "FridaCore.xcframework" ]]; then
|
||||
mv "$f" FridaCore.xcframework/
|
||||
fi
|
||||
done
|
||||
- name: Zip FridaCore.xcframework
|
||||
run: |
|
||||
cd dist
|
||||
zip -r FridaCore.xcframework.zip FridaCore.xcframework
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
files: |
|
||||
dist/FridaCore.xcframework.zip
|
||||
prerelease: ${{ contains(github.ref_name, 'snapshot') }}
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -52,7 +52,6 @@ endif
|
||||
|
||||
extra_deps = []
|
||||
if host_os_family != 'windows'
|
||||
extra_vala_args += '--pkg=gio-unix-2.0'
|
||||
extra_deps += gio_unix_dep
|
||||
endif
|
||||
|
||||
@@ -60,6 +59,11 @@ base_vala_args = [gum_vala_args, '--pkg=gio-2.0', '--pkg=json-glib-1.0']
|
||||
if nice_dep.found()
|
||||
base_vala_args += '--pkg=nice'
|
||||
endif
|
||||
if host_os_family != 'windows'
|
||||
base_vala_args += [
|
||||
'--pkg=gio-unix-2.0',
|
||||
]
|
||||
endif
|
||||
if host_os_family == 'darwin'
|
||||
base_vala_args += [
|
||||
'--pkg=corefoundation',
|
||||
|
||||
+28
-11
@@ -32,18 +32,34 @@ frida_version = get_option('frida_version')
|
||||
if frida_version == ''
|
||||
frida_version = run_command(releng / 'frida_version.py', meson.project_source_root(), check: true).stdout().strip()
|
||||
endif
|
||||
tokens = frida_version.split('.')
|
||||
frida_major_version = tokens[0].to_int()
|
||||
frida_minor_version = tokens[1].to_int()
|
||||
if tokens.length() == 4
|
||||
frida_micro_version = tokens[2].split('-')[0].to_int() - 1
|
||||
frida_nano_version = tokens[3].to_int() + 1
|
||||
|
||||
is_dev = frida_version.contains('-dev.')
|
||||
if is_dev
|
||||
dev_parts = frida_version.split('-dev.')
|
||||
assert(dev_parts.length() == 2)
|
||||
prefix = dev_parts[0]
|
||||
frida_nano_version = dev_parts[1].to_int() + 1
|
||||
else
|
||||
assert(tokens.length() == 3)
|
||||
frida_micro_version = tokens[2].to_int()
|
||||
prefix = frida_version
|
||||
frida_nano_version = 0
|
||||
endif
|
||||
frida_profile = (frida_version != '0.0.0' and frida_nano_version == 0) ? 'prod' : 'dev'
|
||||
|
||||
parts = prefix.split('-')
|
||||
core = parts[0]
|
||||
has_suffix = parts.length() > 1
|
||||
|
||||
core_tokens = core.split('.')
|
||||
assert(core_tokens.length() == 3)
|
||||
|
||||
frida_major_version = core_tokens[0].to_int()
|
||||
frida_minor_version = core_tokens[1].to_int()
|
||||
micro_encoded = core_tokens[2].to_int()
|
||||
|
||||
if is_dev and not has_suffix
|
||||
frida_micro_version = micro_encoded - 1
|
||||
else
|
||||
frida_micro_version = micro_encoded
|
||||
endif
|
||||
|
||||
api_version = '1.0'
|
||||
|
||||
@@ -292,6 +308,7 @@ gum_dep = dependency('frida-gum-1.0', default_options: [
|
||||
gumjs_dep = dependency('frida-gumjs-1.0')
|
||||
gumjs_inspector_dep = dependency('frida-gumjs-inspector-1.0')
|
||||
|
||||
glib_version_req = '>=2.74'
|
||||
glib_options = [
|
||||
'cocoa=disabled',
|
||||
'selinux=disabled',
|
||||
@@ -315,7 +332,7 @@ if optimize_for_prod
|
||||
gee_options += 'disable-internal-asserts=true'
|
||||
endif
|
||||
|
||||
glib_dep = dependency('glib-2.0', version: '>=2.72', default_options: glib_options)
|
||||
glib_dep = dependency('glib-2.0', version: glib_version_req, default_options: glib_options)
|
||||
gobject_dep = dependency('gobject-2.0')
|
||||
gmodule_dep = dependency('gmodule-2.0')
|
||||
gio_dep = dependency('gio-2.0')
|
||||
@@ -346,7 +363,7 @@ quickjs_dep = dependency('quickjs', required: get_option('barebone_backend'), de
|
||||
])
|
||||
lzfse_dep = dependency('lzfse', required: get_option('barebone_backend'))
|
||||
|
||||
native_glib_dep = dependency('glib-2.0', version: '>=2.74', native: true, default_options: glib_options)
|
||||
native_glib_dep = dependency('glib-2.0', version: glib_version_req, native: true, default_options: glib_options)
|
||||
native_gio_dep = dependency('gio-2.0', native: true)
|
||||
native_gee_dep = dependency('gee-0.8', native: true, default_options: gee_options)
|
||||
native_brotlienc_dep = dependency('libbrotlienc', native: true)
|
||||
|
||||
+1
-1
Submodule releng updated: 800f2385c3...c144673b9d.
+39
-3
@@ -106,6 +106,8 @@ type BuildOptions struct {
|
||||
DisableTypeCheck bool
|
||||
SourceMap bool
|
||||
Compress bool
|
||||
Platform esbuild.Platform
|
||||
Externals []string
|
||||
}
|
||||
|
||||
type OutputFormat C.FridaOutputFormat
|
||||
@@ -146,7 +148,7 @@ 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,
|
||||
disableTypeCheck, sourceMap, compress uintptr, cPlatform *C.char, cExternals **C.char, numExternals C.int,
|
||||
onCompleteFn C.FridaBuildCompleteFunc, onCompleteData unsafe.Pointer, onCompleteDataDestroy C.FridaDestroyFunc,
|
||||
onDiagnosticFn C.FridaDiagnosticFunc, onDiagnosticData unsafe.Pointer) {
|
||||
options := BuildOptions{
|
||||
@@ -157,6 +159,8 @@ func _frida_compiler_backend_build(cProjectRoot, cEntrypoint *C.char, outputForm
|
||||
DisableTypeCheck: disableTypeCheck != 0,
|
||||
SourceMap: sourceMap != 0,
|
||||
Compress: compress != 0,
|
||||
Platform: platformFromFrida(C.GoString(cPlatform)),
|
||||
Externals: parseCExternals(cExternals, numExternals),
|
||||
}
|
||||
onComplete := NewCDelegate(onCompleteFn, onCompleteData, onCompleteDataDestroy)
|
||||
onDiagnostic := NewCDelegate(onDiagnosticFn, onDiagnosticData, nil)
|
||||
@@ -181,7 +185,7 @@ func _frida_compiler_backend_build(cProjectRoot, cEntrypoint *C.char, outputForm
|
||||
|
||||
//export _frida_compiler_backend_watch
|
||||
func _frida_compiler_backend_watch(cProjectRoot, cEntrypoint *C.char, outputFormat C.FridaOutputFormat, bundleFormat C.FridaBundleFormat,
|
||||
disableTypeCheck, sourceMap, compress uintptr,
|
||||
disableTypeCheck, sourceMap, compress uintptr, cPlatform *C.char, cExternals **C.char, numExternals C.int,
|
||||
onReadyFn C.FridaWatchReadyFunc, onReadyData unsafe.Pointer, onReadyDataDestroy C.FridaDestroyFunc,
|
||||
onStartingFn C.FridaStartingFunc, onStartingData unsafe.Pointer,
|
||||
onFinishedFn C.FridaFinishedFunc, onFinishedData unsafe.Pointer,
|
||||
@@ -195,6 +199,8 @@ func _frida_compiler_backend_watch(cProjectRoot, cEntrypoint *C.char, outputForm
|
||||
DisableTypeCheck: disableTypeCheck != 0,
|
||||
SourceMap: sourceMap != 0,
|
||||
Compress: compress != 0,
|
||||
Platform: platformFromFrida(C.GoString(cPlatform)),
|
||||
Externals: parseCExternals(cExternals, numExternals),
|
||||
}
|
||||
onReady := NewCDelegate(onReadyFn, onReadyData, onReadyDataDestroy)
|
||||
onStarting := NewCDelegate(onStartingFn, onStartingData, nil)
|
||||
@@ -246,6 +252,35 @@ func _frida_compiler_backend_watch_session_dispose(h uintptr) {
|
||||
handle.Delete()
|
||||
}
|
||||
|
||||
func platformFromFrida(s string) esbuild.Platform {
|
||||
switch s {
|
||||
case "gum":
|
||||
return esbuild.PlatformNode
|
||||
case "browser":
|
||||
return esbuild.PlatformBrowser
|
||||
case "neutral":
|
||||
return esbuild.PlatformNeutral
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown platform: %q", s))
|
||||
}
|
||||
}
|
||||
|
||||
func parseCExternals(cExternals **C.char, numExternals C.int) []string {
|
||||
if numExternals == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
n := int(numExternals)
|
||||
cArray := (*[1 << 20]*C.char)(unsafe.Pointer(cExternals))[:n:n]
|
||||
|
||||
externals := make([]string, n)
|
||||
for i := 0; i < n; i++ {
|
||||
externals[i] = C.GoString(cArray[i])
|
||||
}
|
||||
|
||||
return externals
|
||||
}
|
||||
|
||||
func makeCBuildDiagnosticCallback(onDiagnostic *CDelegate[C.FridaDiagnosticFunc]) BuildDiagnosticCallback {
|
||||
return func(d Diagnostic) {
|
||||
var cPath *C.char
|
||||
@@ -445,9 +480,10 @@ func makeContext(options BuildOptions, callbacks BuildEventCallbacks) (ctx esbui
|
||||
Bundle: true,
|
||||
Outdir: projectRoot,
|
||||
AbsWorkingDir: projectRoot,
|
||||
Platform: esbuild.PlatformNode,
|
||||
Platform: options.Platform,
|
||||
Format: format,
|
||||
Inject: []string{"frida-builtins:///node-globals.js"},
|
||||
External: options.Externals,
|
||||
EntryPoints: []string{entrypoint},
|
||||
Write: false,
|
||||
Plugins: plugins,
|
||||
|
||||
@@ -46,7 +46,8 @@ namespace Frida {
|
||||
|
||||
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);
|
||||
(size_t) (opts.compression == TERSER), opts.platform.to_nick (),
|
||||
opts.externals.to_array (), (owned) on_complete, on_diagnostic);
|
||||
yield;
|
||||
|
||||
if (error_message != null)
|
||||
@@ -96,7 +97,8 @@ namespace Frida {
|
||||
|
||||
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,
|
||||
(size_t) (opts.compression == TERSER), opts.platform.to_nick (),
|
||||
opts.externals.to_array (), (owned) on_ready, on_starting, on_finished,
|
||||
on_output, on_diagnostic);
|
||||
yield;
|
||||
|
||||
@@ -283,13 +285,14 @@ namespace Frida {
|
||||
[CCode (has_target = false)]
|
||||
private delegate void BuildFunc (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);
|
||||
string platform, string[] externals, owned BuildCompleteFunc on_complete,
|
||||
DiagnosticFunc on_diagnostic);
|
||||
|
||||
[CCode (has_target = false)]
|
||||
private delegate void WatchFunc (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);
|
||||
string platform, string[] externals, owned WatchReadyFunc on_ready, StartingFunc on_starting,
|
||||
FinishedFunc on_finished, OutputFunc on_output, DiagnosticFunc on_diagnostic);
|
||||
|
||||
#if COMPILER_BACKEND_STATIC_COMPILATION
|
||||
private extern void _init_go_runtime ();
|
||||
@@ -373,6 +376,27 @@ namespace Frida {
|
||||
set;
|
||||
default = NONE;
|
||||
}
|
||||
|
||||
public JsPlatform platform {
|
||||
get;
|
||||
set;
|
||||
default = GUM;
|
||||
}
|
||||
|
||||
internal Gee.List<string> externals = new Gee.ArrayList<string> ();
|
||||
|
||||
public void clear_externals () {
|
||||
externals.clear ();
|
||||
}
|
||||
|
||||
public void add_external (string external) {
|
||||
externals.add (external);
|
||||
}
|
||||
|
||||
public void enumerate_externals (Func<string> func) {
|
||||
foreach (var external in externals)
|
||||
func (external);
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class BuildOptions : CompilerOptions {
|
||||
@@ -446,4 +470,18 @@ namespace Frida {
|
||||
return Marshal.enum_to_nick<JsCompression> (this);
|
||||
}
|
||||
}
|
||||
|
||||
public enum JsPlatform {
|
||||
GUM,
|
||||
BROWSER,
|
||||
NEUTRAL;
|
||||
|
||||
public static JsPlatform from_nick (string nick) throws Error {
|
||||
return Marshal.enum_from_nick<JsPlatform> (nick);
|
||||
}
|
||||
|
||||
public string to_nick () {
|
||||
return Marshal.enum_to_nick<JsPlatform> (this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,6 +314,9 @@ namespace Frida {
|
||||
|
||||
SocketService? service = null;
|
||||
TimeoutSource? timeout_source = null;
|
||||
bool timed_out = false;
|
||||
bool child_exited = false;
|
||||
int child_status = 0;
|
||||
|
||||
try {
|
||||
string tempdir;
|
||||
@@ -341,7 +344,6 @@ namespace Frida {
|
||||
return false;
|
||||
});
|
||||
idle_source.attach (main_context);
|
||||
|
||||
yield;
|
||||
|
||||
var incoming_handler = service.incoming.connect ((c) => {
|
||||
@@ -350,42 +352,63 @@ namespace Frida {
|
||||
return true;
|
||||
});
|
||||
|
||||
var timer = new Timer ();
|
||||
timeout_source = new TimeoutSource (10);
|
||||
timeout_source = new TimeoutSource.seconds (10);
|
||||
timeout_source.set_callback (() => {
|
||||
timed_out = true;
|
||||
launch_helper.callback ();
|
||||
return Source.CONTINUE;
|
||||
return Source.REMOVE;
|
||||
});
|
||||
timeout_source.attach (main_context);
|
||||
|
||||
string[] argv = { helper_path, socket_address };
|
||||
|
||||
GLib.SpawnFlags flags = GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN | /* GLib.SpawnFlags.CLOEXEC_PIPES */ 256;
|
||||
GLib.SpawnFlags flags =
|
||||
GLib.SpawnFlags.LEAVE_DESCRIPTORS_OPEN |
|
||||
GLib.SpawnFlags.DO_NOT_REAP_CHILD |
|
||||
/* GLib.SpawnFlags.CLOEXEC_PIPES */ 256;
|
||||
|
||||
GLib.Process.spawn_async (null, argv, null, flags, null, out pending_pid);
|
||||
|
||||
while (pending_stream == null && timer.elapsed () < 10.0 && !process_is_dead (pending_pid))
|
||||
var exit_monitor = new ChildExitMonitor (pending_pid, main_context);
|
||||
var exit_handler = exit_monitor.exited.connect ((status) => {
|
||||
child_exited = true;
|
||||
child_status = status;
|
||||
launch_helper.callback ();
|
||||
});
|
||||
|
||||
while (pending_stream == null && !timed_out && !child_exited)
|
||||
yield;
|
||||
|
||||
exit_monitor.disconnect (exit_handler);
|
||||
exit_monitor.stop ();
|
||||
|
||||
timeout_source.destroy ();
|
||||
timeout_source = null;
|
||||
|
||||
service.disconnect (incoming_handler);
|
||||
service.stop ();
|
||||
service = null;
|
||||
timeout_source.destroy ();
|
||||
timeout_source = null;
|
||||
|
||||
if (pending_stream == null)
|
||||
throw new Error.TIMED_OUT ("Unexpectedly timed out while spawning helper process");
|
||||
if (pending_stream == null) {
|
||||
if (child_exited)
|
||||
throw new Error.PROCESS_NOT_FOUND ("Helper exited during launch (status=%d)", child_status);
|
||||
if (timed_out)
|
||||
throw new Error.TIMED_OUT ("Unexpectedly timed out while spawning helper");
|
||||
}
|
||||
|
||||
pending_connection = yield new DBusConnection (pending_stream, ServerGuid.HOST_SESSION_SERVICE,
|
||||
AUTHENTICATION_SERVER | AUTHENTICATION_ALLOW_ANONYMOUS, null, cancellable);
|
||||
|
||||
pending_proxy = yield pending_connection.get_proxy (null, ObjectPath.HELPER, DO_NOT_LOAD_PROPERTIES,
|
||||
cancellable);
|
||||
|
||||
if (pending_connection.is_closed ())
|
||||
throw new Error.NOT_SUPPORTED ("Helper terminated prematurely");
|
||||
} catch (GLib.Error e) {
|
||||
bool died_unexpectedly = pending_pid != 0 && process_is_dead (pending_pid);
|
||||
|
||||
if (pending_pid != 0 && !died_unexpectedly)
|
||||
if (pending_pid != 0 && !child_exited) {
|
||||
Posix.kill ((Posix.pid_t) pending_pid, Posix.Signal.KILL);
|
||||
reap_later.begin (pending_pid);
|
||||
}
|
||||
|
||||
if (timeout_source != null)
|
||||
timeout_source.destroy ();
|
||||
@@ -393,10 +416,6 @@ namespace Frida {
|
||||
if (service != null)
|
||||
service.stop ();
|
||||
|
||||
if (died_unexpectedly) {
|
||||
throw new Error.PROCESS_NOT_FOUND ("Peer process (%d) died unexpectedly: %s",
|
||||
pending_pid, e.message);
|
||||
}
|
||||
if (e is Error)
|
||||
throw (Error) e;
|
||||
throw new Error.PERMISSION_DENIED ("%s", e.message);
|
||||
@@ -422,10 +441,6 @@ namespace Frida {
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private static bool process_is_dead (uint pid) {
|
||||
return Posix.kill ((Posix.pid_t) pid, 0) == -1 && Posix.errno == Posix.ESRCH;
|
||||
}
|
||||
|
||||
private void on_connection_closed (bool remote_peer_vanished, GLib.Error? error) {
|
||||
obtain_request = null;
|
||||
|
||||
@@ -441,7 +456,10 @@ namespace Frida {
|
||||
connection.on_closed.disconnect (on_connection_closed);
|
||||
connection = null;
|
||||
|
||||
Pid pid = process_pid;
|
||||
process_pid = 0;
|
||||
if (pid != 0)
|
||||
reap_later.begin (pid);
|
||||
}
|
||||
|
||||
private void on_output (uint pid, int fd, uint8[] data) {
|
||||
@@ -559,4 +577,88 @@ namespace Frida {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private class ChildExitMonitor : Object {
|
||||
public signal void exited (int status);
|
||||
|
||||
private Pid pid;
|
||||
private MainContext? context;
|
||||
|
||||
private TimeoutSource? source;
|
||||
|
||||
private uint interval_ms = 10;
|
||||
private const uint MAX_INTERVAL_MS = 1000;
|
||||
|
||||
public ChildExitMonitor (Pid pid, MainContext? ctx = null) {
|
||||
this.pid = pid;
|
||||
|
||||
context = ctx ?? MainContext.get_thread_default ();
|
||||
|
||||
arm ();
|
||||
}
|
||||
|
||||
public void stop () {
|
||||
if (source != null) {
|
||||
source.destroy ();
|
||||
source = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void arm () {
|
||||
source = new TimeoutSource (interval_ms);
|
||||
source.set_callback (() => {
|
||||
int status;
|
||||
if (try_reap (pid, out status)) {
|
||||
stop ();
|
||||
exited (status);
|
||||
return Source.REMOVE;
|
||||
}
|
||||
|
||||
if (interval_ms < MAX_INTERVAL_MS) {
|
||||
interval_ms = uint.min (MAX_INTERVAL_MS, 2 * interval_ms);
|
||||
stop ();
|
||||
arm ();
|
||||
return Source.REMOVE;
|
||||
}
|
||||
|
||||
return Source.CONTINUE;
|
||||
});
|
||||
source.attach (context);
|
||||
}
|
||||
|
||||
private static bool try_reap (Pid pid, out int status) {
|
||||
status = 0;
|
||||
var r = Posix.waitpid ((Posix.pid_t) pid, out status, Posix.WNOHANG);
|
||||
if (r > 0)
|
||||
return true;
|
||||
if (r == 0)
|
||||
return false;
|
||||
|
||||
if (Posix.errno == Posix.EINTR)
|
||||
return false;
|
||||
|
||||
if (Posix.errno == Posix.ECHILD)
|
||||
return true;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private async void reap_later (Pid pid) {
|
||||
var monitor = new ChildExitMonitor (pid);
|
||||
|
||||
bool done = false;
|
||||
ulong h = monitor.exited.connect ((status) => {
|
||||
done = true;
|
||||
reap_later.callback ();
|
||||
});
|
||||
|
||||
try {
|
||||
while (!done)
|
||||
yield;
|
||||
} finally {
|
||||
monitor.disconnect (h);
|
||||
monitor.stop ();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -109,8 +109,6 @@ _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
|
||||
|
||||
|
||||
@@ -489,7 +489,7 @@ static void
|
||||
frida_add_app_icons (GHashTable * parameters, NSImage * image)
|
||||
{
|
||||
GVariantBuilder builder;
|
||||
const guint sizes[] = { 16, 32 };
|
||||
const guint sizes[] = { 128 };
|
||||
guint i;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE ("aa{sv}"));
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <gio/gunixmounts.h>
|
||||
#include <gum/gum.h>
|
||||
|
||||
typedef struct _FridaEnumerateProcessesOperation FridaEnumerateProcessesOperation;
|
||||
|
||||
|
||||
@@ -12,12 +12,15 @@ struct _FridaSimmyContext
|
||||
|
||||
void * core_simulator;
|
||||
|
||||
NSString * SimDeviceLaunchApplicationKeyArguments;
|
||||
NSString * SimDeviceLaunchApplicationKeyEnvironment;
|
||||
NSString * SimDeviceLaunchApplicationKeyStandardErrPath;
|
||||
NSString * SimDeviceLaunchApplicationKeyStandardOutPath;
|
||||
NSString * SimDeviceLaunchApplicationKeyTerminateRunningProcess;
|
||||
NSString * SimDeviceLaunchApplicationKeyWaitForDebugger;
|
||||
|
||||
NSString * SimDeviceSpawnKeyArguments;
|
||||
NSString * SimDeviceSpawnKeyEnvironment;
|
||||
NSString * SimDeviceSpawnKeyStderr;
|
||||
NSString * SimDeviceSpawnKeyStdin;
|
||||
NSString * SimDeviceSpawnKeyStdout;
|
||||
@@ -30,6 +33,9 @@ struct _FridaSimmyContext
|
||||
static void frida_simmy_context_destroy (FridaSimmyContext * self);
|
||||
static void frida_simmy_context_emit_devices (FridaSimmyContext * self);
|
||||
|
||||
static NSArray * frida_argv_to_arguments_array (gchar * const * argv, gint argv_length, gint start_index);
|
||||
static NSDictionary * frida_envp_to_environment_dictionary (gchar * const * envp, gint envp_length);
|
||||
|
||||
@interface SimRuntime : NSObject
|
||||
@property (nonatomic, readonly, strong) NSString * identifier;
|
||||
@property (nonatomic, readonly, strong) NSString * shortName;
|
||||
@@ -153,12 +159,15 @@ frida_simmy_context_emit_devices (FridaSimmyContext * self)
|
||||
g_assert (str != NULL); \
|
||||
self->N = *str
|
||||
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyArguments);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyEnvironment);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyStandardErrPath);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyStandardOutPath);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyTerminateRunningProcess);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceLaunchApplicationKeyWaitForDebugger);
|
||||
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceSpawnKeyArguments);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceSpawnKeyEnvironment);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceSpawnKeyStderr);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceSpawnKeyStdin);
|
||||
FRIDA_ASSIGN_CS_CONSTANT (SimDeviceSpawnKeyStdout);
|
||||
@@ -234,7 +243,7 @@ _frida_simmy_device_list_applications (FridaSimmyDevice * self, FridaSimmyDevice
|
||||
}
|
||||
|
||||
void
|
||||
_frida_simmy_device_launch_application (FridaSimmyDevice * self, const gchar * identifier, FridaHostSpawnOptions * options,
|
||||
_frida_simmy_device_launch_application (FridaSimmyDevice * self, const gchar * identifier, FridaHostSpawnOptions * opts,
|
||||
FridaSimmyDeviceLaunchApplicationCompleteFunc on_complete, gpointer on_complete_target,
|
||||
GDestroyNotify on_complete_target_destroy_notify)
|
||||
{
|
||||
@@ -249,20 +258,12 @@ _frida_simmy_device_launch_application (FridaSimmyDevice * self, const gchar * i
|
||||
device = frida_simmy_device_get_handle (self);
|
||||
ctx = frida_simmy_device_get_simmy_context (self);
|
||||
|
||||
pipes = frida_make_stdio_pipes (options->stdio, FALSE, NULL, NULL, &out_fd, &out_name, &err_fd, &err_name, &error);
|
||||
if (opts->has_envp)
|
||||
goto envp_not_supported;
|
||||
|
||||
pipes = frida_make_stdio_pipes (opts->stdio, FALSE, NULL, NULL, &out_fd, &out_name, &err_fd, &err_name, &error);
|
||||
if (error != NULL)
|
||||
{
|
||||
dispatch_async (ctx->dispatch_queue, ^
|
||||
{
|
||||
on_complete (error->message, NULL, on_complete_target);
|
||||
|
||||
g_error_free (error);
|
||||
|
||||
if (on_complete_target_destroy_notify != NULL)
|
||||
on_complete_target_destroy_notify (on_complete_target);
|
||||
});
|
||||
return;
|
||||
}
|
||||
goto propagate_error;
|
||||
|
||||
main_context = g_main_context_ref_thread_default ();
|
||||
|
||||
@@ -275,7 +276,13 @@ _frida_simmy_device_launch_application (FridaSimmyDevice * self, const gchar * i
|
||||
ctx->SimDeviceLaunchApplicationKeyTerminateRunningProcess: @YES,
|
||||
} mutableCopy];
|
||||
|
||||
if (options->stdio == FRIDA_STDIO_PIPE)
|
||||
if (opts->has_argv)
|
||||
launch_opts[ctx->SimDeviceLaunchApplicationKeyArguments] = frida_argv_to_arguments_array (opts->argv, opts->argv_length1, 1);
|
||||
|
||||
if (opts->has_env)
|
||||
launch_opts[ctx->SimDeviceLaunchApplicationKeyEnvironment] = frida_envp_to_environment_dictionary (opts->env, opts->env_length1);
|
||||
|
||||
if (opts->stdio == FRIDA_STDIO_PIPE)
|
||||
{
|
||||
launch_opts[ctx->SimDeviceLaunchApplicationKeyStandardOutPath] = @(out_name);
|
||||
launch_opts[ctx->SimDeviceLaunchApplicationKeyStandardErrPath] = @(err_name);
|
||||
@@ -310,26 +317,18 @@ _frida_simmy_device_launch_application (FridaSimmyDevice * self, const gchar * i
|
||||
|
||||
g_free (out_name);
|
||||
g_free (err_name);
|
||||
}
|
||||
|
||||
void
|
||||
_frida_simmy_device_spawn_program (FridaSimmyDevice * self, const gchar * program, FridaHostSpawnOptions * options,
|
||||
FridaSimmyDeviceSpawnProgramCompleteFunc on_complete, gpointer on_complete_target,
|
||||
GDestroyNotify on_complete_target_destroy_notify)
|
||||
{
|
||||
const FridaStdio stdio = options->stdio;
|
||||
SimDevice * device;
|
||||
FridaSimmyContext * ctx;
|
||||
__block FridaStdioPipes * pipes;
|
||||
__block FridaFileDescriptor * in_fd, * out_fd, * err_fd;
|
||||
GError * error = NULL;
|
||||
__block GMainContext * main_context;
|
||||
return;
|
||||
|
||||
device = frida_simmy_device_get_handle (self);
|
||||
ctx = frida_simmy_device_get_simmy_context (self);
|
||||
|
||||
pipes = frida_make_stdio_pipes (options->stdio, TRUE, &in_fd, NULL, &out_fd, NULL, &err_fd, NULL, &error);
|
||||
if (error != NULL)
|
||||
envp_not_supported:
|
||||
{
|
||||
error = g_error_new_literal (
|
||||
FRIDA_ERROR,
|
||||
FRIDA_ERROR_NOT_SUPPORTED,
|
||||
"The 'envp' option is not supported when spawning Simmy apps, use the 'env' option instead");
|
||||
goto propagate_error;
|
||||
}
|
||||
propagate_error:
|
||||
{
|
||||
dispatch_async (ctx->dispatch_queue, ^
|
||||
{
|
||||
@@ -340,8 +339,34 @@ _frida_simmy_device_spawn_program (FridaSimmyDevice * self, const gchar * progra
|
||||
if (on_complete_target_destroy_notify != NULL)
|
||||
on_complete_target_destroy_notify (on_complete_target);
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_frida_simmy_device_spawn_program (FridaSimmyDevice * self, const gchar * program, FridaHostSpawnOptions * opts,
|
||||
FridaSimmyDeviceSpawnProgramCompleteFunc on_complete, gpointer on_complete_target,
|
||||
GDestroyNotify on_complete_target_destroy_notify)
|
||||
{
|
||||
const FridaStdio stdio = opts->stdio;
|
||||
SimDevice * device;
|
||||
FridaSimmyContext * ctx;
|
||||
__block FridaStdioPipes * pipes;
|
||||
__block FridaFileDescriptor * in_fd, * out_fd, * err_fd;
|
||||
GError * error = NULL;
|
||||
__block GMainContext * main_context;
|
||||
|
||||
device = frida_simmy_device_get_handle (self);
|
||||
ctx = frida_simmy_device_get_simmy_context (self);
|
||||
|
||||
if (opts->has_envp)
|
||||
goto envp_not_supported;
|
||||
|
||||
pipes = frida_make_stdio_pipes (opts->stdio, TRUE, &in_fd, NULL, &out_fd, NULL, &err_fd, NULL, &error);
|
||||
if (error != NULL)
|
||||
goto propagate_error;
|
||||
|
||||
main_context = g_main_context_ref_thread_default ();
|
||||
|
||||
@autoreleasepool
|
||||
@@ -353,17 +378,11 @@ _frida_simmy_device_spawn_program (FridaSimmyDevice * self, const gchar * progra
|
||||
ctx->SimDeviceSpawnKeyWaitForDebugger: @YES,
|
||||
} mutableCopy];
|
||||
|
||||
if (options->has_argv)
|
||||
{
|
||||
NSMutableArray<NSString *> * args;
|
||||
int i;
|
||||
if (opts->has_argv)
|
||||
spawn_opts[ctx->SimDeviceSpawnKeyArguments] = frida_argv_to_arguments_array (opts->argv, opts->argv_length1, 0);
|
||||
|
||||
args = [NSMutableArray arrayWithCapacity:options->argv_length1];
|
||||
for (i = 0; i != options->argv_length1; i++)
|
||||
[args addObject:[NSString stringWithUTF8String:options->argv[i]]];
|
||||
|
||||
spawn_opts[ctx->SimDeviceSpawnKeyArguments] = args;
|
||||
}
|
||||
if (opts->has_env)
|
||||
spawn_opts[ctx->SimDeviceSpawnKeyEnvironment] = frida_envp_to_environment_dictionary (opts->env, opts->env_length1);
|
||||
|
||||
if (stdio == FRIDA_STDIO_PIPE)
|
||||
{
|
||||
@@ -404,6 +423,30 @@ _frida_simmy_device_spawn_program (FridaSimmyDevice * self, const gchar * progra
|
||||
on_complete_target_destroy_notify (on_complete_target);
|
||||
}];
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
envp_not_supported:
|
||||
{
|
||||
error = g_error_new_literal (
|
||||
FRIDA_ERROR,
|
||||
FRIDA_ERROR_NOT_SUPPORTED,
|
||||
"The 'envp' option is not supported when spawning Simmy programs, use the 'env' option instead");
|
||||
goto propagate_error;
|
||||
}
|
||||
propagate_error:
|
||||
{
|
||||
dispatch_async (ctx->dispatch_queue, ^
|
||||
{
|
||||
on_complete (error->message, NULL, on_complete_target);
|
||||
|
||||
g_error_free (error);
|
||||
|
||||
if (on_complete_target_destroy_notify != NULL)
|
||||
on_complete_target_destroy_notify (on_complete_target);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const gchar *
|
||||
@@ -429,3 +472,57 @@ _frida_simmy_runtime_get_root (FridaSimmyRuntime * self)
|
||||
{
|
||||
return ((SimRuntime *) frida_simmy_runtime_get_handle (self)).root.UTF8String;
|
||||
}
|
||||
|
||||
static NSArray *
|
||||
frida_argv_to_arguments_array (gchar * const * argv, gint argv_length, gint start_index)
|
||||
{
|
||||
NSMutableArray * result;
|
||||
gint i;
|
||||
|
||||
result = [NSMutableArray arrayWithCapacity:argv_length];
|
||||
for (i = start_index; i < argv_length; i++)
|
||||
[result addObject:[NSString stringWithUTF8String:argv[i]]];
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static NSDictionary *
|
||||
frida_envp_to_environment_dictionary (gchar * const * envp, gint envp_length)
|
||||
{
|
||||
NSMutableDictionary * result;
|
||||
gint i;
|
||||
|
||||
result = [NSMutableDictionary dictionaryWithCapacity:envp_length];
|
||||
for (i = 0; i != envp_length; i++)
|
||||
{
|
||||
const gchar * pair, * equals_sign, * name_start, * value_start;
|
||||
NSUInteger name_size, value_size;
|
||||
NSString * name, * value;
|
||||
|
||||
pair = envp[i];
|
||||
|
||||
equals_sign = strchr (pair, '=');
|
||||
if (equals_sign == NULL)
|
||||
continue;
|
||||
|
||||
name_start = pair;
|
||||
name_size = equals_sign - name_start;
|
||||
|
||||
value_start = equals_sign + 1;
|
||||
value_size = pair + strlen (pair) - value_start;
|
||||
|
||||
name = [[NSString alloc] initWithBytes:name_start
|
||||
length:name_size
|
||||
encoding:NSUTF8StringEncoding];
|
||||
value = [[NSString alloc] initWithBytes:value_start
|
||||
length:value_size
|
||||
encoding:NSUTF8StringEncoding];
|
||||
|
||||
[result setObject:value forKey:name];
|
||||
|
||||
[value release];
|
||||
[name release];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -235,7 +235,13 @@ namespace Frida {
|
||||
Cancellable? cancellable) throws Error, IOError {
|
||||
var opts = FrontmostQueryOptions._deserialize (options);
|
||||
|
||||
return yield springboard_agent.get_frontmost_application (opts, cancellable);
|
||||
try {
|
||||
return yield springboard_agent.get_frontmost_application (opts, cancellable);
|
||||
} catch (Error e) {
|
||||
if (e is Error.PERMISSION_DENIED)
|
||||
throw new Error.NOT_SUPPORTED ("Frontmost query is only supported with SIP disabled (for now)");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
public async HostApplicationInfo[] enumerate_applications (HashTable<string, Variant> options,
|
||||
@@ -246,12 +252,28 @@ namespace Frida {
|
||||
Future<Gee.List<Simmy.Application>> list_apps_request = device.list_applications ();
|
||||
Future<Gee.List<LaunchdJob>> list_jobs_request = list_launchd_jobs (cancellable);
|
||||
|
||||
var selected_ids = new Gee.HashSet<string> ();
|
||||
opts.enumerate_selected_identifiers (identifier => {
|
||||
selected_ids.add (identifier);
|
||||
});
|
||||
bool include_all_apps = selected_ids.is_empty;
|
||||
|
||||
var apps = new Gee.ArrayList<Simmy.Application> ();
|
||||
foreach (Simmy.Application app in yield list_apps_request.wait_async (cancellable)) {
|
||||
unowned string id = app.identifier;
|
||||
if (include_all_apps || id in selected_ids)
|
||||
apps.add (app);
|
||||
}
|
||||
|
||||
Gee.Map<string, Bytes>? icons = null;
|
||||
if (scope == FULL) {
|
||||
var app_ids = new Gee.ArrayList<string> ();
|
||||
foreach (Simmy.Application app in yield list_apps_request.wait_async (cancellable))
|
||||
foreach (var app in apps)
|
||||
app_ids.add (app.identifier);
|
||||
icons = yield springboard_agent.fetch_application_icons (app_ids, cancellable);
|
||||
try {
|
||||
icons = yield springboard_agent.fetch_application_icons (app_ids, cancellable);
|
||||
} catch (Error e) {
|
||||
}
|
||||
}
|
||||
|
||||
var pids = new Gee.HashMap<string, uint> ();
|
||||
@@ -268,11 +290,11 @@ namespace Frida {
|
||||
}
|
||||
|
||||
var result = new HostApplicationInfo[0];
|
||||
foreach (Simmy.Application app in yield list_apps_request.wait_async (cancellable)) {
|
||||
foreach (var app in apps) {
|
||||
unowned string identifier = app.identifier;
|
||||
|
||||
var info = HostApplicationInfo (identifier, app.display_name, pids[identifier], make_parameters_dict ());
|
||||
if (scope == FULL)
|
||||
if (scope == FULL && icons != null)
|
||||
add_app_icons (info.parameters, icons[identifier]);
|
||||
result += info;
|
||||
}
|
||||
@@ -675,10 +697,10 @@ namespace Frida {
|
||||
return promise.future;
|
||||
}
|
||||
|
||||
public Future<SpawnedProcess> launch_application (string identifier, HostSpawnOptions options) {
|
||||
public Future<SpawnedProcess> launch_application (string identifier, HostSpawnOptions opts) {
|
||||
var promise = new Promise<SpawnedProcess> ();
|
||||
|
||||
_launch_application (identifier, options, (error_message, process) => {
|
||||
_launch_application (identifier, opts, (error_message, process) => {
|
||||
if (error_message != null)
|
||||
promise.reject (new Error.NOT_SUPPORTED ("%s", error_message));
|
||||
else
|
||||
@@ -688,10 +710,10 @@ namespace Frida {
|
||||
return promise.future;
|
||||
}
|
||||
|
||||
public Future<SpawnedProcess> spawn_program (string program, HostSpawnOptions options) {
|
||||
public Future<SpawnedProcess> spawn_program (string program, HostSpawnOptions opts) {
|
||||
var promise = new Promise<SpawnedProcess> ();
|
||||
|
||||
_spawn_program (program, options, (error_message, process) => {
|
||||
_spawn_program (program, opts, (error_message, process) => {
|
||||
if (error_message != null)
|
||||
promise.reject (new Error.NOT_SUPPORTED ("%s", error_message));
|
||||
else
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-gum.git
|
||||
revision = 17.4.2
|
||||
revision = 17.5.2
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
Reference in new issue
Block a user