eset/ipyida

stdout broken after reopen idb

Cirn09 opened this issue · 4 comments

how to reproduce

Open an idb, then close, final reopen.
now "IPython Console" stdout is broken:
Snipaste_2022-07-27_18-15-16

why

when idb open, plugin will load; when idb close, plugin will unload if not have no idaapi.PLUGIN_FIX property.
but IDAPython will not unload, and Python have module cache
I guess the code to hook stdout in ipython will not call again when reopen, because of module cache.

how to fix

The easiest way is set IPyIDAPlugIn.flags = idaapi.PLUGIN_FIX. It will making ipyida would not unload when idb closed.
And it also can help to solve my ida plugin's bug(it's need hook stdout too, and have to set idaapi.PLUGIN_FIX): Cirn09/idavscode#2
PS: I try modify kernel.py:

...

class IPythonKernel(object):
    ...
    def start(self):
        self._ida_stdout = sys.stdout
        self._ida_stderr = sys.stderr
        ...
    
    def stop(self):
        ...
        sys.stdout = self._ida_stdout
        sys.stderr = self._ida_stderr
    ...

it can also fix this bug, I don't know why...

Hey @Cirn09!

Thanks for reporting this! Having idaapi.PLUGIN_FIX set does seem like the way IPyIDA should be implemented. I'll try and test a few things, but will include a fix for this broken stdout after loading another idb, and also make doesn't break IDAVSCode. This fix will be included in the next release.

@Cirn09, should probably consider sys.displayhook instead of hijacking stdout/stderr.

I believe this is the same issue as the 2nd point I mentioned in #50 (comment).

Console output to the IPython console stops working after closing and opening an IDA file. It works correctly the first time. The issue appears to be due to the console being restored back on closing the file, and then not being reinitialized on opening the second file.

The patch I included there fixed the issue for me, although there is probably a better way of doing it.

IPyIDA now has the idaapi.PLUGIN_FIX flag set which fixes the issue.