CommentView Plugin for IDAPro7.0

自从ida升级7.0 之后,hexrays做了很多的改动,以前的插件基本都废掉了。于是想要找个插件就变得很困难,最近分析一个文件需要获取所有的注释,但是那个针对低版本开发的commentview已经无力回天了。虽然晚上有开源的代码,但是实际修改起来比较蛋疼,不知道是不是ida的问题,编译的插件获取的地址基本都是错误的。还是按照以前的使用区段枚举,和inf信息获取的方法获取到的地址都错了,着tm就很尴尬了,测试代码如下:

for (int i = 0; i < get_segm_qty(); i++) {
        segment_t *seg = getnseg(i);
        qstring segname;
        get_segm_name( &segname,seg, 1024);
        msg("segname: %s, start_ea= %08x, end_ea= %08x , size=%08x \n", segname.c_str(), seg->start_ea, seg->end_ea, seg->size());
    }
msg("Database Info: start_ea= %08x, min_ea= %08x, max_ea= %08x, omin_ea= %08x, omax_ea= %08x \n", inf.start_ea, inf.min_ea, inf.max_ea, inf.omin_ea, inf.omax_ea);
    msg("lowoff= %08x, highoff= %08x, main= %08x \n", inf.lowoff, inf.highoff, inf.main);

实际获取到的数据如下,测试环境为OSX + IDA 7.0,如果谁看到了这篇文章还获取到了正确的地址麻烦通知我一声(感谢匿名用户的评论反馈:那个基址问题应该是IDA的BUG,在新的IDA 7.0.171130 (SP1)里已经修正了的,如果是正版的话就升级一下吧。)。

segname: .text, start_ea= 10001000, end_ea= 00000001 , size=effff001 
segname: .idata, start_ea= 10005000, end_ea= 00000006 , size=efffb006 
segname: .rdata, start_ea= 1000513c, end_ea= 00000003 , size=efffaec7 
segname: .data, start_ea= 10006000, end_ea= 00000005 , size=efffa005 
Database Info: start_ea= 10007000, min_ea= ff000000, max_ea= 00000000, omin_ea= 0006000f, omax_ea= 06400007 
lowoff= 00500046, highoff= 00000301, main= 10007000 

获取到的end_ea都是错的。

于是只好改变思路,使用idapython来做,由于以前没怎么用python写过插件,所以到处找代码折腾了这么个东西。好歹是满足了需求了,如果有更多的需求自己修改代码吧。如果做了修改麻烦提交下改动,谢谢。

代码如下:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
'''----------------------------------------------------------------------------------------------------------'
'IDA Comments Viewer for IDA pro 7.0'
'Version:1.0 alpha'
'plugin by obaby'
'http://www.h4ck.org.cn http://findu.co'
'----------------------------------------------------------------------------------------------------------'
'''
import idaapi
from ida_ida import *
import idautils
import idc
from idaapi import Choose2
import ida_kernwin
class chooser_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
#sel = []
#for i in xrange(len(ctx.chooser_selection)):
# sel.append(str(ctx.chooser_selection.at(i)))
#print "command %s selected @ %s" % (self.thing, ", ".join(sel))
pass
def update(self, ctx):
return idaapi.AST_ENABLE_FOR_FORM if idaapi.is_chooser_tform(ctx.form_type) else idaapi.AST_DISABLE_FOR_FORM
class MyChoose2(Choose2):
def __init__(self, title, nb = 5, flags=0, width=None, height=None, embedded=False, modal=False):
Choose2.__init__(
self,
title,
[ ["Address", 16], ["T", 2], ["Instruction/Data", 60], ["Comment", 100]],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = self.get_all_comments() #[ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
self.modal = modal
self.popup_names = [] #["Inzert", "Del leet", "Ehdeet", "Ree frech"]
#print("created %s" % str(self))
def OnClose(self):
print "closed", str(self)
def OnEditLine(self, n):
self.items[n][1] = self.items[n][1] + "*"
#print("editing %d" % n)
def OnInsertLine(self):
self.items.append(self.make_item())
#print("insert line")
def OnSelectLine(self, n):
self.selcount += 1
ea = int(self.items[n][0], 16)
idc.jumpto(ea)
#Warning("[%02d] selectline '%s'" % (self.selcount, n))
def OnGetLine(self, n):
#print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
#print("getsize -&gt; %d" % n)
return n
def OnDeleteLine(self, n):
#print("del %d " % n)
del self.items[n]
return n
def OnRefresh(self, n):
#print("refresh %d" % n)
return n
def OnGetIcon(self, n):
r = self.items[n]
t = self.icon + r[1].count("*")
#print "geticon", n, t
return t
def show(self):
return self.Show(self.modal) &gt;= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def check_isin_filter(self, cmt):
cmt_str = str(cmt)
if cmt_str.startswith('void') or cmt_str.startswith('char') \
or cmt_str.startswith('int') or cmt_str.startswith('switch') \
or cmt_str.startswith('jump') or cmt_str.startswith('size_t') \
or cmt_str.startswith('dw') or cmt_str.startswith('nSize') \
or cmt_str.startswith('hFile') or cmt_str.startswith('lp'):
return True
else:
return False
def get_all_comments(self):
cmts = []
for seg in idautils.Segments():
print 'Anylising:', idc.SegName(seg), hex(idc.SegStart(seg)), hex(idc.SegEnd(seg)) + '\n'
ea = idc.SegStart(seg)
start = idc.SegStart(seg)
end = idc.SegEnd(seg)
while ea &lt; end:
if ea != idc.BADADDR:
cmt = idc.GetCommentEx(ea, True)
if cmt:
if self.check_isin_filter(cmt):
print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt
else:
current_cmt = [format(ea, '#16X'), 'R', idc.GetDisasm(ea), cmt]
cmts.append(current_cmt)
self.n += 1
print " Address: ", format(ea, '#16X'), 'R', 'Comment:', cmt
cmt2 = idc.GetCommentEx(ea, False)
if cmt2:
if self.check_isin_filter(cmt2):
print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt2
else:
current_cmt = [format(ea, '#16X'), 'N', idc.GetDisasm(ea), cmt2]
cmts.append(current_cmt)
self.n += 1
print " Address: ",format(ea, '#16X'), 'N', 'Comment:', cmt2
ea = idc.next_head(ea, end)
return cmts
def OnGetLineAttr(self, n):
pass
#print("getlineattr %d" % n)
#if n == 1:
# return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Comments List", nb=10, modal=modal)
r = c.show()
#c.get_all_comments() # get all comments
form = idaapi.get_current_tform()
for thing in ["A", "B"]:
idaapi.attach_action_to_popup(form, None, "choose2:act%s" % thing)
# -----------------------------------------------------------------------
def test_choose2_embedded():
global c
c = MyChoose2("Comments List", nb=12, embedded=True, width=123, height=222)
r = c.Embedded()
if r == 1:
try:
if test_embedded:
o, sel = _idaapi.choose2_get_embedded(c)
print("o=%s, type(o)=%s" % (str(o), type(o)))
test_embedded(o)
finally:
c.Close()
class show_cmts_plugin_t(idaapi.plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "IDA Comments Viewer: generate all comments of the idb"
help = "Bugs and report: http://www.h4ck.org.cn"
wanted_name = "Comments Viewer by obaby"
wanted_hotkey = "Ctr-Alt-F8"
def init(self):
print '----------------------------------------------------------------------------------------------------------'
print 'IDA Comments Viewer for IDA pro 7.0'
print 'Version:1.0 alpha'
print 'plugin by obaby'
print 'http://www.h4ck.org.cn http://findu.co'
print '----------------------------------------------------------------------------------------------------------'
return idaapi.PLUGIN_OK
def run(self, arg):
print "Start to analyzing all comments in idb..."
ida_kernwin.show_wait_box('Analyzing comments in progress, this will take a while.')
test_choose2(False)
ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.')
print "Finished,have a good time"
def term(self):
ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.')
def PLUGIN_ENTRY():
return show_cmts_plugin_t()
'''----------------------------------------------------------------------------------------------------------' 'IDA Comments Viewer for IDA pro 7.0' 'Version:1.0 alpha' 'plugin by obaby' 'http://www.h4ck.org.cn http://findu.co' '----------------------------------------------------------------------------------------------------------' ''' import idaapi from ida_ida import * import idautils import idc from idaapi import Choose2 import ida_kernwin class chooser_handler_t(idaapi.action_handler_t): def __init__(self, thing): idaapi.action_handler_t.__init__(self) self.thing = thing def activate(self, ctx): #sel = [] #for i in xrange(len(ctx.chooser_selection)): # sel.append(str(ctx.chooser_selection.at(i))) #print "command %s selected @ %s" % (self.thing, ", ".join(sel)) pass def update(self, ctx): return idaapi.AST_ENABLE_FOR_FORM if idaapi.is_chooser_tform(ctx.form_type) else idaapi.AST_DISABLE_FOR_FORM class MyChoose2(Choose2): def __init__(self, title, nb = 5, flags=0, width=None, height=None, embedded=False, modal=False): Choose2.__init__( self, title, [ ["Address", 16], ["T", 2], ["Instruction/Data", 60], ["Comment", 100]], flags = flags, width = width, height = height, embedded = embedded) self.n = 0 self.items = self.get_all_comments() #[ self.make_item() for x in xrange(0, nb+1) ] self.icon = 5 self.selcount = 0 self.modal = modal self.popup_names = [] #["Inzert", "Del leet", "Ehdeet", "Ree frech"] #print("created %s" % str(self)) def OnClose(self): print "closed", str(self) def OnEditLine(self, n): self.items[n][1] = self.items[n][1] + "*" #print("editing %d" % n) def OnInsertLine(self): self.items.append(self.make_item()) #print("insert line") def OnSelectLine(self, n): self.selcount += 1 ea = int(self.items[n][0], 16) idc.jumpto(ea) #Warning("[%02d] selectline '%s'" % (self.selcount, n)) def OnGetLine(self, n): #print("getline %d" % n) return self.items[n] def OnGetSize(self): n = len(self.items) #print("getsize -&gt; %d" % n) return n def OnDeleteLine(self, n): #print("del %d " % n) del self.items[n] return n def OnRefresh(self, n): #print("refresh %d" % n) return n def OnGetIcon(self, n): r = self.items[n] t = self.icon + r[1].count("*") #print "geticon", n, t return t def show(self): return self.Show(self.modal) &gt;= 0 def make_item(self): r = [str(self.n), "func_%04d" % self.n] self.n += 1 return r def check_isin_filter(self, cmt): cmt_str = str(cmt) if cmt_str.startswith('void') or cmt_str.startswith('char') \ or cmt_str.startswith('int') or cmt_str.startswith('switch') \ or cmt_str.startswith('jump') or cmt_str.startswith('size_t') \ or cmt_str.startswith('dw') or cmt_str.startswith('nSize') \ or cmt_str.startswith('hFile') or cmt_str.startswith('lp'): return True else: return False def get_all_comments(self): cmts = [] for seg in idautils.Segments(): print 'Anylising:', idc.SegName(seg), hex(idc.SegStart(seg)), hex(idc.SegEnd(seg)) + '\n' ea = idc.SegStart(seg) start = idc.SegStart(seg) end = idc.SegEnd(seg) while ea &lt; end: if ea != idc.BADADDR: cmt = idc.GetCommentEx(ea, True) if cmt: if self.check_isin_filter(cmt): print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt else: current_cmt = [format(ea, '#16X'), 'R', idc.GetDisasm(ea), cmt] cmts.append(current_cmt) self.n += 1 print " Address: ", format(ea, '#16X'), 'R', 'Comment:', cmt cmt2 = idc.GetCommentEx(ea, False) if cmt2: if self.check_isin_filter(cmt2): print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt2 else: current_cmt = [format(ea, '#16X'), 'N', idc.GetDisasm(ea), cmt2] cmts.append(current_cmt) self.n += 1 print " Address: ",format(ea, '#16X'), 'N', 'Comment:', cmt2 ea = idc.next_head(ea, end) return cmts def OnGetLineAttr(self, n): pass #print("getlineattr %d" % n) #if n == 1: # return [0xFF0000, 0] # ----------------------------------------------------------------------- def test_choose2(modal=False): global c c = MyChoose2("Comments List", nb=10, modal=modal) r = c.show() #c.get_all_comments() # get all comments form = idaapi.get_current_tform() for thing in ["A", "B"]: idaapi.attach_action_to_popup(form, None, "choose2:act%s" % thing) # ----------------------------------------------------------------------- def test_choose2_embedded(): global c c = MyChoose2("Comments List", nb=12, embedded=True, width=123, height=222) r = c.Embedded() if r == 1: try: if test_embedded: o, sel = _idaapi.choose2_get_embedded(c) print("o=%s, type(o)=%s" % (str(o), type(o))) test_embedded(o) finally: c.Close() class show_cmts_plugin_t(idaapi.plugin_t): flags = idaapi.PLUGIN_UNL comment = "IDA Comments Viewer: generate all comments of the idb" help = "Bugs and report: http://www.h4ck.org.cn" wanted_name = "Comments Viewer by obaby" wanted_hotkey = "Ctr-Alt-F8" def init(self): print '----------------------------------------------------------------------------------------------------------' print 'IDA Comments Viewer for IDA pro 7.0' print 'Version:1.0 alpha' print 'plugin by obaby' print 'http://www.h4ck.org.cn http://findu.co' print '----------------------------------------------------------------------------------------------------------' return idaapi.PLUGIN_OK def run(self, arg): print "Start to analyzing all comments in idb..." ida_kernwin.show_wait_box('Analyzing comments in progress, this will take a while.') test_choose2(False) ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.') print "Finished,have a good time" def term(self): ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.') def PLUGIN_ENTRY(): return show_cmts_plugin_t()
'''----------------------------------------------------------------------------------------------------------'
 'IDA Comments Viewer for IDA pro 7.0'
 'Version:1.0 alpha'
 'plugin by obaby'
 'http://www.h4ck.org.cn http://findu.co'
 '----------------------------------------------------------------------------------------------------------'
'''


import idaapi
from ida_ida import *
import idautils
import idc
from idaapi import Choose2
import ida_kernwin


class chooser_handler_t(idaapi.action_handler_t):
    def __init__(self, thing):
        idaapi.action_handler_t.__init__(self)
        self.thing = thing

    def activate(self, ctx):
        #sel = []
        #for i in xrange(len(ctx.chooser_selection)):
        #    sel.append(str(ctx.chooser_selection.at(i)))
        #print "command %s selected @ %s" % (self.thing, ", ".join(sel))
        pass

    def update(self, ctx):
        return idaapi.AST_ENABLE_FOR_FORM if idaapi.is_chooser_tform(ctx.form_type) else idaapi.AST_DISABLE_FOR_FORM


class MyChoose2(Choose2):

    def __init__(self, title, nb = 5, flags=0, width=None, height=None, embedded=False, modal=False):
        Choose2.__init__(
            self,
            title,
            [ ["Address", 16], ["T", 2], ["Instruction/Data", 60], ["Comment", 100]],
            flags = flags,
            width = width,
            height = height,
            embedded = embedded)
        self.n = 0
        self.items = self.get_all_comments() #[ self.make_item() for x in xrange(0, nb+1) ]
        self.icon = 5
        self.selcount = 0
        self.modal = modal
        self.popup_names = [] #["Inzert", "Del leet", "Ehdeet", "Ree frech"]

        #print("created %s" % str(self))

    def OnClose(self):
        print "closed", str(self)

    def OnEditLine(self, n):
        self.items[n][1] = self.items[n][1] + "*"
        #print("editing %d" % n)

    def OnInsertLine(self):
        self.items.append(self.make_item())
        #print("insert line")

    def OnSelectLine(self, n):
        self.selcount += 1

        ea = int(self.items[n][0], 16)
        idc.jumpto(ea)
        #Warning("[%02d] selectline '%s'" % (self.selcount, n))

    def OnGetLine(self, n):
        #print("getline %d" % n)
        return self.items[n]

    def OnGetSize(self):
        n = len(self.items)
        #print("getsize -&gt; %d" % n)
        return n

    def OnDeleteLine(self, n):
        #print("del %d " % n)
        del self.items[n]
        return n

    def OnRefresh(self, n):
        #print("refresh %d" % n)
        return n

    def OnGetIcon(self, n):
        r = self.items[n]
        t = self.icon + r[1].count("*")
        #print "geticon", n, t
        return t

    def show(self):
        return self.Show(self.modal) &gt;= 0

    def make_item(self):
        r = [str(self.n), "func_%04d" % self.n]
        self.n += 1
        return r

    def check_isin_filter(self, cmt):
        cmt_str = str(cmt)
        if cmt_str.startswith('void') or cmt_str.startswith('char') \
                or cmt_str.startswith('int') or cmt_str.startswith('switch') \
                or cmt_str.startswith('jump') or cmt_str.startswith('size_t') \
                or cmt_str.startswith('dw') or cmt_str.startswith('nSize') \
                or cmt_str.startswith('hFile') or cmt_str.startswith('lp'):
            return True
        else:
            return False

    def get_all_comments(self):
        cmts = []
        for seg in idautils.Segments():
            print 'Anylising:', idc.SegName(seg), hex(idc.SegStart(seg)), hex(idc.SegEnd(seg)) + '\n'
            ea = idc.SegStart(seg)
            start = idc.SegStart(seg)
            end = idc.SegEnd(seg)
            while ea &lt; end:

                if ea != idc.BADADDR:
                    cmt = idc.GetCommentEx(ea, True)
                    if cmt:
                        if self.check_isin_filter(cmt):
                            print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt
                        else:
                            current_cmt = [format(ea, '#16X'), 'R', idc.GetDisasm(ea), cmt]
                            cmts.append(current_cmt)
                            self.n += 1
                            print " Address: ", format(ea, '#16X'), 'R', 'Comment:', cmt

                    cmt2 = idc.GetCommentEx(ea, False)
                    if cmt2:
                        if self.check_isin_filter(cmt2):
                            print " Address: ",format(ea, '#16X'),'In fliter,IGN:', cmt2
                        else:
                            current_cmt = [format(ea, '#16X'), 'N', idc.GetDisasm(ea), cmt2]
                            cmts.append(current_cmt)
                            self.n += 1
                            print " Address: ",format(ea, '#16X'), 'N', 'Comment:', cmt2
                ea = idc.next_head(ea, end)
        return cmts


    def OnGetLineAttr(self, n):
        pass
        #print("getlineattr %d" % n)
        #if n == 1:
        #    return [0xFF0000, 0]


 # -----------------------------------------------------------------------
def test_choose2(modal=False):
    global c
    c = MyChoose2("Comments List", nb=10, modal=modal)
    r = c.show()
    #c.get_all_comments() # get all comments
    form = idaapi.get_current_tform()
    for thing in ["A", "B"]:
        idaapi.attach_action_to_popup(form, None, "choose2:act%s" % thing)


# -----------------------------------------------------------------------
def test_choose2_embedded():
    global c
    c = MyChoose2("Comments List", nb=12, embedded=True, width=123, height=222)
    r = c.Embedded()
    if r == 1:
        try:
            if test_embedded:
                o, sel = _idaapi.choose2_get_embedded(c)
                print("o=%s, type(o)=%s" % (str(o), type(o)))
                test_embedded(o)
        finally:
            c.Close()


class show_cmts_plugin_t(idaapi.plugin_t):
    flags = idaapi.PLUGIN_UNL
    comment = "IDA Comments Viewer: generate all comments of the idb"
    help = "Bugs and report: http://www.h4ck.org.cn"
    wanted_name = "Comments Viewer by obaby"
    wanted_hotkey = "Ctr-Alt-F8"

    def init(self):
        print '----------------------------------------------------------------------------------------------------------'
        print 'IDA Comments Viewer for IDA pro 7.0'
        print 'Version:1.0 alpha'
        print 'plugin by obaby'
        print 'http://www.h4ck.org.cn http://findu.co'
        print '----------------------------------------------------------------------------------------------------------'
        return idaapi.PLUGIN_OK

    def run(self, arg):
        print "Start to analyzing all comments in idb..."
        ida_kernwin.show_wait_box('Analyzing comments in progress, this will take a while.')
        test_choose2(False)
        ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.')
        print "Finished,have a good time"



    def term(self):
        ida_kernwin.hide_wait_box('Analyzing comments in progress, this will take a while.')





def PLUGIN_ENTRY():
    return show_cmts_plugin_t()

 

Github:https://github.com/obaby/CommentView-4-IDAPRO-7.0

☆版权☆

* 网站名称:obaby@mars
* 网址:https://lang.ma/
* 个性:https://oba.by/
* 本文标题: 《CommentView Plugin for IDAPro7.0》
* 本文链接:https://baby.lc/2018/01/6176
* 短链接:https://oba.by/?p=6176
* 转载文章请标明文章来源,原文标题以及原文链接。请遵从 《署名-非商业性使用-相同方式共享 2.5 中国大陆 (CC BY-NC-SA 2.5 CN) 》许可协议。


You may also like

8 comments

  1. Level 1
    Firefox 58 Firefox 58 Mac OS X 10.13 Mac OS X 10.13 cn中国–浙江–杭州 电信

    那个基址问题应该是IDA的BUG,在新的IDA 7.0.171130 (SP1)里已经修正了的,如果是正版的话就升级一下吧。

    1. 公主 Queen 
      Firefox 57 Firefox 57 Mac OS X 10.13 Mac OS X 10.13 cn中国–山东–青岛 联通

      呃。原来是酱紫,可惜我的不是正版的~~

  2. Level 1
    TheWorld Browser TheWorld Browser Windows 7 Windows 7 cn中国–广东–惠州 电信

    你好,请问
    错误sad‘invalid syntax’, (”, 98, 42, ‘ return self.Show(self.modal) >= 0\n’))
    是怎么回事?

  3. Level 1
    TheWorld Browser TheWorld Browser Windows 7 Windows 7 cn中国–广东–惠州 电信

    #print(“getsize -> %d” % n)

  4. Level 1
    TheWorld Browser TheWorld Browser Windows 10 Windows 10 cn中国–湖南–岳阳 移动

    这个搜索注释只能搜索 “注释”,重复注释跟函数注释不行耶

    1. 公主 Queen 
      Firefox 63 Firefox 63 Mac OS X 10.14 Mac OS X 10.14 cn中国–山东–青岛 联通

      你可以看下idc.GetCommentEx这个api有没有其它的参数,或者换新版的ida 使用插件的方式尝试一下。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注