There's a bit more to this question than meets the eye.
In IDA, each instruction can optionally have a color set on it. Additionally, each graph node can optionally have a color set on it.
If an instruction does not have a color set on it, its background color defaults to the node's color. If the node does not have a color set on it, its background color defaults to the background color for disassembly for the current IDA theme (Options | Colors... | Disassembly). Each node also has two narrow horizontal bands, one located just above the node's instructions and one located below. These bands are always colored with the node's own background color, or the disassembly theme color if no color has been set on the node.
When you use the color chooser in the upper-left corner of a graph node, IDA sets the color on the node as well as on each instruction within the node. You can set a color on an individual instruction via the UI with Edit | Other | Color instruction...
There does not seem to be any way to unset the color of a node or instruction using only the UI (aside from "Undo"). The programmatic way to unset a color from an item or node is to specify the color as
idc.DEFCOLOR which equals
0xffffffff (not to be confused with the color white, which is represented by
- If you want to programmatically perform the equivalent of setting a node color via the UI, you need to set the node color both on the node itself and also on each instruction within the node.
- Unsetting the color from an instruction or node can be done using
- A screen refresh is needed - see below.
Here's what's working for me, on IDA 8.2.230124:
from itertools import islice
def setNodeColor(ea, color, nodeOnly=False):
node_info = idaapi.node_info_t()
node_info.bg_color = color
func = idaapi.get_func(ea)
flowchart = idaapi.FlowChart(func)
block = list(islice(filter(lambda b: b.start_ea <= ea < b.end_ea, flowchart), 1))
idaapi.set_node_info(func.start_ea, block.id, node_info, idaapi.NIF_BG_COLOR)
if not nodeOnly:
for head in idautils.Heads(block.start_ea, block.end_ea):
idc.set_color(head, CIC_ITEM, color)
ea = idc.get_screen_ea()
color = 0xffff00 # use idc.DEFCOLOR to revert to default
IMPORTANT: Note the last line:
idc.refresh_idaview_anyway(). Without this line, the screen may be left in an outdated or inconsistent state. However, for performance reasons, if you are updating multiple nodes, you should only do this once at the end. That's why I didn't place it inside the function definition.