Skip to content
This repository was archived by the owner on Dec 24, 2025. It is now read-only.

Commit a0be95b

Browse files
Arnaud DiederenArnaud Diederen
authored andcommitted
IDAPython for IDA 7.0 SP1
1 parent d99a893 commit a0be95b

25 files changed

Lines changed: 602 additions & 372 deletions

Scripts/AsmViewer.py

Lines changed: 63 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,14 @@
33
# The sample will allow you to open an assembly file and display it in color
44
# (c) Hex-Rays
55
#
6-
import idaapi
7-
import idautils
8-
import idc
6+
97
import os
108

9+
import ida_idaapi
10+
import ida_kernwin
11+
import ida_lines
12+
import idautils
13+
1114
# ----------------------------------------------------------------------
1215
class asm_colorizer_t(object):
1316
def is_id(self, ch):
@@ -79,11 +82,38 @@ def colorize(self, lines):
7982
x += 1
8083
self.add_line(s)
8184

85+
86+
class base_asmview_ah_t(ida_kernwin.action_handler_t):
87+
def __init__(self, obj):
88+
ida_kernwin.action_handler_t.__init__(self)
89+
self.obj = obj
90+
91+
def update(self, ctx):
92+
if self.obj.view and self.obj.view.GetWidget() == ctx.widget:
93+
return ida_kernwin.AST_ENABLE_FOR_WIDGET
94+
else:
95+
return ida_kernwin.AST_DISABLE_FOR_WIDGET
96+
97+
98+
class refresh_ah_t(base_asmview_ah_t):
99+
def activate(self, ctx):
100+
self.obj.view.reload_file()
101+
print("Reloaded")
102+
103+
104+
class close_ah_t(base_asmview_ah_t):
105+
def activate(self, ctx):
106+
self.obj.view.Close()
107+
print("Closed")
108+
109+
82110
# -----------------------------------------------------------------------
83-
class asmview_t(idaapi.simplecustviewer_t, asm_colorizer_t):
111+
class asmview_t(ida_kernwin.simplecustviewer_t, asm_colorizer_t):
84112
def Create(self, fn):
85113
# Create the customview
86-
if not idaapi.simplecustviewer_t.Create(self, "Viewing file - %s" % os.path.basename(fn)):
114+
if not ida_kernwin.simplecustviewer_t.Create(
115+
self,
116+
"Viewing file - %s" % os.path.basename(fn)):
87117
return False
88118

89119
self.instruction_list = idautils.GetInstructionList()
@@ -95,9 +125,6 @@ def Create(self, fn):
95125
if not self.reload_file():
96126
return False
97127

98-
self.id_refresh = self.AddPopupMenu("Refresh")
99-
self.id_close = self.AddPopupMenu("Close")
100-
101128
return True
102129

103130
def reload_file(self):
@@ -123,38 +150,25 @@ def add_line(self, s=None):
123150
self.AddLine(s)
124151

125152
def as_comment(self, s):
126-
return idaapi.COLSTR(s, idaapi.SCOLOR_RPTCMT)
153+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_RPTCMT)
127154

128155
def as_id(self, s):
129156
t = s.lower()
130157
if t in self.register_list:
131-
return idaapi.COLSTR(s, idaapi.SCOLOR_REG)
158+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_REG)
132159
elif t in self.instruction_list:
133-
return idaapi.COLSTR(s, idaapi.SCOLOR_INSN)
160+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_INSN)
134161
else:
135162
return s
136163

137164
def as_string(self, s):
138-
return idaapi.COLSTR(s, idaapi.SCOLOR_STRING)
165+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_STRING)
139166

140167
def as_num(self, s):
141-
return idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER)
168+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_NUMBER)
142169

143170
def as_directive(self, s):
144-
return idaapi.COLSTR(s, idaapi.SCOLOR_KEYWORD)
145-
146-
def OnPopupMenu(self, menu_id):
147-
"""
148-
A context (or popup) menu item was executed.
149-
@param menu_id: ID previously registered with AddPopupMenu()
150-
@return: Boolean
151-
"""
152-
if self.id_refresh == menu_id:
153-
return self.reload_file()
154-
elif self.id_close == menu_id:
155-
self.Close()
156-
return True
157-
return False
171+
return ida_lines.COLSTR(s, ida_lines.SCOLOR_KEYWORD)
158172

159173
def OnKeydown(self, vkey, shift):
160174
"""
@@ -170,8 +184,8 @@ def OnKeydown(self, vkey, shift):
170184
lineno = self.GetLineNo()
171185
if lineno is not None:
172186
line, fg, bg = self.GetLine(lineno)
173-
if line and line[0] != idaapi.SCOLOR_INV:
174-
s = idaapi.SCOLOR_INV + line + idaapi.SCOLOR_INV
187+
if line and line[0] != ida_lines.SCOLOR_INV:
188+
s = ida_lines.SCOLOR_INV + line + ida_lines.SCOLOR_INV
175189
self.EditLine(lineno, s, fg, bg)
176190
self.Refresh()
177191
elif vkey == ord('C'):
@@ -186,8 +200,11 @@ def OnKeydown(self, vkey, shift):
186200
return True
187201

188202
# -----------------------------------------------------------------------
189-
class asmviewplg(idaapi.plugin_t):
190-
flags = idaapi.PLUGIN_KEEP
203+
ACTNAME_REFRESH = "asmview_t::refresh"
204+
ACTNAME_CLOSE = "asmview_t::close"
205+
206+
class asmviewplg(ida_idaapi.plugin_t):
207+
flags = ida_idaapi.PLUGIN_KEEP
191208
comment = "ASM viewer"
192209
help = "This is help"
193210
wanted_name = "ASM file viewer"
@@ -196,17 +213,30 @@ def __init__(self):
196213
self.view = None
197214

198215
def init(self):
199-
return idaapi.PLUGIN_KEEP
216+
# Register actions
217+
ida_kernwin.register_action(
218+
ida_kernwin.action_desc_t(
219+
ACTNAME_REFRESH, "Refresh", refresh_ah_t(self)))
220+
ida_kernwin.register_action(
221+
ida_kernwin.action_desc_t(
222+
ACTNAME_CLOSE, "Close", close_ah_t(self)))
223+
return ida_idaapi.PLUGIN_KEEP
224+
200225
def run(self, arg):
201226
if self.view:
202227
self.Close()
203-
fn = idaapi.ask_file(0, "*.asm", "Select ASM file to view")
228+
fn = ida_kernwin.ask_file(0, "*.asm", "Select ASM file to view")
204229
if not fn:
205230
return
206231
self.view = asmview_t()
207232
if not self.view.Create(fn):
208233
return
209234
self.view.Show()
235+
widget = self.view.GetWidget()
236+
237+
# Attach actions to this widget's popup menu
238+
ida_kernwin.attach_action_to_popup(widget, None, ACTNAME_REFRESH)
239+
ida_kernwin.attach_action_to_popup(widget, None, ACTNAME_CLOSE)
210240

211241
def term(self):
212242
if self.view:

Scripts/CallStackWalk.py

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,19 @@
44
55
Run the application with the debugger, suspend the debugger, select a thread and finally run the script.
66
7-
Copyright (c) 1990-2009 Hex-Rays
7+
Copyright (c) 1990-2017 Hex-Rays
88
ALL RIGHTS RESERVED.
9-
10-
11-
v1.0 - initial version
12-
v1.0.1 - added stack segment bitness detection, thus works with 64bit processes too
139
"""
14-
import idaapi
15-
import idc
10+
import ida_ua
11+
import ida_bytes
12+
import ida_kernwin
13+
import ida_funcs
14+
import ida_name
15+
import ida_ida
16+
import ida_idp
17+
import ida_segment
18+
import ida_dbg
1619
import idautils
17-
from ida_kernwin import Choose
1820

1921
# -----------------------------------------------------------------------
2022
# class to take a copy of a segment_t
@@ -24,6 +26,7 @@ def __init__(self, s):
2426
self.end_ea = s.end_ea
2527
self.perm = s.perm
2628
self.bitness = s.bitness
29+
2730
def __cmp__(self, other):
2831
return cmp(self.start_ea, other.start_ea)
2932

@@ -51,18 +54,18 @@ def IsPrevInsnCall(ea):
5154
is a CALL instruction
5255
"""
5356
global CallPattern
54-
if ea == idaapi.BADADDR or ea < 10:
57+
if ea == ida_idaapi.BADADDR or ea < 10:
5558
return None
5659

5760
for delta, opcodes in CallPattern:
5861
# assume caller's ea
5962
caller = ea + delta
6063
# get the bytes
61-
bytes = [x for x in GetDataList(caller, len(opcodes), 1)]
64+
bytes = [x for x in idautils.GetDataList(caller, len(opcodes), 1)]
6265
# do we have a match? is it a call instruction?
6366
if bytes == opcodes:
64-
tmp = idaapi.insn_t()
65-
if idaapi.decode_insn(tmp, caller) and idaapi.is_call_insn(tmp):
67+
insn = ida_ua.insn_t()
68+
if ida_ua.decode_insn(insn, caller) and ida_idp.is_call_insn(insn):
6669
return caller
6770
return None
6871

@@ -79,32 +82,35 @@ class Result:
7982
def __init__(self, caller, sp):
8083
self.caller = caller
8184
self.sp = sp
82-
f = idaapi.get_func(caller)
83-
self.displ = ""
85+
f = ida_funcs.get_func(caller)
86+
self.displ = "%08x: " % caller
8487
if f:
85-
self.displ += idc.get_func_name(caller)
88+
self.displ += ida_funcs.get_func_name(caller)
8689
t = caller - f.start_ea
8790
if t > 0: self.displ += "+" + hex(t)
8891
else:
8992
self.displ += hex(caller)
9093
self.displ += " [" + hex(sp) + "]"
9194

95+
def __str__(self):
96+
return self.displ
97+
9298
# get stack pointer
93-
sp = cpu.Esp
94-
seg = idaapi.getseg(sp)
99+
sp = idautils.cpu.Esp
100+
seg = ida_segment.getseg(sp)
95101
if not seg:
96102
return (False, "Could not locate stack segment!")
97103

98104
stack_seg = Seg(seg)
99105
word_size = 2 ** (seg.bitness + 1)
100106
callers = []
101-
sp = cpu.Esp - word_size
107+
sp = idautils.cpu.Esp - word_size
102108
while sp < stack_seg.end_ea:
103109
sp += word_size
104110
ptr = idautils.GetDataList(sp, 1, word_size).next()
105-
seg = idaapi.getseg(ptr)
111+
seg = ida_segment.getseg(ptr)
106112
# only accept executable segments
107-
if (not seg) or ((seg.perm & idaapi.SEGPERM_EXEC) == 0):
113+
if (not seg) or ((seg.perm & ida_segment.SEGPERM_EXEC) == 0):
108114
continue
109115
# try to find caller
110116
caller = IsPrevInsnCall(ptr)
@@ -118,69 +124,63 @@ def __init__(self, caller, sp):
118124
if ret:
119125
ea = ret[0]
120126
# function exists?
121-
f = idaapi.get_func(ea)
127+
f = ida_funcs.get_func(ea)
122128
if not f:
123129
# create function
124-
idc.add_func(ea, idaapi.BADADDR)
130+
ida_funcs.add_func(ea)
125131

126132
# get the flags
127-
f = idc.get_flags(caller)
133+
f = ida_bytes.get_flags(caller)
128134
# no code there?
129-
if not is_code(f):
130-
create_insn(caller)
135+
if not ida_bytes.is_code(f):
136+
ida_ua.create_insn(caller)
131137

132138
callers.append(Result(caller, sp))
133139
#
134140
return (True, callers)
135141

136142
# -----------------------------------------------------------------------
137143
# Chooser class
138-
class CallStackWalkChoose(Choose):
144+
class CallStackWalkChoose(ida_kernwin.Choose):
139145
def __init__(self, title, items):
140-
Choose.__init__(self, title, [ ["Caller", 16], ["Display", 250] ])
146+
ida_kernwin.Choose.__init__(
147+
self,
148+
title,
149+
[["Location", 30]])
141150
self.items = items
142-
143-
def OnGetLine(self, n):
144-
o = self.items[n]
145-
line = []
146-
line.append("%X" % o.caller)
147-
line.append("%s" % o.displ)
148-
return line
151+
self.modal = True
149152

150153
def OnGetSize(self):
151154
return len(self.items)
152155

156+
def OnGetLine(self, n):
157+
return [str(self.items[n])]
158+
153159
def OnSelectLine(self, n):
154-
o = self.items[n]
155-
jumpto(o.caller)
156-
return (Choose.NOTHING_CHANGED, )
160+
ida_kernwin.jumpto(self.items[n].caller)
157161

158162
# -----------------------------------------------------------------------
159163
def main():
160-
if not idaapi.is_debugger_on():
161-
idc.warning("Please run the process first!")
164+
if not ida_dbg.is_debugger_on():
165+
ida_kernwin.warning("Please run the process first!")
162166
return
163-
if idaapi.get_process_state() != -1:
164-
idc.warning("Please suspend the debugger first!")
167+
if ida_dbg.get_process_state() != -1:
168+
ida_kernwin.warning("Please suspend the debugger first!")
165169
return
166170

167-
# only avail from IdaPython r232
168-
if hasattr(idaapi, "NearestName"):
169-
# get all debug names
170-
dn = idaapi.get_debug_names(idaapi.cvar.inf.min_ea, idaapi.cvar.inf.max_ea)
171-
# initiate a nearest name search (using debug names)
172-
nn = idaapi.NearestName(dn)
173-
else:
174-
nn = None
171+
# get all debug namesp
172+
dn = ida_name.get_debug_names(ida_ida.cvar.inf.min_ea, ida_ida.cvar.inf.max_ea)
173+
# initiate a nearest name search (using debug names)
174+
nn = ida_name.NearestName(dn)
175175

176176
ret, callstack = CallStackWalk(nn)
177177
if ret:
178-
title = "Call stack walker (thread %X)" % (get_current_thread())
179-
idaapi.close_chooser(title)
178+
title = "Call stack walker (thread %X)" % (ida_dbg.get_current_thread())
179+
ida_kernwin.close_chooser(title)
180180
c = CallStackWalkChoose(title, callstack)
181-
c.Show()
181+
c.Show(True)
182182
else:
183-
idc.warning("Failed to walk the stack:" + callstack)
183+
ida_kernwin.warning("Failed to walk the stack:" + callstack)
184184

185185
# -----------------------------------------------------------------------
186186
main()

0 commit comments

Comments
 (0)