frida / frida-python

Frida Python bindings
Other
766 stars 145 forks source link

on_message need carry script Object to reply frida in on_message callback #233

Closed pop-m closed 1 year ago

pop-m commented 1 year ago

I think on_message needs to carry the Script object that generates the message (multiple process hooks will generate multiple script objects), so that the post method can be called in the callback to reply to frida.

oleavr commented 1 year ago

Thanks! This would need to take the callback arity into account, to match the behavior of the native code when calling the signal handler. One could argue we already have such a bug here since we currently require both message and data, but it should be possible to omit data if it's not needed.

pop-m commented 1 year ago

I'm very sorry as I'm not very knowledgeable about other codes. i can show you my code:

// javascript
Java.perform(()=>{
  setTimeout(()=>{
    console.log("start");
    send({"request"});
    recv("response", (message, data) => {
        console.log("end");
    }, 1000);
})
# python

def on_message(message, data):
    if message['type'] == "send":
      if message["payload"] == "request":
        # do something in python
        # todo: need to reply frida "bbb", but need call post method of Script object

# some logic to generate many pid to attach, the script corresponding to each pid is different
pids = [111,222,333,444,555]
for pid in pids:
    session = device.attach(pid)
    script = session.create_script(load_script(js_map[pid]))
    script.on('message', on_message)

I think every callback needs to know the source, then can do something in callback if carry script to callback, the on_meesage method will be this:

def on_message(script, message, data):
    if message['type'] == "send":
      if message["payload"] == "request":
        # do something in python
        script.post({"type": "response"})
yotamN commented 1 year ago

It breaks backward compatibility and not for a good enough reason in my opinion. I'm not strictly against adding arguments that would be helpful to the callback but you can achieve the same thing quite easily without it so the decision boils down to whether this is a common enough pattern and whether the workaround is too verbose. Your code could look something like that:

def create_on_message(script):
    def on_message(message, data):
        if message['type'] == "send":
            if message["payload"] == "request":
                # do something in python
                # todo: need to reply frida "bbb", but need call post method of Script object
    return on_message

# some logic to generate many pid to attach, the script corresponding to each pid is different
pids = [111,222,333,444,555]
for pid in pids:
    session = device.attach(pid)
    script = session.create_script(load_script(js_map[pid]))
    script.on('message', create_on_message(script))

Notice that I'm creating a closure with the relevant script object for each callback.

pop-m commented 1 year ago

ok thanks, this seems to solve my problem, and I really didn't take forward compatibility into account. But if forward compatibility is not considered, I think it may be better to add it, because it can make the code more concise Anyway, thank you for your patience

yotamN commented 1 year ago

We are still bound by backward compatibility so it won't be merged soon.
For cleanness sake, I will close this PR, I'm glad to hear the solution worked for you.

pop-m commented 1 year ago

ok, thank you