3
\$\begingroup\$

I'm using Frida to run a script on a process, and I want to wait for it to send the result back to me, as a callback.

My current code looks like this:

def check(target): global msg script_to_run = ''' (omitted for brevity) ''' # callback to handle the output of the script def on_message(message, data): global msg if message['type'] == 'send': msg = message['payload'] session = device.attach(target.pid) script = session.create_script(script_to_run) script.on('message', on_message) script.load() # Wait for the script to send us a message while msg == None: pass return msg == 'true' 

The while loop in particular looks a bit unoptimized, and I'm also worried about how I used that global variable... it will pollute the global scope.

EDIT: As it turns out, I was approaching this in the wrong direction. See my answer below for details.

\$\endgroup\$
3
  • \$\begingroup\$ At the very least, I found I should change the pass for a sleep(0): stackoverflow.com/a/790246/12735366 \$\endgroup\$ Commented Sep 4, 2022 at 19:41
  • \$\begingroup\$ This feels too vague to really answer. How is check(target) used? You're transforming an asynchronous function into a synchronous one, which defeats the entire point. \$\endgroup\$ Commented Sep 4, 2022 at 21:46
  • \$\begingroup\$ Yes, sorry, I realize now that messages aren’t the proper way to go about it, I should use the RPC api. I’ll elaborate both question and answer when I get home \$\endgroup\$ Commented Sep 4, 2022 at 21:47

2 Answers 2

4
\$\begingroup\$

So, as it turns out, I was approaching this problem in the wrong direction.

Instead of trying to wait on an asynchronous message, I discovered that Frida has an RPC API.

Here's how I re-wrote my code:

import frida # --snip-- def check(target): session = frida.attach(target.pid) script = session.create_script(''' rpc.exports = { check: function () { // --snip-- return true; } }; ''') script.load() return script.exports.check() 

Much more succinct, doesn't use globals, and doesn't use a while loop to block.

\$\endgroup\$
1
\$\begingroup\$

I am not familiar with Frida, but looking at the examples found at https://frida.re/docs/messages/ I think you should do your processing in the callback "on_message", instead of passing it to the main thread.

The Frida examples end with sys.stdin.read() which acts like a wait-forever loop. The callback is probably executing in a different thread.

So change your last lines to

# Wait for the script to send us a message sys.stdin.read() 

And change the callback to

def on_message(message, data): if message['type'] == 'send': print(message['payload'] == 'true') 

Don't worry about poluting the global namespace. You are the only one using it :-)

\$\endgroup\$
1
  • \$\begingroup\$ Well, see the problem is that this function is going to be part of a larger program. So, I need to get the result back in the main thread, and block until then. \$\endgroup\$ Commented Sep 4, 2022 at 19:22

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.