For example, we often find ourselves reversing a file format parser for one reason or another. Many of them support various FourCC-based formats (like MOV, RealMedia, Shockwave, PNG, ICC, ...) and as such usually have code that resembles this:

These compares are useful to locate as they will usually be dealing with an input file and given some complementary runtime data, these locations can help us understand a bit about how the parser may work. So, as Elias Bachaalany demonstrated on the Hex-Rays blog (http://www.hexblog.com/?p=119) IDA supports custom viewer creations. I'll show how to implement a quick, clickable interface to FourCC compares within a binary.
First, we need code to find FourCC compares:
import string
fourccs = []
# loop functions
for func in Functions():
# loop instructions
for instr in FuncItems(func):
# only care about compares
disasm = GetDisasm(instr)
if "cmp" in disasm and "offset" not in disasm:
# ensure immediate compare
if GetOpType(instr, 1) == 5 and GetOpType(instr, 0) == 1:
# ensure at least 3 bytes of ASCII in the immediate
opval = GetOpnd(instr, 1)
try:
opval = int(opval[:-1], 16)
opval = struct.pack('>L', opval)
except ValueError:
pass
oplen = len(opval)
opstrlen = len("".join((x for x in opval if x in string.printable)))
if (opstrlen >= 3):
# change it to character representation in IDA
OpChr(instr, 1)
fourccs.append((instr, opval))
print "0x%08x: %s" % (instr, GetOpnd(instr, 1))
This should output something like the following:

Now, we can build a custom viewer and populate it with our data:
class FourCCViewer(idaapi.simplecustviewer_t):
def __init__(self, data):
self.fourccs = data
self.Create()
print "Launching FourCC subview..."
self.Show()
def Create(self):
title = "FourCCs"
idaapi.simplecustviewer_t.Create(self, title)
comment = idaapi.COLSTR("; Double-click to follow", idaapi.SCOLOR_BINPREF)
self.AddLine(comment)
comment = idaapi.COLSTR("; Hover for preview", idaapi.SCOLOR_BINPREF)
self.AddLine(comment)
for item in self.fourccs:
addy = item[0]
immvalue = item[1]
address_element = idaapi.COLSTR("0x%08x: " % addy, idaapi.SCOLOR_REG)
value_element = idaapi.COLSTR("%s" % immvalue, idaapi.SCOLOR_STRING)
line = address_element + value_element
self.AddLine(line)
return True
def OnDblClick(self, something):
line = self.GetCurrentLine()
if "0x" not in line: return False
# skip COLSTR formatting, find address
addy = int(line[2:line.find(":")], 16)
Jump(addy)
return True
def OnHint(self, lineno):
if lineno < 2: return False
else: lineno -= 2
line = self.GetCurrentLine()
if "0x" not in line: return False
# skip COLSTR formatting, find address
addy = int(line[2:line.find(":")], 16)
disasm = idaapi.COLSTR(GetDisasm(addy) + "\n", idaapi.SCOLOR_DREF)
return (1, disasm)
Now we just need to instantiate an instance of FourCCViewer and it should pop up a new subview that looks like so (assuming you've already run the fourCC finding code above):
foo = FourCCViewer(fourccs)

Pretty simple stuff, but it can come in handy when you've got an arsenal of extra analysis runs you perform prior to reversing a complex binary. A slightly more interesting use case for this was when displaying data scraped from a run time histogram of Shockwave's memory manager as Logan and I spoke about at CanSecWest this year:

That's all for now, hopefully we can get some more MindshaRE posts in the pipeline.
--
Aaron
