mirror of
https://github.com/frida/frida-core.git
synced 2026-11-08 17:12:49 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2e071ed78 | ||
|
|
bc7f73b492 | ||
|
|
f91a3c92fe | ||
|
|
6eacc889cd | ||
|
|
d21ba21aea | ||
|
|
cfcdc26d29 | ||
|
|
69555bbbb6 |
No files matched your search
@@ -428,6 +428,8 @@ static void frida_agent_context_emit_mach_stub_code (FridaAgentContext * self, g
|
||||
static void frida_agent_context_emit_pthread_stub_code (FridaAgentContext * self, guint8 * code, GumDarwinModuleResolver * resolver,
|
||||
GumDarwinMapper * mapper);
|
||||
|
||||
static gboolean frida_convert_thread_state_for_task (mach_port_t task, thread_state_flavor_t flavor, gconstpointer in_state,
|
||||
mach_msg_type_number_t in_state_count, gpointer out_state, mach_msg_type_number_t * out_state_count, GError ** error);
|
||||
static mach_port_t frida_obtain_thread_port_for_thread_id (mach_port_t task, uint64_t thread_id);
|
||||
static kern_return_t frida_get_thread_state (mach_port_t thread, thread_state_flavor_t flavor, gpointer state,
|
||||
mach_msg_type_number_t * count);
|
||||
@@ -2583,16 +2585,24 @@ static gboolean
|
||||
frida_inject_instance_start_thread (FridaInjectInstance * self, GError ** error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
thread_state_t thread_state;
|
||||
mach_msg_type_number_t thread_state_count;
|
||||
kern_return_t kr;
|
||||
const gchar * failed_operation;
|
||||
FridaHelperContext * ctx = self->backend->context;
|
||||
dispatch_source_t source;
|
||||
|
||||
kr = thread_create (self->task, &self->thread);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "thread_create");
|
||||
thread_state = g_alloca (self->thread_state_count * sizeof (natural_t));
|
||||
thread_state_count = self->thread_state_count;
|
||||
|
||||
kr = frida_set_thread_state (self->thread, self->thread_state_flavor, self->thread_state_data, self->thread_state_count);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "set_thread_state");
|
||||
if (!frida_convert_thread_state_for_task (self->task, self->thread_state_flavor, self->thread_state_data, self->thread_state_count,
|
||||
thread_state, &thread_state_count, error))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
kr = thread_create_running (self->task, self->thread_state_flavor, thread_state, thread_state_count, &self->thread);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "thread_create");
|
||||
|
||||
source = dispatch_source_create (DISPATCH_SOURCE_TYPE_MACH_SEND, self->thread, DISPATCH_MACH_SEND_DEAD, ctx->dispatch_queue);
|
||||
self->thread_monitor_source = source;
|
||||
@@ -2601,9 +2611,6 @@ frida_inject_instance_start_thread (FridaInjectInstance * self, GError ** error)
|
||||
dispatch_source_set_event_handler_f (source, frida_inject_instance_on_mach_thread_dead);
|
||||
dispatch_resume (source);
|
||||
|
||||
kr = thread_resume (self->thread);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "thread_resume");
|
||||
|
||||
success = TRUE;
|
||||
|
||||
goto beach;
|
||||
@@ -5072,6 +5079,52 @@ frida_agent_context_emit_arm64_pthread_stub_body (FridaAgentContext * self, Frid
|
||||
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
frida_convert_thread_state_for_task (mach_port_t task, thread_state_flavor_t flavor, gconstpointer in_state,
|
||||
mach_msg_type_number_t in_state_count, gpointer out_state, mach_msg_type_number_t * out_state_count,
|
||||
GError ** error)
|
||||
{
|
||||
gboolean success = FALSE;
|
||||
kern_return_t kr;
|
||||
const gchar * failed_operation;
|
||||
thread_act_array_t threads = NULL;
|
||||
mach_msg_type_number_t thread_count = 0;
|
||||
|
||||
kr = task_threads (task, &threads, &thread_count);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "task_threads");
|
||||
|
||||
kr = frida_convert_thread_state (threads[0], FRIDA_CONVERT_THREAD_STATE_OUT, flavor, in_state, in_state_count,
|
||||
out_state, out_state_count);
|
||||
CHECK_MACH_RESULT (kr, ==, KERN_SUCCESS, "thread_convert_thread_state");
|
||||
|
||||
success = TRUE;
|
||||
|
||||
goto beach;
|
||||
|
||||
mach_failure:
|
||||
{
|
||||
g_set_error (error,
|
||||
FRIDA_ERROR,
|
||||
FRIDA_ERROR_NOT_SUPPORTED,
|
||||
"Unexpected error while converting thread state for task (%s returned '%s')",
|
||||
failed_operation, mach_error_string (kr));
|
||||
goto beach;
|
||||
}
|
||||
beach:
|
||||
{
|
||||
mach_msg_type_number_t i;
|
||||
|
||||
if (threads != NULL)
|
||||
{
|
||||
for (i = 0; i != thread_count; i++)
|
||||
mach_port_deallocate (mach_task_self (), threads[i]);
|
||||
vm_deallocate (mach_task_self (), (vm_address_t) threads, thread_count * sizeof (thread_t));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
|
||||
static mach_port_t
|
||||
frida_obtain_thread_port_for_thread_id (mach_port_t task, uint64_t thread_id)
|
||||
{
|
||||
|
||||
@@ -244,11 +244,7 @@ namespace Frida {
|
||||
}
|
||||
|
||||
private FruityHostSession? host_session;
|
||||
private Promise<Fruity.LockdownClient>? lockdown_client_request;
|
||||
private Promise<Fruity.Tunnel?>? tunnel_request;
|
||||
private Timer? lockdown_client_timer;
|
||||
|
||||
private const double MAX_LOCKDOWN_CLIENT_AGE = 30.0;
|
||||
|
||||
public FruityHostSessionProvider (string name, Variant? icon, Fruity.DeviceDetails details) {
|
||||
Object (
|
||||
@@ -271,19 +267,6 @@ namespace Frida {
|
||||
if (tunnel != null)
|
||||
yield tunnel.close (cancellable);
|
||||
}
|
||||
|
||||
if (lockdown_client_request != null) {
|
||||
Fruity.LockdownClient? lockdown = null;
|
||||
try {
|
||||
lockdown = yield get_lockdown_client (cancellable);
|
||||
} catch (Error e) {
|
||||
}
|
||||
|
||||
if (lockdown != null) {
|
||||
on_lockdown_client_closed (lockdown);
|
||||
yield lockdown.close (cancellable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public async HostSession create (HostSessionOptions? options, Cancellable? cancellable) throws Error, IOError {
|
||||
@@ -392,15 +375,46 @@ namespace Frida {
|
||||
var tunnel = yield find_tunnel (cancellable);
|
||||
if (tunnel != null) {
|
||||
Fruity.ServiceInfo? service_info = null;
|
||||
bool needs_checkin = false;
|
||||
try {
|
||||
service_info = tunnel.discovery.get_service (service_name);
|
||||
} catch (Error e) {
|
||||
if (!(e is Error.NOT_SUPPORTED))
|
||||
throw e;
|
||||
}
|
||||
if (service_info == null)
|
||||
if (service_info == null) {
|
||||
service_info = tunnel.discovery.get_service (service_name + ".shim.remote");
|
||||
return yield tunnel.open_tcp_connection (service_info.port, cancellable);
|
||||
needs_checkin = true;
|
||||
}
|
||||
|
||||
var stream = yield tunnel.open_tcp_connection (service_info.port, cancellable);
|
||||
|
||||
if (needs_checkin) {
|
||||
var service = new Fruity.PlistServiceClient (stream);
|
||||
|
||||
var checkin = new Fruity.Plist ();
|
||||
checkin.set_string ("Request", "RSDCheckin");
|
||||
checkin.set_string ("Label", "Xcode");
|
||||
checkin.set_string ("ProtocolVersion", "2");
|
||||
|
||||
try {
|
||||
yield service.query (checkin, cancellable);
|
||||
|
||||
var result = yield service.read_message (cancellable);
|
||||
if (result.has ("Error")) {
|
||||
var error_type = result.get_string ("Error");
|
||||
if (error_type == "ServiceProhibited")
|
||||
throw new Error.PERMISSION_DENIED ("Service prohibited");
|
||||
throw new Error.NOT_SUPPORTED ("%s", error_type);
|
||||
}
|
||||
} catch (Fruity.PlistServiceError e) {
|
||||
throw new Error.PROTOCOL ("%s", e.message);
|
||||
} catch (Frida.Fruity.PlistError e) {
|
||||
throw new Error.PROTOCOL ("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
try {
|
||||
@@ -445,50 +459,15 @@ namespace Frida {
|
||||
}
|
||||
|
||||
private async Fruity.LockdownClient get_lockdown_client (Cancellable? cancellable) throws Error, IOError {
|
||||
if (lockdown_client_timer != null) {
|
||||
if (lockdown_client_timer.elapsed () > MAX_LOCKDOWN_CLIENT_AGE)
|
||||
on_lockdown_client_closed (lockdown_client_request.future.value);
|
||||
else
|
||||
lockdown_client_timer.start ();
|
||||
}
|
||||
|
||||
while (lockdown_client_request != null) {
|
||||
try {
|
||||
return yield lockdown_client_request.future.wait_async (cancellable);
|
||||
} catch (Error e) {
|
||||
throw e;
|
||||
} catch (IOError e) {
|
||||
cancellable.set_error_if_cancelled ();
|
||||
}
|
||||
}
|
||||
lockdown_client_request = new Promise<Fruity.LockdownClient> ();
|
||||
|
||||
try {
|
||||
var client = yield Fruity.LockdownClient.open (device_details, cancellable);
|
||||
yield client.start_session (cancellable);
|
||||
client.closed.connect (on_lockdown_client_closed);
|
||||
|
||||
lockdown_client_request.resolve (client);
|
||||
lockdown_client_timer = new Timer ();
|
||||
|
||||
return client;
|
||||
} catch (GLib.Error e) {
|
||||
var api_error = new Error.NOT_SUPPORTED ("%s", e.message);
|
||||
|
||||
lockdown_client_request.reject (api_error);
|
||||
lockdown_client_request = null;
|
||||
lockdown_client_timer = null;
|
||||
|
||||
throw_api_error (api_error);
|
||||
} catch (Frida.Fruity.LockdownError e) {
|
||||
throw new Error.NOT_SUPPORTED ("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
private void on_lockdown_client_closed (Fruity.LockdownClient client) {
|
||||
client.closed.disconnect (on_lockdown_client_closed);
|
||||
lockdown_client_request = null;
|
||||
lockdown_client_timer = null;
|
||||
}
|
||||
|
||||
private async Fruity.Tunnel? find_tunnel (Cancellable? cancellable) throws Error, IOError {
|
||||
while (tunnel_request != null) {
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[wrap-git]
|
||||
url = https://github.com/frida/frida-gum.git
|
||||
revision = 16.3.0
|
||||
revision = 16.3.2
|
||||
depth = 1
|
||||
|
||||
[provide]
|
||||
|
||||
Reference in new issue
Block a user