Skip to content

Instantly share code, notes, and snippets.

@Jinmo
Last active March 18, 2023 02:44
Show Gist options
  • Save Jinmo/de47a5bcec8e8875d4a51053161b2e06 to your computer and use it in GitHub Desktop.
Save Jinmo/de47a5bcec8e8875d4a51053161b2e06 to your computer and use it in GitHub Desktop.
IDA Pro stdin readline support
import idaapi
from Queue import Queue
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtWidgets import qApp, QMainWindow, QWidget, QLineEdit
def _query(window, predicate):
results = []
def _recursive(widget):
for item in widget.children():
if not isinstance(item, QWidget):
continue
if predicate(item):
results.append(item)
_recursive(item)
_recursive(window)
return results
def _get_widget():
window = None
for widget in qApp.topLevelWidgets():
if isinstance(widget, QMainWindow):
window = widget
break
if window is None:
return
def _predicate(item):
cls = item.metaObject().className()
return cls == 'ConsoleWidget'
docks = _query(window, _predicate)
return docks[0]
_dock = _get_widget()
_text = _query(_dock, lambda widget: isinstance(widget, QLineEdit))[0]
class PythonStdin(object):
def read(self, nbytes):
raise NotImplementedError
def readline(self):
queue = Queue()
cli = python_input_cli(queue)
cli.register()
_text.clear()
# Tricky part: clearing the console
while True:
try:
result = queue.get(timeout=0.01)
break
except:
idaapi.hide_wait_box()
QCoreApplication.processEvents()
pass
cli.unregister()
return result
class python_input_cli(idaapi.cli_t):
flags = 0
sname = 'py >>'
lname = 'Python input'
hint = "When python stdin triggers"
def __init__(self, queue):
super(python_input_cli, self).__init__()
self.queue = queue
def OnExecuteLine(self, line):
self.queue.put(line + '\n')
def OnKeydown(self, line, x, sellen, vkey, shift):
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
return None
sys.stdin = PythonStdin()
data = raw_input('>> ')
print repr(data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment