Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Socket not closed, when GhidraBridge Object gets out of scope #65

Open
maxeisele opened this issue Feb 17, 2022 · 5 comments
Open

Socket not closed, when GhidraBridge Object gets out of scope #65

maxeisele opened this issue Feb 17, 2022 · 5 comments

Comments

@maxeisele
Copy link

maxeisele commented Feb 17, 2022

I have observed, that the socket to ghidra is not closed, when the GhidraBridge Object gets out of scope. It gets closed, when the whole python process terminates. We have a long running python process and do some ghidra operations from time to time via a remotifyied class:

with ghidra_bridge.GhidraBridge(  ) as bridge:
            RemoteGhidraClass = bridge.remoteify(RemoteGhidra)
            remote_ghidra = RemoteGhidraClass().do_something()

In the log from Ghidra, we can see WARNING:jfx_bridge.bridge:Handling connection from ('127.0.0.1', 55500) each time the above code is called (with different port of course), but the connection gets not closed.
Also we experience some hung ups now and then. Could that be related? We have also experienced hangs, when keeping the GhidraBridge Object alive across the different calls. What would be the correct was here?

At the same time, we are experiencing following error log:

[ERROR bridge.py:522 run()] 'utf-8' codec can't decode byte 0xaa in position 327679: invalid start byte
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/jfx_bridge/bridge.py", line 504, in run
    msg_dict = json.loads(data.decode("utf-8"))
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xaa in position 327679: invalid start byte

@justfoxing
Copy link
Owner

I'm assuming that decode error is from the same code as the user who opened justfoxing/jfx_bridge#17 , yeah? If not, would love to see your code as well. Let's handle the debugging for that one in that issue.

The exact time when the bridge socket gets closed is a bit messy - it happens when there's no references left to the bridge, and any bridged object will maintain a reference. If you're keeping something like remote_ghidra to use outside the block, the bridge it came over will stay alive as well. (Also, it's entirely possible I left bugs here - there's a strong potential for cyclic dependencies that would result in things living forever).

It sounds like there's a range of issues here, with not enough info for me to see what's going on. My recommendation would be to not create multiple ghidra_bridges - instead, alter your code so that the first time you create a bridge, you keep it around to use for subsequent operations. Then, if you have issues after that, I'd love to be able to see your code as well as the error - that'd help me be able to give better advice.

@maxeisele
Copy link
Author

First, thanks for your fast reply

I'm assuming that decode error is from the same code as the user who opened justfoxing/jfx_bridge#17 , yeah? If not, would love to see your code as well. Let's handle the debugging for that one in that issue.

Right, some communication error.

The exact time when the bridge socket gets closed is a bit messy - it happens when there's no references left to the bridge, and any bridged object will maintain a reference. If you're keeping something like remote_ghidra to use outside the block, the bridge it came over will stay alive as well. (Also, it's entirely possible I left bugs here - there's a strong potential for cyclic dependencies that would result in things living forever).

I will refactor the code such, that I will keep one ghidra bridge alive and see if I still experience these hangs. If yes, I will try to provide code to reproduce it.

@maxeisele
Copy link
Author

Regarding, the opened sockets. If you execute this code multiple times in a jupyter notebook, the sockets are note closed, and a new one is opened on each execution.

import ghidra_bridge
import logging as log

def long_runing_function():
    ret = []
    for i in range(100):
        ret.append(i)

    return ret



bridge = ghidra_bridge.GhidraBridge(
                response_timeout=3600,
                interactive_mode=False,
                loglevel=log.DEBUG
        )
remote_function = bridge.remoteify(long_runing_function)

ret = remote_function()

Let's discuss the decode error in issue justfoxing/jfx_bridge#17

@justfoxing
Copy link
Owner

justfoxing commented Feb 18, 2022 via email

@justfoxing
Copy link
Owner

Alternatively, you could try wrapping the bridge creation in something a little like the following, so that it only ever gets run once, regardless of how many times its cell is rerun.

try:
    if bridge is None:
        raise Exception()
except Exception:
    bridge = ghidra_bridge.GhidraBridge(...)

justfoxing added a commit to justfoxing/jfx_bridge that referenced this issue Feb 19, 2022
… BridgeConn.send_cmd (and other functions) could try to put data on the socket at the same time. If there was enough data, the socket.send() might return partway, a thread switch might happen, and another thread might begin its message halfway through the first message.

Attempting as a fix for justfoxing/ghidra_bridge#65
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants