Skip to content

Commit

Permalink
fruity: Clean up OS-specific bits
Browse files Browse the repository at this point in the history
  • Loading branch information
oleavr committed Jul 8, 2024
1 parent 3f6b41d commit 6d3ea5f
Show file tree
Hide file tree
Showing 11 changed files with 648 additions and 1,470 deletions.
2 changes: 1 addition & 1 deletion meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ if host_os_family == 'darwin'
backend_libs_private += ['-Wl,-framework,Foundation', '-lbsm']
endif
if host_os == 'macos'
backend_libs_private += ['-Wl,-framework,AppKit', '-Wl,-framework,IOKit']
backend_libs_private += ['-Wl,-framework,AppKit']
endif
if host_os in ['ios', 'tvos']
backend_libs_private += ['-Wl,-framework,CoreGraphics', '-Wl,-framework,UIKit']
Expand Down
191 changes: 0 additions & 191 deletions src/fruity/xpc-linux.vala → src/fruity/device-monitor-linux.vala
Original file line number Diff line number Diff line change
@@ -1,196 +1,5 @@
[CCode (gir_namespace = "FridaFruity", gir_version = "1.0")]
namespace Frida.Fruity {
#if 0
public sealed class LinuxTunnelFinder : Object, TunnelFinder {
public async Tunnel? find_tunnel (string udid, Cancellable? cancellable) throws Error, IOError {
NcmPeer? peer = yield locate_ncm_peer (udid, cancellable);
if (peer == null)
return null;

var bootstrap_disco = yield DiscoveryService.open (
yield peer.open_tcp_connection (58783, cancellable), cancellable);

var tunnel_service = bootstrap_disco.get_service ("com.apple.internal.dt.coredevice.untrusted.tunnelservice");
var pairing_transport = new XpcPairingTransport (yield peer.open_tcp_connection (tunnel_service.port, cancellable));
var pairing_service = yield PairingService.open (pairing_transport, cancellable);

TunnelConnection tc = yield pairing_service.open_tunnel (peer.address, cancellable);

var disco = yield DiscoveryService.open (yield tc.open_connection (tc.remote_rsd_port, cancellable), cancellable);

return new LinuxTunnel (tc, disco);
}

private static async NcmPeer? locate_ncm_peer (string udid, Cancellable? cancellable) throws Error, IOError {
var device_ifaddrs = new Gee.ArrayList<unowned Linux.Network.IfAddrs> ();
var fruit_finder = FruitFinder.make_default ();
string raw_udid = udid.replace ("-", "");
Linux.Network.IfAddrs ifaddrs;
Linux.Network.getifaddrs (out ifaddrs);
for (unowned Linux.Network.IfAddrs candidate = ifaddrs; candidate != null; candidate = candidate.ifa_next) {
if (candidate.ifa_addr.sa_family != Posix.AF_INET6)
continue;

string? candidate_udid = fruit_finder.udid_from_iface (candidate.ifa_name);
if (candidate_udid != raw_udid)
continue;

device_ifaddrs.add (candidate);
}
if (device_ifaddrs.is_empty)
return null;

var sockets = new Gee.ArrayList<Socket> ();
var sources = new Gee.ArrayList<Source> ();
var readable_sockets = new Gee.ArrayQueue<Socket> ();
bool timed_out = false;
bool waiting = false;

var remote_address = new InetSocketAddress.from_string ("ff02::fb", 5353);
var remoted_mdns_request = make_remoted_mdns_request ();
var main_context = MainContext.get_thread_default ();

foreach (unowned Linux.Network.IfAddrs ifaddr in device_ifaddrs) {
try {
var sock = new Socket (IPV6, DATAGRAM, UDP);
sock.bind (SocketAddress.from_native ((void *) ifaddr.ifa_addr, sizeof (Posix.SockAddrIn6)), false);
sock.send_to (remote_address, remoted_mdns_request.get_data (), cancellable);

var source = sock.create_source (IN, cancellable);
source.set_callback (() => {
readable_sockets.offer (sock);
if (waiting)
locate_ncm_peer.callback ();
return Source.REMOVE;
});
source.attach (main_context);

sockets.add (sock);
sources.add (source);
} catch (GLib.Error e) {
}
}

var timeout_source = new TimeoutSource.seconds (2);
timeout_source.set_callback (() => {
timed_out = true;
if (waiting)
locate_ncm_peer.callback ();
return Source.REMOVE;
});
timeout_source.attach (main_context);
sources.add (timeout_source);

Socket? sock;
while ((sock = readable_sockets.poll ()) == null && !timed_out) {
waiting = true;
yield;
waiting = false;
}

foreach (var source in sources)
source.destroy ();

if (sock == null && timed_out)
throw new Error.TIMED_OUT ("Unexpectedly timed out while waiting for mDNS reply");

InetSocketAddress sender;
try {
SocketAddress raw_sender;
var response_buf = new uint8[2048];
sock.receive_from (out raw_sender, response_buf, cancellable);
sender = (InetSocketAddress) raw_sender;
} catch (GLib.Error e) {
throw new Error.TRANSPORT ("%s", e.message);
}

return new NcmPeer ("%s%%%u".printf (sender.address.to_string (), sender.scope_id));
}

private static Bytes make_remoted_mdns_request () {
uint16 transaction_id = 0;
uint16 flags = 0;
uint16 num_questions = 1;
uint16 answer_rrs = 0;
uint16 authority_rrs = 0;
uint16 additional_rrs = 0;
string components[] = { "_remoted", "_tcp", "local" };
uint16 record_type = 12;
uint16 dns_class = 1;
return new BufferBuilder (BIG_ENDIAN)
.append_uint16 (transaction_id)
.append_uint16 (flags)
.append_uint16 (num_questions)
.append_uint16 (answer_rrs)
.append_uint16 (authority_rrs)
.append_uint16 (additional_rrs)
.append_uint8 ((uint8) components[0].length)
.append_string (components[0], StringTerminator.NONE)
.append_uint8 ((uint8) components[1].length)
.append_string (components[1], StringTerminator.NONE)
.append_uint8 ((uint8) components[2].length)
.append_string (components[2], StringTerminator.NUL)
.append_uint16 (record_type)
.append_uint16 (dns_class)
.build ();
}

private class NcmPeer {
public string address;

public class NcmPeer (string address) {
this.address = address;
}

public async IOStream open_tcp_connection (uint16 port, Cancellable? cancellable) throws Error, IOError {
SocketConnection connection;
try {
NetworkAddress service_address = NetworkAddress.parse (address, port);

var client = new SocketClient ();
connection = yield client.connect_async (service_address, cancellable);
} catch (GLib.Error e) {
throw new Error.TRANSPORT ("%s", e.message);
}

Tcp.enable_nodelay (connection.socket);

return connection;
}
}
}
#endif

private sealed class LinuxTunnel : Object, Tunnel {
public DiscoveryService discovery {
get {
return _discovery;
}
}

private TunnelConnection tunnel_connection;
private DiscoveryService _discovery;

public LinuxTunnel (TunnelConnection conn, DiscoveryService disco) {
tunnel_connection = conn;
_discovery = disco;
}

public async void close (Cancellable? cancellable) throws IOError {
tunnel_connection.cancel ();
}

public async IOStream open_tcp_connection (uint16 port, Cancellable? cancellable) throws Error, IOError {
var netstack = tunnel_connection.tunnel_netstack;
var endpoint = (InetSocketAddress) Object.new (typeof (InetSocketAddress),
address: tunnel_connection.remote_address,
port: port,
scope_id: netstack.scope_id
);
return yield netstack.open_tcp_connection (endpoint, cancellable);
}
}

public class LinuxFruitFinder : Object, FruitFinder {
public string? udid_from_iface (string ifname) throws Error {
var net = "/sys/class/net";
Expand Down
Loading

0 comments on commit 6d3ea5f

Please sign in to comment.