Skip to content

Commit

Permalink
Changes to support binary data on stdin and stdout
Browse files Browse the repository at this point in the history
  • Loading branch information
Your Name committed May 16, 2024
1 parent c0fb9c6 commit 28fb2df
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 42 deletions.
88 changes: 61 additions & 27 deletions inject/inject.vala
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ namespace Frida.Inject {
return false;
}

script_runner.on_stdin (line);
script_runner.on_stdin (line, null);

return true;
}
Expand All @@ -414,7 +414,12 @@ namespace Frida.Inject {

buf[n] = 0;

script_runner.on_stdin ((string) buf);
if (script_runner.terminal_mode == TerminalMode.BINARY) {
var bytes = new Bytes (buf[0:n]);
script_runner.on_stdin ("", bytes);
} else {
script_runner.on_stdin ((string) buf, null);
}

return true;
}
Expand Down Expand Up @@ -549,7 +554,7 @@ namespace Frida.Inject {
var stage = new Json.Node.alloc ().init_string ("early");

try {
yield rpc_client.call ("init", new Json.Node[] { stage, parameters }, io_cancellable);
yield rpc_client.call ("init", new Json.Node[] { stage, parameters }, null, io_cancellable);
} catch (GLib.Error e) {
}
}
Expand Down Expand Up @@ -591,15 +596,22 @@ namespace Frida.Inject {
private async TerminalMode query_terminal_mode () {
Json.Node mode_value;
try {
mode_value = yield rpc_client.call ("getFridaTerminalMode", new Json.Node[] {}, io_cancellable);
mode_value = yield rpc_client.call ("getFridaTerminalMode", new Json.Node[] {}, null, io_cancellable);
} catch (GLib.Error e) {
return COOKED;
}

if (mode_value.get_value_type () != typeof (string))
return COOKED;

return (mode_value.get_string () == "raw") ? TerminalMode.RAW : TerminalMode.COOKED;
switch (mode_value.get_string ()) {
case "raw":
return TerminalMode.RAW;
case "binary":
return TerminalMode.BINARY;
default:
return TerminalMode.COOKED;
}
}

private void apply_terminal_mode (TerminalMode mode) throws Error {
Expand Down Expand Up @@ -632,10 +644,10 @@ namespace Frida.Inject {
}
#endif

public void on_stdin (string data) {
var data_value = new Json.Node.alloc ().init_string (data);
public void on_stdin (string str, Bytes? data) {
var str_value = new Json.Node.alloc ().init_string (str);

rpc_client.call.begin ("onFridaStdin", new Json.Node[] { data_value }, io_cancellable);
rpc_client.call.begin ("onFridaStdin", new Json.Node[] { str_value }, data, io_cancellable);
}

private void on_script_file_changed (File file, File? other_file, FileMonitorEvent event_type) {
Expand Down Expand Up @@ -675,7 +687,7 @@ namespace Frida.Inject {
handled = try_handle_log_message (message);
break;
case "send":
handled = try_handle_stdout_message (message);
handled = try_handle_stdout_message (message, data);
break;
default:
handled = false;
Expand Down Expand Up @@ -722,13 +734,13 @@ namespace Frida.Inject {
*
* {"type":"send","payload":["frida:stdout","DATA"]}
*/
private bool try_handle_stdout_message (Json.Object message) {
private bool try_handle_stdout_message (Json.Object message, Bytes? data) {
var payload = message.get_member ("payload");
if (payload.get_node_type () != Json.NodeType.ARRAY)
return false;

var tuple = payload.get_array ();
if (tuple.get_length () != 2)
if (tuple.get_length () < 1)
return false;

var first_element = tuple.get_element (0);
Expand All @@ -744,31 +756,53 @@ namespace Frida.Inject {
return false;
}

var second_element = tuple.get_element (1);
if (second_element.get_value_type () != typeof (string))
return false;
var str = second_element.get_string ();
if (tuple.get_length () > 1) {
var second_element = tuple.get_element (1);

switch (type) {
case "frida:stdout":
stdout.write (str.data);
stdout.flush ();
return true;
case "frida:stderr":
stderr.write (str.data);
return true;
default:
if (second_element.get_value_type () != typeof (string))
return false;

var str = second_element.get_string ();

if (str != null) {
switch (type) {
case "frida:stdout":
stdout.write (str.data);
stdout.flush ();
break;
case "frida:stderr":
stderr.write (str.data);
break;
default:
return false;
}
}
}

if (data != null) {
switch (type) {
case "frida:stdout":
stdout.write (data.get_data ());
stdout.flush ();
break;
case "frida:stderr":
stderr.write (data.get_data ());
break;
default:
return false;
}
}
return true;
}

private async void post_rpc_message (string json, Cancellable? cancellable) throws Error, IOError {
script.post (json, null);
private async void post_rpc_message (string json, Bytes? data, Cancellable? cancellable) throws Error, IOError {
script.post (json, data);
}
}

private enum TerminalMode {
COOKED,
RAW
RAW,
BINARY
}
}
6 changes: 3 additions & 3 deletions lib/base/rpc.vala
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Frida {
Object (peer: peer);
}

public async Json.Node call (string method, Json.Node[] args, Cancellable? cancellable) throws Error, IOError {
public async Json.Node call (string method, Json.Node[] args, Bytes? data, Cancellable? cancellable) throws Error, IOError {
string request_id = Uuid.string_random ();

var request = new Json.Builder ();
Expand Down Expand Up @@ -39,7 +39,7 @@ namespace Frida {
pending_responses[request_id] = pending;

try {
yield peer.post_rpc_message (raw_request, cancellable);
yield peer.post_rpc_message (raw_request, data, cancellable);
} catch (Error e) {
if (pending_responses.unset (request_id))
pending.complete_with_error (e);
Expand Down Expand Up @@ -158,6 +158,6 @@ namespace Frida {
}

public interface RpcPeer : Object {
public abstract async void post_rpc_message (string json, Cancellable? cancellable) throws Error, IOError;
public abstract async void post_rpc_message (string json, Bytes? data, Cancellable? cancellable) throws Error, IOError;
}
}
6 changes: 3 additions & 3 deletions lib/gadget/gadget.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ namespace Frida.Gadget {
var stage = new Json.Node.alloc ().init_string ((peek_state () == State.CREATED) ? "early" : "late");

try {
yield rpc_client.call ("init", new Json.Node[] { stage, parameters }, null);
yield rpc_client.call ("init", new Json.Node[] { stage, parameters }, null, null);
} catch (GLib.Error e) {
}
}
Expand Down Expand Up @@ -1449,8 +1449,8 @@ namespace Frida.Gadget {
return true;
}

private async void post_rpc_message (string json, Cancellable? cancellable) throws Error, IOError {
engine.post_to_script (id, json);
private async void post_rpc_message (string json, Bytes? data, Cancellable? cancellable) throws Error, IOError {
engine.post_to_script (id, json, data);
}
}

Expand Down
6 changes: 3 additions & 3 deletions lib/payload/script-engine.vala
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ namespace Frida {
var reason_value = new Json.Node.alloc ().init_string (reason.to_nick ());

try {
yield rpc_client.call ("dispose", new Json.Node[] { reason_value }, null);
yield rpc_client.call ("dispose", new Json.Node[] { reason_value }, null, null);
} catch (GLib.Error e) {
}

Expand Down Expand Up @@ -467,10 +467,10 @@ namespace Frida {
this.debug_message (message);
}

private async void post_rpc_message (string json, Cancellable? cancellable) throws Error, IOError {
private async void post_rpc_message (string json, Bytes? data, Cancellable? cancellable) throws Error, IOError {
if (script == null)
throw new Error.INVALID_OPERATION ("Script is destroyed");
script.post (json);
script.post (json, data);
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion src/barebone/script.vala
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,9 @@ namespace Frida {

public void post (string json, Bytes? data) {
var json_val = ctx.make_string (json);
invoke_void (dispatch_message_func, { json_val }, runtime_obj);
var data_val = ctx.make_array_buffer (data.get_data ());
invoke_void (dispatch_message_func, { json_val, data_val }, runtime_obj);
ctx.free_value (data_val);
ctx.free_value (json_val);

perform_pending_io ();
Expand Down
4 changes: 2 additions & 2 deletions src/compiler/compiler.vala
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ namespace Frida {
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 ()),
}, cancellable);
}, null, cancellable);
return bundle.get_string ();
}

Expand All @@ -288,7 +288,7 @@ namespace Frida {
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 ()),
}, cancellable);
}, null, cancellable);
}

private static string compute_project_root (string entrypoint, CompilerOptions options) {
Expand Down
6 changes: 3 additions & 3 deletions src/host-session-service.vala
Original file line number Diff line number Diff line change
Expand Up @@ -1331,10 +1331,10 @@ namespace Frida {
protected virtual void on_event (string type, Json.Array event) {
}

protected async Json.Node call (string method, Json.Node[] args, Cancellable? cancellable) throws Error, IOError {
protected async Json.Node call (string method, Json.Node[] args, Bytes? data, Cancellable? cancellable) throws Error, IOError {
yield ensure_loaded (cancellable);

return yield rpc_client.call (method, args, cancellable);
return yield rpc_client.call (method, args, data, cancellable);
}

protected async void post (Json.Node message, Cancellable? cancellable) throws Error, IOError {
Expand Down Expand Up @@ -1504,7 +1504,7 @@ namespace Frida {
printerr ("%s\n", json);
}

private async void post_rpc_message (string json, Cancellable? cancellable) throws Error, IOError {
private async void post_rpc_message (string json, Bytes? data, Cancellable? cancellable) throws Error, IOError {
try {
yield session.post_messages ({ AgentMessage (SCRIPT, script, json, false, {}) }, 0, cancellable);
} catch (GLib.Error e) {
Expand Down

0 comments on commit 28fb2df

Please sign in to comment.