The “command-line input” (CLI), situated at the bottom of IDA’s window, is a very powerful tool to quickly execute commands in the language that is currently selected.
Typically, that language will be Python
, and one can use helpers such as idc.here()
to retrieve the address of the cursor location.
However, when some debuggers such as GDB
or WinDbg
are used, the CLI can be switched to one specific to the debugger being used, thereby providing a way to input commands that will be sent the debugger backend.
Alas, when one is debugging using GDB
(for example), Python-specific helpers such as idc.here()
are not available in that CLI anymore.
That means users will have to typically copy information from the listings, and then paste it into the CLI, which is very tedious in addition to being error-prone.
An experienced IDA user recently came up to us with this issue, and suggested that we implement some “variable substitution”, before the text is sent to the backend (be it a debugger, or Python)
For example, the markers:
$!
would be replaced with the current address,$[
with the address of the beginning of the current selection,$]
with the address of the end of the current selectionWe were very enthusiastic about this idea at first, but we quickly realized that this would open a can of worms, which we didn’t feel comfortable opening.
Here are some of the reasons:
0xXXXXXXXX
, #XXXXXXXX
, or even decimal? Depending on who will receive the text to execute, this matters$!
) we support, it will never meet all the needs of all our users. It’s probably better if whatever solution we bring, doesn’t rely on a hard-coded set of substitutions.All-in-all, we decided that it might get very messy, very quickly, and that this first approach of implementing expension in IDA itself, is probably not the strongest idea.
However, the idea is just too good to give up about entirely, and perhaps we can come up with something “lighter”, that could be implemented in IDA 7.2 already (and even before, in fact), and would be helpful most of the time.
IDA ships with PyQt5
, a set of Python Qt bindings which lets us take advantage of pretty much all the features offered by Qt.
For example, it’s possible to place a “filter” on top of the CLI’s input field, that will perform the expansion, in-place.
The benefits of this are approach are:
What follows, is a draft of how this could be done. It currently:
$!
into the current address, and0xXXXXXXXX
Perhaps someone will find this useful, and improve on it… (don’t hesitate to contact us at support@hex-rays.com for suggestions!)
import re from PyQt5 import QtCore, QtGui, QtWidgets import ida_kernwin dock = ida_kernwin.find_widget("Output window") if dock: py_dock = ida_kernwin.PluginForm.FormToPyQtWidget(dock) line_edit = py_dock.findChild(QtWidgets.QLineEdit) if line_edit: try: line_edit.removeEventFilter(kpf) except: pass class filter_t(QtCore.QObject): def eventFilter(self, obj, event): if event.type() == QtCore.QEvent.KeyRelease: self.expand_markers(obj) return QtCore.QObject.eventFilter(self, obj, event) def expand_markers(self, obj): text = obj.text() ea = ida_kernwin.get_screen_ea() exp_text = re.sub(r"\$!", "0x%x" % ea, text) if exp_text != text: obj.setText(exp_text) kpf = filter_t() line_edit.installEventFilter(kpf) print("All set")
Elias Bachaalany has a follow-up blog post about this topic: http://0xeb.net/2019/04/climacros-ida-productivity-tool/