mirror of
https://github.com/frida/frida-core.git
synced 2026-11-08 08:05:58 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a41a960fe | ||
|
|
25bd49299a | ||
|
|
c84323b6ac | ||
|
|
45aef70f35 | ||
|
|
eb8efdf40a | ||
|
|
025e5c433d | ||
|
|
f9314073dc | ||
|
|
4011e34449 | ||
|
|
2fef8d7d20 | ||
|
|
9f681e26f1 | ||
|
|
18a156817f | ||
|
|
2ea8b6278e | ||
|
|
40ce660b54 | ||
|
|
7913d880c2 | ||
|
|
34e718e4a3 | ||
|
|
10d6f866b1 | ||
|
|
d5bc484072 | ||
|
|
04bd09b7b7 | ||
|
|
ef7dd9701c | ||
|
|
8777bbe8af | ||
|
|
8734d9875a | ||
|
|
d043c66c75 |
No files matched your search
@@ -451,7 +451,10 @@ jobs:
|
||||
cd build
|
||||
cp -a tests/frida-tests tests/labrats lib/agent/frida-agent.so /tmp/pkg/
|
||||
tar -C /tmp/pkg -cf /tmp/runner.tar .
|
||||
/opt/sabrelite/run.sh /tmp/runner.tar /opt/frida/frida-tests
|
||||
/opt/sabrelite/run.sh /tmp/runner.tar \
|
||||
"cp /opt/frida/frida-tests /opt/frida/frida-agent.so /tmp/ && \
|
||||
ln -sP /opt/frida/labrats /tmp/labrats && \
|
||||
/tmp/frida-tests"
|
||||
|
||||
# This job is used to check that the Linux helpers are built correctly for all
|
||||
# supported architectures. We do this because the binary artifacts are checked
|
||||
|
||||
@@ -103,6 +103,9 @@ namespace Frida.Agent {
|
||||
private SpawnMonitor? spawn_monitor;
|
||||
private ThreadSuspendMonitor? thread_suspend_monitor;
|
||||
private UnwindSitter? unwind_sitter;
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
private NativeCloakMirror? native_cloak_mirror;
|
||||
#endif
|
||||
|
||||
private delegate void CompletionNotify ();
|
||||
|
||||
@@ -350,6 +353,9 @@ namespace Frida.Agent {
|
||||
bool enable_unwind_broker = true;
|
||||
bool enable_exit_monitor = true;
|
||||
bool enable_thread_suspend_monitor = true;
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
bool in_emulated_realm = false;
|
||||
#endif
|
||||
foreach (unowned string option in tokens[1:]) {
|
||||
if (option == "eternal")
|
||||
ensure_eternalized ();
|
||||
@@ -365,6 +371,10 @@ namespace Frida.Agent {
|
||||
enable_exit_monitor = false;
|
||||
else if (option == "thread-suspend-monitor:off")
|
||||
enable_thread_suspend_monitor = false;
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
else if (option == "realm:emulated")
|
||||
in_emulated_realm = true;
|
||||
#endif
|
||||
}
|
||||
|
||||
if (exceptor_mode != FULL)
|
||||
@@ -374,6 +384,10 @@ namespace Frida.Agent {
|
||||
|
||||
try {
|
||||
yield setup_connection_with_transport_uri (transport_uri);
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
if (in_emulated_realm)
|
||||
yield connect_to_native_realm ();
|
||||
#endif
|
||||
} catch (Error e) {
|
||||
start_error = e;
|
||||
main_loop.quit ();
|
||||
@@ -406,6 +420,23 @@ namespace Frida.Agent {
|
||||
padder = null;
|
||||
}
|
||||
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
private async void connect_to_native_realm () throws Error {
|
||||
try {
|
||||
NativeCloak cloak = yield connection.get_proxy (null, ObjectPath.NATIVE_CLOAK, DO_NOT_LOAD_PROPERTIES,
|
||||
null);
|
||||
native_cloak_mirror = new NativeCloakMirror (cloak);
|
||||
native_cloak_mirror.activate ();
|
||||
|
||||
NativeThreadRegistry registry = yield connection.get_proxy (null, ObjectPath.NATIVE_THREAD_REGISTRY,
|
||||
DO_NOT_LOAD_PROPERTIES, null);
|
||||
Gum.ThreadRegistry.set_provider (new NativeThreadProvider (registry));
|
||||
} catch (GLib.Error e) {
|
||||
throw new Error.TRANSPORT ("%s", e.message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private static bool can_allocate_code () {
|
||||
size_t page_size = Gum.query_page_size ();
|
||||
|
||||
@@ -1478,6 +1509,8 @@ namespace Frida.Agent {
|
||||
private Socket? emulated_socket;
|
||||
private BridgeState? emulated_bridge_state;
|
||||
private Thread<void>? emulated_worker;
|
||||
private NativeCloakService? native_cloak;
|
||||
private NativeThreadRegistryService? native_thread_registry;
|
||||
|
||||
private async AgentSessionProvider? try_get_emulated_provider (Cancellable? cancellable) throws IOError {
|
||||
if (get_emulated_request == null)
|
||||
@@ -1517,6 +1550,8 @@ namespace Frida.Agent {
|
||||
emulated_agent = nb_api.load_library_ext (emulated_agent_path, RTLD_LAZY, classloader_namespace);
|
||||
} else {
|
||||
emulated_agent = nb_api.load_library (emulated_agent_path, RTLD_LAZY);
|
||||
if (emulated_agent == null && nb_api.load_library_ext != null)
|
||||
emulated_agent = nb_api.load_library_ext (emulated_agent_path, RTLD_LAZY, null);
|
||||
}
|
||||
if (emulated_agent == null)
|
||||
throw new Error.NOT_SUPPORTED ("Process is not using emulation");
|
||||
@@ -1556,6 +1591,7 @@ namespace Frida.Agent {
|
||||
* code being discarded, which seems like an edge-case the translator doesn't handle.
|
||||
*/
|
||||
parameters.append ("|exceptor:off|exit-monitor:off");
|
||||
parameters.append ("|realm:emulated");
|
||||
|
||||
emulated_bridge_state = new BridgeState (parameters.str);
|
||||
|
||||
@@ -1564,6 +1600,13 @@ namespace Frida.Agent {
|
||||
var connection = yield new DBusConnection (stream, ServerGuid.HOST_SESSION_SERVICE,
|
||||
AUTHENTICATION_SERVER | AUTHENTICATION_ALLOW_ANONYMOUS, null, cancellable);
|
||||
|
||||
native_cloak = new NativeCloakService ();
|
||||
connection.register_object (ObjectPath.NATIVE_CLOAK, (NativeCloak) native_cloak);
|
||||
|
||||
native_thread_registry = new NativeThreadRegistryService ();
|
||||
connection.register_object (ObjectPath.NATIVE_THREAD_REGISTRY,
|
||||
(NativeThreadRegistry) native_thread_registry);
|
||||
|
||||
AgentSessionProvider provider = yield connection.get_proxy (null, ObjectPath.AGENT_SESSION_PROVIDER,
|
||||
DO_NOT_LOAD_PROPERTIES, cancellable);
|
||||
|
||||
@@ -1611,6 +1654,16 @@ namespace Frida.Agent {
|
||||
emulated_worker = null;
|
||||
}
|
||||
|
||||
if (native_thread_registry != null) {
|
||||
native_thread_registry.close ();
|
||||
native_thread_registry = null;
|
||||
}
|
||||
|
||||
if (native_cloak != null) {
|
||||
native_cloak.close ();
|
||||
native_cloak = null;
|
||||
}
|
||||
|
||||
emulated_socket = null;
|
||||
|
||||
if (emulated_agent != null) {
|
||||
@@ -1771,6 +1824,201 @@ namespace Frida.Agent {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ANDROID && (X86 || X86_64)
|
||||
private sealed class NativeCloakService : Object, NativeCloak, Gum.Cloak.Observer {
|
||||
private MainContext main_context = MainContext.ref_thread_default ();
|
||||
private bool observing = false;
|
||||
|
||||
public uint[] activate (Cancellable? cancellable) {
|
||||
Gum.Cloak.add_observer (this);
|
||||
observing = true;
|
||||
|
||||
uint[] threads = {};
|
||||
Gum.Cloak.enumerate_threads (id => {
|
||||
threads += (uint) id;
|
||||
return true;
|
||||
});
|
||||
return threads;
|
||||
}
|
||||
|
||||
public void close () {
|
||||
if (!observing)
|
||||
return;
|
||||
|
||||
Gum.Cloak.remove_observer (this);
|
||||
observing = false;
|
||||
}
|
||||
|
||||
public void thread_added (Gum.ThreadId id) {
|
||||
schedule (() => {
|
||||
thread_cloaked ((uint) id);
|
||||
return Source.REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
public void thread_removed (Gum.ThreadId id) {
|
||||
schedule (() => {
|
||||
thread_uncloaked ((uint) id);
|
||||
return Source.REMOVE;
|
||||
});
|
||||
}
|
||||
|
||||
private void schedule (owned SourceFunc function) {
|
||||
var source = new IdleSource ();
|
||||
source.set_callback ((owned) function);
|
||||
source.attach (main_context);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class NativeThreadRegistryService : Object, NativeThreadRegistry {
|
||||
private unowned Gum.ThreadRegistry? registry;
|
||||
private ulong added_handler = 0;
|
||||
private ulong removed_handler = 0;
|
||||
private ulong renamed_handler = 0;
|
||||
|
||||
public NativeThreadInfo[] activate (Cancellable? cancellable) {
|
||||
registry = Gum.ThreadRegistry.obtain ();
|
||||
|
||||
NativeThreadInfo[] threads = {};
|
||||
|
||||
registry.lock ();
|
||||
|
||||
added_handler = registry.thread_added.connect (on_thread_added);
|
||||
removed_handler = registry.thread_removed.connect (on_thread_removed);
|
||||
renamed_handler = registry.thread_renamed.connect (on_thread_renamed);
|
||||
|
||||
registry.enumerate_threads (thread => {
|
||||
threads += NativeThreadInfo ((uint) thread.id, thread.name ?? "");
|
||||
return true;
|
||||
});
|
||||
|
||||
registry.unlock ();
|
||||
|
||||
return threads;
|
||||
}
|
||||
|
||||
public void deactivate (Cancellable? cancellable) {
|
||||
close ();
|
||||
}
|
||||
|
||||
public void close () {
|
||||
if (registry == null)
|
||||
return;
|
||||
|
||||
registry.disconnect (added_handler);
|
||||
registry.disconnect (removed_handler);
|
||||
registry.disconnect (renamed_handler);
|
||||
registry = null;
|
||||
}
|
||||
|
||||
private void on_thread_added (Gum.ThreadDetails thread) {
|
||||
thread_added (NativeThreadInfo ((uint) thread.id, thread.name ?? ""));
|
||||
}
|
||||
|
||||
private void on_thread_removed (Gum.ThreadDetails thread) {
|
||||
thread_removed ((uint) thread.id);
|
||||
}
|
||||
|
||||
private void on_thread_renamed (Gum.ThreadDetails thread, string? previous_name) {
|
||||
thread_renamed ((uint) thread.id, thread.name ?? "");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if ANDROID && (ARM || ARM64)
|
||||
private sealed class NativeCloakMirror : Object {
|
||||
public NativeCloak native_cloak {
|
||||
get;
|
||||
construct;
|
||||
}
|
||||
|
||||
public NativeCloakMirror (NativeCloak native_cloak) {
|
||||
Object (native_cloak: native_cloak);
|
||||
}
|
||||
|
||||
public void activate () throws GLib.Error {
|
||||
native_cloak.thread_cloaked.connect (on_thread_cloaked);
|
||||
native_cloak.thread_uncloaked.connect (on_thread_uncloaked);
|
||||
|
||||
foreach (uint id in native_cloak.activate (null))
|
||||
on_thread_cloaked (id);
|
||||
}
|
||||
|
||||
private void on_thread_cloaked (uint id) {
|
||||
if (!Gum.Cloak.has_thread (id))
|
||||
Gum.Cloak.add_thread (id);
|
||||
}
|
||||
|
||||
private void on_thread_uncloaked (uint id) {
|
||||
Gum.Cloak.remove_thread (id);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class NativeThreadProvider : Object, Gum.ThreadProvider {
|
||||
public NativeThreadRegistry native_registry {
|
||||
get;
|
||||
construct;
|
||||
}
|
||||
|
||||
private unowned Gum.ThreadRegistry registry;
|
||||
private ulong added_handler = 0;
|
||||
private ulong removed_handler = 0;
|
||||
private ulong renamed_handler = 0;
|
||||
|
||||
public NativeThreadProvider (NativeThreadRegistry native_registry) {
|
||||
Object (native_registry: native_registry);
|
||||
}
|
||||
|
||||
public void activate (Gum.ThreadRegistry registry) {
|
||||
this.registry = registry;
|
||||
|
||||
added_handler = native_registry.thread_added.connect (add_thread);
|
||||
removed_handler = native_registry.thread_removed.connect (on_thread_removed);
|
||||
renamed_handler = native_registry.thread_renamed.connect (on_thread_renamed);
|
||||
|
||||
NativeThreadInfo[] threads;
|
||||
try {
|
||||
threads = native_registry.activate (null);
|
||||
} catch (GLib.Error e) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var thread in threads)
|
||||
add_thread (thread);
|
||||
}
|
||||
|
||||
public void deactivate () {
|
||||
native_registry.disconnect (added_handler);
|
||||
native_registry.disconnect (removed_handler);
|
||||
native_registry.disconnect (renamed_handler);
|
||||
|
||||
try {
|
||||
native_registry.deactivate (null);
|
||||
} catch (GLib.Error e) {
|
||||
}
|
||||
}
|
||||
|
||||
private void add_thread (NativeThreadInfo thread) {
|
||||
var details = Gum.ThreadDetails ();
|
||||
details.id = thread.id;
|
||||
if (thread.name != "") {
|
||||
details.name = thread.name;
|
||||
details.flags = NAME;
|
||||
}
|
||||
|
||||
registry.register (details);
|
||||
}
|
||||
|
||||
private void on_thread_removed (uint id) {
|
||||
registry.unregister (id);
|
||||
}
|
||||
|
||||
private void on_thread_renamed (uint id, string name) {
|
||||
registry.rename (id, (name != "") ? name : null);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private sealed class LiveAgentSession : BaseAgentSession {
|
||||
public uint registration_id {
|
||||
get;
|
||||
|
||||
+12
-2
@@ -6,6 +6,8 @@ namespace Frida {
|
||||
|
||||
private Gee.Map<ChannelId?, weak IOStream> channels =
|
||||
new Gee.HashMap<ChannelId?, weak IOStream> (ChannelId.hash, ChannelId.equal);
|
||||
private Gee.Map<ChannelId?, IOStream> unlinked_channels =
|
||||
new Gee.HashMap<ChannelId?, IOStream> (ChannelId.hash, ChannelId.equal);
|
||||
|
||||
~ChannelRegistry () {
|
||||
clear ();
|
||||
@@ -18,25 +20,33 @@ namespace Frida {
|
||||
channel_stream.abandon ();
|
||||
}
|
||||
channels.clear ();
|
||||
unlinked_channels.clear ();
|
||||
}
|
||||
|
||||
public void register (ChannelId id, IOStream stream) {
|
||||
stream.set_data ("channel-registry-entry", new Entry (this, id));
|
||||
lock (channels)
|
||||
lock (channels) {
|
||||
channels[id] = stream;
|
||||
unlinked_channels[id] = stream;
|
||||
}
|
||||
}
|
||||
|
||||
public IOStream link (ChannelId id) throws Error {
|
||||
IOStream? stream;
|
||||
lock (channels)
|
||||
IOStream? unlinked_stream = null;
|
||||
lock (channels) {
|
||||
stream = channels[id];
|
||||
unlinked_channels.unset (id, out unlinked_stream);
|
||||
}
|
||||
if (stream == null)
|
||||
throw new Error.INVALID_ARGUMENT ("Invalid channel ID");
|
||||
return stream;
|
||||
}
|
||||
|
||||
public void unlink (ChannelId id) {
|
||||
IOStream? unlinked_stream = null;
|
||||
lock (channels) {
|
||||
unlinked_channels.unset (id, out unlinked_stream);
|
||||
if (!channels.unset (id))
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -133,6 +133,36 @@ namespace Frida {
|
||||
Cancellable? cancellable) throws GLib.Error;
|
||||
}
|
||||
|
||||
#if ANDROID
|
||||
[DBus (name = "re.frida.NativeThreadRegistry17")]
|
||||
public interface NativeThreadRegistry : Object {
|
||||
public abstract NativeThreadInfo[] activate (Cancellable? cancellable) throws GLib.Error;
|
||||
public abstract void deactivate (Cancellable? cancellable) throws GLib.Error;
|
||||
|
||||
public signal void thread_added (NativeThreadInfo thread);
|
||||
public signal void thread_removed (uint id);
|
||||
public signal void thread_renamed (uint id, string name);
|
||||
}
|
||||
|
||||
[DBus (name = "re.frida.NativeCloak17")]
|
||||
public interface NativeCloak : Object {
|
||||
public abstract uint[] activate (Cancellable? cancellable) throws GLib.Error;
|
||||
|
||||
public signal void thread_cloaked (uint id);
|
||||
public signal void thread_uncloaked (uint id);
|
||||
}
|
||||
|
||||
public struct NativeThreadInfo {
|
||||
public uint id;
|
||||
public string name;
|
||||
|
||||
public NativeThreadInfo (uint id, string name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
[DBus (name = "re.frida.AgentMessageSink17")]
|
||||
public interface AgentMessageSink : Object {
|
||||
public abstract async void post_messages (AgentMessage[] messages, uint batch_id,
|
||||
@@ -2802,6 +2832,8 @@ namespace Frida {
|
||||
public const string AGENT_SESSION_PROVIDER = "/re/frida/AgentSessionProvider";
|
||||
public const string AGENT_SESSION = "/re/frida/AgentSession";
|
||||
public const string AGENT_CONTROLLER = "/re/frida/AgentController";
|
||||
public const string NATIVE_THREAD_REGISTRY = "/re/frida/NativeThreadRegistry";
|
||||
public const string NATIVE_CLOAK = "/re/frida/NativeCloak";
|
||||
public const string AGENT_MESSAGE_SINK = "/re/frida/AgentMessageSink";
|
||||
public const string GADGET_SESSION = "/re/frida/GadgetSession";
|
||||
public const string CHANNEL = "/re/frida/Channel";
|
||||
|
||||
+1
-1
Submodule releng updated: 564352a3ea...164a6a4117.
Generated
+4
-4
@@ -8,7 +8,7 @@
|
||||
"name": "frida-barebone-script-runtime",
|
||||
"version": "1.0.0",
|
||||
"devDependencies": {
|
||||
"@types/frida-gum": "^19.12.0",
|
||||
"@types/frida-gum": "^19.13.0",
|
||||
"esbuild": "^0.25.5",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
@@ -439,9 +439,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/frida-gum": {
|
||||
"version": "19.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.12.0.tgz",
|
||||
"integrity": "sha512-fqXtwFA8AwE89tSdNHlaY+hNWI5j62bcO1xk5w0NSuHBIH6KRxYzIK6rp/JP7TXtRKU2ewBwx81FrHTfGF0q7w==",
|
||||
"version": "19.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.13.0.tgz",
|
||||
"integrity": "sha512-tbmEZj9JUt3S6FqFE4XJPi/WhQuUU0/sM1IWS1KDKqvy6077hwNjG1v4MC3wpk+FO/WzfZ8G1gAKqAKJosfj1Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"watch": "tsc -w"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/frida-gum": "^19.12.0",
|
||||
"@types/frida-gum": "^19.13.0",
|
||||
"esbuild": "^0.25.5",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
|
||||
Generated
+4
-4
@@ -36,7 +36,7 @@
|
||||
"@frida/util": "^1.0.3",
|
||||
"@frida/vm": "^2.0.0",
|
||||
"@frida/web-streams": "^1.0.0",
|
||||
"@types/frida-gum": "^19.12.0",
|
||||
"@types/frida-gum": "^19.13.0",
|
||||
"@types/node": "18.19.103",
|
||||
"frida-fs": "7.1.1"
|
||||
}
|
||||
@@ -270,9 +270,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/frida-gum": {
|
||||
"version": "19.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.12.0.tgz",
|
||||
"integrity": "sha512-fqXtwFA8AwE89tSdNHlaY+hNWI5j62bcO1xk5w0NSuHBIH6KRxYzIK6rp/JP7TXtRKU2ewBwx81FrHTfGF0q7w==",
|
||||
"version": "19.13.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-19.13.0.tgz",
|
||||
"integrity": "sha512-tbmEZj9JUt3S6FqFE4XJPi/WhQuUU0/sM1IWS1KDKqvy6077hwNjG1v4MC3wpk+FO/WzfZ8G1gAKqAKJosfj1Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"@frida/util": "^1.0.3",
|
||||
"@frida/vm": "^2.0.0",
|
||||
"@frida/web-streams": "^1.0.0",
|
||||
"@types/frida-gum": "^19.12.0",
|
||||
"@types/frida-gum": "^19.13.0",
|
||||
"@types/node": "18.19.103",
|
||||
"frida-fs": "7.1.1"
|
||||
}
|
||||
|
||||
@@ -1074,7 +1074,9 @@ namespace Frida {
|
||||
lldb_session = new LLDBSession (lldb, process, null, ExceptionHandlingStatus.FULL, device);
|
||||
yield lldb_session.kill (cancellable);
|
||||
yield lldb_session.close (cancellable);
|
||||
} catch (Error e) {
|
||||
} catch (GLib.Error e) {
|
||||
if (e is IOError.CANCELLED)
|
||||
throw (IOError) e;
|
||||
var process_control = yield Idun.ProcessControlService.open (device, cancellable);
|
||||
yield process_control.kill (pid, cancellable);
|
||||
}
|
||||
|
||||
@@ -2433,7 +2433,7 @@ namespace Frida {
|
||||
|
||||
Gum.Linux.enumerate_ranges ((Posix.pid_t) session.pid, READ | EXECUTE, d => {
|
||||
unowned Gum.FileMapping? file = d.file;
|
||||
if (file != null && file.path.has_prefix ("memfd:"))
|
||||
if (file != null && file.path.has_prefix ("/memfd:"))
|
||||
return true;
|
||||
if (d.range.size >= code.length) {
|
||||
code_start = d.range.base_address + d.range.size - round_size_to_page_size (code.length);
|
||||
|
||||
@@ -1791,7 +1791,11 @@ namespace Frida {
|
||||
}
|
||||
|
||||
MatchInfo info;
|
||||
if (!/^([0-9a-f]+)-([0-9a-f]+) rw-p 00000000 00:00 0 *$/m.match (raw_maps, 0, out info)) {
|
||||
try {
|
||||
var anon_rw_pattern = new Regex ("^([0-9a-f]+)-([0-9a-f]+) rw-p 00000000 00:00 0 *$", MULTILINE | RAW);
|
||||
if (!anon_rw_pattern.match (raw_maps, 0, out info))
|
||||
assert_not_reached ();
|
||||
} catch (RegexError e) {
|
||||
assert_not_reached ();
|
||||
}
|
||||
assert (info != null);
|
||||
@@ -2478,7 +2482,7 @@ namespace Frida {
|
||||
if (stdout_pipe == null) {
|
||||
try {
|
||||
var process = new Subprocess.newv ({ "logcat", "-b", "crash", "-B" },
|
||||
STDIN_INHERIT | STDOUT_PIPE | STDERR_SILENCE);
|
||||
STDOUT_PIPE | STDERR_SILENCE);
|
||||
|
||||
logcat = process;
|
||||
stdout_pipe = process.get_stdout_pipe ();
|
||||
@@ -2894,7 +2898,7 @@ namespace Frida {
|
||||
},
|
||||
module_list => {
|
||||
foreach (var path in module_list)
|
||||
modules.add_value (new Variant.variant (new Variant.tuple ({ path })));
|
||||
modules.add_value (new Variant.variant (new Variant.tuple ({ path.make_valid () })));
|
||||
});
|
||||
|
||||
vardict_add (reply, "modules", modules.end ());
|
||||
@@ -3111,7 +3115,7 @@ namespace Frida {
|
||||
|
||||
switch (attachment_type) {
|
||||
case SyscallTracer.AttachmentType.STRING:
|
||||
return (string) data;
|
||||
return ((string) data).make_valid ();
|
||||
case SyscallTracer.AttachmentType.BYTES: {
|
||||
if (arg_type != null) {
|
||||
Variant? v = try_decode_timespec (arg_type, data, len);
|
||||
@@ -3208,7 +3212,7 @@ namespace Frida {
|
||||
if (name_len != 0)
|
||||
Memory.copy (str, path + 1, name_len);
|
||||
|
||||
return new Variant.tuple ({ "unix-abstract", (string) str });
|
||||
return new Variant.tuple ({ "unix-abstract", ((string) str).make_valid () });
|
||||
}
|
||||
|
||||
size_t n = 1;
|
||||
@@ -3218,7 +3222,7 @@ namespace Frida {
|
||||
var str = new uint8[n + 1];
|
||||
Memory.copy (str, path, n);
|
||||
|
||||
return new Variant.tuple ({ "unix", (string) str });
|
||||
return new Variant.tuple ({ "unix", ((string) str).make_valid () });
|
||||
}
|
||||
default:
|
||||
return null;
|
||||
|
||||
@@ -449,8 +449,13 @@ namespace Frida {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!/^([0-9a-f]+)-([0-9a-f]+) (\S{4}) ([0-9a-f]+) ([0-9a-f]{2,}:[0-9a-f]{2,}) (\d+) *([^\n]*)$/m.match (
|
||||
contents, 0, out info)) {
|
||||
try {
|
||||
var line_pattern = new Regex (
|
||||
"""^([0-9a-f]+)-([0-9a-f]+) (\S{4}) ([0-9a-f]+) ([0-9a-f]{2,}:[0-9a-f]{2,}) (\d+) *([^\n]*)$""",
|
||||
MULTILINE | RAW);
|
||||
if (!line_pattern.match (contents, 0, out info))
|
||||
assert_not_reached ();
|
||||
} catch (RegexError e) {
|
||||
assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/efni.git
|
||||
revision = 329dd8e94505e95e066251e3d4dfe25d0e55eec3
|
||||
revision = 72f90afcc1f7c663db4de934e9f7ab9d3f67d4b1
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-gum.git
|
||||
revision = 17.25.2
|
||||
revision = 17.26.2
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida-forks/glib.git
|
||||
revision = c366177b9292432a26f6903fa82a71d83e4927eb
|
||||
revision = f11db6352345ad21deb5f5783bb988bfca2a3d85
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/idun.git
|
||||
revision = 6248f41225e1111735e5b4281c1e0cc53f00ff17
|
||||
revision = 59f682f4aba229ca73d175f66f3fa6d9e2f4b7a0
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida-forks/lwip.git
|
||||
revision = f8424fd177ae3654fa040b8b6bc0c32de7fd6ad9
|
||||
revision = 6ab74462bd4a5afb13394942ab031d7bee005b4c
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace Frida.InjectorTest {
|
||||
|
||||
GLib.Test.add_func ("/Injector/resource-leaks", test_resource_leaks);
|
||||
|
||||
#if LINUX
|
||||
GLib.Test.add_func ("/Injector/Linux/inject-with-non-utf8-mapping", test_injection_with_non_utf8_mapping);
|
||||
#endif
|
||||
|
||||
#if DARWIN
|
||||
GLib.Test.add_func ("/Injector/suspended-injection-current-arch", () => {
|
||||
test_suspended_injection (Frida.Test.Arch.CURRENT);
|
||||
@@ -149,6 +153,45 @@ namespace Frida.InjectorTest {
|
||||
rat.close ();
|
||||
}
|
||||
|
||||
#if LINUX
|
||||
private void test_injection_with_non_utf8_mapping () {
|
||||
var logfile = File.new_for_path (Frida.Test.path_to_temporary_file ("non-utf8-mapping.log"));
|
||||
try {
|
||||
logfile.delete ();
|
||||
} catch (GLib.Error delete_error) {
|
||||
}
|
||||
var envp = new string[] {
|
||||
"FRIDA_LABRAT_LOGFILE=" + logfile.get_path ()
|
||||
};
|
||||
|
||||
var sleeper = File.new_for_path (Frida.Test.Labrats.path_to_executable ("sleeper"));
|
||||
var sleeper_copy = File.new_for_path (Frida.Test.path_to_temporary_file ("sleeper-\xff"));
|
||||
try {
|
||||
sleeper.copy (sleeper_copy, OVERWRITE);
|
||||
} catch (GLib.Error e) {
|
||||
assert_not_reached ();
|
||||
}
|
||||
FileUtils.chmod (sleeper_copy.get_path (), 0700);
|
||||
|
||||
var rat = new Labrat.from_path (sleeper_copy.get_path (), envp);
|
||||
|
||||
rat.inject ("simple-agent", "");
|
||||
rat.wait_for_uninject ();
|
||||
assert_true (content_of (logfile) == ">m<");
|
||||
|
||||
try {
|
||||
rat.process.kill ();
|
||||
|
||||
logfile.delete ();
|
||||
sleeper_copy.delete ();
|
||||
} catch (GLib.Error e) {
|
||||
assert_not_reached ();
|
||||
}
|
||||
|
||||
rat.close ();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if DARWIN
|
||||
private void test_suspended_injection (Frida.Test.Arch arch) {
|
||||
var logfile = File.new_for_path (Frida.Test.path_to_temporary_file ("suspended-injection.log"));
|
||||
@@ -193,8 +236,12 @@ namespace Frida.InjectorTest {
|
||||
private PendingUninject? pending_uninject;
|
||||
|
||||
public Labrat (string name, string[] envp, Frida.Test.Arch arch = Frida.Test.Arch.CURRENT) {
|
||||
this.from_path (Frida.Test.Labrats.path_to_executable (name), envp, arch);
|
||||
}
|
||||
|
||||
public Labrat.from_path (string path, string[] envp, Frida.Test.Arch arch = Frida.Test.Arch.CURRENT) {
|
||||
try {
|
||||
process = Frida.Test.Process.start (Frida.Test.Labrats.path_to_executable (name), null, envp, arch);
|
||||
process = Frida.Test.Process.start (path, null, envp, arch);
|
||||
} catch (Error e) {
|
||||
printerr ("\nFAIL: %s\n\n", e.message);
|
||||
assert_not_reached ();
|
||||
|
||||
Reference in new issue
Block a user