diff --git a/bindings/gumjs/runtime/message-dispatcher.js b/bindings/gumjs/runtime/message-dispatcher.js index 6661d0414..c1d1ba2fc 100644 --- a/bindings/gumjs/runtime/message-dispatcher.js +++ b/bindings/gumjs/runtime/message-dispatcher.js @@ -67,13 +67,15 @@ function MessageDispatcher() { } } - function reply(id, type, result, params) { - params = params || []; - - if (result instanceof ArrayBuffer) - send(['frida:rpc', id, type, undefined].concat(params), result); - else - send(['frida:rpc', id, type, result].concat(params)); + function reply(id, type, result, params = []) { + if (Array.isArray(result) && result.length === 2 && result[1] instanceof ArrayBuffer) { + const [value, data] = result; + send(['frida:rpc', id, type, value, ...params], data); + } else if (result instanceof ArrayBuffer) { + send(['frida:rpc', id, type, undefined, ...params], result); + } else { + send(['frida:rpc', id, type, result, ...params]); + } } function dispatchMessages() { diff --git a/tests/gumjs/script.c b/tests/gumjs/script.c index 59600eed7..b442a428b 100644 --- a/tests/gumjs/script.c +++ b/tests/gumjs/script.c @@ -52,6 +52,7 @@ TESTLIST_BEGIN (script) TESTENTRY (method_can_return_null) TESTENTRY (method_can_receive_binary_data) TESTENTRY (method_can_return_binary_data) + TESTENTRY (method_can_return_value_and_binary_data) TESTENTRY (method_list_can_be_queried) TESTENTRY (calling_inexistent_method_should_throw_error) TESTGROUP_END () @@ -6072,6 +6073,19 @@ TESTCASE (method_can_return_binary_data) "59 6f"); } +TESTCASE (method_can_return_value_and_binary_data) +{ + COMPILE_AND_LOAD_SCRIPT ( + "rpc.exports.read = () => {" + "const buf = Memory.allocUtf8String(\"Yo\");" + "return [{meta: 'data'}, buf.readByteArray(2)];" + "};"); + POST_MESSAGE ("[\"frida:rpc\",42,\"call\",\"read\",[]]"); + EXPECT_SEND_MESSAGE_WITH_PAYLOAD_AND_DATA ( + "[\"frida:rpc\",42,\"ok\",{\"meta\":\"data\"}]", + "59 6f"); +} + TESTCASE (method_list_can_be_queried) { COMPILE_AND_LOAD_SCRIPT ("rpc.exports = { a() {}, b() {}, c() {} };");