Merge pull request #1 from aundro/ida68

IDA Pro 6.8 support
This commit is contained in:
Elias Bachaalany
2015-04-20 22:30:05 -07:00
138 changed files with 49628 additions and 49321 deletions

View File

@@ -1,156 +1,156 @@
"""
Original code by Bryce Boe: http://www.bryceboe.com/2010/09/01/submitting-binaries-to-virustotal/
Modified by Elias Bachaalany <elias at hex-rays.com>
"""
import hashlib, httplib, mimetypes, os, pprint, simplejson, sys, urlparse
# -----------------------------------------------------------------------
DEFAULT_TYPE = 'application/octet-stream'
FILE_REPORT_URL = 'https://www.virustotal.com/api/get_file_report.json'
SCAN_URL = 'https://www.virustotal.com/api/scan_file.json'
API_KEY = "" # Put API key here. Register an account in VT Community
# -----------------------------------------------------------------------
# The following function is modified from the snippet at:
# http://code.activestate.com/recipes/146306/
def _encode_multipart_formdata(fields, files=()):
"""
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for key, value in fields.items():
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
(key, filename))
content_type = mimetypes.guess_type(filename)[0] or DEFAULT_TYPE
L.append('Content-Type: %s' % content_type)
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
# -----------------------------------------------------------------------
def _post_multipart(url, fields, files=()):
"""
url is the full to send the post request to.
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return body of http response.
"""
content_type, data = _encode_multipart_formdata(fields, files)
url_parts = urlparse.urlparse(url)
if url_parts.scheme == 'http':
h = httplib.HTTPConnection(url_parts.netloc)
elif url_parts.scheme == 'https':
h = httplib.HTTPSConnection(url_parts.netloc)
else:
raise Exception('Unsupported URL scheme')
path = urlparse.urlunparse(('', '') + url_parts[2:])
h.request('POST', path, data, {'content-type':content_type})
return h.getresponse().read()
# -----------------------------------------------------------------------
def set_apikey(key, dbg = False):
"""
Set the VT API key
"""
global API_KEY
API_KEY = key
if dbg:
httplib.HTTPConnection.debuglevel = 1
# -----------------------------------------------------------------------
def scan_file(filename):
"""
Uploads a file for scanning.
@param filename: The filename to upload
@return: - None if upload failed
- scan_id value if upload succeeds
- raises an exception on IO failures
"""
files = [('file', filename, open(filename, 'rb').read())]
json = _post_multipart(SCAN_URL, {'key':API_KEY}, files)
data = simplejson.loads(json)
return str(data['scan_id']) if data['result'] == 1 else None
# -----------------------------------------------------------------------
def get_file_md5_hash(filename):
f = open(filename, 'rb')
r = hashlib.md5(f.read()).hexdigest()
f.close()
return r
# -----------------------------------------------------------------------
def get_file_report(filename=None, md5sum=None):
"""
Returns an report for a file or md5su.
@param filename: File name to get report. The file is used just
to compute its MD5Sum
@param md5sum: MD5sum string (in case filename was not passed)
@return: - None: if file was not previously analyzed
- A dictionary if report exists: key=scanner, value=reported name
"""
if filename is None and md5sum is None:
raise Exception('Either filename or md5sum should be passed!')
# Filename passed? Compute its MD5
if filename:
global LAST_FILE_HASH
LAST_FILE_HASH = md5sum = get_file_md5_hash(filename)
# Form the request
json = _post_multipart(FILE_REPORT_URL, {'resource':md5sum, 'key':API_KEY})
data = simplejson.loads(json)
if data['result'] != 1:
# No results
return None
else:
# date, result_dict = data['report']
return data['report'][1]
# -----------------------------------------------------------------------
def pretty_print(obj):
pprint.pprint(obj)
# -----------------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage: %s filename' % sys.argv[0])
sys.exit(1)
filename = sys.argv[1]
if not os.path.isfile(filename):
print('%s is not a valid file' % filename)
sys.exit(1)
"""
Original code by Bryce Boe: http://www.bryceboe.com/2010/09/01/submitting-binaries-to-virustotal/
Modified by Elias Bachaalany <elias at hex-rays.com>
"""
import hashlib, httplib, mimetypes, os, pprint, simplejson, sys, urlparse
# -----------------------------------------------------------------------
DEFAULT_TYPE = 'application/octet-stream'
FILE_REPORT_URL = 'https://www.virustotal.com/api/get_file_report.json'
SCAN_URL = 'https://www.virustotal.com/api/scan_file.json'
API_KEY = "" # Put API key here. Register an account in VT Community
# -----------------------------------------------------------------------
# The following function is modified from the snippet at:
# http://code.activestate.com/recipes/146306/
def _encode_multipart_formdata(fields, files=()):
"""
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return (content_type, body) ready for httplib.HTTP instance
"""
BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
CRLF = '\r\n'
L = []
for key, value in fields.items():
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"' % key)
L.append('')
L.append(value)
for (key, filename, value) in files:
L.append('--' + BOUNDARY)
L.append('Content-Disposition: form-data; name="%s"; filename="%s"' %
(key, filename))
content_type = mimetypes.guess_type(filename)[0] or DEFAULT_TYPE
L.append('Content-Type: %s' % content_type)
L.append('')
L.append(value)
L.append('--' + BOUNDARY + '--')
L.append('')
body = CRLF.join(L)
content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
return content_type, body
# -----------------------------------------------------------------------
def _post_multipart(url, fields, files=()):
"""
url is the full to send the post request to.
fields is a dictionary of name to value for regular form fields.
files is a sequence of (name, filename, value) elements for data to be
uploaded as files.
Return body of http response.
"""
content_type, data = _encode_multipart_formdata(fields, files)
url_parts = urlparse.urlparse(url)
if url_parts.scheme == 'http':
h = httplib.HTTPConnection(url_parts.netloc)
elif url_parts.scheme == 'https':
h = httplib.HTTPSConnection(url_parts.netloc)
else:
raise Exception('Unsupported URL scheme')
path = urlparse.urlunparse(('', '') + url_parts[2:])
h.request('POST', path, data, {'content-type':content_type})
return h.getresponse().read()
# -----------------------------------------------------------------------
def set_apikey(key, dbg = False):
"""
Set the VT API key
"""
global API_KEY
API_KEY = key
if dbg:
httplib.HTTPConnection.debuglevel = 1
# -----------------------------------------------------------------------
def scan_file(filename):
"""
Uploads a file for scanning.
@param filename: The filename to upload
@return: - None if upload failed
- scan_id value if upload succeeds
- raises an exception on IO failures
"""
files = [('file', filename, open(filename, 'rb').read())]
json = _post_multipart(SCAN_URL, {'key':API_KEY}, files)
data = simplejson.loads(json)
return str(data['scan_id']) if data['result'] == 1 else None
# -----------------------------------------------------------------------
def get_file_md5_hash(filename):
f = open(filename, 'rb')
r = hashlib.md5(f.read()).hexdigest()
f.close()
return r
# -----------------------------------------------------------------------
def get_file_report(filename=None, md5sum=None):
"""
Returns an report for a file or md5su.
@param filename: File name to get report. The file is used just
to compute its MD5Sum
@param md5sum: MD5sum string (in case filename was not passed)
@return: - None: if file was not previously analyzed
- A dictionary if report exists: key=scanner, value=reported name
"""
if filename is None and md5sum is None:
raise Exception('Either filename or md5sum should be passed!')
# Filename passed? Compute its MD5
if filename:
global LAST_FILE_HASH
LAST_FILE_HASH = md5sum = get_file_md5_hash(filename)
# Form the request
json = _post_multipart(FILE_REPORT_URL, {'resource':md5sum, 'key':API_KEY})
data = simplejson.loads(json)
if data['result'] != 1:
# No results
return None
else:
# date, result_dict = data['report']
return data['report'][1]
# -----------------------------------------------------------------------
def pretty_print(obj):
pprint.pprint(obj)
# -----------------------------------------------------------------------
if __name__ == '__main__':
if len(sys.argv) != 2:
print('Usage: %s filename' % sys.argv[0])
sys.exit(1)
filename = sys.argv[1]
if not os.path.isfile(filename):
print('%s is not a valid file' % filename)
sys.exit(1)
get_file_report(filename=filename)

View File

@@ -1,216 +1,216 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# The sample will allow you to open an assembly file and display it in color
# (c) Hex-Rays
#
import idaapi
import idautils
import idc
import os
# ----------------------------------------------------------------------
class asm_colorizer_t(object):
def is_id(self, ch):
return ch == '_' or ch.isalpha() or '0' <= ch <= '9'
def get_identifier(self, line, x, e):
i = x
is_digit = line[i].isdigit()
while i < e:
ch = line[i]
if not self.is_id(ch):
if ch != '.' or not is_digit:
break
i += 1
return (i, line[x:i])
def get_quoted_string(self, line, x, e):
quote = line[x]
i = x + 1
while i < e:
ch = line[i]
if ch == '\\' and line[i+1] == quote:
i += 1
elif ch == quote:
i += 1 # also take the quote
break
i += 1
return (i, line[x:i])
def colorize(self, lines):
for line in lines:
line = line.rstrip()
if not line:
self.add_line()
continue
x = 0
e = len(line)
s = ""
while x < e:
ch = line[x]
# String?
if ch == '"' or ch == "'":
x, w = self.get_quoted_string(line, x, e)
s += self.as_string(w)
# Tab?
elif ch == '\t':
s += ' ' * 4
x += 1
# Comment?
elif ch == ';':
s += self.as_comment(line[x:])
# Done with this line
break
elif ch == '.' and x + 1 < e:
x, w = self.get_identifier(line, x + 1, e)
s += self.as_directive(ch + w)
# Identifiers?
elif self.is_id(ch):
x, w = self.get_identifier(line, x, e)
# Number?
if ch.isdigit():
s += self.as_num(w)
# Other identifier
else:
s += self.as_id(w)
# Output as is
else:
s += ch
x += 1
self.add_line(s)
# -----------------------------------------------------------------------
class asmview_t(idaapi.simplecustviewer_t, asm_colorizer_t):
def Create(self, fn):
# Create the customview
if not idaapi.simplecustviewer_t.Create(self, "Viewing file - %s" % os.path.basename(fn)):
return False
self.instruction_list = idautils.GetInstructionList()
self.instruction_list.extend(["ret"])
self.register_list = idautils.GetRegisterList()
self.register_list.extend(["eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp"])
self.fn = fn
if not self.reload_file():
return False
self.id_refresh = self.AddPopupMenu("Refresh")
self.id_close = self.AddPopupMenu("Close")
return True
def reload_file(self):
if not self.colorize_file(self.fn):
self.Close()
return False
return True
def colorize_file(self, fn):
try:
f = open(fn, "r")
lines = f.readlines()
f.close()
self.ClearLines()
self.colorize(lines)
return True
except:
return False
def add_line(self, s=None):
if not s:
s = ""
self.AddLine(s)
def as_comment(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_RPTCMT)
def as_id(self, s):
t = s.lower()
if t in self.register_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_REG)
elif t in self.instruction_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_INSN)
else:
return s
def as_string(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_STRING)
def as_num(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER)
def as_directive(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_KEYWORD)
def OnPopupMenu(self, menu_id):
"""
A context (or popup) menu item was executed.
@param menu_id: ID previously registered with AddPopupMenu()
@return: Boolean
"""
if self.id_refresh == menu_id:
return self.reload_file()
elif self.id_close == menu_id:
self.Close()
return True
return False
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return Boolean. True if you handled the event
"""
# ESCAPE
if vkey == 27:
self.Close()
elif vkey == ord('H'):
lineno = self.GetLineNo()
if lineno is not None:
line, fg, bg = self.GetLine(lineno)
if line and line[0] != idaapi.SCOLOR_INV:
s = idaapi.SCOLOR_INV + line + idaapi.SCOLOR_INV
self.EditLine(lineno, s, fg, bg)
self.Refresh()
elif vkey == ord('C'):
self.ClearLines()
self.Refresh()
elif vkey == ord('S'):
print "Selection (x1, y1, x2, y2) = ", self.GetSelection()
elif vkey == ord('I'):
print "Position (line, x, y) = ", self.GetPos(mouse = 0)
else:
return False
return True
# -----------------------------------------------------------------------
class asmviewplg(idaapi.plugin_t):
flags = idaapi.PLUGIN_KEEP
comment = "ASM viewer"
help = "This is help"
wanted_name = "ASM file viewer"
wanted_hotkey = "Alt-F8"
def __init__(self):
self.view = None
def init(self):
return idaapi.PLUGIN_KEEP
def run(self, arg):
if self.view:
self.Close()
fn = idc.AskFile(0, "*.asm", "Select ASM file to view")
if not fn:
return
self.view = asmview_t()
if not self.view.Create(fn):
return
self.view.Show()
def term(self):
if self.view:
self.view.Close()
def PLUGIN_ENTRY():
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# The sample will allow you to open an assembly file and display it in color
# (c) Hex-Rays
#
import idaapi
import idautils
import idc
import os
# ----------------------------------------------------------------------
class asm_colorizer_t(object):
def is_id(self, ch):
return ch == '_' or ch.isalpha() or '0' <= ch <= '9'
def get_identifier(self, line, x, e):
i = x
is_digit = line[i].isdigit()
while i < e:
ch = line[i]
if not self.is_id(ch):
if ch != '.' or not is_digit:
break
i += 1
return (i, line[x:i])
def get_quoted_string(self, line, x, e):
quote = line[x]
i = x + 1
while i < e:
ch = line[i]
if ch == '\\' and line[i+1] == quote:
i += 1
elif ch == quote:
i += 1 # also take the quote
break
i += 1
return (i, line[x:i])
def colorize(self, lines):
for line in lines:
line = line.rstrip()
if not line:
self.add_line()
continue
x = 0
e = len(line)
s = ""
while x < e:
ch = line[x]
# String?
if ch == '"' or ch == "'":
x, w = self.get_quoted_string(line, x, e)
s += self.as_string(w)
# Tab?
elif ch == '\t':
s += ' ' * 4
x += 1
# Comment?
elif ch == ';':
s += self.as_comment(line[x:])
# Done with this line
break
elif ch == '.' and x + 1 < e:
x, w = self.get_identifier(line, x + 1, e)
s += self.as_directive(ch + w)
# Identifiers?
elif self.is_id(ch):
x, w = self.get_identifier(line, x, e)
# Number?
if ch.isdigit():
s += self.as_num(w)
# Other identifier
else:
s += self.as_id(w)
# Output as is
else:
s += ch
x += 1
self.add_line(s)
# -----------------------------------------------------------------------
class asmview_t(idaapi.simplecustviewer_t, asm_colorizer_t):
def Create(self, fn):
# Create the customview
if not idaapi.simplecustviewer_t.Create(self, "Viewing file - %s" % os.path.basename(fn)):
return False
self.instruction_list = idautils.GetInstructionList()
self.instruction_list.extend(["ret"])
self.register_list = idautils.GetRegisterList()
self.register_list.extend(["eax", "ebx", "ecx", "edx", "edi", "esi", "ebp", "esp"])
self.fn = fn
if not self.reload_file():
return False
self.id_refresh = self.AddPopupMenu("Refresh")
self.id_close = self.AddPopupMenu("Close")
return True
def reload_file(self):
if not self.colorize_file(self.fn):
self.Close()
return False
return True
def colorize_file(self, fn):
try:
f = open(fn, "r")
lines = f.readlines()
f.close()
self.ClearLines()
self.colorize(lines)
return True
except:
return False
def add_line(self, s=None):
if not s:
s = ""
self.AddLine(s)
def as_comment(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_RPTCMT)
def as_id(self, s):
t = s.lower()
if t in self.register_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_REG)
elif t in self.instruction_list:
return idaapi.COLSTR(s, idaapi.SCOLOR_INSN)
else:
return s
def as_string(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_STRING)
def as_num(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_NUMBER)
def as_directive(self, s):
return idaapi.COLSTR(s, idaapi.SCOLOR_KEYWORD)
def OnPopupMenu(self, menu_id):
"""
A context (or popup) menu item was executed.
@param menu_id: ID previously registered with AddPopupMenu()
@return: Boolean
"""
if self.id_refresh == menu_id:
return self.reload_file()
elif self.id_close == menu_id:
self.Close()
return True
return False
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return Boolean. True if you handled the event
"""
# ESCAPE
if vkey == 27:
self.Close()
elif vkey == ord('H'):
lineno = self.GetLineNo()
if lineno is not None:
line, fg, bg = self.GetLine(lineno)
if line and line[0] != idaapi.SCOLOR_INV:
s = idaapi.SCOLOR_INV + line + idaapi.SCOLOR_INV
self.EditLine(lineno, s, fg, bg)
self.Refresh()
elif vkey == ord('C'):
self.ClearLines()
self.Refresh()
elif vkey == ord('S'):
print "Selection (x1, y1, x2, y2) = ", self.GetSelection()
elif vkey == ord('I'):
print "Position (line, x, y) = ", self.GetPos(mouse = 0)
else:
return False
return True
# -----------------------------------------------------------------------
class asmviewplg(idaapi.plugin_t):
flags = idaapi.PLUGIN_KEEP
comment = "ASM viewer"
help = "This is help"
wanted_name = "ASM file viewer"
wanted_hotkey = "Alt-F8"
def __init__(self):
self.view = None
def init(self):
return idaapi.PLUGIN_KEEP
def run(self, arg):
if self.view:
self.Close()
fn = idc.AskFile(0, "*.asm", "Select ASM file to view")
if not fn:
return
self.view = asmview_t()
if not self.view.Create(fn):
return
self.view.Show()
def term(self):
if self.view:
self.view.Close()
def PLUGIN_ENTRY():
return asmviewplg()

View File

@@ -1,101 +1,101 @@
# -----------------------------------------------------------------------
# Debugger command prompt with CustomViewers
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
def SendDbgCommand(cmd):
"""Sends a command to the debugger and returns the output string.
An exception will be raised if the debugger is not running or the current debugger does not export
the 'SendDbgCommand' IDC command.
"""
s = Eval('SendDbgCommand("%s");' % cmd)
if s.startswith("IDC_FAILURE"):
raise Exception, "Debugger command is available only when the debugger is active!"
return s
# -----------------------------------------------------------------------
class dbgcmd_t(simplecustviewer_t):
def Create(self):
# Form the title
title = "Debugger command window"
# Create the customview
if not simplecustviewer_t.Create(self, title):
return False
self.last_cmd = ""
self.menu_clear = self.AddPopupMenu("Clear")
self.menu_cmd = self.AddPopupMenu("New command")
self.ResetOutput()
return True
def IssueCommand(self):
s = idaapi.askstr(0, self.last_cmd, "Please enter a debugger command")
if not s:
return
# Save last command
self.last_cmd = s
# Add it using a different color
self.AddLine("debugger>" + idaapi.COLSTR(s, idaapi.SCOLOR_VOIDOP))
try:
r = SendDbgCommand(s).split("\n")
for s in r:
self.AddLine(idaapi.COLSTR(s, idaapi.SCOLOR_LIBNAME))
except:
self.AddLine(idaapi.COLSTR("Debugger is not active or does not export SendDbgCommand()", idaapi.SCOLOR_ERROR))
self.Refresh()
def ResetOutput(self):
self.ClearLines()
self.AddLine(idaapi.COLSTR("Please press INS to enter command; X to clear output", idaapi.SCOLOR_AUTOCMT))
self.Refresh()
def OnKeydown(self, vkey, shift):
# ESCAPE?
if vkey == 27:
self.Close()
# VK_INSERT
elif vkey == 45:
self.IssueCommand()
elif vkey == ord('X'):
self.ResetOutput()
else:
return False
return True
def OnPopupMenu(self, menu_id):
if menu_id == self.menu_clear:
self.ResetOutput()
elif menu_id == self.menu_cmd:
self.IssueCommand()
else:
# Unhandled
return False
return True
# -----------------------------------------------------------------------
def show_win():
x = dbgcmd_t()
if not x.Create():
print "Failed to create debugger command line!"
return None
x.Show()
return x
try:
# created already?
dbgcmd
dbgcmd.Close()
del dbgcmd
except:
pass
dbgcmd = show_win()
if not dbgcmd:
del dbgcmd
# -----------------------------------------------------------------------
# Debugger command prompt with CustomViewers
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
def SendDbgCommand(cmd):
"""Sends a command to the debugger and returns the output string.
An exception will be raised if the debugger is not running or the current debugger does not export
the 'SendDbgCommand' IDC command.
"""
s = Eval('SendDbgCommand("%s");' % cmd)
if s.startswith("IDC_FAILURE"):
raise Exception, "Debugger command is available only when the debugger is active!"
return s
# -----------------------------------------------------------------------
class dbgcmd_t(simplecustviewer_t):
def Create(self):
# Form the title
title = "Debugger command window"
# Create the customview
if not simplecustviewer_t.Create(self, title):
return False
self.last_cmd = ""
self.menu_clear = self.AddPopupMenu("Clear")
self.menu_cmd = self.AddPopupMenu("New command")
self.ResetOutput()
return True
def IssueCommand(self):
s = idaapi.askstr(0, self.last_cmd, "Please enter a debugger command")
if not s:
return
# Save last command
self.last_cmd = s
# Add it using a different color
self.AddLine("debugger>" + idaapi.COLSTR(s, idaapi.SCOLOR_VOIDOP))
try:
r = SendDbgCommand(s).split("\n")
for s in r:
self.AddLine(idaapi.COLSTR(s, idaapi.SCOLOR_LIBNAME))
except:
self.AddLine(idaapi.COLSTR("Debugger is not active or does not export SendDbgCommand()", idaapi.SCOLOR_ERROR))
self.Refresh()
def ResetOutput(self):
self.ClearLines()
self.AddLine(idaapi.COLSTR("Please press INS to enter command; X to clear output", idaapi.SCOLOR_AUTOCMT))
self.Refresh()
def OnKeydown(self, vkey, shift):
# ESCAPE?
if vkey == 27:
self.Close()
# VK_INSERT
elif vkey == 45:
self.IssueCommand()
elif vkey == ord('X'):
self.ResetOutput()
else:
return False
return True
def OnPopupMenu(self, menu_id):
if menu_id == self.menu_clear:
self.ResetOutput()
elif menu_id == self.menu_cmd:
self.IssueCommand()
else:
# Unhandled
return False
return True
# -----------------------------------------------------------------------
def show_win():
x = dbgcmd_t()
if not x.Create():
print "Failed to create debugger command line!"
return None
x.Show()
return x
try:
# created already?
dbgcmd
dbgcmd.Close()
del dbgcmd
except:
pass
dbgcmd = show_win()
if not dbgcmd:
del dbgcmd

View File

@@ -1,105 +1,105 @@
"""
A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
"""
import re
from idaapi import Choose
# -----------------------------------------------------------------------
def CmdDriverList():
s = Eval('WinDbgCommand("lm o");')
if "IDC_FAILURE" in s: return False
return s
# -----------------------------------------------------------------------
def CmdDrvObj(drvname, flag=2):
return Eval('WinDbgCommand("!drvobj %s %d");' % (drvname, flag))
# -----------------------------------------------------------------------
def CmdReloadForce():
s = Eval('WinDbgCommand(".reload /f");')
if "IDC_FAILURE" in s: return False
return True
# -----------------------------------------------------------------------
# class to hold dispatch entry information
class DispatchEntry:
def __init__(self, addr, name):
self.addr = addr
self.name = name
def __repr__(self):
return "%08X: %s" % (self.addr, self.name)
# -----------------------------------------------------------------------
def GetDriverDispatch():
# return a list of arrays of the form: [addr, name]
ret_list = []
# build the RE for parsing output from the "lm o" command
re_drv = re.compile('^[a-f0-9]+\s+[a-f0-9]+\s+(\S+)', re.I)
# build the RE for parsing output from the "!drvobj DRV_NAME 2" command
re_tbl = re.compile('^\[\d{2}\]\s+IRP_MJ_(\S+)\s+([0-9a-f]+)', re.I)
# force reloading of module symbols
if not CmdReloadForce():
print "Could not communicate with WinDbg, make sure the debugger is running!"
return None
# get driver list
lm_out = CmdDriverList()
if not lm_out:
return "Failed to get driver list!"
# for each line
for line in lm_out.split("\n"):
# parse
r = re_drv.match(line)
if not r: continue
# extract driver name
drvname = r.group(1).strip()
# execute "drvobj" command
tbl_out = CmdDrvObj(drvname)
if not tbl_out:
print "Failed to get driver object for", drvname
continue
# for each line
for line in tbl_out.split("\n"):
# parse
r = re_tbl.match(line)
if not r: continue
disp_addr = int(r.group(2), 16) # convert hex string to number
disp_name = "Dispatch" + r.group(1)
ret_list.append(DispatchEntry(disp_addr, drvname + "_" + disp_name))
return ret_list
# -----------------------------------------------------------------------
# Chooser class
class DispatchChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.addr)
# -----------------------------------------------------------------------
# main
r = GetDriverDispatch()
if r:
c = DispatchChoose(r, "Dispatch table browser")
c.choose()
else:
"""
A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
"""
import re
from idaapi import Choose
# -----------------------------------------------------------------------
def CmdDriverList():
s = Eval('WinDbgCommand("lm o");')
if "IDC_FAILURE" in s: return False
return s
# -----------------------------------------------------------------------
def CmdDrvObj(drvname, flag=2):
return Eval('WinDbgCommand("!drvobj %s %d");' % (drvname, flag))
# -----------------------------------------------------------------------
def CmdReloadForce():
s = Eval('WinDbgCommand(".reload /f");')
if "IDC_FAILURE" in s: return False
return True
# -----------------------------------------------------------------------
# class to hold dispatch entry information
class DispatchEntry:
def __init__(self, addr, name):
self.addr = addr
self.name = name
def __repr__(self):
return "%08X: %s" % (self.addr, self.name)
# -----------------------------------------------------------------------
def GetDriverDispatch():
# return a list of arrays of the form: [addr, name]
ret_list = []
# build the RE for parsing output from the "lm o" command
re_drv = re.compile('^[a-f0-9]+\s+[a-f0-9]+\s+(\S+)', re.I)
# build the RE for parsing output from the "!drvobj DRV_NAME 2" command
re_tbl = re.compile('^\[\d{2}\]\s+IRP_MJ_(\S+)\s+([0-9a-f]+)', re.I)
# force reloading of module symbols
if not CmdReloadForce():
print "Could not communicate with WinDbg, make sure the debugger is running!"
return None
# get driver list
lm_out = CmdDriverList()
if not lm_out:
return "Failed to get driver list!"
# for each line
for line in lm_out.split("\n"):
# parse
r = re_drv.match(line)
if not r: continue
# extract driver name
drvname = r.group(1).strip()
# execute "drvobj" command
tbl_out = CmdDrvObj(drvname)
if not tbl_out:
print "Failed to get driver object for", drvname
continue
# for each line
for line in tbl_out.split("\n"):
# parse
r = re_tbl.match(line)
if not r: continue
disp_addr = int(r.group(2), 16) # convert hex string to number
disp_name = "Dispatch" + r.group(1)
ret_list.append(DispatchEntry(disp_addr, drvname + "_" + disp_name))
return ret_list
# -----------------------------------------------------------------------
# Chooser class
class DispatchChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
idc.Jump(o.addr)
# -----------------------------------------------------------------------
# main
r = GetDriverDispatch()
if r:
c = DispatchChoose(r, "Dispatch table browser")
c.choose()
else:
print "Failed to retrieve dispatchers list!"

View File

@@ -1,139 +1,139 @@
"""
FindInstructions.py: A script to help you find desired opcodes/instructions in a database
The script accepts opcodes and assembly statements (which will be assembled) separated by semicolon
The general syntax is:
find(asm or opcodes, x=Bool, asm_where=ea)
* Example:
find("asm_statement1;asm_statement2;de ea dc 0d e0;asm_statement3;xx yy zz;...")
* To filter-out non-executable segments pass x=True
find("jmp dword ptr [esp]", x=True)
* To specify in which context the instructions should be assembled, pass asm_where=ea:
find("jmp dword ptr [esp]", asm_where=here())
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
# -----------------------------------------------------------------------
def FindInstructions(instr, asm_where=None):
"""
Finds instructions/opcodes
@return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
"""
if not asm_where:
# get first segment
asm_where = FirstSeg()
if asm_where == idaapi.BADADDR:
return (False, "No segments defined")
# regular expression to distinguish between opcodes and instructions
re_opcode = re.compile('^[0-9a-f]{2} *', re.I)
# split lines
lines = instr.split(";")
# all the assembled buffers (for each instruction)
bufs = []
for line in lines:
if re_opcode.match(line):
# convert from hex string to a character list then join the list to form one string
buf = ''.join([chr(int(x, 16)) for x in line.split()])
else:
# assemble the instruction
ret, buf = Assemble(asm_where, line)
if not ret:
return (False, "Failed to assemble:"+line)
# add the assembled buffer
bufs.append(buf)
# join the buffer into one string
buf = ''.join(bufs)
# take total assembled instructions length
tlen = len(buf)
# convert from binary string to space separated hex string
bin_str = ' '.join(["%02X" % ord(x) for x in buf])
# find all binary strings
print "Searching for: [%s]" % bin_str
ea = MinEA()
ret = []
while True:
ea = FindBinary(ea, SEARCH_DOWN, bin_str)
if ea == idaapi.BADADDR:
break
ret.append(ea)
Message(".")
ea += tlen
if not ret:
return (False, "Could not match [%s]" % bin_str)
Message("\n")
return (True, ret)
# -----------------------------------------------------------------------
# Chooser class
class SearchResultChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
Jump(o.ea)
# -----------------------------------------------------------------------
# class to represent the results
class SearchResult:
def __init__(self, ea):
self.ea = ea
if not isCode(GetFlags(ea)):
MakeCode(ea)
t = idaapi.generate_disasm_line(ea)
if t:
line = idaapi.tag_remove(t)
else:
line = ""
func = GetFunctionName(ea)
self.display = hex(ea) + ": "
if func:
self.display += func + ": "
else:
n = SegName(ea)
if n: self.display += n + ": "
self.display += line
def __str__(self):
return self.display
# -----------------------------------------------------------------------
def find(s=None, x=False, asm_where=None):
b, ret = FindInstructions(s, asm_where)
if b:
# executable segs only?
if x:
results = []
for ea in ret:
seg = idaapi.getseg(ea)
if (not seg) or (seg.perm & idaapi.SEGPERM_EXEC) == 0:
continue
results.append(SearchResult(ea))
else:
results = [SearchResult(ea) for ea in ret]
title = "Search result for: [%s]" % s
idaapi.close_chooser(title)
c = SearchResultChoose(results, title)
c.choose()
else:
print ret
# -----------------------------------------------------------------------
print "Please use find('asm_stmt1;xx yy;...', x=Bool,asm_where=ea) to search for instructions or opcodes. Specify x=true to filter out non-executable segments"
"""
FindInstructions.py: A script to help you find desired opcodes/instructions in a database
The script accepts opcodes and assembly statements (which will be assembled) separated by semicolon
The general syntax is:
find(asm or opcodes, x=Bool, asm_where=ea)
* Example:
find("asm_statement1;asm_statement2;de ea dc 0d e0;asm_statement3;xx yy zz;...")
* To filter-out non-executable segments pass x=True
find("jmp dword ptr [esp]", x=True)
* To specify in which context the instructions should be assembled, pass asm_where=ea:
find("jmp dword ptr [esp]", asm_where=here())
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
# -----------------------------------------------------------------------
def FindInstructions(instr, asm_where=None):
"""
Finds instructions/opcodes
@return: Returns a tuple(True, [ ea, ... ]) or a tuple(False, "error message")
"""
if not asm_where:
# get first segment
asm_where = FirstSeg()
if asm_where == idaapi.BADADDR:
return (False, "No segments defined")
# regular expression to distinguish between opcodes and instructions
re_opcode = re.compile('^[0-9a-f]{2} *', re.I)
# split lines
lines = instr.split(";")
# all the assembled buffers (for each instruction)
bufs = []
for line in lines:
if re_opcode.match(line):
# convert from hex string to a character list then join the list to form one string
buf = ''.join([chr(int(x, 16)) for x in line.split()])
else:
# assemble the instruction
ret, buf = Assemble(asm_where, line)
if not ret:
return (False, "Failed to assemble:"+line)
# add the assembled buffer
bufs.append(buf)
# join the buffer into one string
buf = ''.join(bufs)
# take total assembled instructions length
tlen = len(buf)
# convert from binary string to space separated hex string
bin_str = ' '.join(["%02X" % ord(x) for x in buf])
# find all binary strings
print "Searching for: [%s]" % bin_str
ea = MinEA()
ret = []
while True:
ea = FindBinary(ea, SEARCH_DOWN, bin_str)
if ea == idaapi.BADADDR:
break
ret.append(ea)
Message(".")
ea += tlen
if not ret:
return (False, "Could not match [%s]" % bin_str)
Message("\n")
return (True, ret)
# -----------------------------------------------------------------------
# Chooser class
class SearchResultChoose(Choose):
def __init__(self, list, title):
Choose.__init__(self, list, title)
self.width = 250
def enter(self, n):
o = self.list[n-1]
Jump(o.ea)
# -----------------------------------------------------------------------
# class to represent the results
class SearchResult:
def __init__(self, ea):
self.ea = ea
if not isCode(GetFlags(ea)):
MakeCode(ea)
t = idaapi.generate_disasm_line(ea)
if t:
line = idaapi.tag_remove(t)
else:
line = ""
func = GetFunctionName(ea)
self.display = hex(ea) + ": "
if func:
self.display += func + ": "
else:
n = SegName(ea)
if n: self.display += n + ": "
self.display += line
def __str__(self):
return self.display
# -----------------------------------------------------------------------
def find(s=None, x=False, asm_where=None):
b, ret = FindInstructions(s, asm_where)
if b:
# executable segs only?
if x:
results = []
for ea in ret:
seg = idaapi.getseg(ea)
if (not seg) or (seg.perm & idaapi.SEGPERM_EXEC) == 0:
continue
results.append(SearchResult(ea))
else:
results = [SearchResult(ea) for ea in ret]
title = "Search result for: [%s]" % s
idaapi.close_chooser(title)
c = SearchResultChoose(results, title)
c.choose()
else:
print ret
# -----------------------------------------------------------------------
print "Please use find('asm_stmt1;xx yy;...', x=Bool,asm_where=ea) to search for instructions or opcodes. Specify x=true to filter out non-executable segments"

View File

@@ -1,124 +1,124 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to:
# - enumerate imports
# - enumerate entrypoints
# - Use PluginForm class
# - Use PySide with PluginForm to create a Python UI
#
# (c) Hex-Rays
#
import idaapi
import idautils
from idaapi import PluginForm
from PySide import QtGui, QtCore
# --------------------------------------------------------------------------
class ImpExpForm_t(PluginForm):
def imports_names_cb(self, ea, name, ord):
self.items.append((ea, '' if not name else name, ord))
# True -> Continue enumeration
return True
def BuildImports(self):
tree = {}
nimps = idaapi.get_import_module_qty()
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if not name:
continue
# Create a list for imported names
self.items = []
# Enum imported entries in this module
idaapi.enum_import_names(i, self.imports_names_cb)
if name not in tree:
tree[name] = []
tree[name].extend(self.items)
return tree
def BuildExports(self):
return list(idautils.Entries())
def PopulateTree(self):
# Clear previous items
self.tree.clear()
# Build imports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Imports")
for dll_name, imp_entries in self.BuildImports().items():
imp_dll = QtGui.QTreeWidgetItem(root)
imp_dll.setText(0, dll_name)
for imp_ea, imp_name, imp_ord in imp_entries:
item = QtGui.QTreeWidgetItem(imp_dll)
item.setText(0, "%s [0x%08x]" %(imp_name, imp_ea))
# Build exports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Exports")
for exp_i, exp_ord, exp_ea, exp_name in self.BuildExports():
item = QtGui.QTreeWidgetItem(root)
item.setText(0, "%s [#%d] [0x%08x]" % (exp_name, exp_ord, exp_ea))
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
# Create tree control
self.tree = QtGui.QTreeWidget()
self.tree.setHeaderLabels(("Names",))
self.tree.setColumnWidth(0, 100)
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.tree)
self.PopulateTree()
# Populate PluginForm
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
global ImpExpForm
del ImpExpForm
print "Closed"
def Show(self):
"""Creates the form is not created or focuses it if it was"""
return PluginForm.Show(self,
"Imports / Exports viewer",
options = PluginForm.FORM_PERSIST)
# --------------------------------------------------------------------------
def main():
global ImpExpForm
try:
ImpExpForm
except:
ImpExpForm = ImpExpForm_t()
ImpExpForm.Show()
# --------------------------------------------------------------------------
# -----------------------------------------------------------------------
# This is an example illustrating how to:
# - enumerate imports
# - enumerate entrypoints
# - Use PluginForm class
# - Use PySide with PluginForm to create a Python UI
#
# (c) Hex-Rays
#
import idaapi
import idautils
from idaapi import PluginForm
from PySide import QtGui, QtCore
# --------------------------------------------------------------------------
class ImpExpForm_t(PluginForm):
def imports_names_cb(self, ea, name, ord):
self.items.append((ea, '' if not name else name, ord))
# True -> Continue enumeration
return True
def BuildImports(self):
tree = {}
nimps = idaapi.get_import_module_qty()
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if not name:
continue
# Create a list for imported names
self.items = []
# Enum imported entries in this module
idaapi.enum_import_names(i, self.imports_names_cb)
if name not in tree:
tree[name] = []
tree[name].extend(self.items)
return tree
def BuildExports(self):
return list(idautils.Entries())
def PopulateTree(self):
# Clear previous items
self.tree.clear()
# Build imports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Imports")
for dll_name, imp_entries in self.BuildImports().items():
imp_dll = QtGui.QTreeWidgetItem(root)
imp_dll.setText(0, dll_name)
for imp_ea, imp_name, imp_ord in imp_entries:
item = QtGui.QTreeWidgetItem(imp_dll)
item.setText(0, "%s [0x%08x]" %(imp_name, imp_ea))
# Build exports
root = QtGui.QTreeWidgetItem(self.tree)
root.setText(0, "Exports")
for exp_i, exp_ord, exp_ea, exp_name in self.BuildExports():
item = QtGui.QTreeWidgetItem(root)
item.setText(0, "%s [#%d] [0x%08x]" % (exp_name, exp_ord, exp_ea))
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
# Create tree control
self.tree = QtGui.QTreeWidget()
self.tree.setHeaderLabels(("Names",))
self.tree.setColumnWidth(0, 100)
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(self.tree)
self.PopulateTree()
# Populate PluginForm
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
global ImpExpForm
del ImpExpForm
print "Closed"
def Show(self):
"""Creates the form is not created or focuses it if it was"""
return PluginForm.Show(self,
"Imports / Exports viewer",
options = PluginForm.FORM_PERSIST)
# --------------------------------------------------------------------------
def main():
global ImpExpForm
try:
ImpExpForm
except:
ImpExpForm = ImpExpForm_t()
ImpExpForm.Show()
# --------------------------------------------------------------------------
main()

View File

@@ -1,85 +1,85 @@
import idaapi
import idc
from idaapi import Choose2
def parse_pte(str):
try:
parse_pte.re
except:
parse_pte.re = re.compile('PDE at ([0-9a-f]+)\s*PTE at ([0-9a-f]+)\ncontains ([0-9a-f]+)\s*contains ([0-9a-f]+)\npfn ([0-9]+)\s*([^ ]+)\s*pfn ([0-9a-f]+)\s*([^\r\n]+)', re.I | re.M)
parse_pte.items = ('pde', 'pte', 'pdec', 'ptec', 'pdepfn', 'pdepfns', 'ptepfn', 'ptepfns')
m = parse_pte.re.search(s)
r = {}
for i in range(0, len(parse_pte.items)):
r[parse_pte.items[i]] = m.group(i+1)
return r
class MyChoose2(Choose2):
def __init__(self, title, ea1, ea2):
Choose2.__init__(self, title, [ ["VA", 10], ["PTE attr", 30] ])
self.ea1 = ea1
self.ea2 = ea2
self.n = 0
self.icon = 5
self.items = []
self.Refresh()
self.selcount = 0
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
self.Refresh()
return n
def OnRefresh(self, n):
print("refresh %d" % n)
return n
def Refresh(self):
items = []
PG = 0x1000
ea1 = self.ea1
npages = (self.ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
r = parse_pte(r)
items.append([hex(ea1), r['ptepfns']])
ea1 += PG
self.items = items
print(self.items)
return True
@staticmethod
def Execute(ea1, ea2):
c = MyChoose2("PTE Viewer [%x..%x]" % (ea1, ea2), ea1, ea2)
return (c, c.Show())
def DumpPTE(ea1, ea2):
items = []
PG = 0x1000
npages = (ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
print r
r = parse_pte(r)
print("VA: %08X PTE: %s PDE: %s" % (ea1, r['ptepfns'], r['pdepfns']))
ea1 += PG
def DumpSegPTE(ea):
DumpPTE(idc.SegStart(ea), idc.SegEnd(ea))
DumpSegPTE(here())
#MyChoose2.Execute(0xF718F000, 0xF718F000+0x1000)
import idaapi
import idc
from idaapi import Choose2
def parse_pte(str):
try:
parse_pte.re
except:
parse_pte.re = re.compile('PDE at ([0-9a-f]+)\s*PTE at ([0-9a-f]+)\ncontains ([0-9a-f]+)\s*contains ([0-9a-f]+)\npfn ([0-9]+)\s*([^ ]+)\s*pfn ([0-9a-f]+)\s*([^\r\n]+)', re.I | re.M)
parse_pte.items = ('pde', 'pte', 'pdec', 'ptec', 'pdepfn', 'pdepfns', 'ptepfn', 'ptepfns')
m = parse_pte.re.search(s)
r = {}
for i in range(0, len(parse_pte.items)):
r[parse_pte.items[i]] = m.group(i+1)
return r
class MyChoose2(Choose2):
def __init__(self, title, ea1, ea2):
Choose2.__init__(self, title, [ ["VA", 10], ["PTE attr", 30] ])
self.ea1 = ea1
self.ea2 = ea2
self.n = 0
self.icon = 5
self.items = []
self.Refresh()
self.selcount = 0
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
self.Refresh()
return n
def OnRefresh(self, n):
print("refresh %d" % n)
return n
def Refresh(self):
items = []
PG = 0x1000
ea1 = self.ea1
npages = (self.ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
r = parse_pte(r)
items.append([hex(ea1), r['ptepfns']])
ea1 += PG
self.items = items
print(self.items)
return True
@staticmethod
def Execute(ea1, ea2):
c = MyChoose2("PTE Viewer [%x..%x]" % (ea1, ea2), ea1, ea2)
return (c, c.Show())
def DumpPTE(ea1, ea2):
items = []
PG = 0x1000
npages = (ea2 - ea1) / PG
for i in range(npages):
r = idc.SendDbgCommand("!pte %x" % ea1)
if not r:
return False
print r
r = parse_pte(r)
print("VA: %08X PTE: %s PDE: %s" % (ea1, r['ptepfns'], r['pdepfns']))
ea1 += PG
def DumpSegPTE(ea):
DumpPTE(idc.SegStart(ea), idc.SegEnd(ea))
DumpSegPTE(here())
#MyChoose2.Execute(0xF718F000, 0xF718F000+0x1000)

View File

@@ -1,149 +1,149 @@
"""
A script that graphs all the exception handlers in a given process
It will be easy to see what thread uses what handler and what handlers are commonly used between threads
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
from idaapi import GraphViewer
# -----------------------------------------------------------------------
# Since Windbg debug module does not support get_thread_sreg_base()
# we will call the debugger engine "dg" command and parse its output
def WindbgGetRegBase(tid):
s = idc.Eval('WinDbgCommand("dg %x")' % cpu.fs)
if "IDC_FAILURE" in s:
return 0
m = re.compile("[0-9a-f]{4} ([0-9a-f]{8})")
t = m.match(s.split('\n')[-2])
if not t:
return 0
return int(t.group(1), 16)
# -----------------------------------------------------------------------
def GetFsBase(tid):
idc.SelectThread(tid)
base = idaapi.dbg_get_thread_sreg_base(tid, cpu.fs)
if base != 0:
return base
return WindbgGetRegBase(tid)
# -----------------------------------------------------------------------
# Walks the SEH chain and returns a list of handlers
def GetExceptionChain(tid):
fs_base = GetFsBase(tid)
exc_rr = Dword(fs_base)
result = []
while exc_rr != 0xffffffff:
prev = Dword(exc_rr)
handler = Dword(exc_rr + 4)
exc_rr = prev
result.append(handler)
return result
# -----------------------------------------------------------------------
class SEHGraph(GraphViewer):
def __init__(self, title, result):
GraphViewer.__init__(self, title)
self.result = result
self.names = {} # ea -> name
def OnRefresh(self):
self.Clear()
addr_id = {}
for (tid, chain) in self.result.items():
# Each node data will contain a tuple of the form: (Boolean->Is_thread, Int->Value, String->Label)
# For threads the is_thread will be true and the value will hold the thread id
# For exception handlers, is_thread=False and Value=Handler address
# Add the thread node
id_parent = self.AddNode( (True, tid, "Thread %X" % tid) )
# Add each handler
for handler in chain:
# Check if a function is created at the handler's address
f = idaapi.get_func(handler)
if not f:
# create function
idc.MakeFunction(handler, idaapi.BADADDR)
# Node label is function name or address
s = GetFunctionName(handler)
if not s:
s = "%x" % handler
# cache name
self.names[handler] = s
# Get the node id given the handler address
# We use an addr -> id dictionary so that similar addresses get similar node id
if not addr_id.has_key(handler):
id = self.AddNode( (False, handler, s) )
addr_id[handler] = id # add this ID
else:
id = addr_id[handler]
# Link handlers to each other
self.AddEdge(id_parent, id)
id_parent = id
return True
def OnGetText(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
return (label, 0xff00f0)
return label
def OnDblClick(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
idc.SelectThread(value)
self.Show()
s = "SEH chain for " + hex(value)
t = "-" * len(s)
print t
print s
print t
for handler in self.result[value]:
print "%x: %s" % (handler, self.names[handler])
print t
else:
idc.Jump(value)
return True
# -----------------------------------------------------------------------
def main():
if not idaapi.dbg_can_query():
print "The debugger must be active and suspended before using this script!"
return
# Save current thread id
tid = GetCurrentThreadId()
# Iterate through all function instructions and take only call instructions
result = {}
for tid in idautils.Threads():
result[tid] = GetExceptionChain(tid)
# Restore previously selected thread
idc.SelectThread(tid)
# Build the graph
g = SEHGraph("SEH graph", result)
g.Show()
main()
"""
A script that graphs all the exception handlers in a given process
It will be easy to see what thread uses what handler and what handlers are commonly used between threads
Copyright (c) 1990-2009 Hex-Rays
ALL RIGHTS RESERVED.
v1.0 - initial version
"""
import idaapi
import idautils
import idc
from idaapi import GraphViewer
# -----------------------------------------------------------------------
# Since Windbg debug module does not support get_thread_sreg_base()
# we will call the debugger engine "dg" command and parse its output
def WindbgGetRegBase(tid):
s = idc.Eval('WinDbgCommand("dg %x")' % cpu.fs)
if "IDC_FAILURE" in s:
return 0
m = re.compile("[0-9a-f]{4} ([0-9a-f]{8})")
t = m.match(s.split('\n')[-2])
if not t:
return 0
return int(t.group(1), 16)
# -----------------------------------------------------------------------
def GetFsBase(tid):
idc.SelectThread(tid)
base = idaapi.dbg_get_thread_sreg_base(tid, cpu.fs)
if base != 0:
return base
return WindbgGetRegBase(tid)
# -----------------------------------------------------------------------
# Walks the SEH chain and returns a list of handlers
def GetExceptionChain(tid):
fs_base = GetFsBase(tid)
exc_rr = Dword(fs_base)
result = []
while exc_rr != 0xffffffff:
prev = Dword(exc_rr)
handler = Dword(exc_rr + 4)
exc_rr = prev
result.append(handler)
return result
# -----------------------------------------------------------------------
class SEHGraph(GraphViewer):
def __init__(self, title, result):
GraphViewer.__init__(self, title)
self.result = result
self.names = {} # ea -> name
def OnRefresh(self):
self.Clear()
addr_id = {}
for (tid, chain) in self.result.items():
# Each node data will contain a tuple of the form: (Boolean->Is_thread, Int->Value, String->Label)
# For threads the is_thread will be true and the value will hold the thread id
# For exception handlers, is_thread=False and Value=Handler address
# Add the thread node
id_parent = self.AddNode( (True, tid, "Thread %X" % tid) )
# Add each handler
for handler in chain:
# Check if a function is created at the handler's address
f = idaapi.get_func(handler)
if not f:
# create function
idc.MakeFunction(handler, idaapi.BADADDR)
# Node label is function name or address
s = GetFunctionName(handler)
if not s:
s = "%x" % handler
# cache name
self.names[handler] = s
# Get the node id given the handler address
# We use an addr -> id dictionary so that similar addresses get similar node id
if not addr_id.has_key(handler):
id = self.AddNode( (False, handler, s) )
addr_id[handler] = id # add this ID
else:
id = addr_id[handler]
# Link handlers to each other
self.AddEdge(id_parent, id)
id_parent = id
return True
def OnGetText(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
return (label, 0xff00f0)
return label
def OnDblClick(self, node_id):
is_thread, value, label = self[node_id]
if is_thread:
idc.SelectThread(value)
self.Show()
s = "SEH chain for " + hex(value)
t = "-" * len(s)
print t
print s
print t
for handler in self.result[value]:
print "%x: %s" % (handler, self.names[handler])
print t
else:
idc.Jump(value)
return True
# -----------------------------------------------------------------------
def main():
if not idaapi.dbg_can_query():
print "The debugger must be active and suspended before using this script!"
return
# Save current thread id
tid = GetCurrentThreadId()
# Iterate through all function instructions and take only call instructions
result = {}
for tid in idautils.Threads():
result[tid] = GetExceptionChain(tid)
# Restore previously selected thread
idc.SelectThread(tid)
# Build the graph
g = SEHGraph("SEH graph", result)
g.Show()
main()

View File

@@ -1,367 +1,367 @@
# -----------------------------------------------------------------------
# VirusTotal IDA Plugin
# By Elias Bachaalany <elias at hex-rays.com>
# (c) Hex-Rays 2011
#
# Special thanks:
# - VirusTotal team
# - Bryce Boe for his VirusTotal Python code
#
import idaapi
import idc
from idaapi import Choose2, plugin_t
import BboeVt as vt
import webbrowser
import urllib
import os
PLUGIN_TEST = 0
# -----------------------------------------------------------------------
# Configuration file
VT_CFGFILE = os.path.join(idaapi.get_user_idadir(), "virustotal.cfg")
# -----------------------------------------------------------------------
# VirusTotal Icon in PNG format
VT_ICON = (
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
"\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2"
"\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C"
"\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00"
"\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51"
"\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB"
"\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29"
"\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8"
"\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E"
"\xC5\x16\x2D\x54\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82")
# -----------------------------------------------------------------------
class VirusTotalConfig(object):
def __init__(self):
self.Default()
def Default(self):
self.md5sum = GetInputMD5()
self.infile = idaapi.dbg_get_input_path()
if not self.infile:
self.infile = ""
# Persistent options
self.apikey = ""
self.options = 1 | 2
def Read(self):
"""
Read configuration from file
"""
if not os.path.exists(VT_CFGFILE):
return
f = open(VT_CFGFILE, 'r')
lines = f.readlines()
for i, line in enumerate(lines):
line = line.strip()
if i == 0:
self.apikey = line
elif i == 1:
self.options = int(line)
else:
break
def Write(self):
"""
Write configuration to file
"""
lines = (self.apikey.strip(), str(self.options))
try:
f = open(VT_CFGFILE, 'w')
f.write("\n".join(lines))
f.close()
except:
pass
# -----------------------------------------------------------------------
def VtReport(apikey, filename=None, md5sum=None):
if filename is None and md5sum is None:
return (False, "No parameters passed!")
# Check filename existance
if filename is not None and not os.path.exists(filename):
return (False, "Input file '%s' does not exist!" % filename)
#print("fn=%s md5=%s" % (filename, md5sum))
# Get file report from VirusTotal
try:
vt.set_apikey(apikey)
result = vt.get_file_report(filename=filename, md5sum=md5sum)
except Exception as e:
return (False, "Exception:\n%s" % str(e))
# Already analyzed?
if result is not None:
# Transform the results
items = []
for av, mwname in result.items():
mwname = str(mwname) if mwname else "n/a"
av = str(av)
items.append([av, mwname])
result = items
return (True, result)
# -----------------------------------------------------------------------
class VirusTotalChooser(Choose2):
"""
Chooser class to display results from VT
"""
def __init__(self, title, items, icon, embedded=False):
Choose2.__init__(self,
title,
[ ["Antivirus", 20], ["Result", 40] ],
embedded=embedded)
self.items = items
self.icon = icon
def GetItems(self):
return self.items
def SetItems(self, items):
self.items = [] if items is None else items
def OnClose(self):
pass
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnSelectLine(self, n):
# Google search for the malware name and the antivirus name
s = urllib.urlencode({"q" : " ".join(self.items[n])})
webbrowser.open_new_tab("http://www.google.com/search?%s" % s)
# --------------------------------------------------------------------------
class VirusTotalForm(Form):
def __init__(self, icon):
self.EChooser = VirusTotalChooser("E1", [], icon, embedded=True)
Form.__init__(self, r"""STARTITEM {id:txtInput}
VirusTotal - IDAPython plugin v1.0 (c) Hex-Rays
{FormChangeCb}
<#API key#~A~pi key:{txtApiKey}>
Options:
<#Open results in a chooser when form closes#~P~opout results on close:{rOptRemember}>
<#Use MD5 checksum#~M~D5Sum:{rOptMD5}>
<#Use file on disk#~F~ile:{rOptFile}>{grpOptions}>
<#Type input (file or MD5 string)#~I~nput:{txtInput}>
<Results:{cEChooser}>
<#Get reports from VT#~R~eport:{btnReport}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'txtApiKey' : Form.StringInput(swidth=80),
'grpOptions' : Form.ChkGroupControl(("rOptRemember", "rOptMD5", "rOptFile")),
'txtInput' : Form.FileInput(open=True),
'btnReport' : Form.ButtonInput(self.OnReportClick),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnReportClick(self, code=0):
pass
def OnFormChange(self, fid):
if fid == self.rOptMD5.id or fid == self.rOptFile.id:
input = (self.cfg.md5sum, self.cfg.infile)
if fid == self.rOptMD5.id:
c1 = self.rOptMD5
c2 = self.rOptFile
idx = 0
else:
c1 = self.rOptFile
c2 = self.rOptMD5
idx = 1
v = not self.GetControlValue(c1)
if v: idx = not idx
# Uncheck the opposite input type
self.SetControlValue(c2, v)
# Set input field depending on input type
self.SetControlValue(self.txtInput, input[idx])
#
# Report button
#
elif fid == self.btnReport.id:
input = self.GetControlValue(self.txtInput)
as_file = self.GetControlValue(self.rOptFile)
apikey = self.GetControlValue(self.txtApiKey)
ok, r = VtReport(self.cfg.apikey,
filename=input if as_file else None,
md5sum=None if as_file else input)
# Error?
if not ok:
idc.Warning(r)
return 1
# Pass the result
self.EChooser.SetItems(r)
# We have results and it was a file? Print its MD5
if r and as_file:
print("%s: %s" % (vt.LAST_FILE_HASH, input))
# Refresh the embedded chooser control
# (Could also clear previous results if not were retrieved during this run)
self.RefreshField(self.cEChooser)
# Store the input for the caller
self.cfg.input = input
# No results and file as input was supplied?
if r is None:
if as_file:
# Propose to upload
if idc.AskYN(0, "HIDECANCEL\nNo previous results. Do you want to submit the file:\n\n'%s'\n\nto VirusTotal?" % input) == 0:
return 1
try:
r = vt.scan_file(input)
except Exception as e:
idc.Warning("Exceptio during upload: %s" % str(e))
else:
if r is None:
idc.Warning("Failed to upload the file!")
else:
idc.Warning("File uploaded. Check again later to get the analysis report. Scan id: %s" % r)
else:
idc.Warning("No results found for hash: %s" % input)
return 1
def Show(self, cfg):
# Compile the form once
if not self.Compiled():
_, args = self.Compile()
#print args[0]
# Populate the form
self.txtApiKey.value = cfg.apikey
self.grpOptions.value = cfg.options
self.txtInput.value = cfg.infile if self.rOptFile.checked else cfg.md5sum
# Remember the config
self.cfg = cfg
# Execute the form
ok = self.Execute()
# Forget the cfg
del self.cfg
# Success?
if ok != 0:
# Update config
cfg.options = self.grpOptions.value
cfg.apikey = self.txtApiKey.value
# Popup results?
if self.rOptRemember.checked:
ok = 2
return ok
# -----------------------------------------------------------------------
class VirusTotalPlugin_t(plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "VirusTotal plugin for IDA"
help = ""
wanted_name = "VirusTotal report"
wanted_hotkey = "Alt-F8"
def init(self):
# Some initialization
self.icon_id = 0
return idaapi.PLUGIN_OK
def run(self, arg=0):
# Load icon from the memory and save its id
self.icon_id = idaapi.load_custom_icon(data=VT_ICON, format="png")
if self.icon_id == 0:
raise RuntimeError("Failed to load icon data!")
# Create config object
cfg = VirusTotalConfig()
# Read previous config
cfg.Read()
# Create form
f = VirusTotalForm(self.icon_id)
# Show the form
ok = f.Show(cfg)
if ok == 0:
f.Free()
return
# Save configuration
cfg.Write()
# Spawn a non-modal chooser w/ the results if any
if ok == 2 and f.EChooser.GetItems():
VirusTotalChooser(
"VirusTotal results [%s]" % cfg.input,
f.EChooser.GetItems(),
self.icon_id).Show()
f.Free()
return
def term(self):
# Free the custom icon
if self.icon_id != 0:
idaapi.free_custom_icon(self.icon_id)
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return VirusTotalPlugin_t()
# --------------------------------------------------------------------------
if PLUGIN_TEST:
# Create form
f = PLUGIN_ENTRY()
f.init()
f.run()
f.term()
# -----------------------------------------------------------------------
# VirusTotal IDA Plugin
# By Elias Bachaalany <elias at hex-rays.com>
# (c) Hex-Rays 2011
#
# Special thanks:
# - VirusTotal team
# - Bryce Boe for his VirusTotal Python code
#
import idaapi
import idc
from idaapi import Choose2, plugin_t
import BboeVt as vt
import webbrowser
import urllib
import os
PLUGIN_TEST = 0
# -----------------------------------------------------------------------
# Configuration file
VT_CFGFILE = os.path.join(idaapi.get_user_idadir(), "virustotal.cfg")
# -----------------------------------------------------------------------
# VirusTotal Icon in PNG format
VT_ICON = (
"\x89\x50\x4E\x47\x0D\x0A\x1A\x0A\x00\x00\x00\x0D\x49\x48\x44\x52"
"\x00\x00\x00\x10\x00\x00\x00\x10\x04\x03\x00\x00\x00\xED\xDD\xE2"
"\x52\x00\x00\x00\x30\x50\x4C\x54\x45\x03\x8B\xD3\x5C\xB4\xE3\x9C"
"\xD1\xED\xF7\xFB\xFD\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\xD3\xF2\x42\x61\x00\x00\x00"
"\x4B\x49\x44\x41\x54\x78\x9C\x2D\xCA\xC1\x0D\x80\x30\x0C\x43\x51"
"\x27\x2C\x50\x89\x05\x40\x2C\x40\xEB\xFD\x77\xC3\x76\xC9\xE9\xEB"
"\xC5\x20\x5F\xE8\x1A\x0F\x97\xA3\xD0\xE4\x1D\xF9\x49\xD1\x59\x29"
"\x4C\x43\x9B\xD0\x15\x01\xB5\x4A\x9C\xE4\x70\x14\x39\xB3\x31\xF8"
"\x15\x70\x04\xF4\xDA\x20\x39\x02\x8A\x0D\xA8\x0F\x94\xA7\x09\x0E"
"\xC5\x16\x2D\x54\x00\x00\x00\x00\x49\x45\x4E\x44\xAE\x42\x60\x82")
# -----------------------------------------------------------------------
class VirusTotalConfig(object):
def __init__(self):
self.Default()
def Default(self):
self.md5sum = GetInputMD5()
self.infile = idaapi.dbg_get_input_path()
if not self.infile:
self.infile = ""
# Persistent options
self.apikey = ""
self.options = 1 | 2
def Read(self):
"""
Read configuration from file
"""
if not os.path.exists(VT_CFGFILE):
return
f = open(VT_CFGFILE, 'r')
lines = f.readlines()
for i, line in enumerate(lines):
line = line.strip()
if i == 0:
self.apikey = line
elif i == 1:
self.options = int(line)
else:
break
def Write(self):
"""
Write configuration to file
"""
lines = (self.apikey.strip(), str(self.options))
try:
f = open(VT_CFGFILE, 'w')
f.write("\n".join(lines))
f.close()
except:
pass
# -----------------------------------------------------------------------
def VtReport(apikey, filename=None, md5sum=None):
if filename is None and md5sum is None:
return (False, "No parameters passed!")
# Check filename existance
if filename is not None and not os.path.exists(filename):
return (False, "Input file '%s' does not exist!" % filename)
#print("fn=%s md5=%s" % (filename, md5sum))
# Get file report from VirusTotal
try:
vt.set_apikey(apikey)
result = vt.get_file_report(filename=filename, md5sum=md5sum)
except Exception as e:
return (False, "Exception:\n%s" % str(e))
# Already analyzed?
if result is not None:
# Transform the results
items = []
for av, mwname in result.items():
mwname = str(mwname) if mwname else "n/a"
av = str(av)
items.append([av, mwname])
result = items
return (True, result)
# -----------------------------------------------------------------------
class VirusTotalChooser(Choose2):
"""
Chooser class to display results from VT
"""
def __init__(self, title, items, icon, embedded=False):
Choose2.__init__(self,
title,
[ ["Antivirus", 20], ["Result", 40] ],
embedded=embedded)
self.items = items
self.icon = icon
def GetItems(self):
return self.items
def SetItems(self, items):
self.items = [] if items is None else items
def OnClose(self):
pass
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnSelectLine(self, n):
# Google search for the malware name and the antivirus name
s = urllib.urlencode({"q" : " ".join(self.items[n])})
webbrowser.open_new_tab("http://www.google.com/search?%s" % s)
# --------------------------------------------------------------------------
class VirusTotalForm(Form):
def __init__(self, icon):
self.EChooser = VirusTotalChooser("E1", [], icon, embedded=True)
Form.__init__(self, r"""STARTITEM {id:txtInput}
VirusTotal - IDAPython plugin v1.0 (c) Hex-Rays
{FormChangeCb}
<#API key#~A~pi key:{txtApiKey}>
Options:
<#Open results in a chooser when form closes#~P~opout results on close:{rOptRemember}>
<#Use MD5 checksum#~M~D5Sum:{rOptMD5}>
<#Use file on disk#~F~ile:{rOptFile}>{grpOptions}>
<#Type input (file or MD5 string)#~I~nput:{txtInput}>
<Results:{cEChooser}>
<#Get reports from VT#~R~eport:{btnReport}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'txtApiKey' : Form.StringInput(swidth=80),
'grpOptions' : Form.ChkGroupControl(("rOptRemember", "rOptMD5", "rOptFile")),
'txtInput' : Form.FileInput(open=True),
'btnReport' : Form.ButtonInput(self.OnReportClick),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnReportClick(self, code=0):
pass
def OnFormChange(self, fid):
if fid == self.rOptMD5.id or fid == self.rOptFile.id:
input = (self.cfg.md5sum, self.cfg.infile)
if fid == self.rOptMD5.id:
c1 = self.rOptMD5
c2 = self.rOptFile
idx = 0
else:
c1 = self.rOptFile
c2 = self.rOptMD5
idx = 1
v = not self.GetControlValue(c1)
if v: idx = not idx
# Uncheck the opposite input type
self.SetControlValue(c2, v)
# Set input field depending on input type
self.SetControlValue(self.txtInput, input[idx])
#
# Report button
#
elif fid == self.btnReport.id:
input = self.GetControlValue(self.txtInput)
as_file = self.GetControlValue(self.rOptFile)
apikey = self.GetControlValue(self.txtApiKey)
ok, r = VtReport(self.cfg.apikey,
filename=input if as_file else None,
md5sum=None if as_file else input)
# Error?
if not ok:
idc.Warning(r)
return 1
# Pass the result
self.EChooser.SetItems(r)
# We have results and it was a file? Print its MD5
if r and as_file:
print("%s: %s" % (vt.LAST_FILE_HASH, input))
# Refresh the embedded chooser control
# (Could also clear previous results if not were retrieved during this run)
self.RefreshField(self.cEChooser)
# Store the input for the caller
self.cfg.input = input
# No results and file as input was supplied?
if r is None:
if as_file:
# Propose to upload
if idc.AskYN(0, "HIDECANCEL\nNo previous results. Do you want to submit the file:\n\n'%s'\n\nto VirusTotal?" % input) == 0:
return 1
try:
r = vt.scan_file(input)
except Exception as e:
idc.Warning("Exceptio during upload: %s" % str(e))
else:
if r is None:
idc.Warning("Failed to upload the file!")
else:
idc.Warning("File uploaded. Check again later to get the analysis report. Scan id: %s" % r)
else:
idc.Warning("No results found for hash: %s" % input)
return 1
def Show(self, cfg):
# Compile the form once
if not self.Compiled():
_, args = self.Compile()
#print args[0]
# Populate the form
self.txtApiKey.value = cfg.apikey
self.grpOptions.value = cfg.options
self.txtInput.value = cfg.infile if self.rOptFile.checked else cfg.md5sum
# Remember the config
self.cfg = cfg
# Execute the form
ok = self.Execute()
# Forget the cfg
del self.cfg
# Success?
if ok != 0:
# Update config
cfg.options = self.grpOptions.value
cfg.apikey = self.txtApiKey.value
# Popup results?
if self.rOptRemember.checked:
ok = 2
return ok
# -----------------------------------------------------------------------
class VirusTotalPlugin_t(plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "VirusTotal plugin for IDA"
help = ""
wanted_name = "VirusTotal report"
wanted_hotkey = "Alt-F8"
def init(self):
# Some initialization
self.icon_id = 0
return idaapi.PLUGIN_OK
def run(self, arg=0):
# Load icon from the memory and save its id
self.icon_id = idaapi.load_custom_icon(data=VT_ICON, format="png")
if self.icon_id == 0:
raise RuntimeError("Failed to load icon data!")
# Create config object
cfg = VirusTotalConfig()
# Read previous config
cfg.Read()
# Create form
f = VirusTotalForm(self.icon_id)
# Show the form
ok = f.Show(cfg)
if ok == 0:
f.Free()
return
# Save configuration
cfg.Write()
# Spawn a non-modal chooser w/ the results if any
if ok == 2 and f.EChooser.GetItems():
VirusTotalChooser(
"VirusTotal results [%s]" % cfg.input,
f.EChooser.GetItems(),
self.icon_id).Show()
f.Free()
return
def term(self):
# Free the custom icon
if self.icon_id != 0:
idaapi.free_custom_icon(self.icon_id)
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return VirusTotalPlugin_t()
# --------------------------------------------------------------------------
if PLUGIN_TEST:
# Create form
f = PLUGIN_ENTRY()
f.init()
f.run()
f.term()

View File

@@ -1,68 +1,68 @@
"""
User contributed script: MSDN API HELP plugin
This script fetches the API reference (from MSDN) of a given highlighted identifier
and returns the results in a new web browser page.
This script depends on the feedparser package: http://code.google.com/p/feedparser/
10/05/2010
- initial version
"""
import idaapi
# -----------------------------------------------------------------------
class msdnapihelp_plugin_t(idaapi.plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "Online MSDN API Help"
help = "Help me"
wanted_name = "MSDN API Help"
wanted_hotkey = "F3"
def init(self):
return idaapi.PLUGIN_OK
@staticmethod
def sanitize_name(name):
t = idaapi.FUNC_IMPORT_PREFIX
if name.startswith(t):
return name[len(t):]
return name
def run(self, arg):
# Get the highlighted identifier
id = idaapi.get_highlighted_identifier()
if not id:
print "No identifier was highlighted"
return
import webbrowser
try:
import feedparser
except:
idaapi.warning('Feedparser package not installed')
return
id = self.sanitize_name(id)
print "Looking up '%s' in MSDN online" % id
d = feedparser.parse("http://social.msdn.microsoft.com/Search/Feed.aspx?locale=en-us&format=RSS&Query=%s" % id)
if len(d['entries']) > 0:
url = d['entries'][0].link
webbrowser.open_new_tab(url)
else:
print "API documentation not found for: %s" % id
def term(self):
pass
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return msdnapihelp_plugin_t()
"""
User contributed script: MSDN API HELP plugin
This script fetches the API reference (from MSDN) of a given highlighted identifier
and returns the results in a new web browser page.
This script depends on the feedparser package: http://code.google.com/p/feedparser/
10/05/2010
- initial version
"""
import idaapi
# -----------------------------------------------------------------------
class msdnapihelp_plugin_t(idaapi.plugin_t):
flags = idaapi.PLUGIN_UNL
comment = "Online MSDN API Help"
help = "Help me"
wanted_name = "MSDN API Help"
wanted_hotkey = "F3"
def init(self):
return idaapi.PLUGIN_OK
@staticmethod
def sanitize_name(name):
t = idaapi.FUNC_IMPORT_PREFIX
if name.startswith(t):
return name[len(t):]
return name
def run(self, arg):
# Get the highlighted identifier
id = idaapi.get_highlighted_identifier()
if not id:
print "No identifier was highlighted"
return
import webbrowser
try:
import feedparser
except:
idaapi.warning('Feedparser package not installed')
return
id = self.sanitize_name(id)
print "Looking up '%s' in MSDN online" % id
d = feedparser.parse("http://social.msdn.microsoft.com/Search/Feed.aspx?locale=en-us&format=RSS&Query=%s" % id)
if len(d['entries']) > 0:
url = d['entries'][0].link
webbrowser.open_new_tab(url)
else:
print "API documentation not found for: %s" % id
def term(self):
pass
# -----------------------------------------------------------------------
def PLUGIN_ENTRY():
return msdnapihelp_plugin_t()

View File

@@ -1,4 +1,4 @@
#ifndef _BASETSD_H
#define _BASETSD_H
/* Microsoft free compilers seem to lack this file and Python needs it */
#endif
#ifndef _BASETSD_H
#define _BASETSD_H
/* Microsoft free compilers seem to lack this file and Python needs it */
#endif

View File

@@ -24,7 +24,7 @@ from distutils import sysconfig
VERBOSE = True
IDA_MAJOR_VERSION = 6
IDA_MINOR_VERSION = 7
IDA_MINOR_VERSION = 8
if 'IDA' in os.environ:
IDA_SDK = os.environ['IDA']
@@ -40,7 +40,7 @@ else:
# IDAPython version
VERSION_MAJOR = 1
VERSION_MINOR = 7
VERSION_PATCH = 1
VERSION_PATCH = 0
# Determine Python version
PYTHON_MAJOR_VERSION = int(platform.python_version()[0])

View File

@@ -1,53 +1,53 @@
Assorted notes
--------------
Wrapped functions and constants:
All the symbols from the idaapi module are listed in symbollist.txt.
Documentation for the plugin API functions functions is in the IDA
SDK header files. All function and symbol names directly translate
to the C++ counterparts. If you try to use a function that is not
wrapped yet you will get an exception like this:
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: name 'foobar' is not defined
If this happens you can check the function in symbollist.txt. If it
is not included and it should be please report it to the author.
Data types:
All the C++ data types are mapped to corresponding Python data types.
For example ea_t maps to a Python integer. Complex data types (like
structures and classes) are mapped to Python classes that have the
same attributes as the original type.
Arguments and return values:
Generally all function arguments should be the same type as specified
by the original headers. Pointers to complex types (structures, classes)
are checked and must match the original declarations.
For example comment = get_func_comment("aa", 0) will raise an exception:
Traceback (most recent call last):
File "<string>", line 1, in ?
TypeError: Type error. Got aa, expected _p_func_t
When calling functions that return a string in a buffer (usually with
maximum size) the buffer and size parameter is omitted. These functions
return either the result in a string or None if the call fails and returns
NULL. The output buffers are maximized at MAXSTR.
Example:
C++: get_func_name(0x1234, buf, sizeof(buf));
Python: name = get_func_name(0x1234)
Any function that should return a char * is going to return either a
Python string (up to MAXSTR) or None.
Assorted notes
--------------
Wrapped functions and constants:
All the symbols from the idaapi module are listed in symbollist.txt.
Documentation for the plugin API functions functions is in the IDA
SDK header files. All function and symbol names directly translate
to the C++ counterparts. If you try to use a function that is not
wrapped yet you will get an exception like this:
Traceback (most recent call last):
File "<string>", line 1, in ?
NameError: name 'foobar' is not defined
If this happens you can check the function in symbollist.txt. If it
is not included and it should be please report it to the author.
Data types:
All the C++ data types are mapped to corresponding Python data types.
For example ea_t maps to a Python integer. Complex data types (like
structures and classes) are mapped to Python classes that have the
same attributes as the original type.
Arguments and return values:
Generally all function arguments should be the same type as specified
by the original headers. Pointers to complex types (structures, classes)
are checked and must match the original declarations.
For example comment = get_func_comment("aa", 0) will raise an exception:
Traceback (most recent call last):
File "<string>", line 1, in ?
TypeError: Type error. Got aa, expected _p_func_t
When calling functions that return a string in a buffer (usually with
maximum size) the buffer and size parameter is omitted. These functions
return either the result in a string or None if the call fails and returns
NULL. The output buffers are maximized at MAXSTR.
Example:
C++: get_func_name(0x1234, buf, sizeof(buf));
Python: name = get_func_name(0x1234)
Any function that should return a char * is going to return either a
Python string (up to MAXSTR) or None.

View File

@@ -1,50 +1,50 @@
#---------------------------------------------------------------------
# Chooser test
#
# This script demonstrates the usage of the class-based chooser.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
from idaapi import Choose
#
# Modal chooser
#
# Get a modal Choose instance
chooser = Choose([], "MyChooser", 1)
# List to choose from
chooser.list = [ "First", "Second", "Third" ]
# Set the width
chooser.width = 50
# Run the chooser
ch = chooser.choose()
# Print the results
if ch > 0:
print "You chose %d which is %s" % (ch, chooser.list[ch-1])
else:
print "Escape from chooser"
#
# Normal chooser
#
class MyChoose(Choose):
"""
You have to subclass Chooser to override the enter() method
"""
def __init__(self, list=[], name="Choose"):
Choose.__init__(self, list, name)
# Set the width
self.width = 50
self.deflt = 1
def enter(self, n):
print "Enter called. Do some stuff here."
print "The chosen item is %d = %s" % (n, self.list[n-1])
print "Now press ESC to leave."
# Get a Choose instance
chooser = MyChoose([ "First", "Second", "Third" ], "MyChoose")
# Run the chooser
ch = chooser.choose()
#---------------------------------------------------------------------
# Chooser test
#
# This script demonstrates the usage of the class-based chooser.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
from idaapi import Choose
#
# Modal chooser
#
# Get a modal Choose instance
chooser = Choose([], "MyChooser", 1)
# List to choose from
chooser.list = [ "First", "Second", "Third" ]
# Set the width
chooser.width = 50
# Run the chooser
ch = chooser.choose()
# Print the results
if ch > 0:
print "You chose %d which is %s" % (ch, chooser.list[ch-1])
else:
print "Escape from chooser"
#
# Normal chooser
#
class MyChoose(Choose):
"""
You have to subclass Chooser to override the enter() method
"""
def __init__(self, list=[], name="Choose"):
Choose.__init__(self, list, name)
# Set the width
self.width = 50
self.deflt = 1
def enter(self, n):
print "Enter called. Do some stuff here."
print "The chosen item is %d = %s" % (n, self.list[n-1])
print "Now press ESC to leave."
# Get a Choose instance
chooser = MyChoose([ "First", "Second", "Third" ], "MyChoose")
# Run the chooser
ch = chooser.choose()

View File

@@ -1,19 +1,19 @@
#---------------------------------------------------------------------
# Colour test
#
# This script demonstrates the usage of background colours.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
# Set the colour of the current segment to BLUE
SetColor(here(), CIC_SEGM, 0xc02020)
# Set the colour of the current function to GREEN
SetColor(here(), CIC_FUNC, 0x208020)
# Set the colour of the current item to RED
SetColor(here(), CIC_ITEM, 0x2020c0)
# Print the colours just set
print "%x" % GetColor(here(), CIC_SEGM)
print "%x" % GetColor(here(), CIC_FUNC)
print "%x" % GetColor(here(), CIC_ITEM)
#---------------------------------------------------------------------
# Colour test
#
# This script demonstrates the usage of background colours.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
# Set the colour of the current segment to BLUE
SetColor(here(), CIC_SEGM, 0xc02020)
# Set the colour of the current function to GREEN
SetColor(here(), CIC_FUNC, 0x208020)
# Set the colour of the current item to RED
SetColor(here(), CIC_ITEM, 0x2020c0)
# Print the colours just set
print "%x" % GetColor(here(), CIC_SEGM)
print "%x" % GetColor(here(), CIC_FUNC)
print "%x" % GetColor(here(), CIC_ITEM)

View File

@@ -1,107 +1,107 @@
#---------------------------------------------------------------------
# Debug notification hook test
#
# This script start the executable and steps through the first five
# instructions. Each instruction is disassembled after execution.
#
# Original Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#
# Maintained By: IDAPython Team
#
#---------------------------------------------------------------------
from idaapi import *
class MyDbgHook(DBG_Hooks):
""" Own debug hook class that implementd the callback functions """
def dbg_process_start(self, pid, tid, ea, name, base, size):
print("Process started, pid=%d tid=%d name=%s" % (pid, tid, name))
def dbg_process_exit(self, pid, tid, ea, code):
print("Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code))
def dbg_library_unload(self, pid, tid, ea, info):
print("Library unloaded: pid=%d tid=%d ea=0x%x info=%s" % (pid, tid, ea, info))
return 0
def dbg_process_attach(self, pid, tid, ea, name, base, size):
print("Process attach pid=%d tid=%d ea=0x%x name=%s base=%x size=%x" % (pid, tid, ea, name, base, size))
def dbg_process_detach(self, pid, tid, ea):
print("Process detached, pid=%d tid=%d ea=0x%x" % (pid, tid, ea))
return 0
def dbg_library_load(self, pid, tid, ea, name, base, size):
print "Library loaded: pid=%d tid=%d name=%s base=%x" % (pid, tid, name, base)
def dbg_bpt(self, tid, ea):
print "Break point at 0x%x pid=%d" % (ea, tid)
# return values:
# -1 - to display a breakpoint warning dialog
# if the process is suspended.
# 0 - to never display a breakpoint warning dialog.
# 1 - to always display a breakpoint warning dialog.
return 0
def dbg_suspend_process(self):
print "Process suspended"
def dbg_exception(self, pid, tid, ea, exc_code, exc_can_cont, exc_ea, exc_info):
print("Exception: pid=%d tid=%d ea=0x%x exc_code=0x%x can_continue=%d exc_ea=0x%x exc_info=%s" % (
pid, tid, ea, exc_code & idaapi.BADADDR, exc_can_cont, exc_ea, exc_info))
# return values:
# -1 - to display an exception warning dialog
# if the process is suspended.
# 0 - to never display an exception warning dialog.
# 1 - to always display an exception warning dialog.
return 0
def dbg_trace(self, tid, ea):
print("Trace tid=%d ea=0x%x" % (tid, ea))
# return values:
# 1 - do not log this trace event;
# 0 - log it
return 0
def dbg_step_into(self):
print("Step into")
self.dbg_step_over()
def dbg_run_to(self, pid, tid=0, ea=0):
print "Runto: tid=%d" % tid
idaapi.continue_process()
def dbg_step_over(self):
eip = GetRegValue("EIP")
print("0x%x %s" % (eip, GetDisasm(eip)))
self.steps += 1
if self.steps >= 5:
request_exit_process()
else:
request_step_over()
# Remove an existing debug hook
try:
if debughook:
print("Removing previous hook ...")
debughook.unhook()
except:
pass
# Install the debug hook
debughook = MyDbgHook()
debughook.hook()
debughook.steps = 0
# Stop at the entry point
ep = GetLongPrm(INF_START_IP)
request_run_to(ep)
# Step one instruction
request_step_over()
# Start debugging
run_requests()
#---------------------------------------------------------------------
# Debug notification hook test
#
# This script start the executable and steps through the first five
# instructions. Each instruction is disassembled after execution.
#
# Original Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#
# Maintained By: IDAPython Team
#
#---------------------------------------------------------------------
from idaapi import *
class MyDbgHook(DBG_Hooks):
""" Own debug hook class that implementd the callback functions """
def dbg_process_start(self, pid, tid, ea, name, base, size):
print("Process started, pid=%d tid=%d name=%s" % (pid, tid, name))
def dbg_process_exit(self, pid, tid, ea, code):
print("Process exited pid=%d tid=%d ea=0x%x code=%d" % (pid, tid, ea, code))
def dbg_library_unload(self, pid, tid, ea, info):
print("Library unloaded: pid=%d tid=%d ea=0x%x info=%s" % (pid, tid, ea, info))
return 0
def dbg_process_attach(self, pid, tid, ea, name, base, size):
print("Process attach pid=%d tid=%d ea=0x%x name=%s base=%x size=%x" % (pid, tid, ea, name, base, size))
def dbg_process_detach(self, pid, tid, ea):
print("Process detached, pid=%d tid=%d ea=0x%x" % (pid, tid, ea))
return 0
def dbg_library_load(self, pid, tid, ea, name, base, size):
print "Library loaded: pid=%d tid=%d name=%s base=%x" % (pid, tid, name, base)
def dbg_bpt(self, tid, ea):
print "Break point at 0x%x pid=%d" % (ea, tid)
# return values:
# -1 - to display a breakpoint warning dialog
# if the process is suspended.
# 0 - to never display a breakpoint warning dialog.
# 1 - to always display a breakpoint warning dialog.
return 0
def dbg_suspend_process(self):
print "Process suspended"
def dbg_exception(self, pid, tid, ea, exc_code, exc_can_cont, exc_ea, exc_info):
print("Exception: pid=%d tid=%d ea=0x%x exc_code=0x%x can_continue=%d exc_ea=0x%x exc_info=%s" % (
pid, tid, ea, exc_code & idaapi.BADADDR, exc_can_cont, exc_ea, exc_info))
# return values:
# -1 - to display an exception warning dialog
# if the process is suspended.
# 0 - to never display an exception warning dialog.
# 1 - to always display an exception warning dialog.
return 0
def dbg_trace(self, tid, ea):
print("Trace tid=%d ea=0x%x" % (tid, ea))
# return values:
# 1 - do not log this trace event;
# 0 - log it
return 0
def dbg_step_into(self):
print("Step into")
self.dbg_step_over()
def dbg_run_to(self, pid, tid=0, ea=0):
print "Runto: tid=%d" % tid
idaapi.continue_process()
def dbg_step_over(self):
eip = GetRegValue("EIP")
print("0x%x %s" % (eip, GetDisasm(eip)))
self.steps += 1
if self.steps >= 5:
request_exit_process()
else:
request_step_over()
# Remove an existing debug hook
try:
if debughook:
print("Removing previous hook ...")
debughook.unhook()
except:
pass
# Install the debug hook
debughook = MyDbgHook()
debughook.hook()
debughook.steps = 0
# Stop at the entry point
ep = GetLongPrm(INF_START_IP)
request_run_to(ep)
# Step one instruction
request_step_over()
# Start debugging
run_requests()

View File

@@ -1,35 +1,35 @@
//
// Reference Lister
//
// List all functions and all references to them in the current section.
//
// Implemented in IDC
//
#include <idc.idc>
static main()
{
auto ea, func, ref;
// Get current ea
ea = ScreenEA();
// Loop from start to end in the current segment
for (func=SegStart(ea);
func != BADADDR && func < SegEnd(ea);
func=NextFunction(func))
{
// If the current address is function process it
if (GetFunctionFlags(func) != -1)
{
Message("Function %s at 0x%x\n", GetFunctionName(func), func);
// Find all code references to func
for (ref=RfirstB(func); ref != BADADDR; ref=RnextB(func, ref))
{
Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref);
}
}
}
}
//
// Reference Lister
//
// List all functions and all references to them in the current section.
//
// Implemented in IDC
//
#include <idc.idc>
static main()
{
auto ea, func, ref;
// Get current ea
ea = ScreenEA();
// Loop from start to end in the current segment
for (func=SegStart(ea);
func != BADADDR && func < SegEnd(ea);
func=NextFunction(func))
{
// If the current address is function process it
if (GetFunctionFlags(func) != -1)
{
Message("Function %s at 0x%x\n", GetFunctionName(func), func);
// Find all code references to func
for (ref=RfirstB(func); ref != BADADDR; ref=RnextB(func, ref))
{
Message(" called from %s(0x%x)\n", GetFunctionName(ref), ref);
}
}
}
}

View File

@@ -1,379 +1,379 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use the Form class
# (c) Hex-Rays
#
from idaapi import Form
#<pycode(ex_askusingform)>
# --------------------------------------------------------------------------
class TestEmbeddedChooserClass(Choose2):
"""
A simple chooser to be used as an embedded chooser
"""
def __init__(self, title, nb = 5, flags=0):
Choose2.__init__(self,
title,
[ ["Address", 10], ["Name", 30] ],
embedded=True, width=30, height=20, flags=flags)
self.n = 0
self.items = [ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnClose(self):
pass
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
print("getsize -> %d" % n)
return n
# --------------------------------------------------------------------------
class MyForm(Form):
def __init__(self):
self.invert = False
self.EChooser = TestEmbeddedChooserClass("E1", flags=Choose2.CH_MULTI)
Form.__init__(self, r"""STARTITEM {id:rNormal}
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL Nevermind
Form Test
{FormChangeCb}
This is a string: +{cStr1}+
This is an address: +{cAddr1}+
Escape\{control}
This is a string: '{cStr2}'
This is a number: {cVal1}
<#Hint1#Enter name:{iStr1}>
<#Hint2#Select color:{iColor1}>
Browse test
<#Select a file to open#Browse to open:{iFileOpen}>
<#Select a file to save#Browse to save:{iFileSave}>
<#Select dir#Browse for dir:{iDir}>
Type
<#Select type#Write a type:{iType}>
Numbers
<##Enter a selector value:{iSegment}>
<##Enter a raw hex:{iRawHex}>
<##Enter a character:{iChar}>
<##Enter an address:{iAddr}>
Button test
<##Button1:{iButton1}> <##Button2:{iButton2}>
Check boxes:
<Error output:{rError}>
<Normal output:{rNormal}>
<Warnings:{rWarnings}>{cGroup1}>
Radio boxes:
<Green:{rGreen}>
<Red:{rRed}>
<Blue:{rBlue}>{cGroup2}>
<Embedded chooser:{cEChooser}>
The end!
""", {
'cStr1': Form.StringLabel("Hello"),
'cStr2': Form.StringLabel("StringTest"),
'cAddr1': Form.NumericLabel(0x401000, Form.FT_ADDR),
'cVal1' : Form.NumericLabel(99, Form.FT_HEX),
'iStr1': Form.StringInput(),
'iColor1': Form.ColorInput(),
'iFileOpen': Form.FileInput(open=True),
'iFileSave': Form.FileInput(save=True),
'iDir': Form.DirInput(),
'iType': Form.StringInput(tp=Form.FT_TYPE),
'iSegment': Form.NumericInput(tp=Form.FT_SEG),
'iRawHex': Form.NumericInput(tp=Form.FT_RAWHEX),
'iAddr': Form.NumericInput(tp=Form.FT_ADDR),
'iChar': Form.NumericInput(tp=Form.FT_CHAR),
'iButton1': Form.ButtonInput(self.OnButton1),
'iButton2': Form.ButtonInput(self.OnButton2),
'cGroup1': Form.ChkGroupControl(("rNormal", "rError", "rWarnings")),
'cGroup2': Form.RadGroupControl(("rRed", "rGreen", "rBlue")),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnButton1(self, code=0):
print("Button1 pressed")
def OnButton2(self, code=0):
print("Button2 pressed")
def OnFormChange(self, fid):
if fid == self.iButton1.id:
print("Button1 fchg;inv=%s" % self.invert)
self.SetFocusedField(self.rNormal)
self.EnableField(self.rError, self.invert)
self.invert = not self.invert
elif fid == self.iButton2.id:
g1 = self.GetControlValue(self.cGroup1)
g2 = self.GetControlValue(self.cGroup2)
d = self.GetControlValue(self.iDir)
f = self.GetControlValue(self.iFileOpen)
print("cGroup2:%x;Dir=%s;fopen=%s;cGroup1:%x" % (g1, d, f, g2))
elif fid == self.cEChooser.id:
l = self.GetControlValue(self.cEChooser)
print("Chooser: %s" % l)
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def stdalone_main():
f = MyForm()
f, args = f.Compile()
print args[0]
print args[1:]
f.rNormal.checked = True
f.rWarnings.checked = True
print hex(f.cGroup1.value)
f.rGreen.selected = True
print f.cGroup2.value
print "Title: '%s'" % f.title
f.Free()
# --------------------------------------------------------------------------
def ida_main():
# Create form
global f
f = MyForm()
# Compile (in order to populate the controls)
f.Compile()
f.iColor1.value = 0x5bffff
f.iDir.value = os.getcwd()
f.rNormal.checked = True
f.rWarnings.checked = True
f.rGreen.selected = True
f.iStr1.value = "Hello"
f.iFileSave.value = "*.*"
f.iFileOpen.value = "*.*"
# Execute the form
ok = f.Execute()
print("r=%d" % ok)
if ok == 1:
print("f.str1=%s" % f.iStr1.value)
print("f.color1=%x" % f.iColor1.value)
print("f.openfile=%s" % f.iFileOpen.value)
print("f.savefile=%s" % f.iFileSave.value)
print("f.dir=%s" % f.iDir.value)
print("f.type=%s" % f.iType.value)
print("f.seg=%s" % f.iSegment.value)
print("f.rawhex=%x" % f.iRawHex.value)
print("f.char=%x" % f.iChar.value)
print("f.addr=%x" % f.iAddr.value)
print("f.cGroup1=%x" % f.cGroup1.value)
print("f.cGroup2=%x" % f.cGroup2.value)
sel = f.EChooser.GetEmbSelection()
if sel is None:
print("No selection")
else:
print("Selection: %s" % sel)
# Dispose the form
f.Free()
# --------------------------------------------------------------------------
def ida_main_legacy():
# Here we simply show how to use the old style form format using Python
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box for %A
using address %$
<~E~nter value:N:32:16::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
num = Form.NumericArgument('N', value=123)
ok = idaapi.AskUsingForm(s,
Form.StringArgument("PyAskUsingForm").arg,
Form.NumericArgument('$', 0x401000).arg,
num.arg)
if ok == 1:
print("You entered: %x" % num.value)
# --------------------------------------------------------------------------
def test_multilinetext_legacy():
# Here we text the multi line text control in legacy mode
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box
<Enter multi line text:t40:80:50::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
ti = textctrl_info_t("Some initial value")
ok = idaapi.AskUsingForm(s, pointer(c_void_p.from_address(ti.clink_ptr)))
if ok == 1:
print("You entered: %s" % ti.text)
del ti
# --------------------------------------------------------------------------
class MyForm2(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
Form.__init__(self, r"""STARTITEM 0
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Form Test
{FormChangeCb}
<Multilinetext:{txtMultiLineText}>
""", {
'txtMultiLineText': Form.MultiLineTextControl(text="Hello"),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
})
def OnFormChange(self, fid):
if fid == self.txtMultiLineText.id:
pass
elif fid == -2:
ti = self.GetControlValue(self.txtMultiLineText)
print "ti.text = %s" % ti.text
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def test_multilinetext(execute=True):
"""Test the multilinetext and combobox controls"""
f = MyForm2()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
assert f.txtMultiLineText.text == f.txtMultiLineText.value
print f.txtMultiLineText.text
f.Free()
# --------------------------------------------------------------------------
class MyForm3(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
self.__n = 0
Form.__init__(self,
r"""BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Dropdown list test
{FormChangeCb}
<Dropdown list (readonly):{cbReadonly}> <Add element:{iButtonAddelement}> <Set index:{iButtonSetIndex}>
<Dropdown list (editable):{cbEditable}> <Set string:{iButtonSetString}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cbReadonly': Form.DropdownListControl(
items=["red", "green", "blue"],
readonly=True,
selval=1),
'cbEditable': Form.DropdownListControl(
items=["1MB", "2MB", "3MB", "4MB"],
readonly=False,
selval="4MB"),
'iButtonAddelement': Form.ButtonInput(self.OnButtonNop),
'iButtonSetIndex': Form.ButtonInput(self.OnButtonNop),
'iButtonSetString': Form.ButtonInput(self.OnButtonNop),
})
def OnButtonNop(self, code=0):
"""Do nothing, we will handle events in the form callback"""
pass
def OnFormChange(self, fid):
if fid == self.iButtonSetString.id:
s = idc.AskStr("none", "Enter value")
if s:
self.SetControlValue(self.cbEditable, s)
elif fid == self.iButtonSetIndex.id:
s = idc.AskStr("1", "Enter index value:")
if s:
try:
i = int(s)
except:
i = 0
self.SetControlValue(self.cbReadonly, i)
elif fid == self.iButtonAddelement.id:
# add a value to the string list
self.__n += 1
self.cbReadonly.add("some text #%d" % self.__n)
# Refresh the control
self.RefreshField(self.cbReadonly)
elif fid == -2:
s = self.GetControlValue(self.cbEditable)
print "user entered: %s" % s
sel_idx = self.GetControlValue(self.cbReadonly)
return 1
# --------------------------------------------------------------------------
def test_dropdown(execute=True):
"""Test the combobox controls, in a modal dialog"""
f = MyForm3()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
print "Editable: %s" % f.cbEditable.value
print "Readonly: %s" % f.cbReadonly.value
f.Free()
# --------------------------------------------------------------------------
tdn_form = None
def test_dropdown_nomodal():
"""Test the combobox controls, in a non-modal form"""
global tdn_form
if tdn_form is None:
tdn_form = MyForm3()
tdn_form.modal = False
tdn_form.openform_flags = idaapi.PluginForm.FORM_TAB
tdn_form, _ = tdn_form.Compile()
tdn_form.Open()
#</pycode(ex_askusingform)>
# --------------------------------------------------------------------------
ida_main()
# -----------------------------------------------------------------------
# This is an example illustrating how to use the Form class
# (c) Hex-Rays
#
from idaapi import Form
#<pycode(ex_askusingform)>
# --------------------------------------------------------------------------
class TestEmbeddedChooserClass(Choose2):
"""
A simple chooser to be used as an embedded chooser
"""
def __init__(self, title, nb = 5, flags=0):
Choose2.__init__(self,
title,
[ ["Address", 10], ["Name", 30] ],
embedded=True, width=30, height=20, flags=flags)
self.n = 0
self.items = [ self.make_item() for x in xrange(0, nb+1) ]
self.icon = 5
self.selcount = 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnClose(self):
pass
def OnGetLine(self, n):
print("getline %d" % n)
return self.items[n]
def OnGetSize(self):
n = len(self.items)
print("getsize -> %d" % n)
return n
# --------------------------------------------------------------------------
class MyForm(Form):
def __init__(self):
self.invert = False
self.EChooser = TestEmbeddedChooserClass("E1", flags=Choose2.CH_MULTI)
Form.__init__(self, r"""STARTITEM {id:rNormal}
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL Nevermind
Form Test
{FormChangeCb}
This is a string: +{cStr1}+
This is an address: +{cAddr1}+
Escape\{control}
This is a string: '{cStr2}'
This is a number: {cVal1}
<#Hint1#Enter name:{iStr1}>
<#Hint2#Select color:{iColor1}>
Browse test
<#Select a file to open#Browse to open:{iFileOpen}>
<#Select a file to save#Browse to save:{iFileSave}>
<#Select dir#Browse for dir:{iDir}>
Type
<#Select type#Write a type:{iType}>
Numbers
<##Enter a selector value:{iSegment}>
<##Enter a raw hex:{iRawHex}>
<##Enter a character:{iChar}>
<##Enter an address:{iAddr}>
Button test
<##Button1:{iButton1}> <##Button2:{iButton2}>
Check boxes:
<Error output:{rError}>
<Normal output:{rNormal}>
<Warnings:{rWarnings}>{cGroup1}>
Radio boxes:
<Green:{rGreen}>
<Red:{rRed}>
<Blue:{rBlue}>{cGroup2}>
<Embedded chooser:{cEChooser}>
The end!
""", {
'cStr1': Form.StringLabel("Hello"),
'cStr2': Form.StringLabel("StringTest"),
'cAddr1': Form.NumericLabel(0x401000, Form.FT_ADDR),
'cVal1' : Form.NumericLabel(99, Form.FT_HEX),
'iStr1': Form.StringInput(),
'iColor1': Form.ColorInput(),
'iFileOpen': Form.FileInput(open=True),
'iFileSave': Form.FileInput(save=True),
'iDir': Form.DirInput(),
'iType': Form.StringInput(tp=Form.FT_TYPE),
'iSegment': Form.NumericInput(tp=Form.FT_SEG),
'iRawHex': Form.NumericInput(tp=Form.FT_RAWHEX),
'iAddr': Form.NumericInput(tp=Form.FT_ADDR),
'iChar': Form.NumericInput(tp=Form.FT_CHAR),
'iButton1': Form.ButtonInput(self.OnButton1),
'iButton2': Form.ButtonInput(self.OnButton2),
'cGroup1': Form.ChkGroupControl(("rNormal", "rError", "rWarnings")),
'cGroup2': Form.RadGroupControl(("rRed", "rGreen", "rBlue")),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cEChooser' : Form.EmbeddedChooserControl(self.EChooser)
})
def OnButton1(self, code=0):
print("Button1 pressed")
def OnButton2(self, code=0):
print("Button2 pressed")
def OnFormChange(self, fid):
if fid == self.iButton1.id:
print("Button1 fchg;inv=%s" % self.invert)
self.SetFocusedField(self.rNormal)
self.EnableField(self.rError, self.invert)
self.invert = not self.invert
elif fid == self.iButton2.id:
g1 = self.GetControlValue(self.cGroup1)
g2 = self.GetControlValue(self.cGroup2)
d = self.GetControlValue(self.iDir)
f = self.GetControlValue(self.iFileOpen)
print("cGroup2:%x;Dir=%s;fopen=%s;cGroup1:%x" % (g1, d, f, g2))
elif fid == self.cEChooser.id:
l = self.GetControlValue(self.cEChooser)
print("Chooser: %s" % l)
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def stdalone_main():
f = MyForm()
f, args = f.Compile()
print args[0]
print args[1:]
f.rNormal.checked = True
f.rWarnings.checked = True
print hex(f.cGroup1.value)
f.rGreen.selected = True
print f.cGroup2.value
print "Title: '%s'" % f.title
f.Free()
# --------------------------------------------------------------------------
def ida_main():
# Create form
global f
f = MyForm()
# Compile (in order to populate the controls)
f.Compile()
f.iColor1.value = 0x5bffff
f.iDir.value = os.getcwd()
f.rNormal.checked = True
f.rWarnings.checked = True
f.rGreen.selected = True
f.iStr1.value = "Hello"
f.iFileSave.value = "*.*"
f.iFileOpen.value = "*.*"
# Execute the form
ok = f.Execute()
print("r=%d" % ok)
if ok == 1:
print("f.str1=%s" % f.iStr1.value)
print("f.color1=%x" % f.iColor1.value)
print("f.openfile=%s" % f.iFileOpen.value)
print("f.savefile=%s" % f.iFileSave.value)
print("f.dir=%s" % f.iDir.value)
print("f.type=%s" % f.iType.value)
print("f.seg=%s" % f.iSegment.value)
print("f.rawhex=%x" % f.iRawHex.value)
print("f.char=%x" % f.iChar.value)
print("f.addr=%x" % f.iAddr.value)
print("f.cGroup1=%x" % f.cGroup1.value)
print("f.cGroup2=%x" % f.cGroup2.value)
sel = f.EChooser.GetEmbSelection()
if sel is None:
print("No selection")
else:
print("Selection: %s" % sel)
# Dispose the form
f.Free()
# --------------------------------------------------------------------------
def ida_main_legacy():
# Here we simply show how to use the old style form format using Python
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box for %A
using address %$
<~E~nter value:N:32:16::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
num = Form.NumericArgument('N', value=123)
ok = idaapi.AskUsingForm(s,
Form.StringArgument("PyAskUsingForm").arg,
Form.NumericArgument('$', 0x401000).arg,
num.arg)
if ok == 1:
print("You entered: %x" % num.value)
# --------------------------------------------------------------------------
def test_multilinetext_legacy():
# Here we text the multi line text control in legacy mode
# Sample form from kernwin.hpp
s = """Sample dialog box
This is sample dialog box
<Enter multi line text:t40:80:50::>
"""
# Use either StringArgument or NumericArgument to pass values to the function
ti = textctrl_info_t("Some initial value")
ok = idaapi.AskUsingForm(s, pointer(c_void_p.from_address(ti.clink_ptr)))
if ok == 1:
print("You entered: %s" % ti.text)
del ti
# --------------------------------------------------------------------------
class MyForm2(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
Form.__init__(self, r"""STARTITEM 0
BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Form Test
{FormChangeCb}
<Multilinetext:{txtMultiLineText}>
""", {
'txtMultiLineText': Form.MultiLineTextControl(text="Hello"),
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
})
def OnFormChange(self, fid):
if fid == self.txtMultiLineText.id:
pass
elif fid == -2:
ti = self.GetControlValue(self.txtMultiLineText)
print "ti.text = %s" % ti.text
else:
print(">>fid:%d" % fid)
return 1
# --------------------------------------------------------------------------
def test_multilinetext(execute=True):
"""Test the multilinetext and combobox controls"""
f = MyForm2()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
assert f.txtMultiLineText.text == f.txtMultiLineText.value
print f.txtMultiLineText.text
f.Free()
# --------------------------------------------------------------------------
class MyForm3(Form):
"""Simple Form to test multilinetext and combo box controls"""
def __init__(self):
self.__n = 0
Form.__init__(self,
r"""BUTTON YES* Yeah
BUTTON NO Nope
BUTTON CANCEL NONE
Dropdown list test
{FormChangeCb}
<Dropdown list (readonly):{cbReadonly}> <Add element:{iButtonAddelement}> <Set index:{iButtonSetIndex}>
<Dropdown list (editable):{cbEditable}> <Set string:{iButtonSetString}>
""", {
'FormChangeCb': Form.FormChangeCb(self.OnFormChange),
'cbReadonly': Form.DropdownListControl(
items=["red", "green", "blue"],
readonly=True,
selval=1),
'cbEditable': Form.DropdownListControl(
items=["1MB", "2MB", "3MB", "4MB"],
readonly=False,
selval="4MB"),
'iButtonAddelement': Form.ButtonInput(self.OnButtonNop),
'iButtonSetIndex': Form.ButtonInput(self.OnButtonNop),
'iButtonSetString': Form.ButtonInput(self.OnButtonNop),
})
def OnButtonNop(self, code=0):
"""Do nothing, we will handle events in the form callback"""
pass
def OnFormChange(self, fid):
if fid == self.iButtonSetString.id:
s = idc.AskStr("none", "Enter value")
if s:
self.SetControlValue(self.cbEditable, s)
elif fid == self.iButtonSetIndex.id:
s = idc.AskStr("1", "Enter index value:")
if s:
try:
i = int(s)
except:
i = 0
self.SetControlValue(self.cbReadonly, i)
elif fid == self.iButtonAddelement.id:
# add a value to the string list
self.__n += 1
self.cbReadonly.add("some text #%d" % self.__n)
# Refresh the control
self.RefreshField(self.cbReadonly)
elif fid == -2:
s = self.GetControlValue(self.cbEditable)
print "user entered: %s" % s
sel_idx = self.GetControlValue(self.cbReadonly)
return 1
# --------------------------------------------------------------------------
def test_dropdown(execute=True):
"""Test the combobox controls, in a modal dialog"""
f = MyForm3()
f, args = f.Compile()
if execute:
ok = f.Execute()
else:
print args[0]
print args[1:]
ok = 0
if ok == 1:
print "Editable: %s" % f.cbEditable.value
print "Readonly: %s" % f.cbReadonly.value
f.Free()
# --------------------------------------------------------------------------
tdn_form = None
def test_dropdown_nomodal():
"""Test the combobox controls, in a non-modal form"""
global tdn_form
if tdn_form is None:
tdn_form = MyForm3()
tdn_form.modal = False
tdn_form.openform_flags = idaapi.PluginForm.FORM_TAB
tdn_form, _ = tdn_form.Compile()
tdn_form.Open()
#</pycode(ex_askusingform)>
# --------------------------------------------------------------------------
ida_main()

View File

@@ -1,133 +1,133 @@
import idaapi
from idaapi import Choose2
#<pycode(py_choose2ex1)>
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))
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", 10], ["Name", 30] ],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = [ 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
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 -> %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) >= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print("getlineattr %d" % n)
if n == 1:
return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Choose2 - sample 1", nb=10, modal=modal)
r = c.show()
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("Choose2 - embedded", 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()
# -----------------------------------------------------------------------
if __name__ == '__main__':
# Register actions
for thing in ["A", "B"]:
actname = "choose2:act%s" % thing
idaapi.register_action(
idaapi.action_desc_t(
actname,
"command %s" % thing,
chooser_handler_t(thing)))
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>
import idaapi
from idaapi import Choose2
#<pycode(py_choose2ex1)>
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))
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", 10], ["Name", 30] ],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = [ 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
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 -> %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) >= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print("getlineattr %d" % n)
if n == 1:
return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Choose2 - sample 1", nb=10, modal=modal)
r = c.show()
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("Choose2 - embedded", 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()
# -----------------------------------------------------------------------
if __name__ == '__main__':
# Register actions
for thing in ["A", "B"]:
actname = "choose2:act%s" % thing
idaapi.register_action(
idaapi.action_desc_t(
actname,
"command %s" % thing,
chooser_handler_t(thing)))
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>

View File

@@ -1,100 +1,100 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to implement a CLI
# (c) Hex-Rays
#
from idaapi import NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR, cli_t
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
lname = "Python CLI"
hint = "pycli hint"
def OnExecuteLine(self, line):
"""
The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
This callback is mandatory.
@param line: typed line(s)
@return Boolean: True-executed line, False-ask for more lines
"""
print "OnExecute:", line
return True
def OnKeydown(self, line, x, sellen, vkey, shift):
"""
A keyboard key has been pressed
This is a generic callback and the CLI is free to do whatever it wants.
This callback is optional.
@param line: current input line
@param x: current x coordinate of the cursor
@param sellen: current selection length (usually 0)
@param vkey: virtual key code. if the key has been handled, it should be returned as zero
@param shift: shift state
@return:
None - Nothing was changed
tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
"""
print "Onkeydown: line=%s x=%d sellen=%d vkey=%d shift=%d" % (line, x, sellen, vkey, shift)
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
"""
The user pressed Tab. Find a completion number N for prefix PREFIX
This callback is optional.
@param prefix: Line prefix at prefix_start (string)
@param n: completion number (int)
@param line: the current line (string)
@param prefix_start: the index where PREFIX starts in LINE (int)
@return: None if no completion could be generated otherwise a String with the completion suggestion
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
if code == NW_OPENIDB:
print "nw_handler(): installing CLI"
mycli.register()
elif code == NW_CLOSEIDB:
print "nw_handler(): removing CLI"
mycli.unregister()
elif code == NW_TERMIDA:
print "nw_handler(): uninstalled nw handler"
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Already installed?
try:
mycli
# remove previous CLI
mycli.unregister()
del mycli
# remove previous handler
nw_handler(NW_TERMIDA)
except:
pass
finally:
mycli = mycli_t()
# register CLI
if mycli.register():
print "CLI installed"
# install new handler
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
else:
del mycli
print "Failed to install CLI"
# -----------------------------------------------------------------------
# This is an example illustrating how to implement a CLI
# (c) Hex-Rays
#
from idaapi import NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR, cli_t
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
lname = "Python CLI"
hint = "pycli hint"
def OnExecuteLine(self, line):
"""
The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
This callback is mandatory.
@param line: typed line(s)
@return Boolean: True-executed line, False-ask for more lines
"""
print "OnExecute:", line
return True
def OnKeydown(self, line, x, sellen, vkey, shift):
"""
A keyboard key has been pressed
This is a generic callback and the CLI is free to do whatever it wants.
This callback is optional.
@param line: current input line
@param x: current x coordinate of the cursor
@param sellen: current selection length (usually 0)
@param vkey: virtual key code. if the key has been handled, it should be returned as zero
@param shift: shift state
@return:
None - Nothing was changed
tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
"""
print "Onkeydown: line=%s x=%d sellen=%d vkey=%d shift=%d" % (line, x, sellen, vkey, shift)
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
"""
The user pressed Tab. Find a completion number N for prefix PREFIX
This callback is optional.
@param prefix: Line prefix at prefix_start (string)
@param n: completion number (int)
@param line: the current line (string)
@param prefix_start: the index where PREFIX starts in LINE (int)
@return: None if no completion could be generated otherwise a String with the completion suggestion
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
if code == NW_OPENIDB:
print "nw_handler(): installing CLI"
mycli.register()
elif code == NW_CLOSEIDB:
print "nw_handler(): removing CLI"
mycli.unregister()
elif code == NW_TERMIDA:
print "nw_handler(): uninstalled nw handler"
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Already installed?
try:
mycli
# remove previous CLI
mycli.unregister()
del mycli
# remove previous handler
nw_handler(NW_TERMIDA)
except:
pass
finally:
mycli = mycli_t()
# register CLI
if mycli.register():
print "CLI installed"
# install new handler
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
else:
del mycli
print "Failed to install CLI"

View File

@@ -1,216 +1,216 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use custom data types in Python
# (c) Hex-Rays
#
from idaapi import data_type_t, data_format_t, NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR
import struct
import ctypes
import platform
#<pycode(ex_custdata)>
# -----------------------------------------------------------------------
class pascal_data_type(data_type_t):
def __init__(self):
data_type_t.__init__(self, name="py_pascal_string",
value_size = 2, menu_name = "Pascal string",
asm_keyword = "pstr")
def calc_item_size(self, ea, maxsize):
# Custom data types may be used in structure definitions. If this case
# ea is a member id. Check for this situation and return 1
if _idaapi.is_member_id(ea):
return 1
# get the length byte
n = _idaapi.get_byte(ea)
# string too big?
if n > maxsize:
return 0
# ok, accept the string
return n + 1
class pascal_data_format(data_format_t):
FORMAT_NAME = "py_pascal_string_pstr"
def __init__(self):
data_format_t.__init__(self, name=pascal_data_format.FORMAT_NAME)
def printf(self, value, current_ea, operand_num, dtid):
# Take the length byte
n = ord(value[0])
o = ['"']
for ch in value[1:]:
b = ord(ch)
if b < 0x20 or b > 128:
o.append(r'\x%02x' % ord(ch))
else:
o.append(ch)
o.append('"')
return "".join(o)
# -----------------------------------------------------------------------
class simplevm_data_type(data_type_t):
ASM_KEYWORD = "svm_emit"
def __init__(self):
data_type_t.__init__(self,
name="py_simple_vm",
value_size = 1,
menu_name = "SimpleVM",
asm_keyword = simplevm_data_type.ASM_KEYWORD)
def calc_item_size(self, ea, maxsize):
if _idaapi.is_member_id(ea):
return 1
# get the opcode and see if it has an imm
n = 5 if (_idaapi.get_byte(ea) & 3) == 0 else 1
# string too big?
if n > maxsize:
return 0
# ok, accept
return n
class simplevm_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_simple_vm_format",
menu_name = "SimpleVM")
# Some tables for the disassembler
INST = {1: 'add', 2: 'mul', 3: 'sub', 4: 'xor', 5: 'mov'}
REGS = {1: 'r1', 2: 'r2', 3: 'r3'}
def disasm(self, inst):
"""A simple local disassembler. In reality one can use a full-blown disassembler to render the text"""
opbyte = ord(inst[0])
op = opbyte >> 4
if not (1<=op<=5):
return None
r1 = (opbyte & 0xf) >> 2
r2 = opbyte & 3
sz = 0
if r2 == 0:
if len(inst) != 5:
return None
imm = struct.unpack_from('L', inst, 1)[0]
sz = 5
else:
imm = None
sz = 1
text = "%s %s, %s" % (
COLSTR(simplevm_data_format.INST[op], idaapi.SCOLOR_INSN),
COLSTR(simplevm_data_format.REGS[r1], idaapi.SCOLOR_REG),
COLSTR("0x%08X" % imm, idaapi.SCOLOR_NUMBER) if imm is not None else COLSTR(simplevm_data_format.REGS[r2], idaapi.SCOLOR_REG))
return (sz, text)
def printf(self, value, current_ea, operand_num, dtid):
r = self.disasm(value)
if not r:
return None
if dtid == 0:
return "%s(%s)" % (simplevm_data_type.ASM_KEYWORD, r[1])
return r[1]
# -----------------------------------------------------------------------
# This format will display DWORD values as MAKE_DWORD(0xHI, 0xLO)
class makedword_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_makedword",
value_size = 4,
menu_name = "Make DWORD")
def printf(self, value, current_ea, operand_num, dtid):
if len(value) != 4: return None
w1 = struct.unpack_from("H", value, 0)[0]
w2 = struct.unpack_from("H", value, 2)[0]
return "MAKE_DWORD(0x%04X, 0x%04X)" % (w2, w1)
# -----------------------------------------------------------------------
# This format will try to load a resource string given a number
# So instead of displaying:
# push 66h
# call message_box_from_rsrc_string
# It can be rendered as;
# push RSRC("The message")
# call message_box_from_rsrc_string
#
# The get_rsrc_string() is not optimal since it loads/unloads the
# DLL each time for a new string. It can be improved in many ways.
class rsrc_string_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_w32rsrcstring",
value_size = 1,
menu_name = "Resource string")
self.cache_node = idaapi.netnode("$ py_w32rsrcstring", 0, 1)
def get_rsrc_string(self, fn, id):
"""
Simple method that loads the input file as a DLL with LOAD_LIBRARY_AS_DATAFILE flag.
It then tries to LoadString()
"""
k32 = ctypes.windll.kernel32
u32 = ctypes.windll.user32
hinst = k32.LoadLibraryExA(fn, 0, 0x2)
if hinst == 0:
return ""
buf = ctypes.create_string_buffer(1024)
r = u32.LoadStringA(hinst, id, buf, 1024-1)
k32.FreeLibrary(hinst)
return buf.value if r else ""
def printf(self, value, current_ea, operand_num, dtid):
# Is it already cached?
val = self.cache_node.supval(current_ea)
# Not cached?
if val == None:
# Retrieve it
num = idaapi.struct_unpack(value)
val = self.get_rsrc_string(idaapi.get_input_file_path(), num)
# Cache it
self.cache_node.supset(current_ea, val)
# Failed to retrieve?
if val == "" or val == "\x00":
return None
# Return the format
return "RSRC_STR(\"%s\")" % COLSTR(val, idaapi.SCOLOR_IMPNAME)
# -----------------------------------------------------------------------
# Table of formats and types to be registered/unregistered
# If a tuple has one element then it is the format to be registered with dtid=0
# If the tuple has more than one element, the tuple[0] is the data type and tuple[1:] are the data formats
new_formats = [
(pascal_data_type(), pascal_data_format()),
(simplevm_data_type(), simplevm_data_format()),
(makedword_data_format(),),
(simplevm_data_format(),)
]
if platform.system() == 'Windows':
new_formats.append((rsrc_string_format(),))
#</pycode(ex_custdata)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
# delete notifications
if code == NW_OPENIDB:
idaapi.register_data_types_and_formats(new_formats)
elif code == NW_CLOSEIDB:
idaapi.unregister_data_types_and_formats(new_formats)
elif code == NW_TERMIDA:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Check if already installed
if idaapi.find_custom_data_type(pascal_data_format.FORMAT_NAME) == -1:
if not idaapi.register_data_types_and_formats(new_formats):
print "Failed to register types!"
else:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
print "Formats installed!"
else:
print "Formats already installed!"
# -----------------------------------------------------------------------
# This is an example illustrating how to use custom data types in Python
# (c) Hex-Rays
#
from idaapi import data_type_t, data_format_t, NW_OPENIDB, NW_CLOSEIDB, NW_TERMIDA, NW_REMOVE, COLSTR
import struct
import ctypes
import platform
#<pycode(ex_custdata)>
# -----------------------------------------------------------------------
class pascal_data_type(data_type_t):
def __init__(self):
data_type_t.__init__(self, name="py_pascal_string",
value_size = 2, menu_name = "Pascal string",
asm_keyword = "pstr")
def calc_item_size(self, ea, maxsize):
# Custom data types may be used in structure definitions. If this case
# ea is a member id. Check for this situation and return 1
if _idaapi.is_member_id(ea):
return 1
# get the length byte
n = _idaapi.get_byte(ea)
# string too big?
if n > maxsize:
return 0
# ok, accept the string
return n + 1
class pascal_data_format(data_format_t):
FORMAT_NAME = "py_pascal_string_pstr"
def __init__(self):
data_format_t.__init__(self, name=pascal_data_format.FORMAT_NAME)
def printf(self, value, current_ea, operand_num, dtid):
# Take the length byte
n = ord(value[0])
o = ['"']
for ch in value[1:]:
b = ord(ch)
if b < 0x20 or b > 128:
o.append(r'\x%02x' % ord(ch))
else:
o.append(ch)
o.append('"')
return "".join(o)
# -----------------------------------------------------------------------
class simplevm_data_type(data_type_t):
ASM_KEYWORD = "svm_emit"
def __init__(self):
data_type_t.__init__(self,
name="py_simple_vm",
value_size = 1,
menu_name = "SimpleVM",
asm_keyword = simplevm_data_type.ASM_KEYWORD)
def calc_item_size(self, ea, maxsize):
if _idaapi.is_member_id(ea):
return 1
# get the opcode and see if it has an imm
n = 5 if (_idaapi.get_byte(ea) & 3) == 0 else 1
# string too big?
if n > maxsize:
return 0
# ok, accept
return n
class simplevm_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_simple_vm_format",
menu_name = "SimpleVM")
# Some tables for the disassembler
INST = {1: 'add', 2: 'mul', 3: 'sub', 4: 'xor', 5: 'mov'}
REGS = {1: 'r1', 2: 'r2', 3: 'r3'}
def disasm(self, inst):
"""A simple local disassembler. In reality one can use a full-blown disassembler to render the text"""
opbyte = ord(inst[0])
op = opbyte >> 4
if not (1<=op<=5):
return None
r1 = (opbyte & 0xf) >> 2
r2 = opbyte & 3
sz = 0
if r2 == 0:
if len(inst) != 5:
return None
imm = struct.unpack_from('L', inst, 1)[0]
sz = 5
else:
imm = None
sz = 1
text = "%s %s, %s" % (
COLSTR(simplevm_data_format.INST[op], idaapi.SCOLOR_INSN),
COLSTR(simplevm_data_format.REGS[r1], idaapi.SCOLOR_REG),
COLSTR("0x%08X" % imm, idaapi.SCOLOR_NUMBER) if imm is not None else COLSTR(simplevm_data_format.REGS[r2], idaapi.SCOLOR_REG))
return (sz, text)
def printf(self, value, current_ea, operand_num, dtid):
r = self.disasm(value)
if not r:
return None
if dtid == 0:
return "%s(%s)" % (simplevm_data_type.ASM_KEYWORD, r[1])
return r[1]
# -----------------------------------------------------------------------
# This format will display DWORD values as MAKE_DWORD(0xHI, 0xLO)
class makedword_data_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_makedword",
value_size = 4,
menu_name = "Make DWORD")
def printf(self, value, current_ea, operand_num, dtid):
if len(value) != 4: return None
w1 = struct.unpack_from("H", value, 0)[0]
w2 = struct.unpack_from("H", value, 2)[0]
return "MAKE_DWORD(0x%04X, 0x%04X)" % (w2, w1)
# -----------------------------------------------------------------------
# This format will try to load a resource string given a number
# So instead of displaying:
# push 66h
# call message_box_from_rsrc_string
# It can be rendered as;
# push RSRC("The message")
# call message_box_from_rsrc_string
#
# The get_rsrc_string() is not optimal since it loads/unloads the
# DLL each time for a new string. It can be improved in many ways.
class rsrc_string_format(data_format_t):
def __init__(self):
data_format_t.__init__(self,
name="py_w32rsrcstring",
value_size = 1,
menu_name = "Resource string")
self.cache_node = idaapi.netnode("$ py_w32rsrcstring", 0, 1)
def get_rsrc_string(self, fn, id):
"""
Simple method that loads the input file as a DLL with LOAD_LIBRARY_AS_DATAFILE flag.
It then tries to LoadString()
"""
k32 = ctypes.windll.kernel32
u32 = ctypes.windll.user32
hinst = k32.LoadLibraryExA(fn, 0, 0x2)
if hinst == 0:
return ""
buf = ctypes.create_string_buffer(1024)
r = u32.LoadStringA(hinst, id, buf, 1024-1)
k32.FreeLibrary(hinst)
return buf.value if r else ""
def printf(self, value, current_ea, operand_num, dtid):
# Is it already cached?
val = self.cache_node.supval(current_ea)
# Not cached?
if val == None:
# Retrieve it
num = idaapi.struct_unpack(value)
val = self.get_rsrc_string(idaapi.get_input_file_path(), num)
# Cache it
self.cache_node.supset(current_ea, val)
# Failed to retrieve?
if val == "" or val == "\x00":
return None
# Return the format
return "RSRC_STR(\"%s\")" % COLSTR(val, idaapi.SCOLOR_IMPNAME)
# -----------------------------------------------------------------------
# Table of formats and types to be registered/unregistered
# If a tuple has one element then it is the format to be registered with dtid=0
# If the tuple has more than one element, the tuple[0] is the data type and tuple[1:] are the data formats
new_formats = [
(pascal_data_type(), pascal_data_format()),
(simplevm_data_type(), simplevm_data_format()),
(makedword_data_format(),),
(simplevm_data_format(),)
]
if platform.system() == 'Windows':
new_formats.append((rsrc_string_format(),))
#</pycode(ex_custdata)>
# -----------------------------------------------------------------------
def nw_handler(code, old=0):
# delete notifications
if code == NW_OPENIDB:
idaapi.register_data_types_and_formats(new_formats)
elif code == NW_CLOSEIDB:
idaapi.unregister_data_types_and_formats(new_formats)
elif code == NW_TERMIDA:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB | NW_REMOVE, nw_handler)
# -----------------------------------------------------------------------
# Check if already installed
if idaapi.find_custom_data_type(pascal_data_format.FORMAT_NAME) == -1:
if not idaapi.register_data_types_and_formats(new_formats):
print "Failed to register types!"
else:
idaapi.notify_when(NW_TERMIDA | NW_OPENIDB | NW_CLOSEIDB, nw_handler)
print "Formats installed!"
else:
print "Formats already installed!"

View File

@@ -1,183 +1,183 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
#<pycode(py_custviewerex1)>
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
print self.thing
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
# self.Jump(0)
return True
def OnClick(self, shift):
"""
User clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnClick, shift=%d" % shift
return True
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
word = self.GetCurrentWord()
if not word: word = "<None>"
print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
"""
Cursor position changed.
@return: Nothing
"""
print "OnCurposChanged"
def OnClose(self):
"""
The view is closing. Use this event to cleanup.
@return: Nothing
"""
print "OnClose " + self.title
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# ESCAPE?
if vkey == 27:
self.Close()
# VK_DELETE
elif vkey == 46:
n = self.GetLineNo()
if n is not None:
self.DelLine(n)
self.Refresh()
print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
n = self.GetLineNo()
if n is not None:
v = idc.AskLong(self.GetLineNo(), "Where to go?")
if v:
self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
elif vkey == ord('C'):
print "refreshing current line..."
self.RefreshCurrent()
elif vkey == ord('A'):
s = idc.AskStr("NewLine%d" % self.Count(), "Append new line")
self.AddLine(s)
self.Refresh()
elif vkey == ord('X'):
print "Clearing all lines"
self.ClearLines()
self.Refresh()
elif vkey == ord('I'):
n = self.GetLineNo()
s = idc.AskStr("InsertedLine%d" % n, "Insert new line")
self.InsertLine(n, s)
self.Refresh()
elif vkey == ord('E'):
l = self.GetCurrentLine(notags=1)
if not l:
return False
n = self.GetLineNo()
print "curline=<%s>" % l
l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP)
self.EditLine(n, l)
self.RefreshCurrent()
print "Edited line %d" % n
else:
return False
return True
def OnHint(self, lineno):
"""
Hint requested for the given line number.
@param lineno: The line number (zero based)
@return:
- tuple(number of important lines, hint string)
- None: if no hint available
"""
return (1, "OnHint, line=%d" % lineno)
# -----------------------------------------------------------------------
try:
# created already?
mycv
print "Already created, will close it..."
mycv.Close()
del mycv
except:
pass
def show_win():
x = mycv_t()
if not x.Create():
print "Failed to create!"
return None
x.Show()
tcc = x.GetTCustomControl()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
if not mycv:
del mycv
def make_many(n):
L = []
for i in xrange(1, n+1):
v = mycv_t()
if not v.Create(i):
break
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>
# -----------------------------------------------------------------------
# This is an example illustrating how to use customview in Python
# (c) Hex-Rays
#
import idaapi
import idc
from idaapi import simplecustviewer_t
#<pycode(py_custviewerex1)>
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
print self.thing
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
# self.Jump(0)
return True
def OnClick(self, shift):
"""
User clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnClick, shift=%d" % shift
return True
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
word = self.GetCurrentWord()
if not word: word = "<None>"
print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
"""
Cursor position changed.
@return: Nothing
"""
print "OnCurposChanged"
def OnClose(self):
"""
The view is closing. Use this event to cleanup.
@return: Nothing
"""
print "OnClose " + self.title
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# ESCAPE?
if vkey == 27:
self.Close()
# VK_DELETE
elif vkey == 46:
n = self.GetLineNo()
if n is not None:
self.DelLine(n)
self.Refresh()
print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
n = self.GetLineNo()
if n is not None:
v = idc.AskLong(self.GetLineNo(), "Where to go?")
if v:
self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
elif vkey == ord('C'):
print "refreshing current line..."
self.RefreshCurrent()
elif vkey == ord('A'):
s = idc.AskStr("NewLine%d" % self.Count(), "Append new line")
self.AddLine(s)
self.Refresh()
elif vkey == ord('X'):
print "Clearing all lines"
self.ClearLines()
self.Refresh()
elif vkey == ord('I'):
n = self.GetLineNo()
s = idc.AskStr("InsertedLine%d" % n, "Insert new line")
self.InsertLine(n, s)
self.Refresh()
elif vkey == ord('E'):
l = self.GetCurrentLine(notags=1)
if not l:
return False
n = self.GetLineNo()
print "curline=<%s>" % l
l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP)
self.EditLine(n, l)
self.RefreshCurrent()
print "Edited line %d" % n
else:
return False
return True
def OnHint(self, lineno):
"""
Hint requested for the given line number.
@param lineno: The line number (zero based)
@return:
- tuple(number of important lines, hint string)
- None: if no hint available
"""
return (1, "OnHint, line=%d" % lineno)
# -----------------------------------------------------------------------
try:
# created already?
mycv
print "Already created, will close it..."
mycv.Close()
del mycv
except:
pass
def show_win():
x = mycv_t()
if not x.Create():
print "Failed to create!"
return None
x.Show()
tcc = x.GetTCustomControl()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
if not mycv:
del mycv
def make_many(n):
L = []
for i in xrange(1, n+1):
v = mycv_t()
if not v.Create(i):
break
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>

View File

@@ -1,48 +1,34 @@
#
# Demonstrates some functions from the "dbg" class
#
import idaapi
#from idaapi import dbg_write_memory, dbg_read_memory, dbg_get_thread_sreg_base, dbg_get_registers, dbg_get_memory_info
def dump_meminfo(L):
# startEA, endEA, name, sclass, sbase, bitness, perm
for (startEA, endEA, name, sclass, sbase, bitness, perm) in L:
print "%x: %x name=<%s> sclass=<%s> sbase=%x bitness=%2x perm=%2x" % (startEA, endEA, name, sclass, sbase, bitness, perm)
def test_getmeminfo():
L = idaapi.dbg_get_memory_info()
dump_meminfo(L)
def test_getregs():
L = idaapi.dbg_get_registers()
# name flags class dtyp bit_strings bit_strings_default_mask
for (name, flags, cls, dtype, bit_strings, bit_strings_default_mask) in L:
print "name=<%s> flags=%x class=%x dtype=%x bit_strings_mask=%x" % (name, flags, cls, dtype, bit_strings_default_mask)
if bit_strings:
for s in bit_strings:
print " %s" % s
def test_manual_regions():
L = idaapi.get_manual_regions()
if not L:
print "no manual regions!"
else:
dump_meminfo(L)
def test_readwrite():
ea = cpu.Eip
buf = idaapi.dbg_read_memory(ea, 5)
print "read: ", [hex(ord(x)) for x in buf]
idaapi.dbg_write_memory(ea, buf)
test_manual_regions()
if idaapi.dbg_can_query():
print "%x: fs" % (idaapi.dbg_get_thread_sreg_base(idc.GetCurrentThreadId(), cpu.fs))
test_getmeminfo()
test_getregs()
test_readwrite()
else:
print "run and suspend the debugger first"
from tempo import *;
def test_getmeminfo():
L = tempo.getmeminfo()
out = []
# startEA endEA name sclass sbase bitness perm
for (startEA, endEA, name, sclass, sbase, bitness, perm) in L:
out.append("%x: %x name=<%s> sclass=<%s> sbase=%x bitness=%2x perm=%2x" % (startEA, endEA, name, sclass, sbase, bitness, perm))
f = file(r"d:\temp\out.log", "w")
f.write("\n".join(out))
f.close()
print "dumped meminfo!"
def test_getregs():
# name flags class dtyp bit_strings bit_strings_default_mask
L = tempo.getregs()
out = []
for (name, flags, cls, dtype, bit_strings, bit_strings_default_mask) in L:
out.append("name=<%s> flags=%x class=%x dtype=%x bit_strings_mask=%x" % (name, flags, cls, dtype, bit_strings_default_mask))
if bit_strings:
for s in bit_strings:
out.append(" %s" % s)
f = file(r"d:\temp\out.log", "w")
f.write("\n".join(out))
f.close()
print "dumped regs!"

View File

@@ -1,15 +1,15 @@
import idaapi
def main():
if not idaapi.is_debugger_on():
print "Please run the process first!"
return
if idaapi.get_process_state() != -1:
print "Please suspend the debugger first!"
return
dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA)
for i in dn:
print "%08x: %s" % (i, dn[i])
main()
import idaapi
def main():
if not idaapi.is_debugger_on():
print "Please run the process first!"
return
if idaapi.get_process_state() != -1:
print "Please suspend the debugger first!"
return
dn = idaapi.get_debug_names(idaapi.cvar.inf.minEA, idaapi.cvar.inf.maxEA)
for i in dn:
print "%08x: %s" % (i, dn[i])
main()

View File

@@ -1,16 +1,16 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to extend IDC from Python
# (c) Hex-Rays
#
from idaapi import set_idc_func_ex
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>
# -----------------------------------------------------------------------
# This is an example illustrating how to extend IDC from Python
# (c) Hex-Rays
#
from idaapi import set_idc_func_ex
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>

View File

@@ -1,38 +1,38 @@
import idaapi
import idautils
import idc
class MyChoose2(Choose2):
def __init__(self, title):
Choose2.__init__(self, title, [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | Choose2.CHCOL_PLAIN] ])
self.n = 0
self.icon = 41
self.PopulateItems()
def PopulateItems(self):
self.items = [ [hex(x), GetFunctionName(x), x] for x in idautils.Functions() ]
def OnClose(self):
print "closed ", self.title
def OnSelectLine(self, n):
idc.Jump(self.items[n][2])
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnDeleteLine(self, n):
ea = self.items[n][2]
idc.DelFunction(ea)
return n
def OnRefresh(self, n):
self.PopulateItems()
return n
c = MyChoose2("My functions list")
import idaapi
import idautils
import idc
class MyChoose2(Choose2):
def __init__(self, title):
Choose2.__init__(self, title, [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | Choose2.CHCOL_PLAIN] ])
self.n = 0
self.icon = 41
self.PopulateItems()
def PopulateItems(self):
self.items = [ [hex(x), GetFunctionName(x), x] for x in idautils.Functions() ]
def OnClose(self):
print "closed ", self.title
def OnSelectLine(self, n):
idc.Jump(self.items[n][2])
def OnGetLine(self, n):
return self.items[n]
def OnGetSize(self):
return len(self.items)
def OnDeleteLine(self, n):
ea = self.items[n][2]
idc.DelFunction(ea)
return n
def OnRefresh(self, n):
self.PopulateItems()
return n
c = MyChoose2("My functions list")
c.Show()

View File

@@ -1,43 +1,43 @@
import idaapi
# -----------------------------------------------------------------------
# Using raw IDAAPI
def raw_main(p=True):
f = idaapi.get_func(here())
if not f:
return
q = idaapi.qflow_chart_t("The title", f, 0, 0, idaapi.FC_PREDS)
for n in xrange(0, q.size()):
b = q[n]
if p:
print "%x - %x [%d]:" % (b.startEA, b.endEA, n)
for ns in xrange(0, q.nsucc(n)):
if p:
print "SUCC: %d->%d" % (n, q.succ(n, ns))
for ns in xrange(0, q.npred(n)):
if p:
print "PRED: %d->%d" % (n, q.pred(n, ns))
# -----------------------------------------------------------------------
# Using the class
def cls_main(p=True):
f = idaapi.FlowChart(idaapi.get_func(here()))
for block in f:
if p:
print "%x - %x [%d]:" % (block.startEA, block.endEA, block.id)
for succ_block in block.succs():
if p:
print " %x - %x [%d]:" % (succ_block.startEA, succ_block.endEA, succ_block.id)
for pred_block in block.preds():
if p:
print " %x - %x [%d]:" % (pred_block.startEA, pred_block.endEA, pred_block.id)
q = None
f = None
raw_main(False)
cls_main(True)
import idaapi
# -----------------------------------------------------------------------
# Using raw IDAAPI
def raw_main(p=True):
f = idaapi.get_func(here())
if not f:
return
q = idaapi.qflow_chart_t("The title", f, 0, 0, idaapi.FC_PREDS)
for n in xrange(0, q.size()):
b = q[n]
if p:
print "%x - %x [%d]:" % (b.startEA, b.endEA, n)
for ns in xrange(0, q.nsucc(n)):
if p:
print "SUCC: %d->%d" % (n, q.succ(n, ns))
for ns in xrange(0, q.npred(n)):
if p:
print "PRED: %d->%d" % (n, q.pred(n, ns))
# -----------------------------------------------------------------------
# Using the class
def cls_main(p=True):
f = idaapi.FlowChart(idaapi.get_func(here()))
for block in f:
if p:
print "%x - %x [%d]:" % (block.startEA, block.endEA, block.id)
for succ_block in block.succs():
if p:
print " %x - %x [%d]:" % (succ_block.startEA, succ_block.endEA, succ_block.id)
for pred_block in block.preds():
if p:
print " %x - %x [%d]:" % (pred_block.startEA, pred_block.endEA, pred_block.id)
q = None
f = None
raw_main(False)
cls_main(True)

View File

@@ -1,70 +1,70 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to use the user graphing functionality
# in Python
# (c) Hex-Rays
#
from idaapi import *
class GraphCloser(action_handler_t):
def __init__(self, graph):
action_handler_t.__init__(self)
self.graph = graph
def activate(self, ctx):
self.graph.Close()
def update(self, ctx):
return AST_ENABLE_ALWAYS
class MyGraph(GraphViewer):
def __init__(self, funcname, result):
self.title = "call graph of " + funcname
GraphViewer.__init__(self, self.title)
self.funcname = funcname
self.result = result
def OnRefresh(self):
self.Clear()
id = self.AddNode(self.funcname)
for x in self.result.keys():
callee = self.AddNode(x)
self.AddEdge(id, callee)
return True
def OnGetText(self, node_id):
return str(self[node_id])
def Show(self):
if not GraphViewer.Show(self):
return False
actname = "graph_closer:%s" % self.title
register_action(action_desc_t(actname, "Close %s" % self.title, GraphCloser(self)))
attach_action_to_popup(self.GetTCustomControl(), None, actname)
return True
def show_graph():
f = idaapi.get_func(here())
if not f:
print "Must be in a function"
return
# Iterate through all function instructions and take only call instructions
result = {}
for x in [x for x in FuncItems(f.startEA) if idaapi.is_call_insn(x)]:
for xref in XrefsFrom(x, idaapi.XREF_FAR):
if not xref.iscode: continue
t = GetFunctionName(xref.to)
if not t:
t = hex(xref.to)
result[t] = True
g = MyGraph(GetFunctionName(f.startEA), result)
if g.Show():
return g
else:
return None
g = show_graph()
if g:
print "Graph created and displayed!"
# -----------------------------------------------------------------------
# This is an example illustrating how to use the user graphing functionality
# in Python
# (c) Hex-Rays
#
from idaapi import *
class GraphCloser(action_handler_t):
def __init__(self, graph):
action_handler_t.__init__(self)
self.graph = graph
def activate(self, ctx):
self.graph.Close()
def update(self, ctx):
return AST_ENABLE_ALWAYS
class MyGraph(GraphViewer):
def __init__(self, funcname, result):
self.title = "call graph of " + funcname
GraphViewer.__init__(self, self.title)
self.funcname = funcname
self.result = result
def OnRefresh(self):
self.Clear()
id = self.AddNode(self.funcname)
for x in self.result.keys():
callee = self.AddNode(x)
self.AddEdge(id, callee)
return True
def OnGetText(self, node_id):
return str(self[node_id])
def Show(self):
if not GraphViewer.Show(self):
return False
actname = "graph_closer:%s" % self.title
register_action(action_desc_t(actname, "Close %s" % self.title, GraphCloser(self)))
attach_action_to_popup(self.GetTCustomControl(), None, actname)
return True
def show_graph():
f = idaapi.get_func(here())
if not f:
print "Must be in a function"
return
# Iterate through all function instructions and take only call instructions
result = {}
for x in [x for x in FuncItems(f.startEA) if idaapi.is_call_insn(x)]:
for xref in XrefsFrom(x, idaapi.XREF_FAR):
if not xref.iscode: continue
t = GetFunctionName(xref.to)
if not t:
t = hex(xref.to)
result[t] = True
g = MyGraph(GetFunctionName(f.startEA), result)
if g.Show():
return g
else:
return None
g = show_graph()
if g:
print "Graph created and displayed!"

View File

@@ -1,29 +1,29 @@
# -----------------------------------------------------------------------
# This is an example illustrating how to enumerate imports
# (c) Hex-Rays
#
import idaapi
def imp_cb(ea, name, ord):
if not name:
print "%08x: ord#%d" % (ea, ord)
else:
print "%08x: %s (ord#%d)" % (ea, name, ord)
# True -> Continue enumeration
# False -> Stop enumeration
return True
nimps = idaapi.get_import_module_qty()
print "Found %d import(s)..." % nimps
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if not name:
print "Failed to get import module name for #%d" % i
continue
print "Walking-> %s" % name
idaapi.enum_import_names(i, imp_cb)
# -----------------------------------------------------------------------
# This is an example illustrating how to enumerate imports
# (c) Hex-Rays
#
import idaapi
def imp_cb(ea, name, ord):
if not name:
print "%08x: ord#%d" % (ea, ord)
else:
print "%08x: %s (ord#%d)" % (ea, name, ord)
# True -> Continue enumeration
# False -> Stop enumeration
return True
nimps = idaapi.get_import_module_qty()
print "Found %d import(s)..." % nimps
for i in xrange(0, nimps):
name = idaapi.get_import_module_name(i)
if not name:
print "Failed to get import module name for #%d" % i
continue
print "Walking-> %s" % name
idaapi.enum_import_names(i, imp_cb)
print "All done..."

View File

@@ -1,42 +1,42 @@
import idaapi
PREFIX = idaapi.SCOLOR_INV + ' ' + idaapi.SCOLOR_INV
class prefix_plugin_t(idaapi.plugin_t):
flags = 0
comment = "This is a user defined prefix sample plugin"
help = "This is help"
wanted_name = "user defined prefix"
wanted_hotkey = ""
def user_prefix(self, ea, lnnum, indent, line, bufsize):
#print("ea=%x lnnum=%d indent=%d line=%s bufsize=%d" % (ea, lnnum, indent, line, bufsize))
if (ea % 2 == 0) and indent == -1:
return PREFIX
else:
return ""
def init(self):
self.prefix_installed = idaapi.set_user_defined_prefix(8, self.user_prefix)
if self.prefix_installed:
print("prefix installed")
return idaapi.PLUGIN_KEEP
def run(self, arg):
pass
def term(self):
if self.prefix_installed:
idaapi.set_user_defined_prefix(0, None)
print("prefix uninstalled!")
def PLUGIN_ENTRY():
return prefix_plugin_t()
import idaapi
PREFIX = idaapi.SCOLOR_INV + ' ' + idaapi.SCOLOR_INV
class prefix_plugin_t(idaapi.plugin_t):
flags = 0
comment = "This is a user defined prefix sample plugin"
help = "This is help"
wanted_name = "user defined prefix"
wanted_hotkey = ""
def user_prefix(self, ea, lnnum, indent, line, bufsize):
#print("ea=%x lnnum=%d indent=%d line=%s bufsize=%d" % (ea, lnnum, indent, line, bufsize))
if (ea % 2 == 0) and indent == -1:
return PREFIX
else:
return ""
def init(self):
self.prefix_installed = idaapi.set_user_defined_prefix(8, self.user_prefix)
if self.prefix_installed:
print("prefix installed")
return idaapi.PLUGIN_KEEP
def run(self, arg):
pass
def term(self):
if self.prefix_installed:
idaapi.set_user_defined_prefix(0, None)
print("prefix uninstalled!")
def PLUGIN_ENTRY():
return prefix_plugin_t()

View File

@@ -1,35 +1,35 @@
from idaapi import PluginForm
from PyQt4 import QtCore, QtGui
import sip
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPyQtWidget(form)
self.PopulateForm()
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PyQt</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
pass
plg = MyPluginFormClass()
plg.Show("PyQt hello world")
from idaapi import PluginForm
from PyQt4 import QtCore, QtGui
import sip
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPyQtWidget(form)
self.PopulateForm()
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PyQt</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
pass
plg = MyPluginFormClass()
plg.Show("PyQt hello world")

View File

@@ -1,34 +1,34 @@
from idaapi import PluginForm
from PySide import QtGui, QtCore
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
self.PopulateForm()
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PySide</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
pass
plg = MyPluginFormClass()
plg.Show("PySide hello world")
from idaapi import PluginForm
from PySide import QtGui, QtCore
class MyPluginFormClass(PluginForm):
def OnCreate(self, form):
"""
Called when the plugin form is created
"""
# Get parent widget
self.parent = self.FormToPySideWidget(form)
self.PopulateForm()
def PopulateForm(self):
# Create layout
layout = QtGui.QVBoxLayout()
layout.addWidget(
QtGui.QLabel("Hello from <font color=red>PySide</font>"))
layout.addWidget(
QtGui.QLabel("Hello from <font color=blue>IDAPython</font>"))
self.parent.setLayout(layout)
def OnClose(self, form):
"""
Called when the plugin form is closed
"""
pass
plg = MyPluginFormClass()
plg.Show("PySide hello world")

View File

@@ -1,24 +1,24 @@
#---------------------------------------------------------------------
# This script demonstrates the usage of hotkeys.
#
# Note: Hotkeys only work with the GUI version of IDA and not in
# text mode.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
import idaapi
def foo():
print "Hotkey activated!"
# IDA binds hotkeys to IDC functions so a trampoline IDC function
# must be created
idaapi.CompileLine('static key_2() { RunPythonStatement("foo()"); }')
# Add the hotkey
AddHotkey("2", 'key_2')
# Press 2 to activate foo()
# The hotkey can be removed with
# DelHotkey('2')
#---------------------------------------------------------------------
# This script demonstrates the usage of hotkeys.
#
# Note: Hotkeys only work with the GUI version of IDA and not in
# text mode.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
import idaapi
def foo():
print "Hotkey activated!"
# IDA binds hotkeys to IDC functions so a trampoline IDC function
# must be created
idaapi.CompileLine('static key_2() { RunPythonStatement("foo()"); }')
# Add the hotkey
AddHotkey("2", 'key_2')
# Press 2 to activate foo()
# The hotkey can be removed with
# DelHotkey('2')

View File

@@ -1,49 +1,49 @@
#---------------------------------------------------------------------
# Structure test
#
# This script demonstrates how to create structures and populate them
# with members of different types.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
from idaapi import stroffflag, offflag
sid = GetStrucIdByName("mystr1")
if sid != -1:
DelStruc(sid)
sid = AddStrucEx(-1, "mystr1", 0)
print "%x" % sid
# Test simple data types
simple_types = [ FF_BYTE, FF_WORD, FF_DWRD, FF_QWRD, FF_TBYT, FF_OWRD, FF_FLOAT, FF_DOUBLE, FF_PACKREAL ]
simple_sizes = [ 1, 2, 4, 8, 10, 16, 4, 8, 10 ]
i = 0
for t,nsize in zip(simple_types, simple_sizes):
print "t%x:"% ((t|FF_DATA)&0xFFFFFFFF), AddStrucMember(sid, "t%02d"%i, BADADDR, (t|FF_DATA )&0xFFFFFFFF, -1, nsize)
i+=1
# Test ASCII type
print "ASCII:", AddStrucMember(sid, "tascii", -1, FF_ASCI|FF_DATA, ASCSTR_C, 8)
# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = GetEnum("MACRO_WMI")
#print "Enum:", AddStrucMember(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWRD, eid, 4)
# Test struc member type
msid = GetStrucIdByName("mystr2")
if msid != -1:
DelStruc(msid)
msid = AddStrucEx(-1, "mystr2", 0)
print AddStrucMember(msid, "member1", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)
print AddStrucMember(msid, "member2", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)
msize = GetStrucSize(msid)
print "Struct:", AddStrucMember(sid, "tstruct", -1, FF_STRU|FF_DATA, msid, msize)
print "Stroff:", AddStrucMember(sid, "tstroff", -1, stroffflag()|FF_DWRD, msid, 4)
# Test offset types
print "Offset:", AddStrucMember(sid, "toffset", -1, offflag()|FF_DATA|FF_DWRD, 0, 4)
print "Offset:", SetMemberType(sid, 0, offflag()|FF_DATA|FF_DWRD, 0, 4)
print "Done"
#---------------------------------------------------------------------
# Structure test
#
# This script demonstrates how to create structures and populate them
# with members of different types.
#
# Author: Gergely Erdelyi <gergely.erdelyi@d-dome.net>
#---------------------------------------------------------------------
from idaapi import stroffflag, offflag
sid = GetStrucIdByName("mystr1")
if sid != -1:
DelStruc(sid)
sid = AddStrucEx(-1, "mystr1", 0)
print "%x" % sid
# Test simple data types
simple_types = [ FF_BYTE, FF_WORD, FF_DWRD, FF_QWRD, FF_TBYT, FF_OWRD, FF_FLOAT, FF_DOUBLE, FF_PACKREAL ]
simple_sizes = [ 1, 2, 4, 8, 10, 16, 4, 8, 10 ]
i = 0
for t,nsize in zip(simple_types, simple_sizes):
print "t%x:"% ((t|FF_DATA)&0xFFFFFFFF), AddStrucMember(sid, "t%02d"%i, BADADDR, (t|FF_DATA )&0xFFFFFFFF, -1, nsize)
i+=1
# Test ASCII type
print "ASCII:", AddStrucMember(sid, "tascii", -1, FF_ASCI|FF_DATA, ASCSTR_C, 8)
# Test enum type - Add a defined enum name or load MACRO_WMI from a type library.
#eid = GetEnum("MACRO_WMI")
#print "Enum:", AddStrucMember(sid, "tenum", BADADDR, FF_0ENUM|FF_DATA|FF_DWRD, eid, 4)
# Test struc member type
msid = GetStrucIdByName("mystr2")
if msid != -1:
DelStruc(msid)
msid = AddStrucEx(-1, "mystr2", 0)
print AddStrucMember(msid, "member1", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)
print AddStrucMember(msid, "member2", -1, (FF_DWRD|FF_DATA )&0xFFFFFFFF, -1, 4)
msize = GetStrucSize(msid)
print "Struct:", AddStrucMember(sid, "tstruct", -1, FF_STRU|FF_DATA, msid, msize)
print "Stroff:", AddStrucMember(sid, "tstroff", -1, stroffflag()|FF_DWRD, msid, 4)
# Test offset types
print "Offset:", AddStrucMember(sid, "toffset", -1, offflag()|FF_DATA|FF_DWRD, 0, 4)
print "Offset:", SetMemberType(sid, 0, offflag()|FF_DATA|FF_DWRD, 0, 4)
print "Done"

View File

@@ -1,26 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idapython", "idapython.vcxproj", "{F43D6BB8-B7D6-486A-82E5-BABBA9848525}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug64|Win32 = Debug64|Win32
Release|Win32 = Release|Win32
SemiDebug|Win32 = SemiDebug|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.ActiveCfg = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.Build.0 = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.ActiveCfg = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.Build.0 = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.ActiveCfg = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.Build.0 = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.ActiveCfg = SemiDebug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.Build.0 = SemiDebug|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "idapython", "idapython.vcxproj", "{F43D6BB8-B7D6-486A-82E5-BABBA9848525}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug64|Win32 = Debug64|Win32
Release|Win32 = Release|Win32
SemiDebug|Win32 = SemiDebug|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.ActiveCfg = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug|Win32.Build.0 = Debug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.ActiveCfg = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Debug64|Win32.Build.0 = Debug64|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.ActiveCfg = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.Release|Win32.Build.0 = Release|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.ActiveCfg = SemiDebug|Win32
{F43D6BB8-B7D6-486A-82E5-BABBA9848525}.SemiDebug|Win32.Build.0 = SemiDebug|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

View File

@@ -1,453 +1,453 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug64|Win32">
<Configuration>Debug64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="SemiDebug|Win32">
<Configuration>SemiDebug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F43D6BB8-B7D6-486A-82E5-BABBA9848525}</ProjectGuid>
<RootNamespace>idapython</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</PostBuildEventUseInBuild>
<OutDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WITH_HEXRAYS;NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=3;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>c:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python26\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=0;PLUGINFIX;%(PreprocessorDefinitions);__EA64__</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\..\bin\x86_win_vc\plugins\python.p64</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python26\libs;..\..\lib\x86_win_vc_64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.p64 ..\..\bin\x86_win_bcc\plugins\python.p64</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;4804;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4005;4804;4018;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>C:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Release/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.plw ..\..\bin\x86_win_bcc\plugins\python.plw</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../bin/x86_win_vc/plugins/python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="build.py" />
<None Include="BUILDING.txt" />
<None Include="CHANGES.txt" />
<None Include="obj\x86_win_vc_32\idaapi.py" />
<None Include="python.cfg" />
<None Include="python\idautils.py" />
<None Include="python\idc.py" />
<None Include="python\init.py" />
<None Include="pywraps\deploy.bat" />
<None Include="pywraps\deploy.py" />
<None Include="pywraps\py_appcall.py" />
<None Include="pywraps\py_askusingform.py" />
<None Include="pywraps\py_choose2.py" />
<None Include="pywraps\py_cli.py" />
<None Include="pywraps\py_custdata.py" />
<None Include="pywraps\py_custview.py" />
<None Include="pywraps\py_diskio.py" />
<None Include="pywraps\py_expr.py" />
<None Include="pywraps\py_gdl.py" />
<None Include="pywraps\py_graph.py" />
<None Include="pywraps\py_idaapi.py" />
<None Include="pywraps\py_kernwin.py" />
<None Include="pywraps\py_lines.py" />
<None Include="pywraps\py_nalt.py" />
<None Include="pywraps\py_name.py" />
<None Include="pywraps\py_notifywhen.py" />
<None Include="pywraps\py_plgform.py" />
<None Include="pywraps\py_ua.py" />
<None Include="README.txt" />
<None Include="STATUS.txt" />
<None Include="swig\allins.i" />
<None Include="swig\area.i" />
<None Include="swig\auto.i" />
<None Include="swig\bytes.i" />
<None Include="swig\dbg.i" />
<None Include="swig\diskio.i" />
<None Include="swig\entry.i" />
<None Include="swig\enum.i" />
<None Include="swig\expr.i" />
<None Include="swig\fixup.i" />
<None Include="swig\fpro.i" />
<None Include="swig\frame.i" />
<None Include="swig\funcs.i" />
<None Include="swig\gdl.i" />
<None Include="swig\graph.i" />
<None Include="swig\hexrays.i" />
<None Include="swig\ida.i" />
<None Include="swig\idaapi.i" />
<None Include="swig\idd.i" />
<None Include="swig\idp.i" />
<None Include="swig\ints.i" />
<None Include="swig\kernwin.i" />
<None Include="swig\lines.i" />
<None Include="swig\loader.i" />
<None Include="swig\moves.i" />
<None Include="swig\nalt.i" />
<None Include="swig\name.i" />
<None Include="swig\netnode.i" />
<None Include="swig\offset.i" />
<None Include="swig\pro.i" />
<None Include="swig\queue.i" />
<None Include="swig\search.i" />
<None Include="swig\segment.i" />
<None Include="swig\srarea.i" />
<None Include="swig\strlist.i" />
<None Include="swig\struct.i" />
<None Include="swig\typeconv.i" />
<None Include="swig\typeinf.i" />
<None Include="swig\ua.i" />
<None Include="swig\xref.i" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="idaapi.cpp" />
<ClCompile Include="python.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="idaapi.h" />
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp" />
<ClInclude Include="pywraps\py_bytes.hpp" />
<ClInclude Include="pywraps\py_choose.hpp" />
<ClInclude Include="pywraps\py_choose2.hpp" />
<ClInclude Include="pywraps\py_cli.hpp" />
<ClInclude Include="pywraps\py_custdata.hpp" />
<ClInclude Include="pywraps\py_custview.hpp" />
<ClInclude Include="pywraps\py_cvt.hpp" />
<ClInclude Include="pywraps\py_dbg.hpp" />
<ClInclude Include="pywraps\py_diskio.hpp" />
<ClInclude Include="pywraps\py_expr.hpp" />
<ClInclude Include="pywraps\py_graph.hpp" />
<ClInclude Include="pywraps\py_idaapi.hpp" />
<ClInclude Include="pywraps\py_idp.hpp" />
<ClInclude Include="pywraps\py_kernwin.hpp" />
<ClInclude Include="pywraps\py_lines.hpp" />
<ClInclude Include="pywraps\py_linput.hpp" />
<ClInclude Include="pywraps\py_loader.hpp" />
<ClInclude Include="pywraps\py_nalt.hpp" />
<ClInclude Include="pywraps\py_name.hpp" />
<ClInclude Include="pywraps\py_notifywhen.hpp" />
<ClInclude Include="pywraps\py_plgform.hpp" />
<ClInclude Include="pywraps\py_qfile.hpp" />
<ClInclude Include="pywraps\py_typeinf.hpp" />
<ClInclude Include="pywraps\py_ua.hpp" />
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="C:\Python25\libs\python25.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python25\libs\python25_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug64|Win32">
<Configuration>Debug64</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="SemiDebug|Win32">
<Configuration>SemiDebug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{F43D6BB8-B7D6-486A-82E5-BABBA9848525}</ProjectGuid>
<RootNamespace>idapython</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseOfMfc>false</UseOfMfc>
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">.\Debug64\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</LinkIncremental>
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</PostBuildEventUseInBuild>
<OutDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</OutDir>
<IntDir Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">$(Configuration)\</IntDir>
<LinkIncremental Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</LinkIncremental>
<PostBuildEventUseInBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</PostBuildEventUseInBuild>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WITH_HEXRAYS;NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=3;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>c:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python26\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=5;VER_PATCH=0;PLUGINFIX;%(PreprocessorDefinitions);__EA64__</PreprocessorDefinitions>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4804;4800;4018;4005;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>..\..\bin\x86_win_vc\plugins\python.p64</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python26\libs;..\..\lib\x86_win_vc_64;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.p64 ..\..\bin\x86_win_bcc\plugins\python.p64</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Midl>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Release/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;NDEBUG;WIN32;_WINDOWS;_USRDLL;__NT__;__IDP__;MAXSTR=1024;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;4804;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<FunctionLevelLinking>true</FunctionLevelLinking>
<PrecompiledHeaderOutputFile>.\Release/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Release/</AssemblerListingLocation>
<ObjectFileName>.\Release/</ObjectFileName>
<ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4005;4804;4018;4800;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0419</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>C:\temp\ida\plugins\python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Release/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Release/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Release/idapython.bsc</OutputFile>
</Bscmake>
<PostBuildEvent>
<Command>copy ..\..\bin\x86_win_vc\plugins\python.plw ..\..\bin\x86_win_bcc\plugins\python.plw</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">
<Midl>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MkTypLibCompatible>true</MkTypLibCompatible>
<SuppressStartupBanner>true</SuppressStartupBanner>
<TargetEnvironment>Win32</TargetEnvironment>
<TypeLibraryName>.\Debug/idapython.tlb</TypeLibraryName>
<HeaderFileName>
</HeaderFileName>
</Midl>
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.\pywraps;..\..\include;c:\python27\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NO_OBSOLETE_FUNCS;_DEBUG;__NT__;__IDP__;MAXSTR=1024;WIN32;_WINDOWS;_USRDLL;_CRT_SECURE_NO_WARNINGS;USE_STANDARD_FILE_FUNCTIONS;VER_MAJOR=1;VER_MINOR=3;VER_PATCH=7;PLUGINFIX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeaderOutputFile>.\Debug/idapython.pch</PrecompiledHeaderOutputFile>
<AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
<ObjectFileName>.\Debug/</ObjectFileName>
<ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<SuppressStartupBanner>true</SuppressStartupBanner>
<DebugInformationFormat>EditAndContinue</DebugInformationFormat>
<CallingConvention>Cdecl</CallingConvention>
<DisableSpecificWarnings>4102;4804;4800;4018;%(DisableSpecificWarnings)</DisableSpecificWarnings>
</ClCompile>
<ResourceCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Culture>0x0409</Culture>
</ResourceCompile>
<Link>
<AdditionalOptions>/export:PLUGIN %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>ida.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>../../bin/x86_win_vc/plugins/python.plw</OutputFile>
<SuppressStartupBanner>true</SuppressStartupBanner>
<AdditionalLibraryDirectories>C:\Python27\libs;..\..\lib\x86_win_vc_32;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>.\Debug/idapython.pdb</ProgramDatabaseFile>
<RandomizedBaseAddress>
</RandomizedBaseAddress>
<DataExecutionPrevention>
</DataExecutionPrevention>
<ImportLibrary>.\Debug/idapython.lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
</Link>
<Bscmake>
<SuppressStartupBanner>true</SuppressStartupBanner>
<OutputFile>.\Debug/idapython.bsc</OutputFile>
</Bscmake>
</ItemDefinitionGroup>
<ItemGroup>
<None Include="build.py" />
<None Include="BUILDING.txt" />
<None Include="CHANGES.txt" />
<None Include="obj\x86_win_vc_32\idaapi.py" />
<None Include="python.cfg" />
<None Include="python\idautils.py" />
<None Include="python\idc.py" />
<None Include="python\init.py" />
<None Include="pywraps\deploy.bat" />
<None Include="pywraps\deploy.py" />
<None Include="pywraps\py_appcall.py" />
<None Include="pywraps\py_askusingform.py" />
<None Include="pywraps\py_choose2.py" />
<None Include="pywraps\py_cli.py" />
<None Include="pywraps\py_custdata.py" />
<None Include="pywraps\py_custview.py" />
<None Include="pywraps\py_diskio.py" />
<None Include="pywraps\py_expr.py" />
<None Include="pywraps\py_gdl.py" />
<None Include="pywraps\py_graph.py" />
<None Include="pywraps\py_idaapi.py" />
<None Include="pywraps\py_kernwin.py" />
<None Include="pywraps\py_lines.py" />
<None Include="pywraps\py_nalt.py" />
<None Include="pywraps\py_name.py" />
<None Include="pywraps\py_notifywhen.py" />
<None Include="pywraps\py_plgform.py" />
<None Include="pywraps\py_ua.py" />
<None Include="README.txt" />
<None Include="STATUS.txt" />
<None Include="swig\allins.i" />
<None Include="swig\area.i" />
<None Include="swig\auto.i" />
<None Include="swig\bytes.i" />
<None Include="swig\dbg.i" />
<None Include="swig\diskio.i" />
<None Include="swig\entry.i" />
<None Include="swig\enum.i" />
<None Include="swig\expr.i" />
<None Include="swig\fixup.i" />
<None Include="swig\fpro.i" />
<None Include="swig\frame.i" />
<None Include="swig\funcs.i" />
<None Include="swig\gdl.i" />
<None Include="swig\graph.i" />
<None Include="swig\hexrays.i" />
<None Include="swig\ida.i" />
<None Include="swig\idaapi.i" />
<None Include="swig\idd.i" />
<None Include="swig\idp.i" />
<None Include="swig\ints.i" />
<None Include="swig\kernwin.i" />
<None Include="swig\lines.i" />
<None Include="swig\loader.i" />
<None Include="swig\moves.i" />
<None Include="swig\nalt.i" />
<None Include="swig\name.i" />
<None Include="swig\netnode.i" />
<None Include="swig\offset.i" />
<None Include="swig\pro.i" />
<None Include="swig\queue.i" />
<None Include="swig\search.i" />
<None Include="swig\segment.i" />
<None Include="swig\srarea.i" />
<None Include="swig\strlist.i" />
<None Include="swig\struct.i" />
<None Include="swig\typeconv.i" />
<None Include="swig\typeinf.i" />
<None Include="swig\ua.i" />
<None Include="swig\xref.i" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="idaapi.cpp" />
<ClCompile Include="python.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="idaapi.h" />
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp" />
<ClInclude Include="pywraps\py_bytes.hpp" />
<ClInclude Include="pywraps\py_choose.hpp" />
<ClInclude Include="pywraps\py_choose2.hpp" />
<ClInclude Include="pywraps\py_cli.hpp" />
<ClInclude Include="pywraps\py_custdata.hpp" />
<ClInclude Include="pywraps\py_custview.hpp" />
<ClInclude Include="pywraps\py_cvt.hpp" />
<ClInclude Include="pywraps\py_dbg.hpp" />
<ClInclude Include="pywraps\py_diskio.hpp" />
<ClInclude Include="pywraps\py_expr.hpp" />
<ClInclude Include="pywraps\py_graph.hpp" />
<ClInclude Include="pywraps\py_idaapi.hpp" />
<ClInclude Include="pywraps\py_idp.hpp" />
<ClInclude Include="pywraps\py_kernwin.hpp" />
<ClInclude Include="pywraps\py_lines.hpp" />
<ClInclude Include="pywraps\py_linput.hpp" />
<ClInclude Include="pywraps\py_loader.hpp" />
<ClInclude Include="pywraps\py_nalt.hpp" />
<ClInclude Include="pywraps\py_name.hpp" />
<ClInclude Include="pywraps\py_notifywhen.hpp" />
<ClInclude Include="pywraps\py_plgform.hpp" />
<ClInclude Include="pywraps\py_qfile.hpp" />
<ClInclude Include="pywraps\py_typeinf.hpp" />
<ClInclude Include="pywraps\py_ua.hpp" />
</ItemGroup>
<ItemGroup>
<CustomBuildStep Include="C:\Python25\libs\python25.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python25\libs\python25_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python26\libs\python26_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='SemiDebug|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
<CustomBuildStep Include="C:\Python27\libs\python27_d.lib">
<FileType>Document</FileType>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug64|Win32'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</CustomBuildStep>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -1,320 +1,320 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="python.cpp" />
<ClCompile Include="idaapi.cpp">
<Filter>autogen</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_bytes.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose2.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cli.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custdata.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custview.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cvt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_dbg.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_diskio.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_expr.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_graph.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idaapi.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idp.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_kernwin.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_lines.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_linput.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_loader.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_nalt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_name.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_notifywhen.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_plgform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_qfile.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_typeinf.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_ua.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\pywraps.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="idaapi.h">
<Filter>autogen</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="python.cfg" />
<None Include="swig\allins.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\auto.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\area.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\bytes.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\diskio.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idaapi.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\entry.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\enum.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\expr.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fixup.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fpro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\frame.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\funcs.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\gdl.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\graph.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ida.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idp.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idd.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\dbg.i">
<Filter>swig_i</Filter>
</None>
<None Include="obj\x86_win_vc_32\idaapi.py">
<Filter>autogen</Filter>
</None>
<None Include="swig\ints.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\loader.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\kernwin.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\lines.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\deploy.py">
<Filter>py</Filter>
</None>
<None Include="python\init.py">
<Filter>py</Filter>
</None>
<None Include="python\idautils.py">
<Filter>py</Filter>
</None>
<None Include="python\idc.py">
<Filter>py</Filter>
</None>
<None Include="pywraps\py_appcall.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custdata.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_askusingform.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_choose2.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_cli.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\nalt.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\pro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\name.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\netnode.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\offset.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\py_lines.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custview.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_diskio.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_expr.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_gdl.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_graph.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_idaapi.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_kernwin.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_ua.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_nalt.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_name.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_notifywhen.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_plgform.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\queue.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\search.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\segment.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\srarea.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\strlist.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\struct.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeconv.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeinf.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ua.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\xref.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\moves.i">
<Filter>swig_i</Filter>
</None>
<None Include="BUILDING.txt">
<Filter>TEXT</Filter>
</None>
<None Include="CHANGES.txt">
<Filter>TEXT</Filter>
</None>
<None Include="pywraps\deploy.bat">
<Filter>pywraps</Filter>
</None>
<None Include="STATUS.txt">
<Filter>TEXT</Filter>
</None>
<None Include="README.txt">
<Filter>TEXT</Filter>
</None>
<None Include="swig\hexrays.i">
<Filter>swig_i</Filter>
</None>
<None Include="build.py">
<Filter>py</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="swig_i">
<UniqueIdentifier>{16b55e12-2b1e-4d6d-a1bf-df3400f06d21}</UniqueIdentifier>
</Filter>
<Filter Include="autogen">
<UniqueIdentifier>{f733d65b-1c25-4587-8566-7000875727ff}</UniqueIdentifier>
</Filter>
<Filter Include="py">
<UniqueIdentifier>{e2ec193c-4803-45b0-96c8-bfdc173c14ff}</UniqueIdentifier>
</Filter>
<Filter Include="pywraps">
<UniqueIdentifier>{01459f9f-5d55-4797-aab4-81876a9163d3}</UniqueIdentifier>
</Filter>
<Filter Include="TEXT">
<UniqueIdentifier>{b581ad45-b3f6-4591-baf0-306dab4e0590}</UniqueIdentifier>
</Filter>
</ItemGroup>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="python.cpp" />
<ClCompile Include="idaapi.cpp">
<Filter>autogen</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="pywraps.hpp" />
<ClInclude Include="pywraps\py_askusingform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_bytes.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_choose2.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cli.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custdata.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_custview.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_cvt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_dbg.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_diskio.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_expr.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_graph.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idaapi.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_idp.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_kernwin.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_lines.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_linput.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_loader.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_nalt.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_name.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_notifywhen.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_plgform.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_qfile.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_typeinf.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\py_ua.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="pywraps\pywraps.hpp">
<Filter>pywraps</Filter>
</ClInclude>
<ClInclude Include="idaapi.h">
<Filter>autogen</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="python.cfg" />
<None Include="swig\allins.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\auto.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\area.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\bytes.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\diskio.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idaapi.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\entry.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\enum.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\expr.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fixup.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\fpro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\frame.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\funcs.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\gdl.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\graph.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ida.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idp.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\idd.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\dbg.i">
<Filter>swig_i</Filter>
</None>
<None Include="obj\x86_win_vc_32\idaapi.py">
<Filter>autogen</Filter>
</None>
<None Include="swig\ints.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\loader.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\kernwin.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\lines.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\deploy.py">
<Filter>py</Filter>
</None>
<None Include="python\init.py">
<Filter>py</Filter>
</None>
<None Include="python\idautils.py">
<Filter>py</Filter>
</None>
<None Include="python\idc.py">
<Filter>py</Filter>
</None>
<None Include="pywraps\py_appcall.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custdata.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_askusingform.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_choose2.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_cli.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\nalt.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\pro.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\name.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\netnode.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\offset.i">
<Filter>swig_i</Filter>
</None>
<None Include="pywraps\py_lines.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_custview.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_diskio.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_expr.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_gdl.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_graph.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_idaapi.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_kernwin.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_ua.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_nalt.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_name.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_notifywhen.py">
<Filter>pywraps</Filter>
</None>
<None Include="pywraps\py_plgform.py">
<Filter>pywraps</Filter>
</None>
<None Include="swig\queue.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\search.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\segment.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\srarea.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\strlist.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\struct.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeconv.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\typeinf.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\ua.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\xref.i">
<Filter>swig_i</Filter>
</None>
<None Include="swig\moves.i">
<Filter>swig_i</Filter>
</None>
<None Include="BUILDING.txt">
<Filter>TEXT</Filter>
</None>
<None Include="CHANGES.txt">
<Filter>TEXT</Filter>
</None>
<None Include="pywraps\deploy.bat">
<Filter>pywraps</Filter>
</None>
<None Include="STATUS.txt">
<Filter>TEXT</Filter>
</None>
<None Include="README.txt">
<Filter>TEXT</Filter>
</None>
<None Include="swig\hexrays.i">
<Filter>swig_i</Filter>
</None>
<None Include="build.py">
<Filter>py</Filter>
</None>
</ItemGroup>
<ItemGroup>
<Filter Include="swig_i">
<UniqueIdentifier>{16b55e12-2b1e-4d6d-a1bf-df3400f06d21}</UniqueIdentifier>
</Filter>
<Filter Include="autogen">
<UniqueIdentifier>{f733d65b-1c25-4587-8566-7000875727ff}</UniqueIdentifier>
</Filter>
<Filter Include="py">
<UniqueIdentifier>{e2ec193c-4803-45b0-96c8-bfdc173c14ff}</UniqueIdentifier>
</Filter>
<Filter Include="pywraps">
<UniqueIdentifier>{01459f9f-5d55-4797-aab4-81876a9163d3}</UniqueIdentifier>
</Filter>
<Filter Include="TEXT">
<UniqueIdentifier>{b581ad45-b3f6-4591-baf0-306dab4e0590}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>

View File

@@ -13,6 +13,9 @@ if __name__ == "__main__":
sys.exit(1)
patches = [
# misc
"virtual int idaapi print",
# user_lvar_visitor_t
"virtual int idaapi handle_retrieved_info",
"virtual int idaapi handle_retrieved_mapping",

View File

@@ -8,7 +8,3 @@ REMOVE_CWD_SYS_PATH = 1
// Script timeout (in seconds)
// (A value of 0 disables the timeout)
SCRIPT_TIMEOUT = 3
// Use a local Python library
// If enabled, the "lib" directory tree with modules must be present in IDADIR/python
USE_LOCAL_PYTHON = 0

3614
python.cpp

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -3632,7 +3632,7 @@ def GetSegmentAttr(segea, attr):
seg = idaapi.getseg(segea)
assert seg, "could not find segment at 0x%x" % segea
if attr in [ SEGATTR_ES, SEGATTR_CS, SEGATTR_SS, SEGATTR_DS, SEGATTR_FS, SEGATTR_GS ]:
return idaapi.get_defsr(seg, _SEGATTRMAP[attr])
return idaapi.get_defsr(seg, _SEGATTRMAP[attr][1])
else:
return _IDC_GetAttr(seg, _SEGATTRMAP, attr)
@@ -3651,7 +3651,7 @@ def SetSegmentAttr(segea, attr, value):
seg = idaapi.getseg(segea)
assert seg, "could not find segment at 0x%x" % segea
if attr in [ SEGATTR_ES, SEGATTR_CS, SEGATTR_SS, SEGATTR_DS, SEGATTR_FS, SEGATTR_GS ]:
idaapi.set_defsr(seg, _SEGATTRMAP[attr], value)
idaapi.set_defsr(seg, _SEGATTRMAP[attr][1], value)
else:
_IDC_SetAttr(seg, _SEGATTRMAP, attr, value)
return seg.update()
@@ -3995,7 +3995,11 @@ def SaveFile(filepath, pos, ea, size):
@return: 0 - error, 1 - ok
"""
of = idaapi.fopenM(filepath)
if ( os.path.isfile(filepath) ):
of = idaapi.fopenM(filepath)
else:
of = idaapi.fopenWB(filepath)
if of:
retval = idaapi.base2file(of, pos, ea, ea+size)
@@ -5584,6 +5588,23 @@ def SetMemberComment(sid, member_offset, comment, repeatable):
return idaapi.set_member_cmt(m, comment, repeatable)
def ExpandStruc(sid, offset, delta, recalc):
"""
Expand or shrink a structure type
@param id: structure type ID
@param offset: offset in the structure
@param delta: how many bytes to add or remove
@param recalc: recalculate the locations where the structure
type is used
@return: != 0 - ok
"""
s = idaapi.get_struc(sid)
if not s:
return 0
return idaapi.expand_struc(s, offset, delta, recalc)
def GetFchunkAttr(ea, attr):
"""
Get a function chunk attribute

View File

@@ -108,4 +108,4 @@ userrc = os.path.join(get_user_idadir(), "idapythonrc.py")
if os.path.exists(userrc):
idaapi.IDAPython_ExecScript(userrc, globals())
# All done, ready to rock.
# All done, ready to rock.

View File

@@ -375,4 +375,27 @@ void deinit_pywraps();
void hexrays_clear_python_cfuncptr_t_references(void);
void free_compiled_form_instances(void);
//#define PYGDBG_ENABLED
#ifdef PYGDBG_ENABLED
#define PYGLOG(...) msg(__VA_ARGS__)
#else
#define PYGLOG(...)
#endif
//-------------------------------------------------------------------------
struct pycall_res_t
{
pycall_res_t(PyObject *pyo);
~pycall_res_t();
inline bool success() const { return result.o != NULL; }
newref_t result;
private:
pycall_res_t(); // No.
};
#endif

View File

@@ -1,2 +1,2 @@
@echo off
deploy_all.py
@echo off
deploy_all.py

View File

@@ -1,98 +1,98 @@
"""
Deploy code snips into swig interface files
(c) Hex-Rays
"""
import sys
import re
import os
# creates a regular expression
def make_re(tag, mod_name, prefix):
s = '%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': mod_name, 'tag': tag, 'p': prefix}
return (s, re.compile(s, re.DOTALL))
def convert_path(path_in):
parts = path_in.split('/')
return os.sep.join(parts)
def deploy(mod_name, src_files, dest_file, silent = True):
dest_file = convert_path(dest_file)
src_files = map(convert_path, src_files)
# create regular expressions
templates = (
('pycode', make_re('pycode', mod_name, '#')),
('code', make_re('code', mod_name, '//')),
('inline', make_re('inline', mod_name, '//'))
)
if not os.path.exists(dest_file):
print "File", dest_file, "does not exist and will be skipped"
return
if not os.access(dest_file, os.W_OK):
print "File", dest_file, "is not writable and will be skipped"
return
# read dest file
dest_lines = "".join(file(dest_file, "r").readlines())
# read all source files into one buffer
src_lines = "".join(["".join(file(x, "r").readlines()) for x in src_files])
pcount = 0
for desc, (expr_str, expr) in templates:
# find source pattern
matches = expr.findall(src_lines)
if not matches:
if not silent:
print "Failed to match <%s> source expression against '%s', skipping...!" % (desc, expr_str)
continue
# find pattern in destination
dest = expr.search(dest_lines)
if not dest:
if not silent:
print "Failed to match <%s> destination expression against '%s', skipping..." % (desc, expr_str)
print dest_lines
sys.exit(0)
continue
# accumulate all the strings to be replaced
replaces = []
for src in matches:
replaces.append(src)
dest_lines = dest_lines[:dest.start(1)] + "\n".join(replaces) + dest_lines[dest.end(1):]
pcount += 1
f = file(dest_file, 'w')
if not f:
print "Failed to open destination file:", dest_file
return
f.write(dest_lines)
f.close()
if pcount:
print "Deployed successfully: %s (%d)" % (dest_file, pcount)
else:
print "Nothing was deployed in: %s" % dest_file
def main(argv = None):
if not argv:
argv = sys.argv
if len(argv) != 4:
print "Usage deploy.py modname src_file1,src_file2,... dest_file"
return
mod_name = argv[1]
src_files = argv[2].split(',')
dest_file = argv[3]
deploy(mod_name, src_files, dest_file)
#main(['', 'py_graph', 'py_graph.hpp,py_graph.py', 'graph.i'])
if __name__ == '__main__':
main()
"""
Deploy code snips into swig interface files
(c) Hex-Rays
"""
import sys
import re
import os
# creates a regular expression
def make_re(tag, mod_name, prefix):
s = '%(p)s<%(tag)s\(%(m)s\)>(.+?)%(p)s</%(tag)s\(%(m)s\)>' % {'m': mod_name, 'tag': tag, 'p': prefix}
return (s, re.compile(s, re.DOTALL))
def convert_path(path_in):
parts = path_in.split('/')
return os.sep.join(parts)
def deploy(mod_name, src_files, dest_file, silent = True):
dest_file = convert_path(dest_file)
src_files = map(convert_path, src_files)
# create regular expressions
templates = (
('pycode', make_re('pycode', mod_name, '#')),
('code', make_re('code', mod_name, '//')),
('inline', make_re('inline', mod_name, '//'))
)
if not os.path.exists(dest_file):
print "File", dest_file, "does not exist and will be skipped"
return
if not os.access(dest_file, os.W_OK):
print "File", dest_file, "is not writable and will be skipped"
return
# read dest file
dest_lines = "".join(file(dest_file, "r").readlines())
# read all source files into one buffer
src_lines = "".join(["".join(file(x, "r").readlines()) for x in src_files])
pcount = 0
for desc, (expr_str, expr) in templates:
# find source pattern
matches = expr.findall(src_lines)
if not matches:
if not silent:
print "Failed to match <%s> source expression against '%s', skipping...!" % (desc, expr_str)
continue
# find pattern in destination
dest = expr.search(dest_lines)
if not dest:
if not silent:
print "Failed to match <%s> destination expression against '%s', skipping..." % (desc, expr_str)
print dest_lines
sys.exit(0)
continue
# accumulate all the strings to be replaced
replaces = []
for src in matches:
replaces.append(src)
dest_lines = dest_lines[:dest.start(1)] + "\n".join(replaces) + dest_lines[dest.end(1):]
pcount += 1
f = file(dest_file, 'w')
if not f:
print "Failed to open destination file:", dest_file
return
f.write(dest_lines)
f.close()
if pcount:
print "Deployed successfully: %s (%d)" % (dest_file, pcount)
else:
print "Nothing was deployed in: %s" % dest_file
def main(argv = None):
if not argv:
argv = sys.argv
if len(argv) != 4:
print "Usage deploy.py modname src_file1,src_file2,... dest_file"
return
mod_name = argv[1]
src_files = argv[2].split(',')
dest_file = argv[3]
deploy(mod_name, src_files, dest_file)
#main(['', 'py_graph', 'py_graph.hpp,py_graph.py', 'graph.i'])
if __name__ == '__main__':
main()

View File

@@ -1,172 +1,172 @@
//--------------------------------------------------------------------------
// IDA includes
#include <windows.h>
#include <pro.h>
#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <bytes.hpp>
#include <enum.hpp>
#include <kernwin.hpp>
#include <diskio.hpp>
#include <bytes.hpp>
#include <graph.hpp>
#include <map>
#include <idd.hpp>
#include <dbg.hpp>
#include <ieee.h>
#include <err.h>
#include <expr.hpp>
#include <typeinf.hpp>
#include <struct.hpp>
#include <nalt.hpp>
#include <frame.hpp>
//--------------------------------------------------------------------------
// PyWraps
#include <Python.h>
#include "pywraps.hpp"
#include "swig_stub.h"
#include "py_cvt.hpp"
#include "py_idaapi.hpp"
#include "py_graph.hpp"
#include "py_typeinf.hpp"
#include "py_bytes.hpp"
#include "py_linput.hpp"
#include "py_qfile.hpp"
#include "py_ua.hpp"
#include "py_custdata.hpp"
#include "py_notifywhen.hpp"
#include "py_dbg.hpp"
#include "py_choose2.hpp"
#include "py_plgform.hpp"
#include "py_cli.hpp"
#include "py_custview.hpp"
#include "py_lines.hpp"
#include "py_nalt.hpp"
#include "py_loader.hpp"
#include "py_idp.hpp"
#include "py_kernwin.hpp"
#include "py_askusingform.hpp"
#include "py_expr.hpp"
//--------------------------------------------------------------------------
qvector<PyMethodDef> all_methods;
void driver_add_methods(PyMethodDef *methods)
{
for ( ; methods->ml_name != NULL ; ++methods )
all_methods.push_back(*methods);
}
//--------------------------------------------------------------------------
// Define a class and declare an instance so it gets executed on startup
// It will add the desired methods to the all_methods global variable
#define DRIVER_INIT_METHODS(name) \
class init_##name##_driver_t \
{ \
public: \
init_##name##_driver_t() \
{ \
driver_add_methods(py_methods_##name##); \
} \
} init_##name##_driver;
//--------------------------------------------------------------------------
// PyWraps test drivers
//#include "driver_kernwin.cpp"
//#include "driver_chooser.cpp"
#include "driver_expr.cpp"
//#include "driver_custview.cpp"
//#include "driver_notifywhen.cpp"
//#include "driver_custdata.cpp"
//#include "driver_graph.cpp"
//#include "driver_diskio.cpp"
//#include "driver_bytes.cpp"
//#include "driver_dbg.cpp"
//#include "driver_nalt.cpp"
//#include "driver_cli.cpp"
//--------------------------------------------------------------------------
//#define DRIVER_FIX
#ifdef DRIVER_FIX
#define PLUGIN_FLAGS PLUGIN_FIX
#else
#define PLUGIN_FLAGS 0
#endif
//--------------------------------------------------------------------------
void setup_pywraps()
{
static bool installed = false;
if ( installed )
{
msg("pywraps already installed\n");
return;
}
static const PyMethodDef null_method = {0};
all_methods.push_back(null_method);
Py_InitModule("pywraps", all_methods.begin());
init_pywraps();
msg("pywraps installed!\n");
installed = true;
}
//--------------------------------------------------------------------------
void idaapi run(int /*arg*/)
{
setup_pywraps();
#ifdef DRIVER_RUN
driver_run(0);
#endif
}
//--------------------------------------------------------------------------
//
// Initialize.
//
int idaapi init(void)
{
#ifndef DRIVER_FIX
setup_pywraps();
#endif
#ifdef DRIVER_INIT
return driver_init();
#else
return PLUGIN_KEEP;
#endif
}
//--------------------------------------------------------------------------
void idaapi term(void)
{
#ifdef DRIVER_TERM
driver_term();
#endif
}
//--------------------------------------------------------------------------
//
// PLUGIN DESCRIPTION BLOCK
//
//--------------------------------------------------------------------------
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
PLUGIN_FLAGS, // plugin flags
init, // initialize
term, // terminate. this pointer may be NULL.
run, // invoke plugin
// long comment about the plugin
"PyWraps plugin",
// it could appear in the status line
// or as a hint
"", // multiline help about the plugin
"pywraps", // the preferred short name of the plugin
"" // the preferred hotkey to run the plugin
};
//--------------------------------------------------------------------------
// IDA includes
#include <windows.h>
#include <pro.h>
#include <ida.hpp>
#include <idp.hpp>
#include <loader.hpp>
#include <bytes.hpp>
#include <enum.hpp>
#include <kernwin.hpp>
#include <diskio.hpp>
#include <bytes.hpp>
#include <graph.hpp>
#include <map>
#include <idd.hpp>
#include <dbg.hpp>
#include <ieee.h>
#include <err.h>
#include <expr.hpp>
#include <typeinf.hpp>
#include <struct.hpp>
#include <nalt.hpp>
#include <frame.hpp>
//--------------------------------------------------------------------------
// PyWraps
#include <Python.h>
#include "pywraps.hpp"
#include "swig_stub.h"
#include "py_cvt.hpp"
#include "py_idaapi.hpp"
#include "py_graph.hpp"
#include "py_typeinf.hpp"
#include "py_bytes.hpp"
#include "py_linput.hpp"
#include "py_qfile.hpp"
#include "py_ua.hpp"
#include "py_custdata.hpp"
#include "py_notifywhen.hpp"
#include "py_dbg.hpp"
#include "py_choose2.hpp"
#include "py_plgform.hpp"
#include "py_cli.hpp"
#include "py_custview.hpp"
#include "py_lines.hpp"
#include "py_nalt.hpp"
#include "py_loader.hpp"
#include "py_idp.hpp"
#include "py_kernwin.hpp"
#include "py_askusingform.hpp"
#include "py_expr.hpp"
//--------------------------------------------------------------------------
qvector<PyMethodDef> all_methods;
void driver_add_methods(PyMethodDef *methods)
{
for ( ; methods->ml_name != NULL ; ++methods )
all_methods.push_back(*methods);
}
//--------------------------------------------------------------------------
// Define a class and declare an instance so it gets executed on startup
// It will add the desired methods to the all_methods global variable
#define DRIVER_INIT_METHODS(name) \
class init_##name##_driver_t \
{ \
public: \
init_##name##_driver_t() \
{ \
driver_add_methods(py_methods_##name##); \
} \
} init_##name##_driver;
//--------------------------------------------------------------------------
// PyWraps test drivers
//#include "driver_kernwin.cpp"
//#include "driver_chooser.cpp"
#include "driver_expr.cpp"
//#include "driver_custview.cpp"
//#include "driver_notifywhen.cpp"
//#include "driver_custdata.cpp"
//#include "driver_graph.cpp"
//#include "driver_diskio.cpp"
//#include "driver_bytes.cpp"
//#include "driver_dbg.cpp"
//#include "driver_nalt.cpp"
//#include "driver_cli.cpp"
//--------------------------------------------------------------------------
//#define DRIVER_FIX
#ifdef DRIVER_FIX
#define PLUGIN_FLAGS PLUGIN_FIX
#else
#define PLUGIN_FLAGS 0
#endif
//--------------------------------------------------------------------------
void setup_pywraps()
{
static bool installed = false;
if ( installed )
{
msg("pywraps already installed\n");
return;
}
static const PyMethodDef null_method = {0};
all_methods.push_back(null_method);
Py_InitModule("pywraps", all_methods.begin());
init_pywraps();
msg("pywraps installed!\n");
installed = true;
}
//--------------------------------------------------------------------------
void idaapi run(int /*arg*/)
{
setup_pywraps();
#ifdef DRIVER_RUN
driver_run(0);
#endif
}
//--------------------------------------------------------------------------
//
// Initialize.
//
int idaapi init(void)
{
#ifndef DRIVER_FIX
setup_pywraps();
#endif
#ifdef DRIVER_INIT
return driver_init();
#else
return PLUGIN_KEEP;
#endif
}
//--------------------------------------------------------------------------
void idaapi term(void)
{
#ifdef DRIVER_TERM
driver_term();
#endif
}
//--------------------------------------------------------------------------
//
// PLUGIN DESCRIPTION BLOCK
//
//--------------------------------------------------------------------------
plugin_t PLUGIN =
{
IDP_INTERFACE_VERSION,
PLUGIN_FLAGS, // plugin flags
init, // initialize
term, // terminate. this pointer may be NULL.
run, // invoke plugin
// long comment about the plugin
"PyWraps plugin",
// it could appear in the status line
// or as a hint
"", // multiline help about the plugin
"pywraps", // the preferred short name of the plugin
"" // the preferred hotkey to run the plugin
};

View File

@@ -1,19 +1,19 @@
#include "py_bytes.hpp"
//--------------------------------------------------------------------------
static PyObject *ex_nextthat(PyObject *self, PyObject *args)
{
PyObject *callback;
pyul_t addr, bound;
if ( !PyArg_ParseTuple(args, PY_FMT64 PY_FMT64 "O", &addr, &bound, &callback) )
return NULL;
return Py_BuildValue("i", py_nextthat(pyul_t(addr), pyul_t(bound), callback));
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_bytes[] =
{
{"nextthat", ex_nextthat, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
#include "py_bytes.hpp"
//--------------------------------------------------------------------------
static PyObject *ex_nextthat(PyObject *self, PyObject *args)
{
PyObject *callback;
pyul_t addr, bound;
if ( !PyArg_ParseTuple(args, PY_FMT64 PY_FMT64 "O", &addr, &bound, &callback) )
return NULL;
return Py_BuildValue("i", py_nextthat(pyul_t(addr), pyul_t(bound), callback));
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_bytes[] =
{
{"nextthat", ex_nextthat, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
DRIVER_INIT_METHODS(bytes);

View File

@@ -1,109 +1,109 @@
#include "py_choose2.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_choose2_find(PyObject *self, PyObject *args)
{
char *title;
if ( !PyArg_ParseTuple(args, "s", &title) )
return NULL;
else
return choose2_find(title);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_create(PyObject *self, PyObject *args)
{
PyObject *obj;
int embedded;
if ( !PyArg_ParseTuple(args, "Oi", &obj, &embedded) )
return NULL;
else
return PyInt_FromLong(choose2_create(obj, embedded == 1 ? true : false));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_activate(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_activate(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_close(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_close(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_refresh(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_refresh(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_add_command(PyObject *self, PyObject *args)
{
PyObject *obj;
char *caption;
int flags, menu_index, icon;
if ( !PyArg_ParseTuple(args, "Osiii", &obj, &caption, &flags, &menu_index, &icon) )
return NULL;
else
return PyInt_FromLong(choose2_add_command(obj, caption, flags, menu_index, icon));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_test_embedded(PyObject *self, PyObject *args)
{
return PyLong_FromSize_t(choose2_get_test_embedded());
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded(obj);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded_selection(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded_selection(obj);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_chooser[] =
{
{"py_choose2_find", ex_choose2_find, METH_VARARGS, ""},
{"py_choose2_create", ex_choose2_create, METH_VARARGS, ""},
{"py_choose2_close", ex_choose2_close, METH_VARARGS, ""},
{"py_choose2_activate", ex_choose2_activate, METH_VARARGS, ""},
{"py_choose2_refresh", ex_choose2_refresh, METH_VARARGS, ""},
{"py_choose2_add_command", ex_choose2_add_command, METH_VARARGS, ""},
{"py_choose2_get_test_embedded", ex_choose2_get_test_embedded, METH_VARARGS, ""},
{"py_choose2_get_embedded", ex_choose2_get_embedded, METH_VARARGS, ""},
{"py_choose2_get_embedded_selection", ex_choose2_get_embedded_selection, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} // End of methods
};
DRIVER_INIT_METHODS(chooser);
#include "py_choose2.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_choose2_find(PyObject *self, PyObject *args)
{
char *title;
if ( !PyArg_ParseTuple(args, "s", &title) )
return NULL;
else
return choose2_find(title);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_create(PyObject *self, PyObject *args)
{
PyObject *obj;
int embedded;
if ( !PyArg_ParseTuple(args, "Oi", &obj, &embedded) )
return NULL;
else
return PyInt_FromLong(choose2_create(obj, embedded == 1 ? true : false));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_activate(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_activate(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_close(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_close(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_refresh(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
choose2_refresh(obj);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_add_command(PyObject *self, PyObject *args)
{
PyObject *obj;
char *caption;
int flags, menu_index, icon;
if ( !PyArg_ParseTuple(args, "Osiii", &obj, &caption, &flags, &menu_index, &icon) )
return NULL;
else
return PyInt_FromLong(choose2_add_command(obj, caption, flags, menu_index, icon));
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_test_embedded(PyObject *self, PyObject *args)
{
return PyLong_FromSize_t(choose2_get_test_embedded());
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded(obj);
}
//-------------------------------------------------------------------------
static PyObject *ex_choose2_get_embedded_selection(PyObject *self, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
else
return choose2_get_embedded_selection(obj);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_chooser[] =
{
{"py_choose2_find", ex_choose2_find, METH_VARARGS, ""},
{"py_choose2_create", ex_choose2_create, METH_VARARGS, ""},
{"py_choose2_close", ex_choose2_close, METH_VARARGS, ""},
{"py_choose2_activate", ex_choose2_activate, METH_VARARGS, ""},
{"py_choose2_refresh", ex_choose2_refresh, METH_VARARGS, ""},
{"py_choose2_add_command", ex_choose2_add_command, METH_VARARGS, ""},
{"py_choose2_get_test_embedded", ex_choose2_get_test_embedded, METH_VARARGS, ""},
{"py_choose2_get_embedded", ex_choose2_get_embedded, METH_VARARGS, ""},
{"py_choose2_get_embedded_selection", ex_choose2_get_embedded_selection, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} // End of methods
};
DRIVER_INIT_METHODS(chooser);

View File

@@ -1,29 +1,29 @@
#include "py_custview.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_install_command_interpreter(PyObject *self, PyObject *args)
{
PyObject *py_obj;
if ( !PyArg_ParseTuple(args, "O", &py_obj) )
return NULL;
return PyInt_FromLong(py_install_command_interpreter(py_obj));
}
//-------------------------------------------------------------------------
static PyObject *ex_remove_command_interpreter(PyObject *self, PyObject *args)
{
int cli_idx;
if ( !PyArg_ParseTuple(args, "i", &cli_idx) )
return NULL;
py_remove_command_interpreter(cli_idx);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_cli[] =
{
{"install_command_interpreter", ex_install_command_interpreter, METH_VARARGS, ""},
{"remove_command_interpreter", ex_remove_command_interpreter, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
#include "py_custview.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_install_command_interpreter(PyObject *self, PyObject *args)
{
PyObject *py_obj;
if ( !PyArg_ParseTuple(args, "O", &py_obj) )
return NULL;
return PyInt_FromLong(py_install_command_interpreter(py_obj));
}
//-------------------------------------------------------------------------
static PyObject *ex_remove_command_interpreter(PyObject *self, PyObject *args)
{
int cli_idx;
if ( !PyArg_ParseTuple(args, "i", &cli_idx) )
return NULL;
py_remove_command_interpreter(cli_idx);
Py_RETURN_NONE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_cli[] =
{
{"install_command_interpreter", ex_install_command_interpreter, METH_VARARGS, ""},
{"remove_command_interpreter", ex_remove_command_interpreter, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
DRIVER_INIT_METHODS(cli);

View File

@@ -1,384 +1,384 @@
#include "py_custview.hpp"
//--------------------------------------------------------------------------
class my_custviewer: public customviewer_t
{
private:
cvdata_simpleline_t data;
size_t id_n;
virtual bool on_popup_menu(size_t menu_id)
{
if ( menu_id == id_n )
msg("popup menu N chosen!\n");
return true;
}
virtual bool on_click(int shift)
{
msg("onclick; shift=%d\n", shift);
return true;
}
virtual void on_close()
{
id_n = 0;
msg("closed...\n");
}
virtual bool on_keydown(int key, int shift)
{
switch ( key )
{
case 'N':
warning("The hotkey 'N' has been pressed");
return true;
case 'I':
{
int x, y;
place_t *pl = get_place(false, &x, &y);
if ( pl == NULL )
return false;
msg("x=%d y=%d\n", x, y);
simpleline_t sl = *data.get_line(pl);
sl.bgcolor = bgcolor_t(~uint32(sl.bgcolor));
data.set_line(data.to_lineno(pl), sl);
refresh_current();
return true;
}
case 'A':
{
char buf[100];
qsnprintf(buf, sizeof(buf), "This is line %d\n", data.count());
data.add_line(buf);
msg("Added one more line...\n");
return true;
}
case 'S':
{
twinpos_t p1, p2;
::readsel2(_cv, &p1, &p2);
size_t y1 = data.to_lineno(p1.at);
size_t y2 = data.to_lineno(p2.at);
int x1 = p1.x;
int x2 = p2.x;
msg("(x1=%d y1=%d) (x2=%d y2=%d)", x1, y1, x2, y2);
return true;
}
case 'X':
data.set_minmax();
return true;
case 'R':
refresh();
msg("refreshing!\n");
return true;
case IK_ESCAPE:
close();
return true;
}
return false;
}
virtual void on_curpos_changed()
{
qstring word;
if ( get_current_word(false, word) )
msg("Current word is: %s\n", word.c_str());
}
virtual bool on_hint(place_t *place, int *important_lines, qstring &hint)
{
simpleline_t *line = data.get_line(place);
if ( line == NULL )
return false;
*important_lines = 1;
hint = line->line;
return true;
}
public:
void init_sample_lines()
{
strvec_t &lines = data.get_lines();
static struct
{
const char *text;
bgcolor_t color;
} const sample_lines[] =
{
{ "This is a sample text", 0xFFFFFF },
{ "It will be displayed in the custom view", 0xFFC0C0 },
{ COLSTR("This line will be colored as erroneous", SCOLOR_ERROR), 0xC0FFC0 },
{ COLSTR("Every", SCOLOR_AUTOCMT) " "
COLSTR("word", SCOLOR_DNAME) " "
COLSTR("can", SCOLOR_IMPNAME) " "
COLSTR("be", SCOLOR_NUMBER) " "
COLSTR("colored!", SCOLOR_EXTRA), 0xC0C0FF },
{ " No limit on the number of lines.", 0xC0FFFF },
};
for ( int i=0; i<qnumber(sample_lines); i++ )
{
lines.push_back(simpleline_t("")); // add empty line
lines.push_back(simpleline_t(sample_lines[i].text));
lines.back().bgcolor = sample_lines[i].color;
}
}
my_custviewer()
{
id_n = 0;
init_sample_lines();
data.set_minmax();
}
bool init(const char *title)
{
if ( id_n != 0 )
return true;
if ( !create(title, HAVE_HINT | HAVE_CLICK | HAVE_KEYDOWN | HAVE_CURPOS, &data) )
return false;
id_n = add_popup_menu("Do this", "N");
return true;
}
};
my_custviewer *g_cv;
//-------------------------------------------------------------------------
static PyObject *ex_pyscv_init(PyObject *self, PyObject *args)
{
const char *title;
PyObject *py_link;
if ( !PyArg_ParseTuple(args, "Os", &py_link, &title) )
return NULL;
return pyscv_init(py_link, title);
}
static PyObject *ex_pyscv_add_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
if ( !PyArg_ParseTuple(args, "OO", &py_this, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_add_line(py_this, py_sl));
}
static PyObject *ex_pyscv_delete(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_delete(py_this));
}
static PyObject *ex_pyscv_show(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_show(py_this));
}
static PyObject *ex_pyscv_refresh(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_refresh(py_this));
}
static PyObject *ex_pyscv_close(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_close(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_clear_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_clear_popup_menu(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_del_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return Py_BuildValue("i", pyscv_del_line(py_this, nline));
}
static PyObject *ex_pyscv_get_pos(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_pos(py_this, mouse == 0 ? false : true);
}
static PyObject *ex_pyscv_refresh_current(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return Py_BuildValue("i", pyscv_refresh_current(py_this));
}
static PyObject *ex_pyscv_get_current_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse, notags;
if ( !PyArg_ParseTuple(args, "Oii", &py_this, &mouse, &notags) )
return NULL;
return pyscv_get_current_line(py_this, mouse == 0 ? false : true, notags == 0 ? false : true);
}
static PyObject *ex_pyscv_is_focused(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_is_focused(py_this));
}
static PyObject *ex_pyscv_add_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &py_this, &title, &hotkey) )
return NULL;
return Py_BuildValue("i", pyscv_add_popup_menu(py_this, title, hotkey));
}
static PyObject *ex_pyscv_get_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return pyscv_get_line(py_this, nline);
}
static PyObject *ex_pyscv_jumpto(PyObject *self, PyObject *args)
{
PyObject *py_this;
int x, y;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "ii", &py_this, &lineno, &x, &y) )
return NULL;
return Py_BuildValue("i", pyscv_jumpto(py_this, lineno, x, y));
}
static PyObject *ex_pyscv_edit_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_edit_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_insert_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_insert_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_patch_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t lineno, offs;
int value;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 PY_FMT64 "i", &py_this, &lineno, &offs, &value) )
return NULL;
return Py_BuildValue("i", pyscv_patch_line(py_this, lineno, offs, value));
}
static PyObject *ex_pyscv_count(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue(PY_FMT64, pyscv_count(py_this));
}
static PyObject *ex_pyscv_get_selection(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_get_selection(py_this);
}
static PyObject *ex_pyscv_get_current_word(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_current_word(py_this, mouse != 0);
}
static PyObject *ex_pyscv_clear_lines(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_clear_lines(py_this);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_custview[] =
{
{"pyscv_init", ex_pyscv_init, METH_VARARGS, ""},
{"pyscv_close", ex_pyscv_close, METH_VARARGS, ""},
{"pyscv_add_line", ex_pyscv_add_line, METH_VARARGS, ""},
{"pyscv_delete", ex_pyscv_delete, METH_VARARGS, ""},
{"pyscv_refresh", ex_pyscv_refresh, METH_VARARGS, ""},
{"pyscv_clear_lines", ex_pyscv_clear_lines, METH_VARARGS, ""},
{"pyscv_show", ex_pyscv_show, METH_VARARGS, ""},
{"pyscv_clear_popup_menu", ex_pyscv_clear_popup_menu, METH_VARARGS, ""},
{"pyscv_del_line", ex_pyscv_del_line, METH_VARARGS, ""},
{"pyscv_get_pos", ex_pyscv_get_pos, METH_VARARGS, ""},
{"pyscv_refresh_current", ex_pyscv_refresh_current, METH_VARARGS, ""},
{"pyscv_get_current_line", ex_pyscv_get_current_line, METH_VARARGS, ""},
{"pyscv_is_focused", ex_pyscv_is_focused, METH_VARARGS, ""},
{"pyscv_add_popup_menu", ex_pyscv_add_popup_menu, METH_VARARGS, ""},
{"pyscv_get_line", ex_pyscv_get_line, METH_VARARGS, ""},
{"pyscv_jumpto", ex_pyscv_jumpto, METH_VARARGS, ""},
{"pyscv_edit_line", ex_pyscv_edit_line, METH_VARARGS, ""},
{"pyscv_insert_line", ex_pyscv_insert_line, METH_VARARGS, ""},
{"pyscv_count", ex_pyscv_count, METH_VARARGS, ""},
{"pyscv_patch_line", ex_pyscv_patch_line, METH_VARARGS, ""},
{"pyscv_get_selection", ex_pyscv_get_selection, METH_VARARGS, ""},
{"pyscv_get_current_word", ex_pyscv_get_current_word, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(custview);
#define DRIVER_RUN
void driver_run(int)
{
if ( !g_cv->init("My sample viewer!") )
{
msg("Failed to create cv\n!");
return;
}
g_cv->show();
}
#define DRIVER_INIT
int driver_init()
{
g_cv = new my_custviewer();
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
g_cv->close();
delete g_cv;
}
#include "py_custview.hpp"
//--------------------------------------------------------------------------
class my_custviewer: public customviewer_t
{
private:
cvdata_simpleline_t data;
size_t id_n;
virtual bool on_popup_menu(size_t menu_id)
{
if ( menu_id == id_n )
msg("popup menu N chosen!\n");
return true;
}
virtual bool on_click(int shift)
{
msg("onclick; shift=%d\n", shift);
return true;
}
virtual void on_close()
{
id_n = 0;
msg("closed...\n");
}
virtual bool on_keydown(int key, int shift)
{
switch ( key )
{
case 'N':
warning("The hotkey 'N' has been pressed");
return true;
case 'I':
{
int x, y;
place_t *pl = get_place(false, &x, &y);
if ( pl == NULL )
return false;
msg("x=%d y=%d\n", x, y);
simpleline_t sl = *data.get_line(pl);
sl.bgcolor = bgcolor_t(~uint32(sl.bgcolor));
data.set_line(data.to_lineno(pl), sl);
refresh_current();
return true;
}
case 'A':
{
char buf[100];
qsnprintf(buf, sizeof(buf), "This is line %d\n", data.count());
data.add_line(buf);
msg("Added one more line...\n");
return true;
}
case 'S':
{
twinpos_t p1, p2;
::readsel2(_cv, &p1, &p2);
size_t y1 = data.to_lineno(p1.at);
size_t y2 = data.to_lineno(p2.at);
int x1 = p1.x;
int x2 = p2.x;
msg("(x1=%d y1=%d) (x2=%d y2=%d)", x1, y1, x2, y2);
return true;
}
case 'X':
data.set_minmax();
return true;
case 'R':
refresh();
msg("refreshing!\n");
return true;
case IK_ESCAPE:
close();
return true;
}
return false;
}
virtual void on_curpos_changed()
{
qstring word;
if ( get_current_word(false, word) )
msg("Current word is: %s\n", word.c_str());
}
virtual bool on_hint(place_t *place, int *important_lines, qstring &hint)
{
simpleline_t *line = data.get_line(place);
if ( line == NULL )
return false;
*important_lines = 1;
hint = line->line;
return true;
}
public:
void init_sample_lines()
{
strvec_t &lines = data.get_lines();
static struct
{
const char *text;
bgcolor_t color;
} const sample_lines[] =
{
{ "This is a sample text", 0xFFFFFF },
{ "It will be displayed in the custom view", 0xFFC0C0 },
{ COLSTR("This line will be colored as erroneous", SCOLOR_ERROR), 0xC0FFC0 },
{ COLSTR("Every", SCOLOR_AUTOCMT) " "
COLSTR("word", SCOLOR_DNAME) " "
COLSTR("can", SCOLOR_IMPNAME) " "
COLSTR("be", SCOLOR_NUMBER) " "
COLSTR("colored!", SCOLOR_EXTRA), 0xC0C0FF },
{ " No limit on the number of lines.", 0xC0FFFF },
};
for ( int i=0; i<qnumber(sample_lines); i++ )
{
lines.push_back(simpleline_t("")); // add empty line
lines.push_back(simpleline_t(sample_lines[i].text));
lines.back().bgcolor = sample_lines[i].color;
}
}
my_custviewer()
{
id_n = 0;
init_sample_lines();
data.set_minmax();
}
bool init(const char *title)
{
if ( id_n != 0 )
return true;
if ( !create(title, HAVE_HINT | HAVE_CLICK | HAVE_KEYDOWN | HAVE_CURPOS, &data) )
return false;
id_n = add_popup_menu("Do this", "N");
return true;
}
};
my_custviewer *g_cv;
//-------------------------------------------------------------------------
static PyObject *ex_pyscv_init(PyObject *self, PyObject *args)
{
const char *title;
PyObject *py_link;
if ( !PyArg_ParseTuple(args, "Os", &py_link, &title) )
return NULL;
return pyscv_init(py_link, title);
}
static PyObject *ex_pyscv_add_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
if ( !PyArg_ParseTuple(args, "OO", &py_this, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_add_line(py_this, py_sl));
}
static PyObject *ex_pyscv_delete(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_delete(py_this));
}
static PyObject *ex_pyscv_show(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_show(py_this));
}
static PyObject *ex_pyscv_refresh(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_refresh(py_this));
}
static PyObject *ex_pyscv_close(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_close(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_clear_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
pyscv_clear_popup_menu(py_this);
Py_RETURN_NONE;
}
static PyObject *ex_pyscv_del_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return Py_BuildValue("i", pyscv_del_line(py_this, nline));
}
static PyObject *ex_pyscv_get_pos(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_pos(py_this, mouse == 0 ? false : true);
}
static PyObject *ex_pyscv_refresh_current(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return Py_BuildValue("i", pyscv_refresh_current(py_this));
}
static PyObject *ex_pyscv_get_current_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse, notags;
if ( !PyArg_ParseTuple(args, "Oii", &py_this, &mouse, &notags) )
return NULL;
return pyscv_get_current_line(py_this, mouse == 0 ? false : true, notags == 0 ? false : true);
}
static PyObject *ex_pyscv_is_focused(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue("i", pyscv_is_focused(py_this));
}
static PyObject *ex_pyscv_add_popup_menu(PyObject *self, PyObject *args)
{
PyObject *py_this;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &py_this, &title, &hotkey) )
return NULL;
return Py_BuildValue("i", pyscv_add_popup_menu(py_this, title, hotkey));
}
static PyObject *ex_pyscv_get_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t nline;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64, &py_this, &nline) )
return NULL;
return pyscv_get_line(py_this, nline);
}
static PyObject *ex_pyscv_jumpto(PyObject *self, PyObject *args)
{
PyObject *py_this;
int x, y;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "ii", &py_this, &lineno, &x, &y) )
return NULL;
return Py_BuildValue("i", pyscv_jumpto(py_this, lineno, x, y));
}
static PyObject *ex_pyscv_edit_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_edit_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_insert_line(PyObject *self, PyObject *args)
{
PyObject *py_this, *py_sl;
size_t lineno;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 "O", &py_this, &lineno, &py_sl) )
return NULL;
return Py_BuildValue("i", pyscv_insert_line(py_this, lineno, py_sl));
}
static PyObject *ex_pyscv_patch_line(PyObject *self, PyObject *args)
{
PyObject *py_this;
size_t lineno, offs;
int value;
if ( !PyArg_ParseTuple(args, "O" PY_FMT64 PY_FMT64 "i", &py_this, &lineno, &offs, &value) )
return NULL;
return Py_BuildValue("i", pyscv_patch_line(py_this, lineno, offs, value));
}
static PyObject *ex_pyscv_count(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return Py_BuildValue(PY_FMT64, pyscv_count(py_this));
}
static PyObject *ex_pyscv_get_selection(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_get_selection(py_this);
}
static PyObject *ex_pyscv_get_current_word(PyObject *self, PyObject *args)
{
PyObject *py_this;
int mouse;
if ( !PyArg_ParseTuple(args, "Oi", &py_this, &mouse) )
return NULL;
return pyscv_get_current_word(py_this, mouse != 0);
}
static PyObject *ex_pyscv_clear_lines(PyObject *self, PyObject *args)
{
PyObject *py_this;
if ( !PyArg_ParseTuple(args, "O", &py_this) )
return NULL;
return pyscv_clear_lines(py_this);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_custview[] =
{
{"pyscv_init", ex_pyscv_init, METH_VARARGS, ""},
{"pyscv_close", ex_pyscv_close, METH_VARARGS, ""},
{"pyscv_add_line", ex_pyscv_add_line, METH_VARARGS, ""},
{"pyscv_delete", ex_pyscv_delete, METH_VARARGS, ""},
{"pyscv_refresh", ex_pyscv_refresh, METH_VARARGS, ""},
{"pyscv_clear_lines", ex_pyscv_clear_lines, METH_VARARGS, ""},
{"pyscv_show", ex_pyscv_show, METH_VARARGS, ""},
{"pyscv_clear_popup_menu", ex_pyscv_clear_popup_menu, METH_VARARGS, ""},
{"pyscv_del_line", ex_pyscv_del_line, METH_VARARGS, ""},
{"pyscv_get_pos", ex_pyscv_get_pos, METH_VARARGS, ""},
{"pyscv_refresh_current", ex_pyscv_refresh_current, METH_VARARGS, ""},
{"pyscv_get_current_line", ex_pyscv_get_current_line, METH_VARARGS, ""},
{"pyscv_is_focused", ex_pyscv_is_focused, METH_VARARGS, ""},
{"pyscv_add_popup_menu", ex_pyscv_add_popup_menu, METH_VARARGS, ""},
{"pyscv_get_line", ex_pyscv_get_line, METH_VARARGS, ""},
{"pyscv_jumpto", ex_pyscv_jumpto, METH_VARARGS, ""},
{"pyscv_edit_line", ex_pyscv_edit_line, METH_VARARGS, ""},
{"pyscv_insert_line", ex_pyscv_insert_line, METH_VARARGS, ""},
{"pyscv_count", ex_pyscv_count, METH_VARARGS, ""},
{"pyscv_patch_line", ex_pyscv_patch_line, METH_VARARGS, ""},
{"pyscv_get_selection", ex_pyscv_get_selection, METH_VARARGS, ""},
{"pyscv_get_current_word", ex_pyscv_get_current_word, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(custview);
#define DRIVER_RUN
void driver_run(int)
{
if ( !g_cv->init("My sample viewer!") )
{
msg("Failed to create cv\n!");
return;
}
g_cv->show();
}
#define DRIVER_INIT
int driver_init()
{
g_cv = new my_custviewer();
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
g_cv->close();
delete g_cv;
}

View File

@@ -1,79 +1,79 @@
#include "py_dbg.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_getthreadsregbase(PyObject * /*self*/, PyObject *args)
{
PyObject *py_tid, *py_sreg_value;
if ( !PyArg_ParseTuple(args, "OO", &py_tid, &py_sreg_value) )
return NULL;
return dbg_get_thread_sreg_base(py_tid, py_sreg_value);
}
//-------------------------------------------------------------------------
static PyObject *ex_readmemory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_size;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_size) )
return NULL;
return dbg_read_memory(py_ea, py_size);
}
//-------------------------------------------------------------------------
static PyObject *ex_writememory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_buf;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_buf) )
return NULL;
return dbg_write_memory(py_ea, py_buf);
}
//-------------------------------------------------------------------------
static PyObject *ex_getmeminfo(PyObject * /*self*/, PyObject *args)
{
return dbg_get_memory_info();
}
//-------------------------------------------------------------------------
static PyObject *ex_getregs(PyObject *self, PyObject *args)
{
return dbg_get_registers();
}
//-------------------------------------------------------------------------
static PyObject *ex_appcall(PyObject * /*self*/, PyObject *args)
{
PyObject *app_args, *type, *fields;
int func_ea, tid;
if ( !PyArg_ParseTuple(args, "iiOOO", &func_ea, &tid, &type, &fields, &app_args) )
return NULL;
return py_appcall(func_ea, tid, type, fields, app_args);
}
//-------------------------------------------------------------------------
static PyObject *ex_pytoidc(
PyObject *self,
PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
idc_value_t v;
int sn = 0;
borref_t self_ref(self);
if ( pyvar_to_idcvar(self_ref, &v, &sn) < CIP_OK )
Py_RETURN_NONE;
Py_RETURN_TRUE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_dbg[] =
{
{"getregs", ex_getregs, METH_VARARGS, ""},
{"getmeminfo", ex_getmeminfo, METH_VARARGS, ""},
{"readmemory", ex_readmemory, METH_VARARGS, ""},
{"writememory", ex_writememory, METH_VARARGS, ""},
{"getthreadsregbase", ex_getthreadsregbase, METH_VARARGS, ""},
{"appcall", ex_appcall, METH_VARARGS, ""},
{"pytoidc", ex_pytoidc, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(dbg);
#include "py_dbg.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_getthreadsregbase(PyObject * /*self*/, PyObject *args)
{
PyObject *py_tid, *py_sreg_value;
if ( !PyArg_ParseTuple(args, "OO", &py_tid, &py_sreg_value) )
return NULL;
return dbg_get_thread_sreg_base(py_tid, py_sreg_value);
}
//-------------------------------------------------------------------------
static PyObject *ex_readmemory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_size;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_size) )
return NULL;
return dbg_read_memory(py_ea, py_size);
}
//-------------------------------------------------------------------------
static PyObject *ex_writememory(PyObject * /*self*/, PyObject *args)
{
PyObject *py_ea, *py_buf;
if ( !PyArg_ParseTuple(args, "OO", &py_ea, &py_buf) )
return NULL;
return dbg_write_memory(py_ea, py_buf);
}
//-------------------------------------------------------------------------
static PyObject *ex_getmeminfo(PyObject * /*self*/, PyObject *args)
{
return dbg_get_memory_info();
}
//-------------------------------------------------------------------------
static PyObject *ex_getregs(PyObject *self, PyObject *args)
{
return dbg_get_registers();
}
//-------------------------------------------------------------------------
static PyObject *ex_appcall(PyObject * /*self*/, PyObject *args)
{
PyObject *app_args, *type, *fields;
int func_ea, tid;
if ( !PyArg_ParseTuple(args, "iiOOO", &func_ea, &tid, &type, &fields, &app_args) )
return NULL;
return py_appcall(func_ea, tid, type, fields, app_args);
}
//-------------------------------------------------------------------------
static PyObject *ex_pytoidc(
PyObject *self,
PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
idc_value_t v;
int sn = 0;
borref_t self_ref(self);
if ( pyvar_to_idcvar(self_ref, &v, &sn) < CIP_OK )
Py_RETURN_NONE;
Py_RETURN_TRUE;
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_dbg[] =
{
{"getregs", ex_getregs, METH_VARARGS, ""},
{"getmeminfo", ex_getmeminfo, METH_VARARGS, ""},
{"readmemory", ex_readmemory, METH_VARARGS, ""},
{"writememory", ex_writememory, METH_VARARGS, ""},
{"getthreadsregbase", ex_getthreadsregbase, METH_VARARGS, ""},
{"appcall", ex_appcall, METH_VARARGS, ""},
{"pytoidc", ex_pytoidc, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(dbg);

View File

@@ -1,47 +1,47 @@
#include "py_diskio.hpp"
static PyObject *ex_enumfiles(PyObject * /*self*/, PyObject *args)
{
PyObject *path, *fname, *callback;
if ( !PyArg_ParseTuple(args, "OOO", &path, &fname, &callback) )
return NULL;
return py_enumerate_files(path, fname, callback);
}
//
//static PyObject *ex_linput_close(PyObject * /*self*/, PyObject *args)
//{
// PyObject *obj;
// if ( !PyArg_ParseTuple(args, "O", &obj) )
// return NULL;
// pyl_close(obj);
// Py_RETURN_NONE;
//}
//
//static PyObject *ex_linput_open(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_filename, *py_remote;
// if ( !PyArg_ParseTuple(args, "OOO", &obj, &py_filename, &py_remote) )
// return NULL;
// return pyl_open(obj, py_filename, py_remote);
//}
//
//static PyObject *ex_linput_read(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_size;
// if ( !PyArg_ParseTuple(args, "OO", &obj, &py_size) )
// return NULL;
// return pyl_read(obj, py_size);
//}
static PyMethodDef py_methods_diskio[] =
{
{"enumfiles", ex_enumfiles, METH_VARARGS, ""},
//{"tell", ex_linput_tell, METH_VARARGS, ""},
//{"open", ex_linput_open, METH_VARARGS, ""},
//{"size", ex_linput_tell, METH_VARARGS, ""},
//{"read", ex_linput_read, METH_VARARGS, ""},
//{"close", ex_linput_close, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
#include "py_diskio.hpp"
static PyObject *ex_enumfiles(PyObject * /*self*/, PyObject *args)
{
PyObject *path, *fname, *callback;
if ( !PyArg_ParseTuple(args, "OOO", &path, &fname, &callback) )
return NULL;
return py_enumerate_files(path, fname, callback);
}
//
//static PyObject *ex_linput_close(PyObject * /*self*/, PyObject *args)
//{
// PyObject *obj;
// if ( !PyArg_ParseTuple(args, "O", &obj) )
// return NULL;
// pyl_close(obj);
// Py_RETURN_NONE;
//}
//
//static PyObject *ex_linput_open(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_filename, *py_remote;
// if ( !PyArg_ParseTuple(args, "OOO", &obj, &py_filename, &py_remote) )
// return NULL;
// return pyl_open(obj, py_filename, py_remote);
//}
//
//static PyObject *ex_linput_read(PyObject *self, PyObject *args)
//{
// PyObject *obj, *py_size;
// if ( !PyArg_ParseTuple(args, "OO", &obj, &py_size) )
// return NULL;
// return pyl_read(obj, py_size);
//}
static PyMethodDef py_methods_diskio[] =
{
{"enumfiles", ex_enumfiles, METH_VARARGS, ""},
//{"tell", ex_linput_tell, METH_VARARGS, ""},
//{"open", ex_linput_open, METH_VARARGS, ""},
//{"size", ex_linput_tell, METH_VARARGS, ""},
//{"read", ex_linput_read, METH_VARARGS, ""},
//{"close", ex_linput_close, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(diskio);

View File

@@ -1,56 +1,56 @@
#include "py_expr.hpp"
#pragma warning(push)
#pragma warning(disable: 4244)
//---------------------------------------------------------------------------
#include "py_expr.hpp"
#pragma warning(push)
#pragma warning(disable: 4244)
//---------------------------------------------------------------------------
static PyObject *ex_pyw_register_idc_func(PyObject *self, PyObject *args)
{
char *name, *arg;
PyObject *py_fp;
if ( !PyArg_ParseTuple(args, "ssO", &name, &arg, &py_fp) )
return NULL;
else
return PyLong_FromUnsignedLongLong(pyw_register_idc_func(name, arg, py_fp));
char *name, *arg;
PyObject *py_fp;
if ( !PyArg_ParseTuple(args, "ssO", &name, &arg, &py_fp) )
return NULL;
else
return PyLong_FromUnsignedLongLong(pyw_register_idc_func(name, arg, py_fp));
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
static PyObject *ex_pyw_unregister_idc_func(PyObject *self, PyObject *args)
{
unsigned PY_LONG_LONG ctxptr;
if ( !PyArg_ParseTuple(args, "K", &ctxptr) )
return NULL;
return PyLong_FromLong(pyw_unregister_idc_func(ctxptr));
if ( !PyArg_ParseTuple(args, "K", &ctxptr) )
return NULL;
return PyLong_FromLong(pyw_unregister_idc_func(ctxptr));
}
static PyObject *ex_py_set_idc_func_ex(PyObject *self, PyObject *pyargs)
{
const char *name;
unsigned PY_LONG_LONG fp_ptr;
const char *args;
const char *name;
unsigned PY_LONG_LONG fp_ptr;
const char *args;
int flags;
if ( !PyArg_ParseTuple(pyargs, "sKsi", &name, &fp_ptr, &args, &flags) )
return NULL;
else
return PyLong_FromLong(py_set_idc_func_ex(name, fp_ptr, args, flags));
if ( !PyArg_ParseTuple(pyargs, "sKsi", &name, &fp_ptr, &args, &flags) )
return NULL;
else
return PyLong_FromLong(py_set_idc_func_ex(name, fp_ptr, args, flags));
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
static PyObject *ex_py_get_call_idc_func(PyObject *self, PyObject *args)
{
return PyLong_FromUnsignedLongLong(py_get_call_idc_func());
}
//-------------------------------------------------------------------------
//-------------------------------------------------------------------------
#pragma warning(pop)
//-------------------------------------------------------------------------
static PyMethodDef py_methods_expr[] =
{
{"pyw_register_idc_func", ex_pyw_register_idc_func, METH_VARARGS, ""},
{"pyw_unregister_idc_func", ex_pyw_unregister_idc_func, METH_VARARGS, ""},
{"py_get_call_idc_func", ex_py_get_call_idc_func, METH_VARARGS, ""},
{"py_set_idc_func_ex", ex_py_set_idc_func_ex, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} // End of methods
};
DRIVER_INIT_METHODS(expr);
//-------------------------------------------------------------------------
static PyMethodDef py_methods_expr[] =
{
{"pyw_register_idc_func", ex_pyw_register_idc_func, METH_VARARGS, ""},
{"pyw_unregister_idc_func", ex_pyw_unregister_idc_func, METH_VARARGS, ""},
{"py_get_call_idc_func", ex_py_get_call_idc_func, METH_VARARGS, ""},
{"py_set_idc_func_ex", ex_py_set_idc_func_ex, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} // End of methods
};
DRIVER_INIT_METHODS(expr);

View File

@@ -1,44 +1,44 @@
#include "py_graph.hpp"
//--------------------------------------------------------------------------
//py_choose2_t *last_c2 = NULL;
static PyObject *ex_graph_show(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t *ret = py_graph_t::Show(obj);
return PyBool_FromLong(ret == NULL ? 0 : 1);
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_refresh(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t::Refresh(obj);
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_addcmd(PyObject *self, PyObject *args)
{
PyObject *obj;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &obj, &title, &hotkey) )
return NULL;
Py_ssize_t r = py_graph_t::AddCommand(obj, title, hotkey);
return Py_BuildValue("n", r);
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_graph[] =
{
{"show", ex_graph_show, METH_VARARGS, ""},
{"refresh", ex_graph_refresh, METH_VARARGS, ""},
{"addcmd", ex_graph_addcmd, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
#include "py_graph.hpp"
//--------------------------------------------------------------------------
//py_choose2_t *last_c2 = NULL;
static PyObject *ex_graph_show(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t *ret = py_graph_t::Show(obj);
return PyBool_FromLong(ret == NULL ? 0 : 1);
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_refresh(PyObject * /*self*/, PyObject *args)
{
PyObject *obj;
if ( !PyArg_ParseTuple(args, "O", &obj) )
return NULL;
py_graph_t::Refresh(obj);
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
static PyObject *ex_graph_addcmd(PyObject *self, PyObject *args)
{
PyObject *obj;
const char *title, *hotkey;
if ( !PyArg_ParseTuple(args, "Oss", &obj, &title, &hotkey) )
return NULL;
Py_ssize_t r = py_graph_t::AddCommand(obj, title, hotkey);
return Py_BuildValue("n", r);
}
//--------------------------------------------------------------------------
static PyMethodDef py_methods_graph[] =
{
{"show", ex_graph_show, METH_VARARGS, ""},
{"refresh", ex_graph_refresh, METH_VARARGS, ""},
{"addcmd", ex_graph_addcmd, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(graph);

View File

@@ -1,78 +1,78 @@
#include "py_kernwin.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_add_menu_item(PyObject *self, PyObject *args)
{
const char *menupath, *name, *hotkey;
PyObject *pyfunc, *pyargs;
int flags;
if ( !PyArg_ParseTuple(args, "sssiOO", &menupath, &name, &hotkey, &flags, &pyfunc, &pyargs) )
return NULL;
return py_add_menu_item(menupath, name, hotkey, flags, pyfunc, pyargs);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_menu_item(PyObject *self, PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
if ( py_del_menu_item(self) )
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_sync(PyObject *self, PyObject *args)
{
PyObject *pycall;
int reqf;
if ( !PyArg_ParseTuple(args, "Oi", &pycall, &reqf) )
return NULL;
return PyInt_FromLong(py_execute_sync(pycall, reqf));
}
//-------------------------------------------------------------------------
static PyObject *ex_add_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyfunc;
const char *hotkey;
if ( !PyArg_ParseTuple(args, "sO", &hotkey, &pyfunc) )
return NULL;
else
return py_add_hotkey(hotkey, pyfunc);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyctx;
if ( !PyArg_ParseTuple(args, "O", &pyctx) )
return NULL;
else
return PyInt_FromLong(py_del_hotkey(pyctx) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_ui_request(PyObject *self, PyObject *args)
{
PyObject *py_list;
if ( !PyArg_ParseTuple(args, "O", &py_list) )
return NULL;
else
return PyBool_FromLong(py_execute_ui_requests(py_list) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_kernwin[] =
{
{"py_del_menu_item", ex_del_menu_item, METH_VARARGS, ""},
{"py_add_menu_item", ex_add_menu_item, METH_VARARGS, ""},
{"py_execute_sync", ex_execute_sync, METH_VARARGS, ""},
{"py_add_hotkey", ex_add_hotkey, METH_VARARGS, ""},
{"py_del_hotkey", ex_del_hotkey, METH_VARARGS, ""},
{"py_execute_ui_request", ex_execute_ui_request, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
#include "py_kernwin.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_add_menu_item(PyObject *self, PyObject *args)
{
const char *menupath, *name, *hotkey;
PyObject *pyfunc, *pyargs;
int flags;
if ( !PyArg_ParseTuple(args, "sssiOO", &menupath, &name, &hotkey, &flags, &pyfunc, &pyargs) )
return NULL;
return py_add_menu_item(menupath, name, hotkey, flags, pyfunc, pyargs);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_menu_item(PyObject *self, PyObject *args)
{
if ( !PyArg_ParseTuple(args, "O", &self) )
return NULL;
if ( py_del_menu_item(self) )
Py_RETURN_TRUE;
else
Py_RETURN_FALSE;
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_sync(PyObject *self, PyObject *args)
{
PyObject *pycall;
int reqf;
if ( !PyArg_ParseTuple(args, "Oi", &pycall, &reqf) )
return NULL;
return PyInt_FromLong(py_execute_sync(pycall, reqf));
}
//-------------------------------------------------------------------------
static PyObject *ex_add_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyfunc;
const char *hotkey;
if ( !PyArg_ParseTuple(args, "sO", &hotkey, &pyfunc) )
return NULL;
else
return py_add_hotkey(hotkey, pyfunc);
}
//-------------------------------------------------------------------------
static PyObject *ex_del_hotkey(PyObject *self, PyObject *args)
{
PyObject *pyctx;
if ( !PyArg_ParseTuple(args, "O", &pyctx) )
return NULL;
else
return PyInt_FromLong(py_del_hotkey(pyctx) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyObject *ex_execute_ui_request(PyObject *self, PyObject *args)
{
PyObject *py_list;
if ( !PyArg_ParseTuple(args, "O", &py_list) )
return NULL;
else
return PyBool_FromLong(py_execute_ui_requests(py_list) ? 1 : 0);
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_kernwin[] =
{
{"py_del_menu_item", ex_del_menu_item, METH_VARARGS, ""},
{"py_add_menu_item", ex_add_menu_item, METH_VARARGS, ""},
{"py_execute_sync", ex_execute_sync, METH_VARARGS, ""},
{"py_add_hotkey", ex_add_hotkey, METH_VARARGS, ""},
{"py_del_hotkey", ex_del_hotkey, METH_VARARGS, ""},
{"py_execute_ui_request", ex_execute_ui_request, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(kernwin);

View File

@@ -1,18 +1,18 @@
#include "py_nalt.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_get_switch_info_ex(PyObject *self, PyObject *args)
{
pyul_t ea;
if ( !PyArg_ParseTuple(args, PY_FMT64, &ea) )
return NULL;
return py_get_switch_info_ex(ea_t(ea));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nalt[] =
{
{"get_switch_info_ex", ex_get_switch_info_ex, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
DRIVER_INIT_METHODS(nalt);
#include "py_nalt.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_get_switch_info_ex(PyObject *self, PyObject *args)
{
pyul_t ea;
if ( !PyArg_ParseTuple(args, PY_FMT64, &ea) )
return NULL;
return py_get_switch_info_ex(ea_t(ea));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nalt[] =
{
{"get_switch_info_ex", ex_get_switch_info_ex, METH_VARARGS, ""},
{NULL, NULL, 0, NULL}
};
DRIVER_INIT_METHODS(nalt);

View File

@@ -1,36 +1,36 @@
#include "py_notifywhen.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_notify_when(PyObject *self, PyObject *args)
{
int when;
PyObject *py_callable;
if ( !PyArg_ParseTuple(args, "IO", &when, &py_callable) )
return NULL;
return Py_BuildValue("i", notify_when(when, py_callable));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nw[] =
{
{"notify_when", ex_notify_when, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(nw);
#define DRIVER_INIT
int driver_init()
{
bool ok = pywraps_nw_init();
if ( !ok )
return PLUGIN_SKIP;
pywraps_nw_notify(NW_INITIDA_SLOT);
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
pywraps_nw_notify(NW_TERMIDA_SLOT);
pywraps_nw_term();
}
#include "py_notifywhen.hpp"
//-------------------------------------------------------------------------
static PyObject *ex_notify_when(PyObject *self, PyObject *args)
{
int when;
PyObject *py_callable;
if ( !PyArg_ParseTuple(args, "IO", &when, &py_callable) )
return NULL;
return Py_BuildValue("i", notify_when(when, py_callable));
}
//-------------------------------------------------------------------------
static PyMethodDef py_methods_nw[] =
{
{"notify_when", ex_notify_when, METH_VARARGS, ""},
{NULL, NULL, 0, NULL} /* Sentinel */
};
DRIVER_INIT_METHODS(nw);
#define DRIVER_INIT
int driver_init()
{
bool ok = pywraps_nw_init();
if ( !ok )
return PLUGIN_SKIP;
pywraps_nw_notify(NW_INITIDA_SLOT);
return PLUGIN_KEEP;
}
#define DRIVER_TERM
void driver_term()
{
pywraps_nw_notify(NW_TERMIDA_SLOT);
pywraps_nw_term();
}

View File

@@ -1,336 +1,336 @@
import types
C_TO_PY_CAST = {
'b' : 'char',
'i' : 'int',
'H' : 'uint16',
'h' : 'int16',
'B' : 'uchar',
}
# --------------------------------------------------------------------------------------------
class gen_fmt(object):
def __init__(self, fields, tp = None, bv = None, cast=None, cmt = None):
self.fields = fields
self.tp = tp
# Format to be passed to Py_BuildValue
if not bv:
self.bv = "XXX"
else:
if bv == "K":
self.bv = "PY_FMT64"
else:
self.bv = '"%s"' % bv
if not cast:
if bv == "K":
cast = "pyul_t"
elif bv in C_TO_PY_CAST:
cast = C_TO_PY_CAST[bv]
self.cast = "" if not cast else "(%s)" % cast
self.cmt = cmt
if bv == "K":
self.setcvt = "uint64 v(0); PyGetNumber(value, &v);"
elif bv == 'i':
self.setcvt = "int v = PyInt_AsLong(value);"
else:
self.setcvt = "uint64 v = %sPyInt_AsLong(value);" % self.cast
# --------------------------------------------------------------------------------------------
switch_info_ex_t_gen = [
gen_fmt('regdtyp', bv = 'b', cmt = 'size of the switch expression register as dtyp'),
gen_fmt('flags2', bv = 'i'),
gen_fmt('jcases', bv = 'i', cmt = 'number of entries in the jump table (SWI2_INDIRECT)'),
gen_fmt('regnum', bv = 'i', cmt = 'the switch expression as a register number'),
gen_fmt('flags', bv = 'H', cmt = 'the switch expression as a register number'),
gen_fmt('ncases', bv = 'H', cmt = 'number of cases (excluding default)'),
gen_fmt('defjump', bv = 'K', cmt = 'default jump address'),
gen_fmt('jumps', bv = 'K', cmt = 'jump table address'),
gen_fmt('elbase', bv = 'K', cmt = 'element base'),
gen_fmt('startea', bv = 'K', cmt = 'start of switch idiom'),
gen_fmt('custom', bv = 'K', cmt = 'information for custom tables (filled and used by modules)'),
gen_fmt('ind_lowcase', bv = 'K'),
gen_fmt(['values', 'lowcase'], bv = 'K'),
]
op_t_gen = [
gen_fmt('n', bv = 'b'),
gen_fmt('type', bv = 'B'),
gen_fmt('offb', bv = 'b'),
gen_fmt('offo', bv = 'b'),
gen_fmt('flags', bv = 'B'),
gen_fmt('dtyp', bv = 'b'),
gen_fmt(['reg', 'phrase'], bv = 'H'),
gen_fmt('value', bv = 'K'),
gen_fmt('addr', bv = 'K'),
gen_fmt('specval', bv = 'K'),
gen_fmt('specflag1', bv = 'b'),
gen_fmt('specflag2', bv = 'b'),
gen_fmt('specflag3', bv = 'b'),
gen_fmt('specflag4', bv = 'b')
]
insn_t_gen = [
gen_fmt('cs', bv = 'K'),
gen_fmt('ip', bv = 'K'),
gen_fmt('ea', bv = 'K'),
gen_fmt('itype', bv = 'H'),
gen_fmt('size', bv = 'H'),
gen_fmt('auxpref', bv = 'H'),
gen_fmt('segpref', bv = 'b'),
gen_fmt('insnpref', bv = 'b'),
gen_fmt('Op1', tp = 'op_t'),
gen_fmt('Op2', tp = 'op_t'),
gen_fmt('Op3', tp = 'op_t'),
gen_fmt('Op4', tp = 'op_t'),
gen_fmt('Op5', tp = 'op_t'),
gen_fmt('Op6', tp = 'op_t'),
gen_fmt('flags', bv = 'b')
]
regval_t_gen = [
gen_fmt('rvtype', bv = 'i'),
gen_fmt('ival', bv = 'K'),
gen_fmt('fval', bv = 'd'),
gen_fmt('bytes', bv = 's'),
]
# --------------------------------------------------------------------------------------------
S_LINK_ATTR = 'S_CLINK_NAME' # If the name is a literal, make sure you specify double quotations
S_CMOD_NAME = '_idaapi'
# --------------------------------------------------------------------------------------------
def gen_stub(gen, name, cname = None, tabs=4, gen_py_file = False, gen_c_file = False):
# Assume C type name same as python type name
if not cname:
cname = name
# Python property lines
prop_body = []
# Python get/set bodies
getset_body = []
# C get/set bodies
cgetset_body = []
# some spacing constants
spc = ' ' * tabs
spc2 = spc * 2
nspc = '\n' + spc
nspc2 = '\n' + spc2
cget_link = '%s_get_clink' % cname
#
# Process fields
#
for g in gen:
# a union will be represented by a list
if type(g.fields) != types.ListType:
fields = [g.fields]
else:
fields = g.fields
# join all field names (in case of a union)
flds_name = '_'.join(fields)
# form the method and variable names
set_method = '__set_%s__' % flds_name
get_method = '__get_%s__' % flds_name
cset_method = '%s_set_%s' % (name, flds_name)
cget_method = '%s_get_%s' % (name, flds_name)
fld_name = '__%s__' % flds_name
basic_type = not g.tp
vars = {
'get': get_method,
'set': set_method,
'l': S_LINK_ATTR,
'fld' : fld_name,
'cmod' : S_CMOD_NAME,
'cget': cget_method,
'cset': cset_method,
'csetcvt': g.setcvt,
'cname': cname,
'cgetlink': cget_link,
'cfield1': fields[0],
'bv': g.bv,
'bvcast': g.cast
}
#
# Python code
#
# basic type?
# For basic types we need to create property and get/set methods
if basic_type:
for fld in fields:
prop_body.append('%s = property(%s, %s)' % (fld, get_method, set_method))
if g.cmt:
prop_body.append('"""%s"""' % g.cmt)
#
code = '\n'.join([
# get method
'def %(get)s(self):',
spc2 + 'return %(cmod)s.%(cget)s(self)',
# set method
spc + 'def %(set)s(self, v):',
spc2 + '%(cmod)s.%(cset)s(self, v)',
]) % vars
getset_body.append(code)
#
# C code
#
if basic_type:
code = '\n'.join([
"""static PyObject *%(cget)s(PyObject *self)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
Py_RETURN_NONE;
return Py_BuildValue(%(bv)s, %(bvcast)slink->%(cfield1)s);
}
static void %(cset)s(PyObject *self, PyObject *value)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
return;
%(csetcvt)s
link->%(cfield1)s = %(bvcast)sv;
}
"""
]) % vars
cgetset_body.append(code)
# print 'prop_body->\n\t', '\n\t'.join(prop_body), '\n<'
# print 'getset_body->\n', '\n'.join(getset_body), '\n<'
# print 'cgetset_body->\n', '\n'.join(cgetset_body), '\n<'
vars = {
'name': name,
'cname': cname,
'getlink': cget_link,
'l': S_LINK_ATTR,
'cmod' : S_CMOD_NAME
}
#
# Form the complete Python code
#
py = '\n'.join([
'class %(name)s(py_clinked_object_t):',
# init() code
spc + 'def __init__(self, lnk = None):',
spc2 + 'py_clinked_object_t.__init__(self, lnk)',
'',
spc + 'def _create_clink(self):',
spc2 + 'return _idaapi.%(name)s_create()',
'',
spc + 'def _del_clink(self, lnk):',
spc2 + 'return _idaapi.%(name)s_destroy(lnk)',
'',
spc + 'def assign(self, other):',
spc2 + 'return _idaapi.%(name)s_assign(self, other)',
'',
'',
spc + '#',
spc + '# Autogenerated',
spc + '#',
# get/set code
spc + nspc.join(getset_body),
# props code
spc + nspc.join(prop_body),
]) % vars
#
# Form the Python to C conversion function
#
#
# Form the complete C code
#
ccode = '\n'.join([
# Form the C get link code
"""%(cname)s *%(getlink)s(PyObject *self)
{
if ( !PyObject_HasAttrString(self, %(l)s) )
return NULL;
%(cname)s *r;
PyObject *attr = PyObject_GetAttrString(self, %(l)s);
if ( PyCObject_Check(attr) )
r = (%(cname)s *) PyCObject_AsVoidPtr(attr);
else
r = NULL;
Py_DECREF(attr);
return r;
}
static PyObject *%(cname)s_create()
{
%(cname)s *inst = new %(cname)s();
return PyCObject_FromVoidPtr(inst, NULL);
}
static bool %(cname)s_destroy(PyObject *py_obj)
{
if ( !PyCObject_Check(py_obj) )
return false;
%(cname)s *inst = (%(cname)s *) PyCObject_AsVoidPtr(py_obj);
delete inst;
return true;
}
static bool %(cname)s_assign(PyObject *self, PyObject *other)
{
%(cname)s *lhs = %(cname)s_get_clink(self);
%(cname)s *rhs = %(cname)s_get_clink(other);
if (lhs == NULL || rhs == NULL)
return false;
*lhs = *rhs;
return true;
}
//-------------------------------------------------------------------------
// Auto generated - begin
//
""",
# Form C get/set functions
''.join(cgetset_body),
"""//
// Auto generated - end
//
//-------------------------------------------------------------------------"""
]) % vars
# write the Python file
if gen_py_file:
f = open(name + '.py', 'w')
f.write(py)
f.close()
# write C file
if gen_c_file:
f = open(name + '.cpp', 'w')
f.write(ccode)
f.close()
# --------------------------------------------------------------------------------------------
def main():
files = [
('switch_info_ex_t', switch_info_ex_t_gen),
]
for (n, g) in files:
gen_stub(g, n, gen_py_file = True, gen_c_file = True)
import types
C_TO_PY_CAST = {
'b' : 'char',
'i' : 'int',
'H' : 'uint16',
'h' : 'int16',
'B' : 'uchar',
}
# --------------------------------------------------------------------------------------------
class gen_fmt(object):
def __init__(self, fields, tp = None, bv = None, cast=None, cmt = None):
self.fields = fields
self.tp = tp
# Format to be passed to Py_BuildValue
if not bv:
self.bv = "XXX"
else:
if bv == "K":
self.bv = "PY_FMT64"
else:
self.bv = '"%s"' % bv
if not cast:
if bv == "K":
cast = "pyul_t"
elif bv in C_TO_PY_CAST:
cast = C_TO_PY_CAST[bv]
self.cast = "" if not cast else "(%s)" % cast
self.cmt = cmt
if bv == "K":
self.setcvt = "uint64 v(0); PyGetNumber(value, &v);"
elif bv == 'i':
self.setcvt = "int v = PyInt_AsLong(value);"
else:
self.setcvt = "uint64 v = %sPyInt_AsLong(value);" % self.cast
# --------------------------------------------------------------------------------------------
switch_info_ex_t_gen = [
gen_fmt('regdtyp', bv = 'b', cmt = 'size of the switch expression register as dtyp'),
gen_fmt('flags2', bv = 'i'),
gen_fmt('jcases', bv = 'i', cmt = 'number of entries in the jump table (SWI2_INDIRECT)'),
gen_fmt('regnum', bv = 'i', cmt = 'the switch expression as a register number'),
gen_fmt('flags', bv = 'H', cmt = 'the switch expression as a register number'),
gen_fmt('ncases', bv = 'H', cmt = 'number of cases (excluding default)'),
gen_fmt('defjump', bv = 'K', cmt = 'default jump address'),
gen_fmt('jumps', bv = 'K', cmt = 'jump table address'),
gen_fmt('elbase', bv = 'K', cmt = 'element base'),
gen_fmt('startea', bv = 'K', cmt = 'start of switch idiom'),
gen_fmt('custom', bv = 'K', cmt = 'information for custom tables (filled and used by modules)'),
gen_fmt('ind_lowcase', bv = 'K'),
gen_fmt(['values', 'lowcase'], bv = 'K'),
]
op_t_gen = [
gen_fmt('n', bv = 'b'),
gen_fmt('type', bv = 'B'),
gen_fmt('offb', bv = 'b'),
gen_fmt('offo', bv = 'b'),
gen_fmt('flags', bv = 'B'),
gen_fmt('dtyp', bv = 'b'),
gen_fmt(['reg', 'phrase'], bv = 'H'),
gen_fmt('value', bv = 'K'),
gen_fmt('addr', bv = 'K'),
gen_fmt('specval', bv = 'K'),
gen_fmt('specflag1', bv = 'b'),
gen_fmt('specflag2', bv = 'b'),
gen_fmt('specflag3', bv = 'b'),
gen_fmt('specflag4', bv = 'b')
]
insn_t_gen = [
gen_fmt('cs', bv = 'K'),
gen_fmt('ip', bv = 'K'),
gen_fmt('ea', bv = 'K'),
gen_fmt('itype', bv = 'H'),
gen_fmt('size', bv = 'H'),
gen_fmt('auxpref', bv = 'H'),
gen_fmt('segpref', bv = 'b'),
gen_fmt('insnpref', bv = 'b'),
gen_fmt('Op1', tp = 'op_t'),
gen_fmt('Op2', tp = 'op_t'),
gen_fmt('Op3', tp = 'op_t'),
gen_fmt('Op4', tp = 'op_t'),
gen_fmt('Op5', tp = 'op_t'),
gen_fmt('Op6', tp = 'op_t'),
gen_fmt('flags', bv = 'b')
]
regval_t_gen = [
gen_fmt('rvtype', bv = 'i'),
gen_fmt('ival', bv = 'K'),
gen_fmt('fval', bv = 'd'),
gen_fmt('bytes', bv = 's'),
]
# --------------------------------------------------------------------------------------------
S_LINK_ATTR = 'S_CLINK_NAME' # If the name is a literal, make sure you specify double quotations
S_CMOD_NAME = '_idaapi'
# --------------------------------------------------------------------------------------------
def gen_stub(gen, name, cname = None, tabs=4, gen_py_file = False, gen_c_file = False):
# Assume C type name same as python type name
if not cname:
cname = name
# Python property lines
prop_body = []
# Python get/set bodies
getset_body = []
# C get/set bodies
cgetset_body = []
# some spacing constants
spc = ' ' * tabs
spc2 = spc * 2
nspc = '\n' + spc
nspc2 = '\n' + spc2
cget_link = '%s_get_clink' % cname
#
# Process fields
#
for g in gen:
# a union will be represented by a list
if type(g.fields) != types.ListType:
fields = [g.fields]
else:
fields = g.fields
# join all field names (in case of a union)
flds_name = '_'.join(fields)
# form the method and variable names
set_method = '__set_%s__' % flds_name
get_method = '__get_%s__' % flds_name
cset_method = '%s_set_%s' % (name, flds_name)
cget_method = '%s_get_%s' % (name, flds_name)
fld_name = '__%s__' % flds_name
basic_type = not g.tp
vars = {
'get': get_method,
'set': set_method,
'l': S_LINK_ATTR,
'fld' : fld_name,
'cmod' : S_CMOD_NAME,
'cget': cget_method,
'cset': cset_method,
'csetcvt': g.setcvt,
'cname': cname,
'cgetlink': cget_link,
'cfield1': fields[0],
'bv': g.bv,
'bvcast': g.cast
}
#
# Python code
#
# basic type?
# For basic types we need to create property and get/set methods
if basic_type:
for fld in fields:
prop_body.append('%s = property(%s, %s)' % (fld, get_method, set_method))
if g.cmt:
prop_body.append('"""%s"""' % g.cmt)
#
code = '\n'.join([
# get method
'def %(get)s(self):',
spc2 + 'return %(cmod)s.%(cget)s(self)',
# set method
spc + 'def %(set)s(self, v):',
spc2 + '%(cmod)s.%(cset)s(self, v)',
]) % vars
getset_body.append(code)
#
# C code
#
if basic_type:
code = '\n'.join([
"""static PyObject *%(cget)s(PyObject *self)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
Py_RETURN_NONE;
return Py_BuildValue(%(bv)s, %(bvcast)slink->%(cfield1)s);
}
static void %(cset)s(PyObject *self, PyObject *value)
{
%(cname)s *link = %(cgetlink)s(self);
if ( link == NULL )
return;
%(csetcvt)s
link->%(cfield1)s = %(bvcast)sv;
}
"""
]) % vars
cgetset_body.append(code)
# print 'prop_body->\n\t', '\n\t'.join(prop_body), '\n<'
# print 'getset_body->\n', '\n'.join(getset_body), '\n<'
# print 'cgetset_body->\n', '\n'.join(cgetset_body), '\n<'
vars = {
'name': name,
'cname': cname,
'getlink': cget_link,
'l': S_LINK_ATTR,
'cmod' : S_CMOD_NAME
}
#
# Form the complete Python code
#
py = '\n'.join([
'class %(name)s(py_clinked_object_t):',
# init() code
spc + 'def __init__(self, lnk = None):',
spc2 + 'py_clinked_object_t.__init__(self, lnk)',
'',
spc + 'def _create_clink(self):',
spc2 + 'return _idaapi.%(name)s_create()',
'',
spc + 'def _del_clink(self, lnk):',
spc2 + 'return _idaapi.%(name)s_destroy(lnk)',
'',
spc + 'def assign(self, other):',
spc2 + 'return _idaapi.%(name)s_assign(self, other)',
'',
'',
spc + '#',
spc + '# Autogenerated',
spc + '#',
# get/set code
spc + nspc.join(getset_body),
# props code
spc + nspc.join(prop_body),
]) % vars
#
# Form the Python to C conversion function
#
#
# Form the complete C code
#
ccode = '\n'.join([
# Form the C get link code
"""%(cname)s *%(getlink)s(PyObject *self)
{
if ( !PyObject_HasAttrString(self, %(l)s) )
return NULL;
%(cname)s *r;
PyObject *attr = PyObject_GetAttrString(self, %(l)s);
if ( PyCObject_Check(attr) )
r = (%(cname)s *) PyCObject_AsVoidPtr(attr);
else
r = NULL;
Py_DECREF(attr);
return r;
}
static PyObject *%(cname)s_create()
{
%(cname)s *inst = new %(cname)s();
return PyCObject_FromVoidPtr(inst, NULL);
}
static bool %(cname)s_destroy(PyObject *py_obj)
{
if ( !PyCObject_Check(py_obj) )
return false;
%(cname)s *inst = (%(cname)s *) PyCObject_AsVoidPtr(py_obj);
delete inst;
return true;
}
static bool %(cname)s_assign(PyObject *self, PyObject *other)
{
%(cname)s *lhs = %(cname)s_get_clink(self);
%(cname)s *rhs = %(cname)s_get_clink(other);
if (lhs == NULL || rhs == NULL)
return false;
*lhs = *rhs;
return true;
}
//-------------------------------------------------------------------------
// Auto generated - begin
//
""",
# Form C get/set functions
''.join(cgetset_body),
"""//
// Auto generated - end
//
//-------------------------------------------------------------------------"""
]) % vars
# write the Python file
if gen_py_file:
f = open(name + '.py', 'w')
f.write(py)
f.close()
# write C file
if gen_c_file:
f = open(name + '.cpp', 'w')
f.write(ccode)
f.close()
# --------------------------------------------------------------------------------------------
def main():
files = [
('switch_info_ex_t', switch_info_ex_t_gen),
]
for (n, g) in files:
gen_stub(g, n, gen_py_file = True, gen_c_file = True)
main()

File diff suppressed because it is too large Load Diff

View File

@@ -1,373 +1,401 @@
#ifndef __PY_ASKUSINGFORM__
#define __PY_ASKUSINGFORM__
//<code(py_kernwin)>
//</code(py_kernwin)>
//---------------------------------------------------------------------------
//<inline(py_kernwin)>
#define DECLARE_FORM_ACTIONS form_actions_t *fa = (form_actions_t *)p_fa;
//---------------------------------------------------------------------------
static bool textctrl_info_t_assign(PyObject *self, PyObject *other)
{
textctrl_info_t *lhs = textctrl_info_t_get_clink(self);
textctrl_info_t *rhs = textctrl_info_t_get_clink(other);
if (lhs == NULL || rhs == NULL)
return false;
*lhs = *rhs;
return true;
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_text(PyObject *self, const char *s)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->text = s;
return true;
}
//-------------------------------------------------------------------------
static const char *textctrl_info_t_get_text(PyObject *self)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? "" : ti->text.c_str();
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_flags(PyObject *self, unsigned int flags)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->flags = flags;
return true;
}
//-------------------------------------------------------------------------
static unsigned int textctrl_info_t_get_flags(
PyObject *self,
unsigned int flags)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? 0 : ti->flags;
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_tabsize(
PyObject *self,
unsigned int tabsize)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->tabsize = tabsize;
return true;
}
//-------------------------------------------------------------------------
static unsigned int textctrl_info_t_get_tabsize(
PyObject *self,
unsigned int tabsize)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? 0 : ti->tabsize;
}
//---------------------------------------------------------------------------
static bool formchgcbfa_enable_field(size_t p_fa, int fid, bool enable)
{
DECLARE_FORM_ACTIONS;
return fa->enable_field(fid, enable);
}
//---------------------------------------------------------------------------
static bool formchgcbfa_show_field(size_t p_fa, int fid, bool show)
{
DECLARE_FORM_ACTIONS;
return fa->show_field(fid, show);
}
//---------------------------------------------------------------------------
static bool formchgcbfa_move_field(
size_t p_fa,
int fid,
int x,
int y,
int w,
int h)
{
DECLARE_FORM_ACTIONS;
return fa->move_field(fid, x, y, w, h);
}
//---------------------------------------------------------------------------
static int formchgcbfa_get_focused_field(size_t p_fa)
{
DECLARE_FORM_ACTIONS;
return fa->get_focused_field();
}
//---------------------------------------------------------------------------
static bool formchgcbfa_set_focused_field(size_t p_fa, int fid)
{
DECLARE_FORM_ACTIONS;
return fa->set_focused_field(fid);
}
//---------------------------------------------------------------------------
static void formchgcbfa_refresh_field(size_t p_fa, int fid)
{
DECLARE_FORM_ACTIONS;
return fa->refresh_field(fid);
}
//---------------------------------------------------------------------------
static void formchgcbfa_close(size_t p_fa, int close_normally)
{
DECLARE_FORM_ACTIONS;
fa->close(close_normally);
}
//---------------------------------------------------------------------------
static PyObject *formchgcbfa_get_field_value(
size_t p_fa,
int fid,
int ft,
size_t sz)
{
DECLARE_FORM_ACTIONS;
PYW_GIL_CHECK_LOCKED_SCOPE();
switch ( ft )
{
// dropdown list
case 8:
{
// Readonly? Then return the selected index
if ( sz == 1 )
{
int sel_idx;
if ( fa->get_combobox_value(fid, &sel_idx) )
return PyLong_FromLong(sel_idx);
}
// Not readonly? Then return the qstring
else
{
qstring val;
if ( fa->get_combobox_value(fid, &val) )
return PyString_FromString(val.c_str());
}
break;
}
// multilinetext - tuple representing textctrl_info_t
case 7:
{
textctrl_info_t ti;
if ( fa->get_text_value(fid, &ti) )
return Py_BuildValue("(sII)", ti.text.c_str(), ti.flags, ti.tabsize);
break;
}
// button - uint32
case 4:
{
uval_t val;
if ( fa->get_unsigned_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// ushort
case 2:
{
ushort val;
if ( fa->_get_field_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// string label
case 1:
{
char val[MAXSTR];
if ( fa->get_ascii_value(fid, val, sizeof(val)) )
return PyString_FromString(val);
break;
}
// string input
case 3:
{
qstring val;
val.resize(sz + 1);
if ( fa->get_ascii_value(fid, val.begin(), val.size()) )
return PyString_FromString(val.begin());
break;
}
case 5:
{
intvec_t intvec;
// Returned as 1-base
if (fa->get_chooser_value(fid, &intvec))
{
// Make 0-based
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
(*it)--;
ref_t l(PyW_IntVecToPyList(intvec));
l.incref();
return l.o;
}
break;
}
// Numeric control
case 6:
{
union
{
sel_t sel;
sval_t sval;
uval_t uval;
ulonglong ull;
} u;
switch ( sz )
{
case 'S': // sel_t
{
if ( fa->get_segment_value(fid, &u.sel) )
return Py_BuildValue(PY_FMT64, u.sel);
break;
}
// sval_t
case 'n':
case 'D':
case 'O':
case 'Y':
case 'H':
{
if ( fa->get_signed_value(fid, &u.sval) )
return Py_BuildValue(PY_SFMT64, u.sval);
break;
}
case 'L': // uint64
case 'l': // int64
{
if ( fa->_get_field_value(fid, &u.ull) )
return Py_BuildValue("K", u.ull);
break;
}
case 'N':
case 'M': // uval_t
{
if ( fa->get_unsigned_value(fid, &u.uval) )
return Py_BuildValue(PY_FMT64, u.uval);
break;
}
case '$': // ea_t
{
if ( fa->get_ea_value(fid, &u.uval) )
return Py_BuildValue(PY_FMT64, u.uval);
break;
}
}
break;
}
}
Py_RETURN_NONE;
}
//---------------------------------------------------------------------------
static bool formchgcbfa_set_field_value(
size_t p_fa,
int fid,
int ft,
PyObject *py_val)
{
DECLARE_FORM_ACTIONS;
PYW_GIL_CHECK_LOCKED_SCOPE();
switch ( ft )
{
// dropdown list
case 8:
{
// Editable dropdown list
if ( PyString_Check(py_val) )
{
qstring val(PyString_AsString(py_val));
return fa->set_combobox_value(fid, &val);
}
// Readonly dropdown list
else
{
int sel_idx = PyLong_AsLong(py_val);
return fa->set_combobox_value(fid, &sel_idx);
}
break;
}
// multilinetext - textctrl_info_t
case 7:
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(py_val);
return ti == NULL ? false : fa->set_text_value(fid, ti);
}
// button - uint32
case 4:
{
uval_t val = PyLong_AsUnsignedLong(py_val);
return fa->set_unsigned_value(fid, &val);
}
// ushort
case 2:
{
ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff;
return fa->_set_field_value(fid, &val);
}
// strings
case 3:
case 1:
return fa->set_ascii_value(fid, PyString_AsString(py_val));
// intvec_t
case 5:
{
intvec_t intvec;
// Passed as 0-based
if ( !PyW_PyListToIntVec(py_val, intvec) )
break;
// Make 1-based
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
(*it)++;
return fa->set_chooser_value(fid, &intvec);
}
// Numeric
case 6:
{
uint64 num;
if ( PyW_GetNumber(py_val, &num) )
return fa->_set_field_value(fid, &num);
}
}
return false;
}
#undef DECLARE_FORM_ACTIONS
static size_t py_get_AskUsingForm()
{
// Return a pointer to the function. Note that, although
// the C implementation of AskUsingForm_cv will do some
// Qt/txt widgets generation, the Python's ctypes
// implementation through which the call well go will first
// unblock other threads. No need to do it ourselves.
return (size_t)AskUsingForm_c;
}
static size_t py_get_OpenForm()
{
// See comments above.
return (size_t)OpenForm_c;
}
//</inline(py_kernwin)>
#endif // __PY_ASKUSINGFORM__
#ifndef __PY_ASKUSINGFORM__
#define __PY_ASKUSINGFORM__
//<code(py_kernwin)>
void free_compiled_form_instances(void)
{
while ( !py_compiled_form_vec.empty() )
{
const ref_t &ref = py_compiled_form_vec[0];
qstring title;
if ( !PyW_GetStringAttr(ref.o, "title", &title) )
title = "<unknown title>";
msg("WARNING: Form \"%s\" was not Free()d. Force-freeing.\n", title.c_str());
// Will call 'py_unregister_compiled_form()', and thus trim the vector down.
newref_t unused(PyObject_CallMethod(ref.o, (char *)"Free", "()"));
}
}
//</code(py_kernwin)>
//---------------------------------------------------------------------------
//<inline(py_kernwin)>
#define DECLARE_FORM_ACTIONS form_actions_t *fa = (form_actions_t *)p_fa;
//---------------------------------------------------------------------------
static bool textctrl_info_t_assign(PyObject *self, PyObject *other)
{
textctrl_info_t *lhs = textctrl_info_t_get_clink(self);
textctrl_info_t *rhs = textctrl_info_t_get_clink(other);
if (lhs == NULL || rhs == NULL)
return false;
*lhs = *rhs;
return true;
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_text(PyObject *self, const char *s)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->text = s;
return true;
}
//-------------------------------------------------------------------------
static const char *textctrl_info_t_get_text(PyObject *self)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? "" : ti->text.c_str();
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_flags(PyObject *self, unsigned int flags)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->flags = flags;
return true;
}
//-------------------------------------------------------------------------
static unsigned int textctrl_info_t_get_flags(
PyObject *self,
unsigned int flags)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? 0 : ti->flags;
}
//-------------------------------------------------------------------------
static bool textctrl_info_t_set_tabsize(
PyObject *self,
unsigned int tabsize)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
if ( ti == NULL )
return false;
ti->tabsize = tabsize;
return true;
}
//-------------------------------------------------------------------------
static unsigned int textctrl_info_t_get_tabsize(
PyObject *self,
unsigned int tabsize)
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(self);
return ti == NULL ? 0 : ti->tabsize;
}
//---------------------------------------------------------------------------
static bool formchgcbfa_enable_field(size_t p_fa, int fid, bool enable)
{
DECLARE_FORM_ACTIONS;
return fa->enable_field(fid, enable);
}
//---------------------------------------------------------------------------
static bool formchgcbfa_show_field(size_t p_fa, int fid, bool show)
{
DECLARE_FORM_ACTIONS;
return fa->show_field(fid, show);
}
//---------------------------------------------------------------------------
static bool formchgcbfa_move_field(
size_t p_fa,
int fid,
int x,
int y,
int w,
int h)
{
DECLARE_FORM_ACTIONS;
return fa->move_field(fid, x, y, w, h);
}
//---------------------------------------------------------------------------
static int formchgcbfa_get_focused_field(size_t p_fa)
{
DECLARE_FORM_ACTIONS;
return fa->get_focused_field();
}
//---------------------------------------------------------------------------
static bool formchgcbfa_set_focused_field(size_t p_fa, int fid)
{
DECLARE_FORM_ACTIONS;
return fa->set_focused_field(fid);
}
//---------------------------------------------------------------------------
static void formchgcbfa_refresh_field(size_t p_fa, int fid)
{
DECLARE_FORM_ACTIONS;
return fa->refresh_field(fid);
}
//---------------------------------------------------------------------------
static void formchgcbfa_close(size_t p_fa, int close_normally)
{
DECLARE_FORM_ACTIONS;
fa->close(close_normally);
}
//---------------------------------------------------------------------------
static PyObject *formchgcbfa_get_field_value(
size_t p_fa,
int fid,
int ft,
size_t sz)
{
DECLARE_FORM_ACTIONS;
PYW_GIL_CHECK_LOCKED_SCOPE();
switch ( ft )
{
// dropdown list
case 8:
{
// Readonly? Then return the selected index
if ( sz == 1 )
{
int sel_idx;
if ( fa->get_combobox_value(fid, &sel_idx) )
return PyLong_FromLong(sel_idx);
}
// Not readonly? Then return the qstring
else
{
qstring val;
if ( fa->get_combobox_value(fid, &val) )
return PyString_FromString(val.c_str());
}
break;
}
// multilinetext - tuple representing textctrl_info_t
case 7:
{
textctrl_info_t ti;
if ( fa->get_text_value(fid, &ti) )
return Py_BuildValue("(sII)", ti.text.c_str(), ti.flags, ti.tabsize);
break;
}
// button - uint32
case 4:
{
uval_t val;
if ( fa->get_unsigned_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// ushort
case 2:
{
ushort val;
if ( fa->_get_field_value(fid, &val) )
return PyLong_FromUnsignedLong(val);
break;
}
// string label
case 1:
{
char val[MAXSTR];
if ( fa->get_ascii_value(fid, val, sizeof(val)) )
return PyString_FromString(val);
break;
}
// string input
case 3:
{
qstring val;
val.resize(sz + 1);
if ( fa->get_ascii_value(fid, val.begin(), val.size()) )
return PyString_FromString(val.begin());
break;
}
case 5:
{
intvec_t intvec;
// Returned as 1-base
if (fa->get_chooser_value(fid, &intvec))
{
// Make 0-based
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
(*it)--;
ref_t l(PyW_IntVecToPyList(intvec));
l.incref();
return l.o;
}
break;
}
// Numeric control
case 6:
{
union
{
sel_t sel;
sval_t sval;
uval_t uval;
ulonglong ull;
} u;
switch ( sz )
{
case 'S': // sel_t
{
if ( fa->get_segment_value(fid, &u.sel) )
return Py_BuildValue(PY_FMT64, u.sel);
break;
}
// sval_t
case 'n':
case 'D':
case 'O':
case 'Y':
case 'H':
{
if ( fa->get_signed_value(fid, &u.sval) )
return Py_BuildValue(PY_SFMT64, u.sval);
break;
}
case 'L': // uint64
case 'l': // int64
{
if ( fa->_get_field_value(fid, &u.ull) )
return Py_BuildValue("K", u.ull);
break;
}
case 'N':
case 'M': // uval_t
{
if ( fa->get_unsigned_value(fid, &u.uval) )
return Py_BuildValue(PY_FMT64, u.uval);
break;
}
case '$': // ea_t
{
if ( fa->get_ea_value(fid, &u.uval) )
return Py_BuildValue(PY_FMT64, u.uval);
break;
}
}
break;
}
}
Py_RETURN_NONE;
}
//---------------------------------------------------------------------------
static bool formchgcbfa_set_field_value(
size_t p_fa,
int fid,
int ft,
PyObject *py_val)
{
DECLARE_FORM_ACTIONS;
PYW_GIL_CHECK_LOCKED_SCOPE();
switch ( ft )
{
// dropdown list
case 8:
{
// Editable dropdown list
if ( PyString_Check(py_val) )
{
qstring val(PyString_AsString(py_val));
return fa->set_combobox_value(fid, &val);
}
// Readonly dropdown list
else
{
int sel_idx = PyLong_AsLong(py_val);
return fa->set_combobox_value(fid, &sel_idx);
}
break;
}
// multilinetext - textctrl_info_t
case 7:
{
textctrl_info_t *ti = (textctrl_info_t *)pyobj_get_clink(py_val);
return ti == NULL ? false : fa->set_text_value(fid, ti);
}
// button - uint32
case 4:
{
uval_t val = PyLong_AsUnsignedLong(py_val);
return fa->set_unsigned_value(fid, &val);
}
// ushort
case 2:
{
ushort val = PyLong_AsUnsignedLong(py_val) & 0xffff;
return fa->_set_field_value(fid, &val);
}
// strings
case 3:
case 1:
return fa->set_ascii_value(fid, PyString_AsString(py_val));
// intvec_t
case 5:
{
intvec_t intvec;
// Passed as 0-based
if ( !PyW_PyListToIntVec(py_val, intvec) )
break;
// Make 1-based
for ( intvec_t::iterator it=intvec.begin(); it != intvec.end(); ++it)
(*it)++;
return fa->set_chooser_value(fid, &intvec);
}
// Numeric
case 6:
{
uint64 num;
if ( PyW_GetNumber(py_val, &num) )
return fa->_set_field_value(fid, &num);
}
}
return false;
}
#undef DECLARE_FORM_ACTIONS
static size_t py_get_AskUsingForm()
{
// Return a pointer to the function. Note that, although
// the C implementation of AskUsingForm_cv will do some
// Qt/txt widgets generation, the Python's ctypes
// implementation through which the call well go will first
// unblock other threads. No need to do it ourselves.
return (size_t)AskUsingForm_c;
}
static size_t py_get_OpenForm()
{
// See comments above.
return (size_t)OpenForm_c;
}
static qvector<ref_t> py_compiled_form_vec;
static void py_register_compiled_form(PyObject *py_form)
{
ref_t ref = borref_t(py_form);
if ( !py_compiled_form_vec.has(ref) )
py_compiled_form_vec.push_back(ref);
}
static void py_unregister_compiled_form(PyObject *py_form)
{
ref_t ref = borref_t(py_form);
if ( py_compiled_form_vec.has(ref) )
py_compiled_form_vec.del(ref);
}
//</inline(py_kernwin)>
#endif // __PY_ASKUSINGFORM__

File diff suppressed because it is too large Load Diff

View File

@@ -1,78 +1,78 @@
#ifndef __PY_CHOOSE__
#define __PY_CHOOSE__
//---------------------------------------------------------------------------
//<inline(py_kernwin)>
//---------------------------------------------------------------------------
uint32 idaapi choose_sizer(void *self)
{
PYW_GIL_GET;
newref_t pyres(PyObject_CallMethod((PyObject *)self, "sizer", ""));
return PyInt_AsLong(pyres.o);
}
//---------------------------------------------------------------------------
char *idaapi choose_getl(void *self, uint32 n, char *buf)
{
PYW_GIL_GET;
newref_t pyres(
PyObject_CallMethod(
(PyObject *)self,
"getl",
"l",
n));
const char *res;
if (pyres == NULL || (res = PyString_AsString(pyres.o)) == NULL )
qstrncpy(buf, "<Empty>", MAXSTR);
else
qstrncpy(buf, res, MAXSTR);
return buf;
}
//---------------------------------------------------------------------------
void idaapi choose_enter(void *self, uint32 n)
{
PYW_GIL_GET;
newref_t res(PyObject_CallMethod((PyObject *)self, "enter", "l", n));
}
//---------------------------------------------------------------------------
uint32 choose_choose(
void *self,
int flags,
int x0,int y0,
int x1,int y1,
int width,
int deflt,
int icon)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t pytitle(PyObject_GetAttrString((PyObject *)self, "title"));
const char *title = pytitle != NULL ? PyString_AsString(pytitle.o) : "Choose";
int r = choose(
flags,
x0, y0,
x1, y1,
self,
width,
choose_sizer,
choose_getl,
title,
icon,
deflt,
NULL, /* del */
NULL, /* inst */
NULL, /* update */
NULL, /* edit */
choose_enter,
NULL, /* destroy */
NULL, /* popup_names */
NULL);/* get_icon */
return r;
}
//</inline(py_kernwin)>
#endif // __PY_CHOOSE__
#ifndef __PY_CHOOSE__
#define __PY_CHOOSE__
//---------------------------------------------------------------------------
//<inline(py_kernwin)>
//---------------------------------------------------------------------------
uint32 idaapi choose_sizer(void *self)
{
PYW_GIL_GET;
newref_t pyres(PyObject_CallMethod((PyObject *)self, "sizer", ""));
return PyInt_AsLong(pyres.o);
}
//---------------------------------------------------------------------------
char *idaapi choose_getl(void *self, uint32 n, char *buf)
{
PYW_GIL_GET;
newref_t pyres(
PyObject_CallMethod(
(PyObject *)self,
"getl",
"l",
n));
const char *res;
if (pyres == NULL || (res = PyString_AsString(pyres.o)) == NULL )
qstrncpy(buf, "<Empty>", MAXSTR);
else
qstrncpy(buf, res, MAXSTR);
return buf;
}
//---------------------------------------------------------------------------
void idaapi choose_enter(void *self, uint32 n)
{
PYW_GIL_GET;
newref_t res(PyObject_CallMethod((PyObject *)self, "enter", "l", n));
}
//---------------------------------------------------------------------------
uint32 choose_choose(
void *self,
int flags,
int x0,int y0,
int x1,int y1,
int width,
int deflt,
int icon)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t pytitle(PyObject_GetAttrString((PyObject *)self, "title"));
const char *title = pytitle != NULL ? PyString_AsString(pytitle.o) : "Choose";
int r = choose(
flags,
x0, y0,
x1, y1,
self,
width,
choose_sizer,
choose_getl,
title,
icon,
deflt,
NULL, /* del */
NULL, /* inst */
NULL, /* update */
NULL, /* edit */
choose_enter,
NULL, /* destroy */
NULL, /* popup_names */
NULL);/* get_icon */
return r;
}
//</inline(py_kernwin)>
#endif // __PY_CHOOSE__

File diff suppressed because it is too large Load Diff

View File

@@ -1,408 +1,408 @@
# -----------------------------------------------------------------------
# Standalone and testing code
from ctypes import *
try:
import _idaapi
except:
print("Please try me from inside IDA")
sys.exit(0)
try:
import pywraps
pywraps_there = True
print("Choose2: using pywraps")
_idaapi.choose2_create = pywraps.py_choose2_create
_idaapi.choose2_activate = pywraps.py_choose2_activate
_idaapi.choose2_refresh = pywraps.py_choose2_refresh
_idaapi.choose2_close = pywraps.py_choose2_close
_idaapi.choose2_add_command = pywraps.py_choose2_add_command
_idaapi.choose2_get_embedded = pywraps.py_choose2_get_embedded
_idaapi.choose2_get_embedded_selection = pywraps.py_choose2_get_embedded_selection
try:
# Get function address
# void test_embedded(chooser_info_t *)
TEST_EMBEDDED = CFUNCTYPE(c_void_p, c_void_p)
test_embedded = TEST_EMBEDDED(pywraps.py_choose2_get_test_embedded())
except Exception as e:
test_embedded = None
print("Choose2: Exception: %s" % str(e))
except Exception as e:
pywraps_there = False
print("Choose2: Not using pywraps: %s" % str(e))
# -----------------------------------------------------------------------
#<pycode(py_kernwin)>
class Choose2(object):
"""
Choose2 wrapper class.
Some constants are defined in this class. Please refer to kernwin.hpp for more information.
"""
CH_MODAL = 0x01
"""Modal chooser"""
CH_MULTI = 0x02
"""Allow multi selection"""
CH_MULTI_EDIT = 0x04
CH_NOBTNS = 0x08
CH_ATTRS = 0x10
CH_NOIDB = 0x20
"""use the chooser even without an open database, same as x0=-2"""
CH_UTF8 = 0x40
"""string encoding is utf-8"""
CH_BUILTIN_MASK = 0xF80000
# column flags (are specified in the widths array)
CHCOL_PLAIN = 0x00000000
CHCOL_PATH = 0x00010000
CHCOL_HEX = 0x00020000
CHCOL_DEC = 0x00030000
CHCOL_FORMAT = 0x00070000
def __init__(self, title, cols, flags=0, popup_names=None,
icon=-1, x1=-1, y1=-1, x2=-1, y2=-1, deflt=-1,
embedded=False, width=None, height=None):
"""
Constructs a chooser window.
@param title: The chooser title
@param cols: a list of colums; each list item is a list of two items
example: [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | Choose2.CHCOL_PLAIN] ]
@param flags: One of CH_XXXX constants
@param deflt: Default starting item
@param popup_names: list of new captions to replace this list ["Insert", "Delete", "Edit", "Refresh"]
@param icon: Icon index (the icon should exist in ida resources or an index to a custom loaded icon)
@param x1, y1, x2, y2: The default location
@param embedded: Create as embedded chooser
@param width: Embedded chooser width
@param height: Embedded chooser height
"""
self.title = title
self.flags = flags
self.cols = cols
self.deflt = deflt
self.popup_names = popup_names
self.icon = icon
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
self.embedded = embedded
if embedded:
self.x1 = width
self.y1 = height
def Embedded(self):
"""
Creates an embedded chooser (as opposed to Show())
@return: Returns 1 on success
"""
return _idaapi.choose2_create(self, True)
def GetEmbSelection(self):
"""
Returns the selection associated with an embedded chooser
@return:
- None if chooser is not embedded
- A list with selection indices (0-based)
"""
return _idaapi.choose2_get_embedded_selection(self)
def Show(self, modal=False):
"""
Activates or creates a chooser window
@param modal: Display as modal dialog
@return: For modal choosers it will return the selected item index (0-based)
"""
if modal:
self.flags |= Choose2.CH_MODAL
# Disable the timeout
old = _idaapi.set_script_timeout(0)
n = _idaapi.choose2_create(self, False)
_idaapi.set_script_timeout(old)
# Delete the modal chooser instance
self.Close()
return n
else:
self.flags &= ~Choose2.CH_MODAL
return _idaapi.choose2_create(self, False)
def Activate(self):
"""Activates a visible chooser"""
return _idaapi.choose2_activate(self)
def Refresh(self):
"""Causes the refresh callback to trigger"""
return _idaapi.choose2_refresh(self)
def Close(self):
"""Closes the chooser"""
return _idaapi.choose2_close(self)
def AddCommand(self,
caption,
flags = _idaapi.CHOOSER_POPUP_MENU,
menu_index = -1,
icon = -1,
emb=None):
"""
Deprecated: Use
- register_action()
- attach_action_to_menu()
- attach_action_to_popup()
"""
# Use the 'emb' as a sentinel. It will be passed the correct value from the EmbeddedChooserControl
if self.embedded and ((emb is None) or (emb != 2002)):
raise RuntimeError("Please add a command through EmbeddedChooserControl.AddCommand()")
return _idaapi.choose2_add_command(self, caption, flags, menu_index, icon)
#
# Implement these methods in the subclass:
#
#<pydoc>
# def OnClose(self):
# """
# Called when the window is being closed.
# This callback is mandatory.
# @return: nothing
# """
# pass
#
# def OnGetLine(self, n):
# """Called when the chooser window requires lines.
# This callback is mandatory.
# @param n: Line number (0-based)
# @return: The user should return a list with ncols elements.
# example: a list [col1, col2, col3, ...] describing the n-th line
# """
# return ["col1 val", "col2 val"]
#
# def OnGetSize(self):
# """Returns the element count.
# This callback is mandatory.
# @return: Number of elements
# """
# return len(self.the_list)
#
# def OnEditLine(self, n):
# """
# Called when an item is being edited.
# @param n: Line number (0-based)
# @return: Nothing
# """
# pass
#
# def OnInsertLine(self):
# """
# Called when 'Insert' is selected either via the hotkey or popup menu.
# @return: Nothing
# """
# pass
#
# def OnSelectLine(self, n):
# """
# Called when a line is selected and then Ok or double click was pressed
# @param n: Line number (0-based)
# """
# pass
#
# def OnSelectionChange(self, sel_list):
# """
# Called when the selection changes
# @param sel_list: A list of selected item indices
# """
# pass
#
# def OnDeleteLine(self, n):
# """
# Called when a line is about to be deleted
# @param n: Line number (0-based)
# """
# return self.n
#
# def OnRefresh(self, n):
# """
# Triggered when the 'Refresh' is called from the popup menu item.
#
# @param n: The currently selected line (0-based) at the time of the refresh call
# @return: Return the number of elements
# """
# return self.n
#
# def OnRefreshed(self):
# """
# Triggered when a refresh happens (for example due to column sorting)
# @param n: Line number (0-based)
# @return: Return the number of elements
# """
# return self.n
#
# def OnCommand(self, n, cmd_id):
# """Return int ; check add_chooser_command()"""
# return 0
#
# def OnGetIcon(self, n):
# """
# Return icon number for a given item (or -1 if no icon is avail)
# @param n: Line number (0-based)
# """
# return -1
#
# def OnGetLineAttr(self, n):
# """
# Return list [bgcolor, flags=CHITEM_XXXX] or None; check chooser_item_attrs_t
# @param n: Line number (0-based)
# """
# return [0x0, CHITEM_BOLD]
#</pydoc>
#</pycode(py_kernwin)>
# -----------------------------------------------------------------------
#<pycode(py_choose2ex1)>
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))
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", 10], ["Name", 30] ],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = [ 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
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 -> %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) >= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print("getlineattr %d" % n)
if n == 1:
return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Choose2 - sample 1", nb=10, modal=modal)
r = c.show()
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("Choose2 - embedded", 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()
# -----------------------------------------------------------------------
if __name__ == '__main__':
# Register actions
for thing in ["A", "B"]:
actname = "choose2:act%s" % thing
idaapi.register_action(
idaapi.action_desc_t(
actname,
"command %s" % thing,
chooser_handler_t(thing)))
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>
# -----------------------------------------------------------------------
# Standalone and testing code
from ctypes import *
try:
import _idaapi
except:
print("Please try me from inside IDA")
sys.exit(0)
try:
import pywraps
pywraps_there = True
print("Choose2: using pywraps")
_idaapi.choose2_create = pywraps.py_choose2_create
_idaapi.choose2_activate = pywraps.py_choose2_activate
_idaapi.choose2_refresh = pywraps.py_choose2_refresh
_idaapi.choose2_close = pywraps.py_choose2_close
_idaapi.choose2_add_command = pywraps.py_choose2_add_command
_idaapi.choose2_get_embedded = pywraps.py_choose2_get_embedded
_idaapi.choose2_get_embedded_selection = pywraps.py_choose2_get_embedded_selection
try:
# Get function address
# void test_embedded(chooser_info_t *)
TEST_EMBEDDED = CFUNCTYPE(c_void_p, c_void_p)
test_embedded = TEST_EMBEDDED(pywraps.py_choose2_get_test_embedded())
except Exception as e:
test_embedded = None
print("Choose2: Exception: %s" % str(e))
except Exception as e:
pywraps_there = False
print("Choose2: Not using pywraps: %s" % str(e))
# -----------------------------------------------------------------------
#<pycode(py_kernwin)>
class Choose2(object):
"""
Choose2 wrapper class.
Some constants are defined in this class. Please refer to kernwin.hpp for more information.
"""
CH_MODAL = 0x01
"""Modal chooser"""
CH_MULTI = 0x02
"""Allow multi selection"""
CH_MULTI_EDIT = 0x04
CH_NOBTNS = 0x08
CH_ATTRS = 0x10
CH_NOIDB = 0x20
"""use the chooser even without an open database, same as x0=-2"""
CH_UTF8 = 0x40
"""string encoding is utf-8"""
CH_BUILTIN_MASK = 0xF80000
# column flags (are specified in the widths array)
CHCOL_PLAIN = 0x00000000
CHCOL_PATH = 0x00010000
CHCOL_HEX = 0x00020000
CHCOL_DEC = 0x00030000
CHCOL_FORMAT = 0x00070000
def __init__(self, title, cols, flags=0, popup_names=None,
icon=-1, x1=-1, y1=-1, x2=-1, y2=-1, deflt=-1,
embedded=False, width=None, height=None):
"""
Constructs a chooser window.
@param title: The chooser title
@param cols: a list of colums; each list item is a list of two items
example: [ ["Address", 10 | Choose2.CHCOL_HEX], ["Name", 30 | Choose2.CHCOL_PLAIN] ]
@param flags: One of CH_XXXX constants
@param deflt: Default starting item
@param popup_names: list of new captions to replace this list ["Insert", "Delete", "Edit", "Refresh"]
@param icon: Icon index (the icon should exist in ida resources or an index to a custom loaded icon)
@param x1, y1, x2, y2: The default location
@param embedded: Create as embedded chooser
@param width: Embedded chooser width
@param height: Embedded chooser height
"""
self.title = title
self.flags = flags
self.cols = cols
self.deflt = deflt
self.popup_names = popup_names
self.icon = icon
self.x1 = x1
self.y1 = y1
self.x2 = x2
self.y2 = y2
self.embedded = embedded
if embedded:
self.x1 = width
self.y1 = height
def Embedded(self):
"""
Creates an embedded chooser (as opposed to Show())
@return: Returns 1 on success
"""
return _idaapi.choose2_create(self, True)
def GetEmbSelection(self):
"""
Returns the selection associated with an embedded chooser
@return:
- None if chooser is not embedded
- A list with selection indices (0-based)
"""
return _idaapi.choose2_get_embedded_selection(self)
def Show(self, modal=False):
"""
Activates or creates a chooser window
@param modal: Display as modal dialog
@return: For modal choosers it will return the selected item index (0-based)
"""
if modal:
self.flags |= Choose2.CH_MODAL
# Disable the timeout
old = _idaapi.set_script_timeout(0)
n = _idaapi.choose2_create(self, False)
_idaapi.set_script_timeout(old)
# Delete the modal chooser instance
self.Close()
return n
else:
self.flags &= ~Choose2.CH_MODAL
return _idaapi.choose2_create(self, False)
def Activate(self):
"""Activates a visible chooser"""
return _idaapi.choose2_activate(self)
def Refresh(self):
"""Causes the refresh callback to trigger"""
return _idaapi.choose2_refresh(self)
def Close(self):
"""Closes the chooser"""
return _idaapi.choose2_close(self)
def AddCommand(self,
caption,
flags = _idaapi.CHOOSER_POPUP_MENU,
menu_index = -1,
icon = -1,
emb=None):
"""
Deprecated: Use
- register_action()
- attach_action_to_menu()
- attach_action_to_popup()
"""
# Use the 'emb' as a sentinel. It will be passed the correct value from the EmbeddedChooserControl
if self.embedded and ((emb is None) or (emb != 2002)):
raise RuntimeError("Please add a command through EmbeddedChooserControl.AddCommand()")
return _idaapi.choose2_add_command(self, caption, flags, menu_index, icon)
#
# Implement these methods in the subclass:
#
#<pydoc>
# def OnClose(self):
# """
# Called when the window is being closed.
# This callback is mandatory.
# @return: nothing
# """
# pass
#
# def OnGetLine(self, n):
# """Called when the chooser window requires lines.
# This callback is mandatory.
# @param n: Line number (0-based)
# @return: The user should return a list with ncols elements.
# example: a list [col1, col2, col3, ...] describing the n-th line
# """
# return ["col1 val", "col2 val"]
#
# def OnGetSize(self):
# """Returns the element count.
# This callback is mandatory.
# @return: Number of elements
# """
# return len(self.the_list)
#
# def OnEditLine(self, n):
# """
# Called when an item is being edited.
# @param n: Line number (0-based)
# @return: Nothing
# """
# pass
#
# def OnInsertLine(self):
# """
# Called when 'Insert' is selected either via the hotkey or popup menu.
# @return: Nothing
# """
# pass
#
# def OnSelectLine(self, n):
# """
# Called when a line is selected and then Ok or double click was pressed
# @param n: Line number (0-based)
# """
# pass
#
# def OnSelectionChange(self, sel_list):
# """
# Called when the selection changes
# @param sel_list: A list of selected item indices
# """
# pass
#
# def OnDeleteLine(self, n):
# """
# Called when a line is about to be deleted
# @param n: Line number (0-based)
# """
# return self.n
#
# def OnRefresh(self, n):
# """
# Triggered when the 'Refresh' is called from the popup menu item.
#
# @param n: The currently selected line (0-based) at the time of the refresh call
# @return: Return the number of elements
# """
# return self.n
#
# def OnRefreshed(self):
# """
# Triggered when a refresh happens (for example due to column sorting)
# @param n: Line number (0-based)
# @return: Return the number of elements
# """
# return self.n
#
# def OnCommand(self, n, cmd_id):
# """Return int ; check add_chooser_command()"""
# return 0
#
# def OnGetIcon(self, n):
# """
# Return icon number for a given item (or -1 if no icon is avail)
# @param n: Line number (0-based)
# """
# return -1
#
# def OnGetLineAttr(self, n):
# """
# Return list [bgcolor, flags=CHITEM_XXXX] or None; check chooser_item_attrs_t
# @param n: Line number (0-based)
# """
# return [0x0, CHITEM_BOLD]
#</pydoc>
#</pycode(py_kernwin)>
# -----------------------------------------------------------------------
#<pycode(py_choose2ex1)>
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))
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", 10], ["Name", 30] ],
flags = flags,
width = width,
height = height,
embedded = embedded)
self.n = 0
self.items = [ 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
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 -> %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) >= 0
def make_item(self):
r = [str(self.n), "func_%04d" % self.n]
self.n += 1
return r
def OnGetLineAttr(self, n):
print("getlineattr %d" % n)
if n == 1:
return [0xFF0000, 0]
# -----------------------------------------------------------------------
def test_choose2(modal=False):
global c
c = MyChoose2("Choose2 - sample 1", nb=10, modal=modal)
r = c.show()
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("Choose2 - embedded", 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()
# -----------------------------------------------------------------------
if __name__ == '__main__':
# Register actions
for thing in ["A", "B"]:
actname = "choose2:act%s" % thing
idaapi.register_action(
idaapi.action_desc_t(
actname,
"command %s" % thing,
chooser_handler_t(thing)))
#test_choose2_embedded()
test_choose2(False)
#</pycode(py_choose2ex1)>

View File

@@ -1,295 +1,295 @@
#ifndef __PYWRAPS_CLI__
#define __PYWRAPS_CLI__
//<code(py_cli)>
//--------------------------------------------------------------------------
#define MAX_PY_CLI 12
// Callbacks table
// This structure was devised because the cli callbacks have no user-data parameter
struct py_cli_cbs_t
{
bool (idaapi *execute_line)(const char *line);
bool (idaapi *complete_line)(
qstring *completion,
const char *prefix,
int n,
const char *line,
int x);
bool (idaapi *keydown)(
qstring *line,
int *p_x,
int *p_sellen,
int *vk_key,
int shift);
};
// CLI Python wrapper class
class py_cli_t
{
private:
//--------------------------------------------------------------------------
cli_t cli;
PyObject *self;
qstring cli_sname, cli_lname, cli_hint;
//--------------------------------------------------------------------------
static py_cli_t *py_clis[MAX_PY_CLI];
static const py_cli_cbs_t py_cli_cbs[MAX_PY_CLI];
//--------------------------------------------------------------------------
#define IMPL_PY_CLI_CB(CBN) \
static bool idaapi s_keydown##CBN(qstring *line, int *p_x, int *p_sellen, int *vk_key, int shift) \
{ \
return py_clis[CBN]->on_keydown(line, p_x, p_sellen, vk_key, shift); \
} \
static bool idaapi s_execute_line##CBN(const char *line) \
{ \
return py_clis[CBN]->on_execute_line(line); \
} \
static bool idaapi s_complete_line##CBN(qstring *completion, const char *prefix, int n, const char *line, int x) \
{ \
return py_clis[CBN]->on_complete_line(completion, prefix, n, line, x); \
}
IMPL_PY_CLI_CB(0); IMPL_PY_CLI_CB(1); IMPL_PY_CLI_CB(2); IMPL_PY_CLI_CB(3);
IMPL_PY_CLI_CB(4); IMPL_PY_CLI_CB(5); IMPL_PY_CLI_CB(6); IMPL_PY_CLI_CB(7);
IMPL_PY_CLI_CB(8); IMPL_PY_CLI_CB(9); IMPL_PY_CLI_CB(10); IMPL_PY_CLI_CB(11);
#undef IMPL_PY_CLI_CB
//--------------------------------------------------------------------------
// callback: the user pressed Enter
// CLI is free to execute the line immediately or ask for more lines
// Returns: true-executed line, false-ask for more lines
bool on_execute_line(const char *line)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_EXECUTE_LINE,
"s",
line));
PyW_ShowCbErr(S_ON_EXECUTE_LINE);
return result != NULL && PyObject_IsTrue(result.o);
}
//--------------------------------------------------------------------------
// callback: a keyboard key has been pressed
// This is a generic callback and the CLI is free to do whatever
// it wants.
// line - current input line (in/out argument)
// p_x - pointer to current x coordinate of the cursor (in/out)
// p_sellen - pointer to current selection length (usually 0)
// p_vk_key - pointer to virtual key code (in/out)
// if the key has been handled, it should be reset to 0 by CLI
// shift - shift state
// Returns: true-modified input line or x coordinate or selection length
// This callback is optional
bool on_keydown(
qstring *line,
int *p_x,
int *p_sellen,
int *vk_key,
int shift)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_KEYDOWN,
"siiHi",
line->c_str(),
*p_x,
*p_sellen,
*vk_key,
shift));
bool ok = result != NULL && PyTuple_Check(result.o);
PyW_ShowCbErr(S_ON_KEYDOWN);
if ( ok )
{
Py_ssize_t sz = PyTuple_Size(result.o);
PyObject *item;
#define GET_TUPLE_ENTRY(col, PyThingy, AsThingy, out) \
do \
{ \
if ( sz > col ) \
{ \
borref_t _r(PyTuple_GetItem(result.o, col)); \
if ( _r != NULL && PyThingy##_Check(_r.o) ) \
*out = PyThingy##_##AsThingy(_r.o); \
} \
} while ( false )
GET_TUPLE_ENTRY(0, PyString, AsString, line);
GET_TUPLE_ENTRY(1, PyInt, AsLong, p_x);
GET_TUPLE_ENTRY(2, PyInt, AsLong, p_sellen);
GET_TUPLE_ENTRY(3, PyInt, AsLong, vk_key);
*vk_key &= 0xffff;
#undef GET_TUPLE_ENTRY
}
return ok;
}
// callback: the user pressed Tab
// Find a completion number N for prefix PREFIX
// LINE is given as context information. X is the index where PREFIX starts in LINE
// New prefix should be stored in PREFIX.
// Returns: true if generated a new completion
// This callback is optional
bool on_complete_line(
qstring *completion,
const char *prefix,
int n,
const char *line,
int x)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_COMPLETE_LINE,
"sisi",
prefix,
n,
line,
x));
bool ok = result != NULL && PyString_Check(result.o);
PyW_ShowCbErr(S_ON_COMPLETE_LINE);
if ( ok )
*completion = PyString_AsString(result.o);
return ok;
}
// Private ctor (use bind())
py_cli_t()
{
}
public:
//---------------------------------------------------------------------------
static int bind(PyObject *py_obj)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int cli_idx;
// Find an empty slot
for ( cli_idx = 0; cli_idx < MAX_PY_CLI; ++cli_idx )
{
if ( py_clis[cli_idx] == NULL )
break;
}
py_cli_t *py_cli = NULL;
do
{
// No free slots?
if ( cli_idx >= MAX_PY_CLI )
break;
// Create a new instance
py_cli = new py_cli_t();
PyObject *attr;
// Start populating the 'cli' member
py_cli->cli.size = sizeof(cli_t);
// Store 'flags'
{
ref_t flags_attr(PyW_TryGetAttrString(py_obj, S_FLAGS));
if ( flags_attr == NULL )
py_cli->cli.flags = 0;
else
py_cli->cli.flags = PyLong_AsLong(flags_attr.o);
}
// Store 'sname'
if ( !PyW_GetStringAttr(py_obj, "sname", &py_cli->cli_sname) )
break;
py_cli->cli.sname = py_cli->cli_sname.c_str();
// Store 'lname'
if ( !PyW_GetStringAttr(py_obj, "lname", &py_cli->cli_lname) )
break;
py_cli->cli.lname = py_cli->cli_lname.c_str();
// Store 'hint'
if ( !PyW_GetStringAttr(py_obj, "hint", &py_cli->cli_hint) )
break;
py_cli->cli.hint = py_cli->cli_hint.c_str();
// Store callbacks
if ( !PyObject_HasAttrString(py_obj, S_ON_EXECUTE_LINE) )
break;
py_cli->cli.execute_line = py_cli_cbs[cli_idx].execute_line;
py_cli->cli.complete_line = PyObject_HasAttrString(py_obj, S_ON_COMPLETE_LINE) ? py_cli_cbs[cli_idx].complete_line : NULL;
py_cli->cli.keydown = PyObject_HasAttrString(py_obj, S_ON_KEYDOWN) ? py_cli_cbs[cli_idx].keydown : NULL;
// install CLI
install_command_interpreter(&py_cli->cli);
// Take reference to this object
py_cli->self = py_obj;
Py_INCREF(py_obj);
// Save the instance
py_clis[cli_idx] = py_cli;
return cli_idx;
} while (false);
delete py_cli;
return -1;
}
//---------------------------------------------------------------------------
static void unbind(int cli_idx)
{
// Out of bounds or not set?
if ( cli_idx < 0 || cli_idx >= MAX_PY_CLI || py_clis[cli_idx] == NULL )
return;
py_cli_t *py_cli = py_clis[cli_idx];
remove_command_interpreter(&py_cli->cli);
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_DECREF(py_cli->self);
delete py_cli;
}
py_clis[cli_idx] = NULL;
return;
}
};
py_cli_t *py_cli_t::py_clis[MAX_PY_CLI] = {NULL};
#define DECL_PY_CLI_CB(CBN) { s_execute_line##CBN, s_complete_line##CBN, s_keydown##CBN }
const py_cli_cbs_t py_cli_t::py_cli_cbs[MAX_PY_CLI] =
{
DECL_PY_CLI_CB(0), DECL_PY_CLI_CB(1), DECL_PY_CLI_CB(2), DECL_PY_CLI_CB(3),
DECL_PY_CLI_CB(4), DECL_PY_CLI_CB(5), DECL_PY_CLI_CB(6), DECL_PY_CLI_CB(7),
DECL_PY_CLI_CB(8), DECL_PY_CLI_CB(9), DECL_PY_CLI_CB(10), DECL_PY_CLI_CB(11)
};
#undef DECL_PY_CLI_CB
//</code(py_cli)>
//--------------------------------------------------------------------------
//<inline(py_cli)>
static int py_install_command_interpreter(PyObject *py_obj)
{
return py_cli_t::bind(py_obj);
}
static void py_remove_command_interpreter(int cli_idx)
{
py_cli_t::unbind(cli_idx);
}
//</inline(py_cli)>
//---------------------------------------------------------------------------
#endif // __PYWRAPS_CLI__
#ifndef __PYWRAPS_CLI__
#define __PYWRAPS_CLI__
//<code(py_cli)>
//--------------------------------------------------------------------------
#define MAX_PY_CLI 12
// Callbacks table
// This structure was devised because the cli callbacks have no user-data parameter
struct py_cli_cbs_t
{
bool (idaapi *execute_line)(const char *line);
bool (idaapi *complete_line)(
qstring *completion,
const char *prefix,
int n,
const char *line,
int x);
bool (idaapi *keydown)(
qstring *line,
int *p_x,
int *p_sellen,
int *vk_key,
int shift);
};
// CLI Python wrapper class
class py_cli_t
{
private:
//--------------------------------------------------------------------------
cli_t cli;
PyObject *self;
qstring cli_sname, cli_lname, cli_hint;
//--------------------------------------------------------------------------
static py_cli_t *py_clis[MAX_PY_CLI];
static const py_cli_cbs_t py_cli_cbs[MAX_PY_CLI];
//--------------------------------------------------------------------------
#define IMPL_PY_CLI_CB(CBN) \
static bool idaapi s_keydown##CBN(qstring *line, int *p_x, int *p_sellen, int *vk_key, int shift) \
{ \
return py_clis[CBN]->on_keydown(line, p_x, p_sellen, vk_key, shift); \
} \
static bool idaapi s_execute_line##CBN(const char *line) \
{ \
return py_clis[CBN]->on_execute_line(line); \
} \
static bool idaapi s_complete_line##CBN(qstring *completion, const char *prefix, int n, const char *line, int x) \
{ \
return py_clis[CBN]->on_complete_line(completion, prefix, n, line, x); \
}
IMPL_PY_CLI_CB(0); IMPL_PY_CLI_CB(1); IMPL_PY_CLI_CB(2); IMPL_PY_CLI_CB(3);
IMPL_PY_CLI_CB(4); IMPL_PY_CLI_CB(5); IMPL_PY_CLI_CB(6); IMPL_PY_CLI_CB(7);
IMPL_PY_CLI_CB(8); IMPL_PY_CLI_CB(9); IMPL_PY_CLI_CB(10); IMPL_PY_CLI_CB(11);
#undef IMPL_PY_CLI_CB
//--------------------------------------------------------------------------
// callback: the user pressed Enter
// CLI is free to execute the line immediately or ask for more lines
// Returns: true-executed line, false-ask for more lines
bool on_execute_line(const char *line)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_EXECUTE_LINE,
"s",
line));
PyW_ShowCbErr(S_ON_EXECUTE_LINE);
return result != NULL && PyObject_IsTrue(result.o);
}
//--------------------------------------------------------------------------
// callback: a keyboard key has been pressed
// This is a generic callback and the CLI is free to do whatever
// it wants.
// line - current input line (in/out argument)
// p_x - pointer to current x coordinate of the cursor (in/out)
// p_sellen - pointer to current selection length (usually 0)
// p_vk_key - pointer to virtual key code (in/out)
// if the key has been handled, it should be reset to 0 by CLI
// shift - shift state
// Returns: true-modified input line or x coordinate or selection length
// This callback is optional
bool on_keydown(
qstring *line,
int *p_x,
int *p_sellen,
int *vk_key,
int shift)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_KEYDOWN,
"siiHi",
line->c_str(),
*p_x,
*p_sellen,
*vk_key,
shift));
bool ok = result != NULL && PyTuple_Check(result.o);
PyW_ShowCbErr(S_ON_KEYDOWN);
if ( ok )
{
Py_ssize_t sz = PyTuple_Size(result.o);
PyObject *item;
#define GET_TUPLE_ENTRY(col, PyThingy, AsThingy, out) \
do \
{ \
if ( sz > col ) \
{ \
borref_t _r(PyTuple_GetItem(result.o, col)); \
if ( _r != NULL && PyThingy##_Check(_r.o) ) \
*out = PyThingy##_##AsThingy(_r.o); \
} \
} while ( false )
GET_TUPLE_ENTRY(0, PyString, AsString, line);
GET_TUPLE_ENTRY(1, PyInt, AsLong, p_x);
GET_TUPLE_ENTRY(2, PyInt, AsLong, p_sellen);
GET_TUPLE_ENTRY(3, PyInt, AsLong, vk_key);
*vk_key &= 0xffff;
#undef GET_TUPLE_ENTRY
}
return ok;
}
// callback: the user pressed Tab
// Find a completion number N for prefix PREFIX
// LINE is given as context information. X is the index where PREFIX starts in LINE
// New prefix should be stored in PREFIX.
// Returns: true if generated a new completion
// This callback is optional
bool on_complete_line(
qstring *completion,
const char *prefix,
int n,
const char *line,
int x)
{
PYW_GIL_GET;
newref_t result(
PyObject_CallMethod(
self,
(char *)S_ON_COMPLETE_LINE,
"sisi",
prefix,
n,
line,
x));
bool ok = result != NULL && PyString_Check(result.o);
PyW_ShowCbErr(S_ON_COMPLETE_LINE);
if ( ok )
*completion = PyString_AsString(result.o);
return ok;
}
// Private ctor (use bind())
py_cli_t()
{
}
public:
//---------------------------------------------------------------------------
static int bind(PyObject *py_obj)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int cli_idx;
// Find an empty slot
for ( cli_idx = 0; cli_idx < MAX_PY_CLI; ++cli_idx )
{
if ( py_clis[cli_idx] == NULL )
break;
}
py_cli_t *py_cli = NULL;
do
{
// No free slots?
if ( cli_idx >= MAX_PY_CLI )
break;
// Create a new instance
py_cli = new py_cli_t();
PyObject *attr;
// Start populating the 'cli' member
py_cli->cli.size = sizeof(cli_t);
// Store 'flags'
{
ref_t flags_attr(PyW_TryGetAttrString(py_obj, S_FLAGS));
if ( flags_attr == NULL )
py_cli->cli.flags = 0;
else
py_cli->cli.flags = PyLong_AsLong(flags_attr.o);
}
// Store 'sname'
if ( !PyW_GetStringAttr(py_obj, "sname", &py_cli->cli_sname) )
break;
py_cli->cli.sname = py_cli->cli_sname.c_str();
// Store 'lname'
if ( !PyW_GetStringAttr(py_obj, "lname", &py_cli->cli_lname) )
break;
py_cli->cli.lname = py_cli->cli_lname.c_str();
// Store 'hint'
if ( !PyW_GetStringAttr(py_obj, "hint", &py_cli->cli_hint) )
break;
py_cli->cli.hint = py_cli->cli_hint.c_str();
// Store callbacks
if ( !PyObject_HasAttrString(py_obj, S_ON_EXECUTE_LINE) )
break;
py_cli->cli.execute_line = py_cli_cbs[cli_idx].execute_line;
py_cli->cli.complete_line = PyObject_HasAttrString(py_obj, S_ON_COMPLETE_LINE) ? py_cli_cbs[cli_idx].complete_line : NULL;
py_cli->cli.keydown = PyObject_HasAttrString(py_obj, S_ON_KEYDOWN) ? py_cli_cbs[cli_idx].keydown : NULL;
// install CLI
install_command_interpreter(&py_cli->cli);
// Take reference to this object
py_cli->self = py_obj;
Py_INCREF(py_obj);
// Save the instance
py_clis[cli_idx] = py_cli;
return cli_idx;
} while (false);
delete py_cli;
return -1;
}
//---------------------------------------------------------------------------
static void unbind(int cli_idx)
{
// Out of bounds or not set?
if ( cli_idx < 0 || cli_idx >= MAX_PY_CLI || py_clis[cli_idx] == NULL )
return;
py_cli_t *py_cli = py_clis[cli_idx];
remove_command_interpreter(&py_cli->cli);
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_DECREF(py_cli->self);
delete py_cli;
}
py_clis[cli_idx] = NULL;
return;
}
};
py_cli_t *py_cli_t::py_clis[MAX_PY_CLI] = {NULL};
#define DECL_PY_CLI_CB(CBN) { s_execute_line##CBN, s_complete_line##CBN, s_keydown##CBN }
const py_cli_cbs_t py_cli_t::py_cli_cbs[MAX_PY_CLI] =
{
DECL_PY_CLI_CB(0), DECL_PY_CLI_CB(1), DECL_PY_CLI_CB(2), DECL_PY_CLI_CB(3),
DECL_PY_CLI_CB(4), DECL_PY_CLI_CB(5), DECL_PY_CLI_CB(6), DECL_PY_CLI_CB(7),
DECL_PY_CLI_CB(8), DECL_PY_CLI_CB(9), DECL_PY_CLI_CB(10), DECL_PY_CLI_CB(11)
};
#undef DECL_PY_CLI_CB
//</code(py_cli)>
//--------------------------------------------------------------------------
//<inline(py_cli)>
static int py_install_command_interpreter(PyObject *py_obj)
{
return py_cli_t::bind(py_obj);
}
static void py_remove_command_interpreter(int cli_idx)
{
py_cli_t::unbind(cli_idx);
}
//</inline(py_cli)>
//---------------------------------------------------------------------------
#endif // __PYWRAPS_CLI__

View File

@@ -1,187 +1,187 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Using IDAPython"
try:
import _idaapi
from idaapi import pyidc_opaque_object_t
except:
print "Please run this script from inside IDA"
sys.exit(0)
if pywraps_there:
_idaapi.install_command_interpreter = pywraps.install_command_interpreter
_idaapi.remove_command_interpreter = pywraps.remove_command_interpreter
# -----------------------------------------------------------------------
#<pycode(py_cli)>
class cli_t(pyidc_opaque_object_t):
"""
cli_t wrapper class.
This class allows you to implement your own command line interface handlers.
"""
def __init__(self):
self.__cli_idx = -1
self.__clink__ = None
def register(self, flags = 0, sname = None, lname = None, hint = None):
"""
Registers the CLI.
@param flags: Feature bits. No bits are defined yet, must be 0
@param sname: Short name (displayed on the button)
@param lname: Long name (displayed in the menu)
@param hint: Hint for the input line
@return Boolean: True-Success, False-Failed
"""
# Already registered?
if self.__cli_idx >= 0:
return True
if sname is not None: self.sname = sname
if lname is not None: self.lname = lname
if hint is not None: self.hint = hint
# Register
self.__cli_idx = _idaapi.install_command_interpreter(self)
return False if self.__cli_idx < 0 else True
def unregister(self):
"""
Unregisters the CLI (if it was registered)
"""
if self.__cli_idx < 0:
return False
_idaapi.remove_command_interpreter(self.__cli_idx)
self.__cli_idx = -1
return True
def __del__(self):
self.unregister()
#
# Implement these methods in the subclass:
#
#<pydoc>
# def OnExecuteLine(self, line):
# """
# The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
#
# This callback is mandatory.
#
# @param line: typed line(s)
# @return Boolean: True-executed line, False-ask for more lines
# """
# return True
#
# def OnKeydown(self, line, x, sellen, vkey, shift):
# """
# A keyboard key has been pressed
# This is a generic callback and the CLI is free to do whatever it wants.
#
# This callback is optional.
#
# @param line: current input line
# @param x: current x coordinate of the cursor
# @param sellen: current selection length (usually 0)
# @param vkey: virtual key code. if the key has been handled, it should be returned as zero
# @param shift: shift state
#
# @return:
# None - Nothing was changed
# tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
# It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
# """
# return None
#
# def OnCompleteLine(self, prefix, n, line, prefix_start):
# """
# The user pressed Tab. Find a completion number N for prefix PREFIX
#
# This callback is optional.
#
# @param prefix: Line prefix at prefix_start (string)
# @param n: completion number (int)
# @param line: the current line (string)
# @param prefix_start: the index where PREFIX starts in LINE (int)
#
# @return: None if no completion could be generated otherwise a String with the completion suggestion
# """
# return None
#</pydoc>
#</pycode(py_cli)>
# -----------------------------------------------------------------------
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
lname = "Python CLI"
hint = "pycli hint"
def OnExecuteLine(self, line):
"""
The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
This callback is mandatory.
@param line: typed line(s)
@return Boolean: True-executed line, False-ask for more lines
"""
print "OnExecute:", line
return True
def OnKeydown(self, line, x, sellen, vkey, shift):
"""
A keyboard key has been pressed
This is a generic callback and the CLI is free to do whatever it wants.
This callback is optional.
@param line: current input line
@param x: current x coordinate of the cursor
@param sellen: current selection length (usually 0)
@param vkey: virtual key code. if the key has been handled, it should be returned as zero
@param shift: shift state
@return:
None - Nothing was changed
tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
"""
print "Onkeydown: line=%s x=%d sellen=%d vkey=%d shift=%d" % (line, x, sellen, vkey, shift)
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
"""
The user pressed Tab. Find a completion number N for prefix PREFIX
This callback is optional.
@param prefix: Line prefix at prefix_start (string)
@param n: completion number (int)
@param line: the current line (string)
@param prefix_start: the index where PREFIX starts in LINE (int)
@return: None if no completion could be generated otherwise a String with the completion suggestion
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Using IDAPython"
try:
import _idaapi
from idaapi import pyidc_opaque_object_t
except:
print "Please run this script from inside IDA"
sys.exit(0)
if pywraps_there:
_idaapi.install_command_interpreter = pywraps.install_command_interpreter
_idaapi.remove_command_interpreter = pywraps.remove_command_interpreter
# -----------------------------------------------------------------------
#<pycode(py_cli)>
class cli_t(pyidc_opaque_object_t):
"""
cli_t wrapper class.
This class allows you to implement your own command line interface handlers.
"""
def __init__(self):
self.__cli_idx = -1
self.__clink__ = None
def register(self, flags = 0, sname = None, lname = None, hint = None):
"""
Registers the CLI.
@param flags: Feature bits. No bits are defined yet, must be 0
@param sname: Short name (displayed on the button)
@param lname: Long name (displayed in the menu)
@param hint: Hint for the input line
@return Boolean: True-Success, False-Failed
"""
# Already registered?
if self.__cli_idx >= 0:
return True
if sname is not None: self.sname = sname
if lname is not None: self.lname = lname
if hint is not None: self.hint = hint
# Register
self.__cli_idx = _idaapi.install_command_interpreter(self)
return False if self.__cli_idx < 0 else True
def unregister(self):
"""
Unregisters the CLI (if it was registered)
"""
if self.__cli_idx < 0:
return False
_idaapi.remove_command_interpreter(self.__cli_idx)
self.__cli_idx = -1
return True
def __del__(self):
self.unregister()
#
# Implement these methods in the subclass:
#
#<pydoc>
# def OnExecuteLine(self, line):
# """
# The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
#
# This callback is mandatory.
#
# @param line: typed line(s)
# @return Boolean: True-executed line, False-ask for more lines
# """
# return True
#
# def OnKeydown(self, line, x, sellen, vkey, shift):
# """
# A keyboard key has been pressed
# This is a generic callback and the CLI is free to do whatever it wants.
#
# This callback is optional.
#
# @param line: current input line
# @param x: current x coordinate of the cursor
# @param sellen: current selection length (usually 0)
# @param vkey: virtual key code. if the key has been handled, it should be returned as zero
# @param shift: shift state
#
# @return:
# None - Nothing was changed
# tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
# It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
# """
# return None
#
# def OnCompleteLine(self, prefix, n, line, prefix_start):
# """
# The user pressed Tab. Find a completion number N for prefix PREFIX
#
# This callback is optional.
#
# @param prefix: Line prefix at prefix_start (string)
# @param n: completion number (int)
# @param line: the current line (string)
# @param prefix_start: the index where PREFIX starts in LINE (int)
#
# @return: None if no completion could be generated otherwise a String with the completion suggestion
# """
# return None
#</pydoc>
#</pycode(py_cli)>
# -----------------------------------------------------------------------
#<pycode(ex_cli_ex1)>
class mycli_t(cli_t):
flags = 0
sname = "pycli"
lname = "Python CLI"
hint = "pycli hint"
def OnExecuteLine(self, line):
"""
The user pressed Enter. The CLI is free to execute the line immediately or ask for more lines.
This callback is mandatory.
@param line: typed line(s)
@return Boolean: True-executed line, False-ask for more lines
"""
print "OnExecute:", line
return True
def OnKeydown(self, line, x, sellen, vkey, shift):
"""
A keyboard key has been pressed
This is a generic callback and the CLI is free to do whatever it wants.
This callback is optional.
@param line: current input line
@param x: current x coordinate of the cursor
@param sellen: current selection length (usually 0)
@param vkey: virtual key code. if the key has been handled, it should be returned as zero
@param shift: shift state
@return:
None - Nothing was changed
tuple(line, x, sellen, vkey): if either of the input line or the x coordinate or the selection length has been modified.
It is possible to return a tuple with None elements to preserve old values. Example: tuple(new_line, None, None, None) or tuple(new_line)
"""
print "Onkeydown: line=%s x=%d sellen=%d vkey=%d shift=%d" % (line, x, sellen, vkey, shift)
return None
def OnCompleteLine(self, prefix, n, line, prefix_start):
"""
The user pressed Tab. Find a completion number N for prefix PREFIX
This callback is optional.
@param prefix: Line prefix at prefix_start (string)
@param n: completion number (int)
@param line: the current line (string)
@param prefix_start: the index where PREFIX starts in LINE (int)
@return: None if no completion could be generated otherwise a String with the completion suggestion
"""
print "OnCompleteLine: prefix=%s n=%d line=%s prefix_start=%d" % (prefix, n, line, prefix_start)
return None
#</pycode(ex_cli_ex1)>
# -----------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -1,247 +1,247 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
import struct
if pywraps_there:
_idaapi.register_custom_data_type = pywraps.register_custom_data_type
_idaapi.unregister_custom_data_type = pywraps.unregister_custom_data_type
_idaapi.register_custom_data_format = pywraps.register_custom_data_format
_idaapi.unregister_custom_data_format = pywraps.unregister_custom_data_format
_idaapi.get_custom_data_format = pywraps.get_custom_data_format
_idaapi.get_custom_data_type = pywraps.get_custom_data_type
# -----------------------------------------------------------------------
#<pycode(py_bytes)>
DTP_NODUP = 0x0001
class data_type_t(object):
"""
Custom data type definition. All data types should inherit from this class.
"""
def __init__(self, name, value_size = 0, menu_name = None, hotkey = None, asm_keyword = None, props = 0):
"""Please refer to bytes.hpp / data_type_t in the SDK"""
self.name = name
self.props = props
self.menu_name = menu_name
self.hotkey = hotkey
self.asm_keyword = asm_keyword
self.value_size = value_size
self.id = -1 # Will be initialized after registration
"""Contains the data type id after the data type is registered"""
def register(self):
"""Registers the data type and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_type(self)
def unregister(self):
"""Unregisters the data type and returns True on success"""
# Not registered?
if self.id < 0:
return True
# Try to unregister
r = _idaapi.unregister_custom_data_type(self.id)
# Clear the ID
if r:
self.id = -1
return r
#<pydoc>
# def may_create_at(self, ea, nbytes):
# """
# (optional) If this callback is not defined then this means always may create data type at the given ea.
# @param ea: address of the future item
# @param nbytes: size of the future item
# @return: Boolean
# """
#
# return False
#
# def calc_item_size(self, ea, maxsize):
# """
# (optional) If this callback is defined it means variable size datatype
# This function is used to determine size of the (possible) item at 'ea'
# @param ea: address of the item
# @param maxsize: maximal size of the item
# @return: integer
# Returns: 0-no such item can be created/displayed
# this callback is required only for varsize datatypes
# """
# return 0
#</pydoc>
# -----------------------------------------------------------------------
# Uncomment the corresponding callbacks in the inherited class
class data_format_t(object):
"""Information about a data format"""
def __init__(self, name, value_size = 0, menu_name = None, props = 0, hotkey = None, text_width = 0):
"""Custom data format definition.
@param name: Format name, must be unique
@param menu_name: Visible format name to use in menus
@param props: properties (currently 0)
@param hotkey: Hotkey for the corresponding menu item
@param value_size: size of the value in bytes. 0 means any size is ok
@text_width: Usual width of the text representation
"""
self.name = name
self.menu_name = menu_name
self.props = props
self.hotkey = hotkey
self.value_size = value_size
self.text_width = text_width
self.id = -1 # Will be initialized after registration
"""contains the format id after the format gets registered"""
def register(self, dtid):
"""Registers the data format with the given data type id and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_format(dtid, self)
def unregister(self, dtid):
"""Unregisters the data format with the given data type id"""
# Not registered?
if self.id < 0:
return True
# Unregister
r = _idaapi.unregister_custom_data_format(dtid, self.id)
# Clear the ID
if r:
self.id = -1
return r
#<pydoc>
# def printf(self, value, current_ea, operand_num, dtid):
# """
# Convert a value buffer to colored string.
#
# @param value: The value to be printed
# @param current_ea: The ea of the value
# @param operand_num: The affected operand
# @param dtid: custom data type id (0-standard built-in data type)
# @return: a colored string representing the passed 'value' or None on failure
# """
# return None
#
# def scan(self, input, current_ea, operand_num):
# """
# Convert from uncolored string 'input' to byte value
#
# @param input: input string
# @param current_ea: current address (BADADDR if unknown)
# @param operand_num: current operand number (-1 if unknown)
#
# @return: tuple (Boolean, string)
# - (False, ErrorMessage) if conversion fails
# - (True, Value buffer) if conversion succeeds
# """
# return (False, "Not implemented")
#
# def analyze(self, current_ea, operand_num):
# """
# (optional) Analyze custom data format occurrence.
# It can be used to create xrefs from the current item.
#
# @param current_ea: current address (BADADDR if unknown)
# @param operand_num: current operand number
# @return: None
# """
#
# pass
#</pydoc>
# -----------------------------------------------------------------------
def __walk_types_and_formats(formats, type_action, format_action, installing):
broken = False
for f in formats:
if len(f) == 1:
if not format_action(f[0], 0):
broken = True
break
else:
dt = f[0]
dfs = f[1:]
# install data type before installing formats
if installing and not type_action(dt):
broken = True
break
# process formats using the correct dt.id
for df in dfs:
if not format_action(df, dt.id):
broken = True
break
# uninstall data type after uninstalling formats
if not installing and not type_action(dt):
broken = True
break
return not broken
# -----------------------------------------------------------------------
def register_data_types_and_formats(formats):
"""
Registers multiple data types and formats at once.
To register one type/format at a time use register_custom_data_type/register_custom_data_format
It employs a special table of types and formats described below:
The 'formats' is a list of tuples. If a tuple has one element then it is the format to be registered with dtid=0
If the tuple has more than one element, then tuple[0] is the data type and tuple[1:] are the data formats. For example:
many_formats = [
(pascal_data_type(), pascal_data_format()),
(simplevm_data_type(), simplevm_data_format()),
(makedword_data_format(),),
(simplevm_data_format(),)
]
The first two tuples describe data types and their associated formats.
The last two tuples describe two data formats to be used with built-in data types.
"""
def __reg_format(df, dtid):
df.register(dtid)
if dtid == 0:
print "Registered format '%s' with built-in types, ID=%d" % (df.name, df.id)
else:
print " Registered format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
return df.id != -1
def __reg_type(dt):
dt.register()
print "Registered type '%s', ID=%d" % (dt.name, dt.id)
return dt.id != -1
ok = __walk_types_and_formats(formats, __reg_type, __reg_format, True)
return 1 if ok else -1
# -----------------------------------------------------------------------
def unregister_data_types_and_formats(formats):
"""As opposed to register_data_types_and_formats(), this function
unregisters multiple data types and formats at once.
"""
def __unreg_format(df, dtid):
print "%snregistering format '%s'" % ("U" if dtid == 0 else " u", df.name)
df.unregister(dtid)
return True
def __unreg_type(dt):
print "Unregistering type '%s', ID=%d" % (dt.name, dt.id)
dt.unregister()
return True
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format, False)
return 1 if ok else -1
#</pycode(py_bytes)>
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
import struct
if pywraps_there:
_idaapi.register_custom_data_type = pywraps.register_custom_data_type
_idaapi.unregister_custom_data_type = pywraps.unregister_custom_data_type
_idaapi.register_custom_data_format = pywraps.register_custom_data_format
_idaapi.unregister_custom_data_format = pywraps.unregister_custom_data_format
_idaapi.get_custom_data_format = pywraps.get_custom_data_format
_idaapi.get_custom_data_type = pywraps.get_custom_data_type
# -----------------------------------------------------------------------
#<pycode(py_bytes)>
DTP_NODUP = 0x0001
class data_type_t(object):
"""
Custom data type definition. All data types should inherit from this class.
"""
def __init__(self, name, value_size = 0, menu_name = None, hotkey = None, asm_keyword = None, props = 0):
"""Please refer to bytes.hpp / data_type_t in the SDK"""
self.name = name
self.props = props
self.menu_name = menu_name
self.hotkey = hotkey
self.asm_keyword = asm_keyword
self.value_size = value_size
self.id = -1 # Will be initialized after registration
"""Contains the data type id after the data type is registered"""
def register(self):
"""Registers the data type and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_type(self)
def unregister(self):
"""Unregisters the data type and returns True on success"""
# Not registered?
if self.id < 0:
return True
# Try to unregister
r = _idaapi.unregister_custom_data_type(self.id)
# Clear the ID
if r:
self.id = -1
return r
#<pydoc>
# def may_create_at(self, ea, nbytes):
# """
# (optional) If this callback is not defined then this means always may create data type at the given ea.
# @param ea: address of the future item
# @param nbytes: size of the future item
# @return: Boolean
# """
#
# return False
#
# def calc_item_size(self, ea, maxsize):
# """
# (optional) If this callback is defined it means variable size datatype
# This function is used to determine size of the (possible) item at 'ea'
# @param ea: address of the item
# @param maxsize: maximal size of the item
# @return: integer
# Returns: 0-no such item can be created/displayed
# this callback is required only for varsize datatypes
# """
# return 0
#</pydoc>
# -----------------------------------------------------------------------
# Uncomment the corresponding callbacks in the inherited class
class data_format_t(object):
"""Information about a data format"""
def __init__(self, name, value_size = 0, menu_name = None, props = 0, hotkey = None, text_width = 0):
"""Custom data format definition.
@param name: Format name, must be unique
@param menu_name: Visible format name to use in menus
@param props: properties (currently 0)
@param hotkey: Hotkey for the corresponding menu item
@param value_size: size of the value in bytes. 0 means any size is ok
@text_width: Usual width of the text representation
"""
self.name = name
self.menu_name = menu_name
self.props = props
self.hotkey = hotkey
self.value_size = value_size
self.text_width = text_width
self.id = -1 # Will be initialized after registration
"""contains the format id after the format gets registered"""
def register(self, dtid):
"""Registers the data format with the given data type id and returns the type id or < 0 on failure"""
return _idaapi.register_custom_data_format(dtid, self)
def unregister(self, dtid):
"""Unregisters the data format with the given data type id"""
# Not registered?
if self.id < 0:
return True
# Unregister
r = _idaapi.unregister_custom_data_format(dtid, self.id)
# Clear the ID
if r:
self.id = -1
return r
#<pydoc>
# def printf(self, value, current_ea, operand_num, dtid):
# """
# Convert a value buffer to colored string.
#
# @param value: The value to be printed
# @param current_ea: The ea of the value
# @param operand_num: The affected operand
# @param dtid: custom data type id (0-standard built-in data type)
# @return: a colored string representing the passed 'value' or None on failure
# """
# return None
#
# def scan(self, input, current_ea, operand_num):
# """
# Convert from uncolored string 'input' to byte value
#
# @param input: input string
# @param current_ea: current address (BADADDR if unknown)
# @param operand_num: current operand number (-1 if unknown)
#
# @return: tuple (Boolean, string)
# - (False, ErrorMessage) if conversion fails
# - (True, Value buffer) if conversion succeeds
# """
# return (False, "Not implemented")
#
# def analyze(self, current_ea, operand_num):
# """
# (optional) Analyze custom data format occurrence.
# It can be used to create xrefs from the current item.
#
# @param current_ea: current address (BADADDR if unknown)
# @param operand_num: current operand number
# @return: None
# """
#
# pass
#</pydoc>
# -----------------------------------------------------------------------
def __walk_types_and_formats(formats, type_action, format_action, installing):
broken = False
for f in formats:
if len(f) == 1:
if not format_action(f[0], 0):
broken = True
break
else:
dt = f[0]
dfs = f[1:]
# install data type before installing formats
if installing and not type_action(dt):
broken = True
break
# process formats using the correct dt.id
for df in dfs:
if not format_action(df, dt.id):
broken = True
break
# uninstall data type after uninstalling formats
if not installing and not type_action(dt):
broken = True
break
return not broken
# -----------------------------------------------------------------------
def register_data_types_and_formats(formats):
"""
Registers multiple data types and formats at once.
To register one type/format at a time use register_custom_data_type/register_custom_data_format
It employs a special table of types and formats described below:
The 'formats' is a list of tuples. If a tuple has one element then it is the format to be registered with dtid=0
If the tuple has more than one element, then tuple[0] is the data type and tuple[1:] are the data formats. For example:
many_formats = [
(pascal_data_type(), pascal_data_format()),
(simplevm_data_type(), simplevm_data_format()),
(makedword_data_format(),),
(simplevm_data_format(),)
]
The first two tuples describe data types and their associated formats.
The last two tuples describe two data formats to be used with built-in data types.
"""
def __reg_format(df, dtid):
df.register(dtid)
if dtid == 0:
print "Registered format '%s' with built-in types, ID=%d" % (df.name, df.id)
else:
print " Registered format '%s', ID=%d (dtid=%d)" % (df.name, df.id, dtid)
return df.id != -1
def __reg_type(dt):
dt.register()
print "Registered type '%s', ID=%d" % (dt.name, dt.id)
return dt.id != -1
ok = __walk_types_and_formats(formats, __reg_type, __reg_format, True)
return 1 if ok else -1
# -----------------------------------------------------------------------
def unregister_data_types_and_formats(formats):
"""As opposed to register_data_types_and_formats(), this function
unregisters multiple data types and formats at once.
"""
def __unreg_format(df, dtid):
print "%snregistering format '%s'" % ("U" if dtid == 0 else " u", df.name)
df.unregister(dtid)
return True
def __unreg_type(dt):
print "Unregistering type '%s', ID=%d" % (dt.name, dt.id)
dt.unregister()
return True
ok = __walk_types_and_formats(formats, __unreg_type, __unreg_format, False)
return 1 if ok else -1
#</pycode(py_bytes)>
# -----------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@@ -1,472 +1,472 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys, struct
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
try:
import pywraps
pywraps_there = True
print "Using pywraps"
_idaapi.pyscv_init = pywraps.pyscv_init
_idaapi.pyscv_close = pywraps.pyscv_close
_idaapi.pyscv_add_line = pywraps.pyscv_add_line
_idaapi.pyscv_delete = pywraps.pyscv_delete
_idaapi.pyscv_refresh = pywraps.pyscv_refresh
_idaapi.pyscv_show = pywraps.pyscv_show
_idaapi.pyscv_clear_popup_menu = pywraps.pyscv_clear_popup_menu
_idaapi.pyscv_del_line = pywraps.pyscv_del_line
_idaapi.pyscv_get_pos = pywraps.pyscv_get_pos
_idaapi.pyscv_refresh_current = pywraps.pyscv_refresh_current
_idaapi.pyscv_get_current_line = pywraps.pyscv_get_current_line
_idaapi.pyscv_is_focused = pywraps.pyscv_is_focused
_idaapi.pyscv_add_popup_menu = pywraps.pyscv_add_popup_menu
_idaapi.pyscv_get_line = pywraps.pyscv_get_line
_idaapi.pyscv_jumpto = pywraps.pyscv_jumpto
_idaapi.pyscv_edit_line = pywraps.pyscv_edit_line
_idaapi.pyscv_patch_line = pywraps.pyscv_patch_line
_idaapi.pyscv_insert_line = pywraps.pyscv_insert_line
_idaapi.pyscv_count = pywraps.pyscv_count
_idaapi.pyscv_get_selection = pywraps.pyscv_get_selection
_idaapi.pyscv_clear_lines = pywraps.pyscv_clear_lines
_idaapi.pyscv_get_current_word = pywraps.pyscv_get_current_word
except:
pywraps_there = False
print "Not using pywraps"
# -----------------------------------------------------------------------
#<pycode(py_custviewer)>
class simplecustviewer_t(object):
"""The base class for implementing simple custom viewers"""
def __init__(self):
self.__this = None
def __del__(self):
"""Destructor. It also frees the associated C++ object"""
try:
_idaapi.pyscv_delete(self.__this)
except:
pass
@staticmethod
def __make_sl_arg(line, fgcolor=None, bgcolor=None):
return line if (fgcolor is None and bgcolor is None) else (line, fgcolor, bgcolor)
def Create(self, title):
"""
Creates the custom view. This should be the first method called after instantiation
@param title: The title of the view
@return: Boolean whether it succeeds or fails. It may fail if a window with the same title is already open.
In this case better close existing windows
"""
self.title = title
self.__this = _idaapi.pyscv_init(self, title)
return True if self.__this else False
def Close(self):
"""
Destroys the view.
One has to call Create() afterwards.
Show() can be called and it will call Create() internally.
@return: Boolean
"""
return _idaapi.pyscv_close(self.__this)
def Show(self):
"""
Shows an already created view. It the view was close, then it will call Create() for you
@return: Boolean
"""
return _idaapi.pyscv_show(self.__this)
def Refresh(self):
return _idaapi.pyscv_refresh(self.__this)
def RefreshCurrent(self):
"""Refreshes the current line only"""
return _idaapi.pyscv_refresh_current(self.__this)
def Count(self):
"""Returns the number of lines in the view"""
return _idaapi.pyscv_count(self.__this)
def GetSelection(self):
"""
Returns the selected area or None
@return:
- tuple(x1, y1, x2, y2)
- None if no selection
"""
return _idaapi.pyscv_get_selection(self.__this)
def ClearLines(self):
"""Clears all the lines"""
_idaapi.pyscv_clear_lines(self.__this)
def AddLine(self, line, fgcolor=None, bgcolor=None):
"""
Adds a colored line to the view
@return: Boolean
"""
return _idaapi.pyscv_add_line(self.__this, self.__make_sl_arg(line, fgcolor, bgcolor))
def InsertLine(self, lineno, line, fgcolor=None, bgcolor=None):
"""
Inserts a line in the given position
@return: Boolean
"""
return _idaapi.pyscv_insert_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor))
def EditLine(self, lineno, line, fgcolor=None, bgcolor=None):
"""
Edits an existing line.
@return: Boolean
"""
return _idaapi.pyscv_edit_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor))
def PatchLine(self, lineno, offs, value):
"""Patches an existing line character at the given offset. This is a low level function. You must know what you're doing"""
return _idaapi.pyscv_patch_line(self.__this, lineno, offs, value)
def DelLine(self, lineno):
"""
Deletes an existing line
@return: Boolean
"""
return _idaapi.pyscv_del_line(self.__this, lineno)
def GetLine(self, lineno):
"""
Returns a line
@param lineno: The line number
@return:
Returns a tuple (colored_line, fgcolor, bgcolor) or None
"""
return _idaapi.pyscv_get_line(self.__this, lineno)
def GetCurrentWord(self, mouse = 0):
"""
Returns the current word
@param mouse: Use mouse position or cursor position
@return: None if failed or a String containing the current word at mouse or cursor
"""
return _idaapi.pyscv_get_current_word(self.__this, mouse)
def GetCurrentLine(self, mouse = 0, notags = 0):
"""
Returns the current line.
@param mouse: Current line at mouse pos
@param notags: If True then tag_remove() will be called before returning the line
@return: Returns the current line (colored or uncolored) or None on failure
"""
return _idaapi.pyscv_get_current_line(self.__this, mouse, notags)
def GetPos(self, mouse = 0):
"""
Returns the current cursor or mouse position.
@param mouse: return mouse position
@return: Returns a tuple (lineno, x, y)
"""
return _idaapi.pyscv_get_pos(self.__this, mouse)
def GetLineNo(self, mouse = 0):
"""Calls GetPos() and returns the current line number or -1 on failure"""
r = self.GetPos(mouse)
return -1 if not r else r[0]
def Jump(self, lineno, x=0, y=0):
return _idaapi.pyscv_jumpto(self.__this, lineno, x, y)
def AddPopupMenu(self, title, hotkey=""):
"""
Adds a popup menu item
@param title: The name of the menu item
@param hotkey: Hotkey of the item or just empty
@return: Returns the
"""
return _idaapi.pyscv_add_popup_menu(self.__this, title, hotkey)
def ClearPopupMenu(self):
"""
Clears all previously installed popup menu items.
Use this function if you're generating menu items on the fly (in the OnPopup() callback),
and before adding new items
"""
_idaapi.pyscv_clear_popup_menu(self.__this)
def IsFocused(self):
"""Returns True if the current view is the focused view"""
return _idaapi.pyscv_is_focused(self.__this)
def GetTForm(self):
"""
Return the TForm hosting this view.
@return: The TForm that hosts this view, or None.
"""
return _idaapi.pyscv_get_tform(self.__this)
def GetTCustomControl(self):
"""
Return the TCustomControl underlying this view.
@return: The TCustomControl underlying this view, or None.
"""
return _idaapi.pyscv_get_tcustom_control(self.__this)
# Here are all the supported events
#<pydoc>
# def OnClick(self, shift):
# """
# User clicked in the view
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnClick, shift=%d" % shift
# return True
#
# def OnDblClick(self, shift):
# """
# User dbl-clicked in the view
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnDblClick, shift=%d" % shift
# return True
#
# def OnCursorPosChanged(self):
# """
# Cursor position changed.
# @return: Nothing
# """
# print "OnCurposChanged"
#
# def OnClose(self):
# """
# The view is closing. Use this event to cleanup.
# @return: Nothing
# """
# print "OnClose"
#
# def OnKeydown(self, vkey, shift):
# """
# User pressed a key
# @param vkey: Virtual key code
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# return False
#
# def OnPopup(self):
# """
# Context menu popup is about to be shown. Create items dynamically if you wish
# @return: Boolean. True if you handled the event
# """
# print "OnPopup"
#
# def OnHint(self, lineno):
# """
# Hint requested for the given line number.
# @param lineno: The line number (zero based)
# @return:
# - tuple(number of important lines, hint string)
# - None: if no hint available
# """
# return (1, "OnHint, line=%d" % lineno)
#
# def OnPopupMenu(self, menu_id):
# """
# A context (or popup) menu item was executed.
# @param menu_id: ID previously registered with add_popup_menu()
# @return: Boolean
# """
# print "OnPopupMenu, menu_id=" % menu_id
# return True
#</pydoc>
#</pycode(py_custviewer)>
#<pycode(py_custviewerex1)>
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
print self.thing
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
# self.Jump(0)
return True
def OnClick(self, shift):
"""
User clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnClick, shift=%d" % shift
return True
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
word = self.GetCurrentWord()
if not word: word = "<None>"
print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
"""
Cursor position changed.
@return: Nothing
"""
print "OnCurposChanged"
def OnClose(self):
"""
The view is closing. Use this event to cleanup.
@return: Nothing
"""
print "OnClose " + self.title
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# ESCAPE?
if vkey == 27:
self.Close()
# VK_DELETE
elif vkey == 46:
n = self.GetLineNo()
if n is not None:
self.DelLine(n)
self.Refresh()
print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
n = self.GetLineNo()
if n is not None:
v = idc.AskLong(self.GetLineNo(), "Where to go?")
if v:
self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
elif vkey == ord('C'):
print "refreshing current line..."
self.RefreshCurrent()
elif vkey == ord('A'):
s = idc.AskStr("NewLine%d" % self.Count(), "Append new line")
self.AddLine(s)
self.Refresh()
elif vkey == ord('X'):
print "Clearing all lines"
self.ClearLines()
self.Refresh()
elif vkey == ord('I'):
n = self.GetLineNo()
s = idc.AskStr("InsertedLine%d" % n, "Insert new line")
self.InsertLine(n, s)
self.Refresh()
elif vkey == ord('E'):
l = self.GetCurrentLine(notags=1)
if not l:
return False
n = self.GetLineNo()
print "curline=<%s>" % l
l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP)
self.EditLine(n, l)
self.RefreshCurrent()
print "Edited line %d" % n
else:
return False
return True
def OnHint(self, lineno):
"""
Hint requested for the given line number.
@param lineno: The line number (zero based)
@return:
- tuple(number of important lines, hint string)
- None: if no hint available
"""
return (1, "OnHint, line=%d" % lineno)
# -----------------------------------------------------------------------
try:
# created already?
mycv
print "Already created, will close it..."
mycv.Close()
del mycv
except:
pass
def show_win():
x = mycv_t()
if not x.Create():
print "Failed to create!"
return None
x.Show()
tcc = x.GetTCustomControl()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
if not mycv:
del mycv
def make_many(n):
L = []
for i in xrange(1, n+1):
v = mycv_t()
if not v.Create(i):
break
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>
# -----------------------------------------------------------------------
# Standalone and testing code
import sys, struct
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
try:
import pywraps
pywraps_there = True
print "Using pywraps"
_idaapi.pyscv_init = pywraps.pyscv_init
_idaapi.pyscv_close = pywraps.pyscv_close
_idaapi.pyscv_add_line = pywraps.pyscv_add_line
_idaapi.pyscv_delete = pywraps.pyscv_delete
_idaapi.pyscv_refresh = pywraps.pyscv_refresh
_idaapi.pyscv_show = pywraps.pyscv_show
_idaapi.pyscv_clear_popup_menu = pywraps.pyscv_clear_popup_menu
_idaapi.pyscv_del_line = pywraps.pyscv_del_line
_idaapi.pyscv_get_pos = pywraps.pyscv_get_pos
_idaapi.pyscv_refresh_current = pywraps.pyscv_refresh_current
_idaapi.pyscv_get_current_line = pywraps.pyscv_get_current_line
_idaapi.pyscv_is_focused = pywraps.pyscv_is_focused
_idaapi.pyscv_add_popup_menu = pywraps.pyscv_add_popup_menu
_idaapi.pyscv_get_line = pywraps.pyscv_get_line
_idaapi.pyscv_jumpto = pywraps.pyscv_jumpto
_idaapi.pyscv_edit_line = pywraps.pyscv_edit_line
_idaapi.pyscv_patch_line = pywraps.pyscv_patch_line
_idaapi.pyscv_insert_line = pywraps.pyscv_insert_line
_idaapi.pyscv_count = pywraps.pyscv_count
_idaapi.pyscv_get_selection = pywraps.pyscv_get_selection
_idaapi.pyscv_clear_lines = pywraps.pyscv_clear_lines
_idaapi.pyscv_get_current_word = pywraps.pyscv_get_current_word
except:
pywraps_there = False
print "Not using pywraps"
# -----------------------------------------------------------------------
#<pycode(py_custviewer)>
class simplecustviewer_t(object):
"""The base class for implementing simple custom viewers"""
def __init__(self):
self.__this = None
def __del__(self):
"""Destructor. It also frees the associated C++ object"""
try:
_idaapi.pyscv_delete(self.__this)
except:
pass
@staticmethod
def __make_sl_arg(line, fgcolor=None, bgcolor=None):
return line if (fgcolor is None and bgcolor is None) else (line, fgcolor, bgcolor)
def Create(self, title):
"""
Creates the custom view. This should be the first method called after instantiation
@param title: The title of the view
@return: Boolean whether it succeeds or fails. It may fail if a window with the same title is already open.
In this case better close existing windows
"""
self.title = title
self.__this = _idaapi.pyscv_init(self, title)
return True if self.__this else False
def Close(self):
"""
Destroys the view.
One has to call Create() afterwards.
Show() can be called and it will call Create() internally.
@return: Boolean
"""
return _idaapi.pyscv_close(self.__this)
def Show(self):
"""
Shows an already created view. It the view was close, then it will call Create() for you
@return: Boolean
"""
return _idaapi.pyscv_show(self.__this)
def Refresh(self):
return _idaapi.pyscv_refresh(self.__this)
def RefreshCurrent(self):
"""Refreshes the current line only"""
return _idaapi.pyscv_refresh_current(self.__this)
def Count(self):
"""Returns the number of lines in the view"""
return _idaapi.pyscv_count(self.__this)
def GetSelection(self):
"""
Returns the selected area or None
@return:
- tuple(x1, y1, x2, y2)
- None if no selection
"""
return _idaapi.pyscv_get_selection(self.__this)
def ClearLines(self):
"""Clears all the lines"""
_idaapi.pyscv_clear_lines(self.__this)
def AddLine(self, line, fgcolor=None, bgcolor=None):
"""
Adds a colored line to the view
@return: Boolean
"""
return _idaapi.pyscv_add_line(self.__this, self.__make_sl_arg(line, fgcolor, bgcolor))
def InsertLine(self, lineno, line, fgcolor=None, bgcolor=None):
"""
Inserts a line in the given position
@return: Boolean
"""
return _idaapi.pyscv_insert_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor))
def EditLine(self, lineno, line, fgcolor=None, bgcolor=None):
"""
Edits an existing line.
@return: Boolean
"""
return _idaapi.pyscv_edit_line(self.__this, lineno, self.__make_sl_arg(line, fgcolor, bgcolor))
def PatchLine(self, lineno, offs, value):
"""Patches an existing line character at the given offset. This is a low level function. You must know what you're doing"""
return _idaapi.pyscv_patch_line(self.__this, lineno, offs, value)
def DelLine(self, lineno):
"""
Deletes an existing line
@return: Boolean
"""
return _idaapi.pyscv_del_line(self.__this, lineno)
def GetLine(self, lineno):
"""
Returns a line
@param lineno: The line number
@return:
Returns a tuple (colored_line, fgcolor, bgcolor) or None
"""
return _idaapi.pyscv_get_line(self.__this, lineno)
def GetCurrentWord(self, mouse = 0):
"""
Returns the current word
@param mouse: Use mouse position or cursor position
@return: None if failed or a String containing the current word at mouse or cursor
"""
return _idaapi.pyscv_get_current_word(self.__this, mouse)
def GetCurrentLine(self, mouse = 0, notags = 0):
"""
Returns the current line.
@param mouse: Current line at mouse pos
@param notags: If True then tag_remove() will be called before returning the line
@return: Returns the current line (colored or uncolored) or None on failure
"""
return _idaapi.pyscv_get_current_line(self.__this, mouse, notags)
def GetPos(self, mouse = 0):
"""
Returns the current cursor or mouse position.
@param mouse: return mouse position
@return: Returns a tuple (lineno, x, y)
"""
return _idaapi.pyscv_get_pos(self.__this, mouse)
def GetLineNo(self, mouse = 0):
"""Calls GetPos() and returns the current line number or -1 on failure"""
r = self.GetPos(mouse)
return -1 if not r else r[0]
def Jump(self, lineno, x=0, y=0):
return _idaapi.pyscv_jumpto(self.__this, lineno, x, y)
def AddPopupMenu(self, title, hotkey=""):
"""
Adds a popup menu item
@param title: The name of the menu item
@param hotkey: Hotkey of the item or just empty
@return: Returns the
"""
return _idaapi.pyscv_add_popup_menu(self.__this, title, hotkey)
def ClearPopupMenu(self):
"""
Clears all previously installed popup menu items.
Use this function if you're generating menu items on the fly (in the OnPopup() callback),
and before adding new items
"""
_idaapi.pyscv_clear_popup_menu(self.__this)
def IsFocused(self):
"""Returns True if the current view is the focused view"""
return _idaapi.pyscv_is_focused(self.__this)
def GetTForm(self):
"""
Return the TForm hosting this view.
@return: The TForm that hosts this view, or None.
"""
return _idaapi.pyscv_get_tform(self.__this)
def GetTCustomControl(self):
"""
Return the TCustomControl underlying this view.
@return: The TCustomControl underlying this view, or None.
"""
return _idaapi.pyscv_get_tcustom_control(self.__this)
# Here are all the supported events
#<pydoc>
# def OnClick(self, shift):
# """
# User clicked in the view
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnClick, shift=%d" % shift
# return True
#
# def OnDblClick(self, shift):
# """
# User dbl-clicked in the view
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnDblClick, shift=%d" % shift
# return True
#
# def OnCursorPosChanged(self):
# """
# Cursor position changed.
# @return: Nothing
# """
# print "OnCurposChanged"
#
# def OnClose(self):
# """
# The view is closing. Use this event to cleanup.
# @return: Nothing
# """
# print "OnClose"
#
# def OnKeydown(self, vkey, shift):
# """
# User pressed a key
# @param vkey: Virtual key code
# @param shift: Shift flag
# @return: Boolean. True if you handled the event
# """
# print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# return False
#
# def OnPopup(self):
# """
# Context menu popup is about to be shown. Create items dynamically if you wish
# @return: Boolean. True if you handled the event
# """
# print "OnPopup"
#
# def OnHint(self, lineno):
# """
# Hint requested for the given line number.
# @param lineno: The line number (zero based)
# @return:
# - tuple(number of important lines, hint string)
# - None: if no hint available
# """
# return (1, "OnHint, line=%d" % lineno)
#
# def OnPopupMenu(self, menu_id):
# """
# A context (or popup) menu item was executed.
# @param menu_id: ID previously registered with add_popup_menu()
# @return: Boolean
# """
# print "OnPopupMenu, menu_id=" % menu_id
# return True
#</pydoc>
#</pycode(py_custviewer)>
#<pycode(py_custviewerex1)>
class say_something_handler_t(idaapi.action_handler_t):
def __init__(self, thing):
idaapi.action_handler_t.__init__(self)
self.thing = thing
def activate(self, ctx):
print self.thing
def update(self, ctx):
return idaapi.AST_ENABLE_ALWAYS
# -----------------------------------------------------------------------
class mycv_t(simplecustviewer_t):
def Create(self, sn=None):
# Form the title
title = "Simple custom view test"
if sn:
title += " %d" % sn
# Create the customviewer
if not simplecustviewer_t.Create(self, title):
return False
for i in xrange(0, 100):
self.AddLine("Line %d" % i)
# self.Jump(0)
return True
def OnClick(self, shift):
"""
User clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnClick, shift=%d" % shift
return True
def OnDblClick(self, shift):
"""
User dbl-clicked in the view
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
word = self.GetCurrentWord()
if not word: word = "<None>"
print "OnDblClick, shift=%d, current word=%s" % (shift, word)
return True
def OnCursorPosChanged(self):
"""
Cursor position changed.
@return: Nothing
"""
print "OnCurposChanged"
def OnClose(self):
"""
The view is closing. Use this event to cleanup.
@return: Nothing
"""
print "OnClose " + self.title
def OnKeydown(self, vkey, shift):
"""
User pressed a key
@param vkey: Virtual key code
@param shift: Shift flag
@return: Boolean. True if you handled the event
"""
print "OnKeydown, vk=%d shift=%d" % (vkey, shift)
# ESCAPE?
if vkey == 27:
self.Close()
# VK_DELETE
elif vkey == 46:
n = self.GetLineNo()
if n is not None:
self.DelLine(n)
self.Refresh()
print "Deleted line %d" % n
# Goto?
elif vkey == ord('G'):
n = self.GetLineNo()
if n is not None:
v = idc.AskLong(self.GetLineNo(), "Where to go?")
if v:
self.Jump(v, 0, 5)
elif vkey == ord('R'):
print "refreshing...."
self.Refresh()
elif vkey == ord('C'):
print "refreshing current line..."
self.RefreshCurrent()
elif vkey == ord('A'):
s = idc.AskStr("NewLine%d" % self.Count(), "Append new line")
self.AddLine(s)
self.Refresh()
elif vkey == ord('X'):
print "Clearing all lines"
self.ClearLines()
self.Refresh()
elif vkey == ord('I'):
n = self.GetLineNo()
s = idc.AskStr("InsertedLine%d" % n, "Insert new line")
self.InsertLine(n, s)
self.Refresh()
elif vkey == ord('E'):
l = self.GetCurrentLine(notags=1)
if not l:
return False
n = self.GetLineNo()
print "curline=<%s>" % l
l = l + idaapi.COLSTR("*", idaapi.SCOLOR_VOIDOP)
self.EditLine(n, l)
self.RefreshCurrent()
print "Edited line %d" % n
else:
return False
return True
def OnHint(self, lineno):
"""
Hint requested for the given line number.
@param lineno: The line number (zero based)
@return:
- tuple(number of important lines, hint string)
- None: if no hint available
"""
return (1, "OnHint, line=%d" % lineno)
# -----------------------------------------------------------------------
try:
# created already?
mycv
print "Already created, will close it..."
mycv.Close()
del mycv
except:
pass
def show_win():
x = mycv_t()
if not x.Create():
print "Failed to create!"
return None
x.Show()
tcc = x.GetTCustomControl()
# Register actions
for thing in ["Hello", "World"]:
actname = "custview:say_%s" % thing
idaapi.register_action(
idaapi.action_desc_t(actname, "Say %s" % thing, say_something_handler_t(thing)))
idaapi.attach_action_to_popup(tcc, None, actname)
return x
mycv = show_win()
if not mycv:
del mycv
def make_many(n):
L = []
for i in xrange(1, n+1):
v = mycv_t()
if not v.Create(i):
break
v.Show()
L.append(v)
return L
#</pycode(py_custviewerex1)>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,64 +1,64 @@
#ifndef __PY_IDA_DISKIO__
#define __PY_IDA_DISKIO__
//<code(py_diskio)>
//--------------------------------------------------------------------------
int idaapi py_enumerate_files_cb(const char *file, void *ud)
{
// No need to 'PYW_GIL_GET' here, as this is called synchronously
// and from the same thread as the one that executes
// 'py_enumerate_files'.
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_file(PyString_FromString(file));
newref_t py_ret(
PyObject_CallFunctionObjArgs(
(PyObject *)ud,
py_file.o,
NULL));
return (py_ret == NULL || !PyNumber_Check(py_ret.o)) ? 1 /* stop enum on failure */ : PyInt_AsLong(py_ret.o);
}
//</code(py_diskio)>
//<inline(py_diskio)>
//--------------------------------------------------------------------------
/*
#<pydoc>
def enumerate_files(path, fname, callback):
"""
Enumerate files in the specified directory while the callback returns 0.
@param path: directory to enumerate files in
@param fname: mask of file names to enumerate
@param callback: a callable object that takes the filename as
its first argument and it returns 0 to continue
enumeration or non-zero to stop enumeration.
@return:
None in case of script errors
tuple(code, fname) : If the callback returns non-zero
"""
pass
#</pydoc>
*/
PyObject *py_enumerate_files(PyObject *path, PyObject *fname, PyObject *callback)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
if ( !PyString_Check(path) || !PyString_Check(fname) || !PyCallable_Check(callback) )
break;
const char *_path = PyString_AsString(path);
const char *_fname = PyString_AsString(fname);
if ( _path == NULL || _fname == NULL )
break;
char answer[MAXSTR];
answer[0] = '\0';
int r = enumerate_files(answer, sizeof(answer), _path, _fname, py_enumerate_files_cb, callback);
return Py_BuildValue("(is)", r, answer);
} while ( false );
Py_RETURN_NONE;
}
//</inline(py_diskio)>
#endif
#ifndef __PY_IDA_DISKIO__
#define __PY_IDA_DISKIO__
//<code(py_diskio)>
//--------------------------------------------------------------------------
int idaapi py_enumerate_files_cb(const char *file, void *ud)
{
// No need to 'PYW_GIL_GET' here, as this is called synchronously
// and from the same thread as the one that executes
// 'py_enumerate_files'.
PYW_GIL_CHECK_LOCKED_SCOPE();
newref_t py_file(PyString_FromString(file));
newref_t py_ret(
PyObject_CallFunctionObjArgs(
(PyObject *)ud,
py_file.o,
NULL));
return (py_ret == NULL || !PyNumber_Check(py_ret.o)) ? 1 /* stop enum on failure */ : PyInt_AsLong(py_ret.o);
}
//</code(py_diskio)>
//<inline(py_diskio)>
//--------------------------------------------------------------------------
/*
#<pydoc>
def enumerate_files(path, fname, callback):
"""
Enumerate files in the specified directory while the callback returns 0.
@param path: directory to enumerate files in
@param fname: mask of file names to enumerate
@param callback: a callable object that takes the filename as
its first argument and it returns 0 to continue
enumeration or non-zero to stop enumeration.
@return:
None in case of script errors
tuple(code, fname) : If the callback returns non-zero
"""
pass
#</pydoc>
*/
PyObject *py_enumerate_files(PyObject *path, PyObject *fname, PyObject *callback)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
if ( !PyString_Check(path) || !PyString_Check(fname) || !PyCallable_Check(callback) )
break;
const char *_path = PyString_AsString(path);
const char *_fname = PyString_AsString(fname);
if ( _path == NULL || _fname == NULL )
break;
char answer[MAXSTR];
answer[0] = '\0';
int r = enumerate_files(answer, sizeof(answer), _path, _fname, py_enumerate_files_cb, callback);
return Py_BuildValue("(is)", r, answer);
} while ( false );
Py_RETURN_NONE;
}
//</inline(py_diskio)>
#endif

View File

@@ -1,5 +1,5 @@
#<pycode(py_diskio)>
def enumerate_system_files(subdir, fname, callback):
"""Similar to enumerate_files() however it searches inside IDA directory or its subdirectories"""
return enumerate_files(idadir(subdir), fname, callback)
#</pycode(py_diskio)>
#<pycode(py_diskio)>
def enumerate_system_files(subdir, fname, callback):
"""Similar to enumerate_files() however it searches inside IDA directory or its subdirectories"""
return enumerate_files(idadir(subdir), fname, callback)
#</pycode(py_diskio)>

View File

@@ -1,81 +1,81 @@
#ifndef __PY_EXPR__
#define __PY_EXPR__
//<code(py_expr)>
struct py_idcfunc_ctx_t
{
PyObject *py_func;
qstring name;
int nargs;
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_INCREF(py_func);
}
~py_idcfunc_ctx_t()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_DECREF(py_func);
}
};
//---------------------------------------------------------------------------
static error_t py_call_idc_func(
void *_ctx,
idc_value_t *argv,
idc_value_t *r)
{
// Convert IDC arguments to Python list
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
int cvt;
char errbuf[MAXSTR];
PYW_GIL_CHECK_LOCKED_SCOPE();
ref_vec_t pargs;
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, true, errbuf, sizeof(errbuf)) )
{
// Error during conversion? Create an IDC exception
return PyW_CreateIdcException(r, errbuf);
}
// Call the Python function
newref_t py_result(PyObject_CallObject(
ctx->py_func,
pargs.empty() ? NULL : pargs[0].o));
error_t err;
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
{
err = PyW_CreateIdcException(r, errbuf);
}
else
{
// Convert the result to IDC
r->clear();
cvt = pyvar_to_idcvar(py_result, r);
if ( cvt < CIP_OK )
err = PyW_CreateIdcException(r, "ERROR: bad return value");
else
err = eOk;
}
return err;
}
//</code(py_expr)>
//<inline(py_expr)>
//---------------------------------------------------------------------------
static size_t py_get_call_idc_func()
{
return (size_t)py_call_idc_func;
}
//---------------------------------------------------------------------------
// Internal function:
// - capture the python callable
// - return a C context as a numeric value
#ifndef __PY_EXPR__
#define __PY_EXPR__
//<code(py_expr)>
struct py_idcfunc_ctx_t
{
PyObject *py_func;
qstring name;
int nargs;
py_idcfunc_ctx_t(PyObject *py_func, const char *name, int nargs): py_func(py_func), name(name), nargs(nargs)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_INCREF(py_func);
}
~py_idcfunc_ctx_t()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_DECREF(py_func);
}
};
//---------------------------------------------------------------------------
static error_t py_call_idc_func(
void *_ctx,
idc_value_t *argv,
idc_value_t *r)
{
// Convert IDC arguments to Python list
py_idcfunc_ctx_t *ctx = (py_idcfunc_ctx_t *)_ctx;
int cvt;
char errbuf[MAXSTR];
PYW_GIL_CHECK_LOCKED_SCOPE();
ref_vec_t pargs;
if ( !pyw_convert_idc_args(argv, ctx->nargs, pargs, true, errbuf, sizeof(errbuf)) )
{
// Error during conversion? Create an IDC exception
return PyW_CreateIdcException(r, errbuf);
}
// Call the Python function
newref_t py_result(PyObject_CallObject(
ctx->py_func,
pargs.empty() ? NULL : pargs[0].o));
error_t err;
if ( PyW_GetError(errbuf, sizeof(errbuf)) )
{
err = PyW_CreateIdcException(r, errbuf);
}
else
{
// Convert the result to IDC
r->clear();
cvt = pyvar_to_idcvar(py_result, r);
if ( cvt < CIP_OK )
err = PyW_CreateIdcException(r, "ERROR: bad return value");
else
err = eOk;
}
return err;
}
//</code(py_expr)>
//<inline(py_expr)>
//---------------------------------------------------------------------------
static size_t py_get_call_idc_func()
{
return (size_t)py_call_idc_func;
}
//---------------------------------------------------------------------------
// Internal function:
// - capture the python callable
// - return a C context as a numeric value
static size_t pyw_register_idc_func(
const char *name,
const char *args,
@@ -83,10 +83,10 @@ static size_t pyw_register_idc_func(
{
return (size_t)new py_idcfunc_ctx_t(py_fp, name, strlen(args));
}
//---------------------------------------------------------------------------
// Internal function:
// - free the C context
//---------------------------------------------------------------------------
// Internal function:
// - free the C context
static bool pyw_unregister_idc_func(size_t ctxptr)
{
// Unregister the function
@@ -98,18 +98,18 @@ static bool pyw_unregister_idc_func(size_t ctxptr)
return ok;
}
//---------------------------------------------------------------------------
static bool py_set_idc_func_ex(
const char *name,
size_t fp_ptr,
const char *args,
int flags)
{
return set_idc_func_ex(name, (idc_func_t *)fp_ptr, args, flags);
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
static bool py_set_idc_func_ex(
const char *name,
size_t fp_ptr,
const char *args,
int flags)
{
return set_idc_func_ex(name, (idc_func_t *)fp_ptr, args, flags);
}
//---------------------------------------------------------------------------
// Compile* functions return false when error so the return
// value must be negated for the error string to be returned
bool CompileEx_wrap(
@@ -119,12 +119,12 @@ bool CompileEx_wrap(
{
return !CompileEx(file, del_macros, errbuf, errbufsize);
}
bool Compile_wrap(const char *file, char *errbuf, size_t errbufsize)
{
return !Compile(file, errbuf, errbufsize);
}
bool calcexpr_wrap(
ea_t where,
const char *line,
@@ -133,7 +133,7 @@ bool calcexpr_wrap(
{
return !calcexpr(where, line, rv, errbuf, errbufsize);
}
bool calc_idc_expr_wrap(
ea_t where,
const char *line,
@@ -142,11 +142,11 @@ bool calc_idc_expr_wrap(
{
return !calc_idc_expr(where, line, rv, errbuf, errbufsize);
}
bool CompileLine_wrap(const char *line, char *errbuf, size_t errbufsize)
{
return !CompileLineEx(line, errbuf, errbufsize);
}
//</inline(py_expr)>
#endif
//</inline(py_expr)>
#endif

View File

@@ -1,169 +1,169 @@
# --------------------------------------------------------------------------
import os
import sys
import idaapi
import _idaapi
from sys import getrefcount
import gc
try:
import pywraps
pywraps_there = True
_idaapi.pyw_register_idc_func = pywraps.pyw_register_idc_func
_idaapi.pyw_unregister_idc_func = pywraps.pyw_unregister_idc_func
_idaapi.py_get_call_idc_func = pywraps.py_get_call_idc_func
_idaapi.py_set_idc_func_ex = pywraps.py_set_idc_func_ex
except Exception as e:
pywraps_there = False
print("exception: %s" % str(e))
print("Using PyWraps: %s" % pywraps_there)
# --------------------------------------------------------------------------
#<pycode(py_expr)>
try:
import types
import ctypes
# Callback for IDC func callback (On Windows, we use stdcall)
# typedef error_t idaapi idc_func_t(idc_value_t *argv,idc_value_t *r);
_IDCFUNC_CB_T = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
# A trampoline function that is called from idcfunc_t that will
# call the Python callback with the argv and r properly serialized to python
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_call_idc_func())
except:
def call_idc_func__(*args):
warning("IDC extensions need ctypes library in order to work")
return 0
try:
_IDCFUNC_CB_T = CFUNCTYPE(c_int, c_void_p, c_void_p)
except:
_IDCFUNC_CB_T = None
# --------------------------------------------------------------------------
EXTFUN_BASE = 0x0001
"""requires open database"""
EXTFUN_NORET = 0x0002
"""does not return. the interpreter may clean up its state before calling it."""
EXTFUN_SAFE = 0x0004
"""thread safe function. may be called"""
# --------------------------------------------------------------------------
class _IdcFunction(object):
"""
Internal class that calls pyw_call_idc_func() with a context
"""
def __init__(self, ctxptr):
self.ctxptr = ctxptr
# Take a reference to the ctypes callback
# (note: this will create a circular reference)
self.cb = _IDCFUNC_CB_T(self)
fp_ptr = property(lambda self: ctypes.cast(self.cb, ctypes.c_void_p).value)
def __call__(self, args, res):
return call_idc_func__(self.ctxptr, args, res)
# --------------------------------------------------------------------------
# Dictionary to remember IDC function names along with the context pointer
# retrieved by using the internal pyw_register_idc_func()
__IDC_FUNC_CTXS = {}
# --------------------------------------------------------------------------
def set_idc_func_ex(name, fp=None, args=(), flags=0):
"""
Extends the IDC language by exposing a new IDC function that is backed up by a Python function
This function also unregisters the IDC function if 'fp' was passed as None
@param name: IDC function name to expose
@param fp: Python callable that will receive the arguments and return a tuple.
If this argument is None then the IDC function is unregistered
@param args: Arguments. A tuple of idaapi.VT_XXX constants
@param flags: IDC function flags. A combination of EXTFUN_XXX constants
@return: Boolean.
"""
global __IDC_FUNC_CTXS
# Get the context
f = __IDC_FUNC_CTXS.get(name, None)
# Unregistering?
if fp is None:
# Not registered?
if f is None:
return False
# Break circular reference
del f.cb
# Delete the name from the dictionary
del __IDC_FUNC_CTXS[name]
# Delete the context and unregister the function
return _idaapi.pyw_unregister_idc_func(f.ctxptr)
# Registering a function that is already registered?
if f is not None:
# Unregister it first
set_idc_func_ex(name, None)
# Convert the tupple argument info to a string
args = "".join([chr(x) for x in args])
# Create a context
ctxptr = _idaapi.pyw_register_idc_func(name, args, fp)
if ctxptr == 0:
return False
# Bind the context with the IdcFunc object
f = _IdcFunction(ctxptr)
# Remember the Python context
__IDC_FUNC_CTXS[name] = f
# Register IDC function with a callback
return _idaapi.py_set_idc_func_ex(
name,
f.fp_ptr,
args,
flags)
#</pycode(py_expr)>
# --------------------------------------------------------------------------
def test1():
global MY_IDC_FUNC
try:
# Already registered?
MY_IDC_FUNC
# Unregister
print("Unregistering function")
set_idc_func_ex(MY_IDC_FUNC)
except:
MY_IDC_FUNC = "pysum"
ok = set_idc_func_ex(MY_IDC_FUNC, my_idc_sum, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if not ok:
del MY_IDC_FUNC
#</pycode(ex_expr)>
# --------------------------------------------------------------------------
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>
# --------------------------------------------------------------------------
import os
import sys
import idaapi
import _idaapi
from sys import getrefcount
import gc
try:
import pywraps
pywraps_there = True
_idaapi.pyw_register_idc_func = pywraps.pyw_register_idc_func
_idaapi.pyw_unregister_idc_func = pywraps.pyw_unregister_idc_func
_idaapi.py_get_call_idc_func = pywraps.py_get_call_idc_func
_idaapi.py_set_idc_func_ex = pywraps.py_set_idc_func_ex
except Exception as e:
pywraps_there = False
print("exception: %s" % str(e))
print("Using PyWraps: %s" % pywraps_there)
# --------------------------------------------------------------------------
#<pycode(py_expr)>
try:
import types
import ctypes
# Callback for IDC func callback (On Windows, we use stdcall)
# typedef error_t idaapi idc_func_t(idc_value_t *argv,idc_value_t *r);
_IDCFUNC_CB_T = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_void_p, ctypes.c_void_p)
# A trampoline function that is called from idcfunc_t that will
# call the Python callback with the argv and r properly serialized to python
call_idc_func__ = ctypes.CFUNCTYPE(ctypes.c_long)(_idaapi.py_get_call_idc_func())
except:
def call_idc_func__(*args):
warning("IDC extensions need ctypes library in order to work")
return 0
try:
_IDCFUNC_CB_T = CFUNCTYPE(c_int, c_void_p, c_void_p)
except:
_IDCFUNC_CB_T = None
# --------------------------------------------------------------------------
EXTFUN_BASE = 0x0001
"""requires open database"""
EXTFUN_NORET = 0x0002
"""does not return. the interpreter may clean up its state before calling it."""
EXTFUN_SAFE = 0x0004
"""thread safe function. may be called"""
# --------------------------------------------------------------------------
class _IdcFunction(object):
"""
Internal class that calls pyw_call_idc_func() with a context
"""
def __init__(self, ctxptr):
self.ctxptr = ctxptr
# Take a reference to the ctypes callback
# (note: this will create a circular reference)
self.cb = _IDCFUNC_CB_T(self)
fp_ptr = property(lambda self: ctypes.cast(self.cb, ctypes.c_void_p).value)
def __call__(self, args, res):
return call_idc_func__(self.ctxptr, args, res)
# --------------------------------------------------------------------------
# Dictionary to remember IDC function names along with the context pointer
# retrieved by using the internal pyw_register_idc_func()
__IDC_FUNC_CTXS = {}
# --------------------------------------------------------------------------
def set_idc_func_ex(name, fp=None, args=(), flags=0):
"""
Extends the IDC language by exposing a new IDC function that is backed up by a Python function
This function also unregisters the IDC function if 'fp' was passed as None
@param name: IDC function name to expose
@param fp: Python callable that will receive the arguments and return a tuple.
If this argument is None then the IDC function is unregistered
@param args: Arguments. A tuple of idaapi.VT_XXX constants
@param flags: IDC function flags. A combination of EXTFUN_XXX constants
@return: Boolean.
"""
global __IDC_FUNC_CTXS
# Get the context
f = __IDC_FUNC_CTXS.get(name, None)
# Unregistering?
if fp is None:
# Not registered?
if f is None:
return False
# Break circular reference
del f.cb
# Delete the name from the dictionary
del __IDC_FUNC_CTXS[name]
# Delete the context and unregister the function
return _idaapi.pyw_unregister_idc_func(f.ctxptr)
# Registering a function that is already registered?
if f is not None:
# Unregister it first
set_idc_func_ex(name, None)
# Convert the tupple argument info to a string
args = "".join([chr(x) for x in args])
# Create a context
ctxptr = _idaapi.pyw_register_idc_func(name, args, fp)
if ctxptr == 0:
return False
# Bind the context with the IdcFunc object
f = _IdcFunction(ctxptr)
# Remember the Python context
__IDC_FUNC_CTXS[name] = f
# Register IDC function with a callback
return _idaapi.py_set_idc_func_ex(
name,
f.fp_ptr,
args,
flags)
#</pycode(py_expr)>
# --------------------------------------------------------------------------
def test1():
global MY_IDC_FUNC
try:
# Already registered?
MY_IDC_FUNC
# Unregister
print("Unregistering function")
set_idc_func_ex(MY_IDC_FUNC)
except:
MY_IDC_FUNC = "pysum"
ok = set_idc_func_ex(MY_IDC_FUNC, my_idc_sum, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if not ok:
del MY_IDC_FUNC
#</pycode(ex_expr)>
# --------------------------------------------------------------------------
#<pycode(ex_expr)>
def py_power(n, e):
return n ** e
ok = set_idc_func_ex("pow", py_power, (idaapi.VT_LONG, idaapi.VT_LONG), 0)
if ok:
print("Now the pow() will be present IDC!")
else:
print("Failed to register pow() IDC function")
#</pycode(ex_expr)>

View File

@@ -1,88 +1,88 @@
#<pycode(py_gdl)>
# -----------------------------------------------------------------------
class BasicBlock(object):
"""Basic block class. It is returned by the Flowchart class"""
def __init__(self, id, bb, fc):
self._fc = fc
self.id = id
"""Basic block ID"""
self.startEA = bb.startEA
"""startEA of basic block"""
self.endEA = bb.endEA
"""endEA of basic block"""
self.type = self._fc._q.calc_block_type(self.id)
"""Block type (check fc_block_type_t enum)"""
def preds(self):
"""
Iterates the predecessors list
"""
q = self._fc._q
for i in xrange(0, self._fc._q.npred(self.id)):
yield self._fc[q.pred(self.id, i)]
def succs(self):
"""
Iterates the successors list
"""
q = self._fc._q
for i in xrange(0, q.nsucc(self.id)):
yield self._fc[q.succ(self.id, i)]
# -----------------------------------------------------------------------
class FlowChart(object):
"""
Flowchart class used to determine basic blocks.
Check ex_gdl_qflow_chart.py for sample usage.
"""
def __init__(self, f=None, bounds=None, flags=0):
"""
Constructor
@param f: A func_t type, use get_func(ea) to get a reference
@param bounds: A tuple of the form (start, end). Used if "f" is None
@param flags: one of the FC_xxxx flags. One interesting flag is FC_PREDS
"""
if (f is None) and (bounds is None or type(bounds) != types.TupleType):
raise Exception("Please specifiy either a function or start/end pair")
if bounds is None:
bounds = (BADADDR, BADADDR)
# Create the flowchart
self._q = qflow_chart_t("", f, bounds[0], bounds[1], flags)
size = property(lambda self: self._q.size())
"""Number of blocks in the flow chart"""
def refresh():
"""Refreshes the flow chart"""
self._q.refresh()
def _getitem(self, index):
return BasicBlock(index, self._q[index], self)
def __iter__(self):
return (self._getitem(index) for index in xrange(0, self.size))
def __getitem__(self, index):
"""
Returns a basic block
@return: BasicBlock
"""
if index >= self.size:
raise KeyError
else:
return self._getitem(index)
#</pycode(py_gdl)>
#<pycode(py_gdl)>
# -----------------------------------------------------------------------
class BasicBlock(object):
"""Basic block class. It is returned by the Flowchart class"""
def __init__(self, id, bb, fc):
self._fc = fc
self.id = id
"""Basic block ID"""
self.startEA = bb.startEA
"""startEA of basic block"""
self.endEA = bb.endEA
"""endEA of basic block"""
self.type = self._fc._q.calc_block_type(self.id)
"""Block type (check fc_block_type_t enum)"""
def preds(self):
"""
Iterates the predecessors list
"""
q = self._fc._q
for i in xrange(0, self._fc._q.npred(self.id)):
yield self._fc[q.pred(self.id, i)]
def succs(self):
"""
Iterates the successors list
"""
q = self._fc._q
for i in xrange(0, q.nsucc(self.id)):
yield self._fc[q.succ(self.id, i)]
# -----------------------------------------------------------------------
class FlowChart(object):
"""
Flowchart class used to determine basic blocks.
Check ex_gdl_qflow_chart.py for sample usage.
"""
def __init__(self, f=None, bounds=None, flags=0):
"""
Constructor
@param f: A func_t type, use get_func(ea) to get a reference
@param bounds: A tuple of the form (start, end). Used if "f" is None
@param flags: one of the FC_xxxx flags. One interesting flag is FC_PREDS
"""
if (f is None) and (bounds is None or type(bounds) != types.TupleType):
raise Exception("Please specifiy either a function or start/end pair")
if bounds is None:
bounds = (BADADDR, BADADDR)
# Create the flowchart
self._q = qflow_chart_t("", f, bounds[0], bounds[1], flags)
size = property(lambda self: self._q.size())
"""Number of blocks in the flow chart"""
def refresh():
"""Refreshes the flow chart"""
self._q.refresh()
def _getitem(self, index):
return BasicBlock(index, self._q[index], self)
def __iter__(self):
return (self._getitem(index) for index in xrange(0, self.size))
def __getitem__(self, index):
"""
Returns a basic block
@return: BasicBlock
"""
if index >= self.size:
raise KeyError
else:
return self._getitem(index)
#</pycode(py_gdl)>

File diff suppressed because it is too large Load Diff

View File

@@ -1,161 +1,161 @@
#<pycode(py_graph)>
class GraphViewer(CustomIDAMemo):
"""This class wraps the user graphing facility provided by the graph.hpp file"""
def __init__(self, title, close_open = False):
"""
Constructs the GraphView object.
Please do not remove or rename the private fields
@param title: The title of the graph window
@param close_open: Should it attempt to close an existing graph (with same title) before creating this graph?
"""
self._title = title
self._nodes = []
self._edges = []
self._close_open = close_open
def AddNode(self, obj):
"""Creates a node associated with the given object and returns the node id"""
id = len(self._nodes)
self._nodes.append(obj)
return id
def AddEdge(self, src_node, dest_node):
"""Creates an edge between two given node ids"""
self._edges.append( (src_node, dest_node) )
def Clear(self):
"""Clears all the nodes and edges"""
self._nodes = []
self._edges = []
def __iter__(self):
return (self._nodes[index] for index in xrange(0, len(self._nodes)))
def __getitem__(self, idx):
"""Returns a reference to the object associated with this node id"""
if idx >= len(self._nodes):
raise KeyError
else:
return self._nodes[idx]
def Count(self):
"""Returns the node count"""
return len(self._nodes)
def Close(self):
"""
Closes the graph.
It is possible to call Show() again (which will recreate the graph)
"""
_idaapi.pyg_close(self)
def Show(self):
"""
Shows an existing graph or creates a new one
@return: Boolean
"""
if self._close_open:
frm = _idaapi.find_tform(self._title)
if frm:
_idaapi.close_tform(frm, 0)
return _idaapi.pyg_show(self)
def Select(self, node_id):
"""Selects a node on the graph"""
_idaapi.pyg_select_node(self, node_id)
def AddCommand(self, title, hotkey):
"""
Deprecated: Use
- register_action()
- attach_action_to_popup()
"""
return _idaapi.pyg_add_command(self, title, hotkey)
def OnRefresh(self):
"""
Event called when the graph is refreshed or first created.
From this event you are supposed to create nodes and edges.
This callback is mandatory.
@note: ***It is important to clear previous nodes before adding nodes.***
@return: Returning True tells the graph viewer to use the items. Otherwise old items will be used.
"""
self.Clear()
return True
#<pydoc>
# def OnGetText(self, node_id):
# """
# Triggered when the graph viewer wants the text and color for a given node.
# This callback is triggered one time for a given node (the value will be cached and used later without calling Python).
# When you call refresh then again this callback will be called for each node.
#
# This callback is mandatory.
#
# @return: Return a string to describe the node text or return a tuple (node_text, node_color) to describe both text and color
# """
# return str(self[node_id])
#
# def OnActivate(self):
# """
# Triggered when the graph window gets the focus
# @return: None
# """
# print "Activated...."
#
# def OnDeactivate(self):
# """Triggered when the graph window loses the focus
# @return: None
# """
# print "Deactivated...."
#
# def OnSelect(self, node_id):
# """
# Triggered when a node is being selected
# @return: Return True to allow the node to be selected or False to disallow node selection change
# """
# # allow selection change
# return True
#
# def OnHint(self, node_id):
# """
# Triggered when the graph viewer wants to retrieve hint text associated with a given node
#
# @return: None if no hint is avail or a string designating the hint
# """
# return "hint for " + str(node_id)
#
# def OnClose(self):
# """Triggered when the graph viewer window is being closed
# @return: None
# """
# print "Closing......."
#
# def OnClick(self, node_id):
# """
# Triggered when a node is clicked
# @return: False to ignore the click and True otherwise
# """
# print "clicked on", self[node_id]
# return True
#
# def OnDblClick(self, node_id):
# """
# Triggerd when a node is double-clicked.
# @return: False to ignore the click and True otherwise
# """
# print "dblclicked on", self[node_id]
# return True
#
# def OnCommand(self, cmd_id):
# """
# Deprecated
# """
# pass
#</pydoc>
#</pycode(py_graph)>
#<pycode(py_graph)>
class GraphViewer(CustomIDAMemo):
"""This class wraps the user graphing facility provided by the graph.hpp file"""
def __init__(self, title, close_open = False):
"""
Constructs the GraphView object.
Please do not remove or rename the private fields
@param title: The title of the graph window
@param close_open: Should it attempt to close an existing graph (with same title) before creating this graph?
"""
self._title = title
self._nodes = []
self._edges = []
self._close_open = close_open
def AddNode(self, obj):
"""Creates a node associated with the given object and returns the node id"""
id = len(self._nodes)
self._nodes.append(obj)
return id
def AddEdge(self, src_node, dest_node):
"""Creates an edge between two given node ids"""
self._edges.append( (src_node, dest_node) )
def Clear(self):
"""Clears all the nodes and edges"""
self._nodes = []
self._edges = []
def __iter__(self):
return (self._nodes[index] for index in xrange(0, len(self._nodes)))
def __getitem__(self, idx):
"""Returns a reference to the object associated with this node id"""
if idx >= len(self._nodes):
raise KeyError
else:
return self._nodes[idx]
def Count(self):
"""Returns the node count"""
return len(self._nodes)
def Close(self):
"""
Closes the graph.
It is possible to call Show() again (which will recreate the graph)
"""
_idaapi.pyg_close(self)
def Show(self):
"""
Shows an existing graph or creates a new one
@return: Boolean
"""
if self._close_open:
frm = _idaapi.find_tform(self._title)
if frm:
_idaapi.close_tform(frm, 0)
return _idaapi.pyg_show(self)
def Select(self, node_id):
"""Selects a node on the graph"""
_idaapi.pyg_select_node(self, node_id)
def AddCommand(self, title, hotkey):
"""
Deprecated: Use
- register_action()
- attach_action_to_popup()
"""
return _idaapi.pyg_add_command(self, title, hotkey)
def OnRefresh(self):
"""
Event called when the graph is refreshed or first created.
From this event you are supposed to create nodes and edges.
This callback is mandatory.
@note: ***It is important to clear previous nodes before adding nodes.***
@return: Returning True tells the graph viewer to use the items. Otherwise old items will be used.
"""
self.Clear()
return True
#<pydoc>
# def OnGetText(self, node_id):
# """
# Triggered when the graph viewer wants the text and color for a given node.
# This callback is triggered one time for a given node (the value will be cached and used later without calling Python).
# When you call refresh then again this callback will be called for each node.
#
# This callback is mandatory.
#
# @return: Return a string to describe the node text or return a tuple (node_text, node_color) to describe both text and color
# """
# return str(self[node_id])
#
# def OnActivate(self):
# """
# Triggered when the graph window gets the focus
# @return: None
# """
# print "Activated...."
#
# def OnDeactivate(self):
# """Triggered when the graph window loses the focus
# @return: None
# """
# print "Deactivated...."
#
# def OnSelect(self, node_id):
# """
# Triggered when a node is being selected
# @return: Return True to allow the node to be selected or False to disallow node selection change
# """
# # allow selection change
# return True
#
# def OnHint(self, node_id):
# """
# Triggered when the graph viewer wants to retrieve hint text associated with a given node
#
# @return: None if no hint is avail or a string designating the hint
# """
# return "hint for " + str(node_id)
#
# def OnClose(self):
# """Triggered when the graph viewer window is being closed
# @return: None
# """
# print "Closing......."
#
# def OnClick(self, node_id):
# """
# Triggered when a node is clicked
# @return: False to ignore the click and True otherwise
# """
# print "clicked on", self[node_id]
# return True
#
# def OnDblClick(self, node_id):
# """
# Triggerd when a node is double-clicked.
# @return: False to ignore the click and True otherwise
# """
# print "dblclicked on", self[node_id]
# return True
#
# def OnCommand(self, cmd_id):
# """
# Deprecated
# """
# pass
#</pydoc>
#</pycode(py_graph)>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -68,7 +68,7 @@ bool py_idaview_t::Unbind(PyObject *self)
py_idaview_t *_this = view_extract_this<py_idaview_t>(self);
if ( _this == NULL )
return false;
_this->unbind();
_this->unbind(true);
return true;
}

View File

@@ -405,7 +405,7 @@ static PyObject *ph_get_operand_info(
tid,
_py_getreg,
regvalues.begin(),
&opinf) != 0 )
&opinf) > 0 )
{
break;
}
@@ -1598,7 +1598,7 @@ static const regval_t *idaapi _py_getreg(
{
for ( int i=dbg->registers_size - 1; i >= 0; i-- )
{
if ( stricmp(name, dbg->registers[i].name) == 0 )
if ( strieq(name, dbg->registers(i).name) )
return &regvals[i];
}
static regval_t rv;

View File

@@ -1,121 +1,121 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
if pywraps_there:
_idaapi.execute_sync = pywraps.py_execute_sync
_idaapi.add_hotkey = pywraps.py_add_hotkey
_idaapi.del_hotkey = pywraps.py_del_hotkey
# -----------------------------------------------------------------------
#<pycode(py_kernwin)>
DP_LEFT = 0x0001
DP_TOP = 0x0002
DP_RIGHT = 0x0004
DP_BOTTOM = 0x0008
DP_INSIDE = 0x0010
# if not before, then it is after
# (use DP_INSIDE | DP_BEFORE to insert a tab before a given tab)
# this flag alone cannot be used to determine orientation
DP_BEFORE = 0x0020
# used with combination of other flags
DP_TAB = 0x0040
DP_FLOATING = 0x0080
# ----------------------------------------------------------------------
def load_custom_icon(file_name=None, data=None, format=None):
"""
Loads a custom icon and returns an identifier that can be used with other APIs
If file_name is passed then the other two arguments are ignored.
@param file_name: The icon file name
@param data: The icon data
@param format: The icon data format
@return: Icon id or 0 on failure.
Use free_custom_icon() to free it
"""
if file_name is not None:
return _idaapi.py_load_custom_icon_fn(file_name)
elif not (data is None and format is None):
return _idaapi.py_load_custom_icon_data(data, format)
else:
return 0
# ----------------------------------------------------------------------
def asklong(defval, format):
res, val = _idaapi._asklong(defval, format)
if res == 1:
return val
else:
return None
# ----------------------------------------------------------------------
def askaddr(defval, format):
res, ea = _idaapi._askaddr(defval, format)
if res == 1:
return ea
else:
return None
# ----------------------------------------------------------------------
def askseg(defval, format):
res, sel = _idaapi._askseg(defval, format)
if res == 1:
return sel
else:
return None
# ----------------------------------------------------------------------
class action_handler_t:
def __init__(self):
pass
def activate(self, ctx):
return 0
def update(self, ctx):
pass
#</pycode(py_kernwin)>
# ----------------------------------------------------------------------
from threading import Thread
import time
# ----------------------------------------------------------------------
def myfunction(cnt):
i = 1
while i <= cnt:
print "i=", i
i += 1
time.sleep(1)
print "done!"
def test_thread():
t = Thread(target=myfunction, args=(2,))
t.start()
t.join()
# ----------------------------------------------------------------------
def hotkey_func1():
print "Hello from hotkey handler in Python!"
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
if pywraps_there:
_idaapi.execute_sync = pywraps.py_execute_sync
_idaapi.add_hotkey = pywraps.py_add_hotkey
_idaapi.del_hotkey = pywraps.py_del_hotkey
# -----------------------------------------------------------------------
#<pycode(py_kernwin)>
DP_LEFT = 0x0001
DP_TOP = 0x0002
DP_RIGHT = 0x0004
DP_BOTTOM = 0x0008
DP_INSIDE = 0x0010
# if not before, then it is after
# (use DP_INSIDE | DP_BEFORE to insert a tab before a given tab)
# this flag alone cannot be used to determine orientation
DP_BEFORE = 0x0020
# used with combination of other flags
DP_TAB = 0x0040
DP_FLOATING = 0x0080
# ----------------------------------------------------------------------
def load_custom_icon(file_name=None, data=None, format=None):
"""
Loads a custom icon and returns an identifier that can be used with other APIs
If file_name is passed then the other two arguments are ignored.
@param file_name: The icon file name
@param data: The icon data
@param format: The icon data format
@return: Icon id or 0 on failure.
Use free_custom_icon() to free it
"""
if file_name is not None:
return _idaapi.py_load_custom_icon_fn(file_name)
elif not (data is None and format is None):
return _idaapi.py_load_custom_icon_data(data, format)
else:
return 0
# ----------------------------------------------------------------------
def asklong(defval, format):
res, val = _idaapi._asklong(defval, format)
if res == 1:
return val
else:
return None
# ----------------------------------------------------------------------
def askaddr(defval, format):
res, ea = _idaapi._askaddr(defval, format)
if res == 1:
return ea
else:
return None
# ----------------------------------------------------------------------
def askseg(defval, format):
res, sel = _idaapi._askseg(defval, format)
if res == 1:
return sel
else:
return None
# ----------------------------------------------------------------------
class action_handler_t:
def __init__(self):
pass
def activate(self, ctx):
return 0
def update(self, ctx):
pass
#</pycode(py_kernwin)>
# ----------------------------------------------------------------------
from threading import Thread
import time
# ----------------------------------------------------------------------
def myfunction(cnt):
i = 1
while i <= cnt:
print "i=", i
i += 1
time.sleep(1)
print "done!"
def test_thread():
t = Thread(target=myfunction, args=(2,))
t.start()
t.join()
# ----------------------------------------------------------------------
def hotkey_func1():
print "Hello from hotkey handler in Python!"

View File

@@ -1,214 +1,214 @@
#ifndef __PYWRAPS__LINES__
#define __PYWRAPS__LINES__
//<code(py_lines)>
//------------------------------------------------------------------------
static PyObject *py_get_user_defined_prefix = NULL;
static void idaapi s_py_get_user_defined_prefix(
ea_t ea,
int lnnum,
int indent,
const char *line,
char *buf,
size_t bufsize)
{
PYW_GIL_GET;
newref_t py_ret(
PyObject_CallFunction(
py_get_user_defined_prefix,
PY_FMT64 "iis" PY_FMT64,
ea, lnnum, indent, line, bufsize));
// Error? Display it
// No error? Copy the buffer
if ( !PyW_ShowCbErr("py_get_user_defined_prefix") )
{
Py_ssize_t py_len;
char *py_str;
if ( PyString_AsStringAndSize(py_ret.o, &py_str, &py_len) != -1 )
{
memcpy(buf, py_str, qmin(bufsize, py_len));
if ( py_len < bufsize )
buf[py_len] = '\0';
}
}
}
//</code(py_lines)>
//------------------------------------------------------------------------
//<inline(py_lines)>
//------------------------------------------------------------------------
/*
#<pydoc>
def set_user_defined_prefix(width, callback):
"""
User-defined line-prefixes are displayed just after the autogenerated
line prefixes. In order to use them, the plugin should call the
following function to specify its width and contents.
@param width: the width of the user-defined prefix
@param callback: a get_user_defined_prefix callback to get the contents of the prefix.
Its arguments:
ea - linear address
lnnum - line number
indent - indent of the line contents (-1 means the default instruction)
indent and is used for instruction itself. see explanations for printf_line()
line - the line to be generated. the line usually contains color tags this argument
can be examined to decide whether to generated the prefix
bufsize- the maximum allowed size of the output buffer
It returns a buffer of size < bufsize
In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None
"""
pass
#</pydoc>
*/
static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( width == 0 || pycb == Py_None )
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// ...and clear it
py_get_user_defined_prefix = NULL;
// Uninstall user defind prefix
set_user_defined_prefix(0, NULL);
}
else if ( PyCallable_Check(pycb) )
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// Copy new callback and hold a reference
py_get_user_defined_prefix = pycb;
Py_INCREF(py_get_user_defined_prefix);
set_user_defined_prefix(width, s_py_get_user_defined_prefix);
}
else
{
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
}
//-------------------------------------------------------------------------
/*
#<pydoc>
def tag_remove(colstr):
"""
Remove color escape sequences from a string
@param colstr: the colored string with embedded tags
@return:
None on failure
or a new string w/o the tags
"""
pass
#</pydoc>
*/
PyObject *py_tag_remove(const char *instr)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
size_t sz = strlen(instr);
char *buf = new char[sz + 5];
if ( buf == NULL )
Py_RETURN_NONE;
ssize_t r = tag_remove(instr, buf, sz);
PyObject *res;
if ( r < 0 )
{
Py_INCREF(Py_None);
res = Py_None;
}
else
{
res = PyString_FromString(buf);
}
delete [] buf;
return res;
}
//-------------------------------------------------------------------------
PyObject *py_tag_addr(ea_t ea)
{
char buf[100];
tag_addr(buf, buf + sizeof(buf), ea);
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(buf);
}
//-------------------------------------------------------------------------
int py_tag_skipcode(const char *line)
{
return tag_skipcode(line)-line;
}
//-------------------------------------------------------------------------
int py_tag_skipcodes(const char *line)
{
return tag_skipcodes(line)-line;
}
//-------------------------------------------------------------------------
int py_tag_advance(const char *line, int cnt)
{
return tag_advance(line, cnt)-line;
}
//-------------------------------------------------------------------------
/*
#<pydoc>
def generate_disassembly(ea, max_lines, as_stack, notags):
"""
Generate disassembly lines (many lines) and put them into a buffer
@param ea: address to generate disassembly for
@param max_lines: how many lines max to generate
@param as_stack: Display undefined items as 2/4/8 bytes
@return:
- None on failure
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
the most important line number and a tuple of generated lines
"""
pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
ea_t ea,
int max_lines,
bool as_stack,
bool notags)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( max_lines <= 0 )
Py_RETURN_NONE;
qstring qbuf;
char **lines = new char *[max_lines];
int lnnum;
int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack);
newref_t py_tuple(PyTuple_New(nlines));
for ( int i=0; i<nlines; i++ )
{
const char *s = lines[i];
size_t line_len = strlen(s);
if ( notags )
{
qbuf.resize(line_len+5);
tag_remove(s, &qbuf[0], line_len);
s = (const char *)&qbuf[0];
}
PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
qfree(lines[i]);
}
delete [] lines;
return Py_BuildValue("(iO)", lnnum, py_tuple.o);
}
//</inline(py_lines)>
#endif
#ifndef __PYWRAPS__LINES__
#define __PYWRAPS__LINES__
//<code(py_lines)>
//------------------------------------------------------------------------
static PyObject *py_get_user_defined_prefix = NULL;
static void idaapi s_py_get_user_defined_prefix(
ea_t ea,
int lnnum,
int indent,
const char *line,
char *buf,
size_t bufsize)
{
PYW_GIL_GET;
newref_t py_ret(
PyObject_CallFunction(
py_get_user_defined_prefix,
PY_FMT64 "iis" PY_FMT64,
ea, lnnum, indent, line, bufsize));
// Error? Display it
// No error? Copy the buffer
if ( !PyW_ShowCbErr("py_get_user_defined_prefix") )
{
Py_ssize_t py_len;
char *py_str;
if ( PyString_AsStringAndSize(py_ret.o, &py_str, &py_len) != -1 )
{
memcpy(buf, py_str, qmin(bufsize, py_len));
if ( py_len < bufsize )
buf[py_len] = '\0';
}
}
}
//</code(py_lines)>
//------------------------------------------------------------------------
//<inline(py_lines)>
//------------------------------------------------------------------------
/*
#<pydoc>
def set_user_defined_prefix(width, callback):
"""
User-defined line-prefixes are displayed just after the autogenerated
line prefixes. In order to use them, the plugin should call the
following function to specify its width and contents.
@param width: the width of the user-defined prefix
@param callback: a get_user_defined_prefix callback to get the contents of the prefix.
Its arguments:
ea - linear address
lnnum - line number
indent - indent of the line contents (-1 means the default instruction)
indent and is used for instruction itself. see explanations for printf_line()
line - the line to be generated. the line usually contains color tags this argument
can be examined to decide whether to generated the prefix
bufsize- the maximum allowed size of the output buffer
It returns a buffer of size < bufsize
In order to remove the callback before unloading the plugin, specify the width = 0 or the callback = None
"""
pass
#</pydoc>
*/
static PyObject *py_set_user_defined_prefix(size_t width, PyObject *pycb)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( width == 0 || pycb == Py_None )
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// ...and clear it
py_get_user_defined_prefix = NULL;
// Uninstall user defind prefix
set_user_defined_prefix(0, NULL);
}
else if ( PyCallable_Check(pycb) )
{
// Release old callback reference
Py_XDECREF(py_get_user_defined_prefix);
// Copy new callback and hold a reference
py_get_user_defined_prefix = pycb;
Py_INCREF(py_get_user_defined_prefix);
set_user_defined_prefix(width, s_py_get_user_defined_prefix);
}
else
{
Py_RETURN_FALSE;
}
Py_RETURN_TRUE;
}
//-------------------------------------------------------------------------
/*
#<pydoc>
def tag_remove(colstr):
"""
Remove color escape sequences from a string
@param colstr: the colored string with embedded tags
@return:
None on failure
or a new string w/o the tags
"""
pass
#</pydoc>
*/
PyObject *py_tag_remove(const char *instr)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
size_t sz = strlen(instr);
char *buf = new char[sz + 5];
if ( buf == NULL )
Py_RETURN_NONE;
ssize_t r = tag_remove(instr, buf, sz);
PyObject *res;
if ( r < 0 )
{
Py_INCREF(Py_None);
res = Py_None;
}
else
{
res = PyString_FromString(buf);
}
delete [] buf;
return res;
}
//-------------------------------------------------------------------------
PyObject *py_tag_addr(ea_t ea)
{
char buf[100];
tag_addr(buf, buf + sizeof(buf), ea);
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(buf);
}
//-------------------------------------------------------------------------
int py_tag_skipcode(const char *line)
{
return tag_skipcode(line)-line;
}
//-------------------------------------------------------------------------
int py_tag_skipcodes(const char *line)
{
return tag_skipcodes(line)-line;
}
//-------------------------------------------------------------------------
int py_tag_advance(const char *line, int cnt)
{
return tag_advance(line, cnt)-line;
}
//-------------------------------------------------------------------------
/*
#<pydoc>
def generate_disassembly(ea, max_lines, as_stack, notags):
"""
Generate disassembly lines (many lines) and put them into a buffer
@param ea: address to generate disassembly for
@param max_lines: how many lines max to generate
@param as_stack: Display undefined items as 2/4/8 bytes
@return:
- None on failure
- tuple(most_important_line_number, tuple(lines)) : Returns a tuple containing
the most important line number and a tuple of generated lines
"""
pass
#</pydoc>
*/
PyObject *py_generate_disassembly(
ea_t ea,
int max_lines,
bool as_stack,
bool notags)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( max_lines <= 0 )
Py_RETURN_NONE;
qstring qbuf;
char **lines = new char *[max_lines];
int lnnum;
int nlines = generate_disassembly(ea, lines, max_lines, &lnnum, as_stack);
newref_t py_tuple(PyTuple_New(nlines));
for ( int i=0; i<nlines; i++ )
{
const char *s = lines[i];
size_t line_len = strlen(s);
if ( notags )
{
qbuf.resize(line_len+5);
tag_remove(s, &qbuf[0], line_len);
s = (const char *)&qbuf[0];
}
PyTuple_SetItem(py_tuple.o, i, PyString_FromString(s));
qfree(lines[i]);
}
delete [] lines;
return Py_BuildValue("(iO)", lnnum, py_tuple.o);
}
//</inline(py_lines)>
#endif

View File

@@ -1,34 +1,34 @@
#<pycode(py_lines)>
# ---------------- Color escape sequence defitions -------------------------
COLOR_ADDR_SIZE = 16 if _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL else 8
SCOLOR_FG_MAX = '\x28' # Max color number
SCOLOR_OPND1 = chr(cvar.COLOR_ADDR+1) # Instruction operand 1
SCOLOR_OPND2 = chr(cvar.COLOR_ADDR+2) # Instruction operand 2
SCOLOR_OPND3 = chr(cvar.COLOR_ADDR+3) # Instruction operand 3
SCOLOR_OPND4 = chr(cvar.COLOR_ADDR+4) # Instruction operand 4
SCOLOR_OPND5 = chr(cvar.COLOR_ADDR+5) # Instruction operand 5
SCOLOR_OPND6 = chr(cvar.COLOR_ADDR+6) # Instruction operand 6
SCOLOR_UTF8 = chr(cvar.COLOR_ADDR+10) # Following text is UTF-8 encoded
# ---------------- Line prefix colors --------------------------------------
PALETTE_SIZE = (cvar.COLOR_FG_MAX+_idaapi.COLOR_BG_MAX)
def requires_color_esc(c):
"""
Checks if the given character requires escaping
@param c: character (string of one char)
@return: Boolean
"""
t = ord(c[0])
return c >= COLOR_ON and c <= COLOR_INV
def COLSTR(str, tag):
"""
Utility function to create a colored line
@param str: The string
@param tag: Color tag constant. One of SCOLOR_XXXX
"""
return SCOLOR_ON + tag + str + SCOLOR_OFF + tag
#</pycode(py_lines)>
#<pycode(py_lines)>
# ---------------- Color escape sequence defitions -------------------------
COLOR_ADDR_SIZE = 16 if _idaapi.BADADDR == 0xFFFFFFFFFFFFFFFFL else 8
SCOLOR_FG_MAX = '\x28' # Max color number
SCOLOR_OPND1 = chr(cvar.COLOR_ADDR+1) # Instruction operand 1
SCOLOR_OPND2 = chr(cvar.COLOR_ADDR+2) # Instruction operand 2
SCOLOR_OPND3 = chr(cvar.COLOR_ADDR+3) # Instruction operand 3
SCOLOR_OPND4 = chr(cvar.COLOR_ADDR+4) # Instruction operand 4
SCOLOR_OPND5 = chr(cvar.COLOR_ADDR+5) # Instruction operand 5
SCOLOR_OPND6 = chr(cvar.COLOR_ADDR+6) # Instruction operand 6
SCOLOR_UTF8 = chr(cvar.COLOR_ADDR+10) # Following text is UTF-8 encoded
# ---------------- Line prefix colors --------------------------------------
PALETTE_SIZE = (cvar.COLOR_FG_MAX+_idaapi.COLOR_BG_MAX)
def requires_color_esc(c):
"""
Checks if the given character requires escaping
@param c: character (string of one char)
@return: Boolean
"""
t = ord(c[0])
return c >= COLOR_ON and c <= COLOR_INV
def COLSTR(str, tag):
"""
Utility function to create a colored line
@param str: The string
@param tag: Color tag constant. One of SCOLOR_XXXX
"""
return SCOLOR_ON + tag + str + SCOLOR_OFF + tag
#</pycode(py_lines)>

View File

@@ -1,417 +1,417 @@
#ifndef __PY_IDA_LINPUT__
#define __PY_IDA_LINPUT__
//--------------------------------------------------------------------------
//<inline(py_diskio)>
/*
#<pydoc>
class loader_input_t(pyidc_opaque_object_t):
"""A helper class to work with linput_t related functions.
This class is also used by file loaders scripts.
"""
def __init__(self):
pass
def close(self):
"""Closes the file"""
pass
def open(self, filename, remote = False):
"""Opens a file (or a remote file)
@return: Boolean
"""
pass
def set_linput(self, linput):
"""Links the current loader_input_t instance to a linput_t instance"""
pass
@staticmethod
def from_fp(fp):
"""A static method to construct an instance from a FILE*"""
pass
def open_memory(self, start, size):
"""Create a linput for process memory (By internally calling idaapi.create_memory_linput())
This linput will use dbg->read_memory() to read data
@param start: starting address of the input
@param size: size of the memory area to represent as linput
if unknown, may be passed as 0
"""
pass
def seek(self, pos, whence = SEEK_SET):
"""Set input source position
@return: the new position (not 0 as fseek!)
"""
pass
def tell(self):
"""Returns the current position"""
pass
def getz(self, sz, fpos = -1):
"""Returns a zero terminated string at the given position
@param sz: maximum size of the string
@param fpos: if != -1 then seek will be performed before reading
@return: The string or None on failure.
"""
pass
def gets(self, len):
"""Reads a line from the input file. Returns the read line or None"""
pass
def read(self, size):
"""Reads from the file. Returns the buffer or None"""
pass
def readbytes(self, size, big_endian):
"""Similar to read() but it respect the endianness"""
pass
def file2base(self, pos, ea1, ea2, patchable):
"""
Load portion of file into the database
This function will include (ea1..ea2) into the addressing space of the
program (make it enabled)
@param li: pointer ot input source
@param pos: position in the file
@param (ea1..ea2): range of destination linear addresses
@param patchable: should the kernel remember correspondance of
file offsets to linear addresses.
@return: 1-ok,0-read error, a warning is displayed
"""
pass
def get_char(self):
"""Reads a single character from the file. Returns None if EOF or the read character"""
pass
def opened(self):
"""Checks if the file is opened or not"""
pass
#</pydoc>
*/
class loader_input_t
{
private:
linput_t *li;
int own;
qstring fn;
enum
{
OWN_NONE = 0, // li not created yet
OWN_CREATE = 1, // Owns li because we created it
OWN_FROM_LI = 2, // No ownership we borrowed the li from another class
OWN_FROM_FP = 3, // We got an li instance from an fp instance, we have to unmake_linput() on Close
};
//--------------------------------------------------------------------------
void _from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
this->set_linput((linput_t *)PyCObject_AsVoidPtr(pycobject));
}
//--------------------------------------------------------------------------
void assign(const loader_input_t &rhs)
{
fn = rhs.fn;
li = rhs.li;
own = OWN_FROM_LI;
}
//--------------------------------------------------------------------------
loader_input_t(const loader_input_t &rhs)
{
assign(rhs);
}
public:
// Special attribute that tells the pyvar_to_idcvar how to convert this
// class from and to IDC. The value of this variable must be set to two
int __idc_cvt_id__;
//--------------------------------------------------------------------------
loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( pycobject != NULL && PyCObject_Check(pycobject) )
_from_cobject(pycobject);
}
//--------------------------------------------------------------------------
void close()
{
if ( li == NULL )
return;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
if ( own == OWN_CREATE )
close_linput(li);
else if ( own == OWN_FROM_FP )
unmake_linput(li);
Py_END_ALLOW_THREADS;
li = NULL;
own = OWN_NONE;
}
//--------------------------------------------------------------------------
~loader_input_t()
{
close();
}
//--------------------------------------------------------------------------
bool open(const char *filename, bool remote = false)
{
close();
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
li = open_linput(filename, remote);
if ( li != NULL )
{
// Save file name
fn = filename;
own = OWN_CREATE;
}
Py_END_ALLOW_THREADS;
return li != NULL;
}
//--------------------------------------------------------------------------
void set_linput(linput_t *linput)
{
close();
own = OWN_FROM_LI;
li = linput;
fn.sprnt("<linput_t * %p>", linput);
}
//--------------------------------------------------------------------------
static loader_input_t *from_linput(linput_t *linput)
{
loader_input_t *l = new loader_input_t();
l->set_linput(linput);
return l;
}
//--------------------------------------------------------------------------
// This method can be used to pass a linput_t* from C code
static loader_input_t *from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyCObject_Check(pycobject) )
return NULL;
loader_input_t *l = new loader_input_t();
l->_from_cobject(pycobject);
return l;
}
//--------------------------------------------------------------------------
static loader_input_t *from_fp(FILE *fp)
{
PYW_GIL_GET;
loader_input_t *l = NULL;
Py_BEGIN_ALLOW_THREADS;
linput_t *fp_li = make_linput(fp);
if ( fp_li != NULL )
{
l = new loader_input_t();
l->own = OWN_FROM_FP;
l->fn.sprnt("<FILE * %p>", fp);
l->li = fp_li;
}
Py_END_ALLOW_THREADS;
return l;
}
//--------------------------------------------------------------------------
linput_t *get_linput()
{
return li;
}
//--------------------------------------------------------------------------
bool open_memory(ea_t start, asize_t size = 0)
{
PYW_GIL_GET;
linput_t *l;
Py_BEGIN_ALLOW_THREADS;
l = create_memory_linput(start, size);
if ( l != NULL )
{
close();
li = l;
fn = "<memory>";
own = OWN_CREATE;
}
Py_END_ALLOW_THREADS;
return l != NULL;
}
//--------------------------------------------------------------------------
int32 seek(int32 pos, int whence = SEEK_SET)
{
int32 r;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
r = qlseek(li, pos, whence);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
int32 tell()
{
int32 r;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
r = qltell(li);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
PyObject *getz(size_t sz, int32 fpos = -1)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(sz + 5);
if ( buf == NULL )
break;
Py_BEGIN_ALLOW_THREADS;
qlgetz(li, fpos, buf, sz);
Py_END_ALLOW_THREADS;
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *gets(size_t len)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(len + 5);
if ( buf == NULL )
break;
bool ok;
Py_BEGIN_ALLOW_THREADS;
ok = qlgets(buf, len, li) != NULL;
Py_END_ALLOW_THREADS;
if ( !ok )
{
free(buf);
break;
}
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *read(size_t size)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
ssize_t r;
Py_BEGIN_ALLOW_THREADS;
r = qlread(li, buf, size);
Py_END_ALLOW_THREADS;
if ( r == -1 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
bool opened()
{
return li != NULL;
}
//--------------------------------------------------------------------------
PyObject *readbytes(size_t size, bool big_endian)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
int r;
Py_BEGIN_ALLOW_THREADS;
r = lreadbytes(li, buf, size, big_endian);
Py_END_ALLOW_THREADS;
if ( r == -1 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
int file2base(int32 pos, ea_t ea1, ea_t ea2, int patchable)
{
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = ::file2base(li, pos, ea1, ea2, patchable);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 size()
{
int32 rc;
Py_BEGIN_ALLOW_THREADS;
rc = qlsize(li);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *filename()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(fn.c_str());
}
//--------------------------------------------------------------------------
PyObject *get_char()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int ch;
Py_BEGIN_ALLOW_THREADS;
ch = qlgetc(li);
Py_END_ALLOW_THREADS;
if ( ch == EOF )
Py_RETURN_NONE;
return Py_BuildValue("c", ch);
}
};
//</inline(py_diskio)>
#endif
#ifndef __PY_IDA_LINPUT__
#define __PY_IDA_LINPUT__
//--------------------------------------------------------------------------
//<inline(py_diskio)>
/*
#<pydoc>
class loader_input_t(pyidc_opaque_object_t):
"""A helper class to work with linput_t related functions.
This class is also used by file loaders scripts.
"""
def __init__(self):
pass
def close(self):
"""Closes the file"""
pass
def open(self, filename, remote = False):
"""Opens a file (or a remote file)
@return: Boolean
"""
pass
def set_linput(self, linput):
"""Links the current loader_input_t instance to a linput_t instance"""
pass
@staticmethod
def from_fp(fp):
"""A static method to construct an instance from a FILE*"""
pass
def open_memory(self, start, size):
"""Create a linput for process memory (By internally calling idaapi.create_memory_linput())
This linput will use dbg->read_memory() to read data
@param start: starting address of the input
@param size: size of the memory area to represent as linput
if unknown, may be passed as 0
"""
pass
def seek(self, pos, whence = SEEK_SET):
"""Set input source position
@return: the new position (not 0 as fseek!)
"""
pass
def tell(self):
"""Returns the current position"""
pass
def getz(self, sz, fpos = -1):
"""Returns a zero terminated string at the given position
@param sz: maximum size of the string
@param fpos: if != -1 then seek will be performed before reading
@return: The string or None on failure.
"""
pass
def gets(self, len):
"""Reads a line from the input file. Returns the read line or None"""
pass
def read(self, size):
"""Reads from the file. Returns the buffer or None"""
pass
def readbytes(self, size, big_endian):
"""Similar to read() but it respect the endianness"""
pass
def file2base(self, pos, ea1, ea2, patchable):
"""
Load portion of file into the database
This function will include (ea1..ea2) into the addressing space of the
program (make it enabled)
@param li: pointer ot input source
@param pos: position in the file
@param (ea1..ea2): range of destination linear addresses
@param patchable: should the kernel remember correspondance of
file offsets to linear addresses.
@return: 1-ok,0-read error, a warning is displayed
"""
pass
def get_char(self):
"""Reads a single character from the file. Returns None if EOF or the read character"""
pass
def opened(self):
"""Checks if the file is opened or not"""
pass
#</pydoc>
*/
class loader_input_t
{
private:
linput_t *li;
int own;
qstring fn;
enum
{
OWN_NONE = 0, // li not created yet
OWN_CREATE = 1, // Owns li because we created it
OWN_FROM_LI = 2, // No ownership we borrowed the li from another class
OWN_FROM_FP = 3, // We got an li instance from an fp instance, we have to unmake_linput() on Close
};
//--------------------------------------------------------------------------
void _from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
this->set_linput((linput_t *)PyCObject_AsVoidPtr(pycobject));
}
//--------------------------------------------------------------------------
void assign(const loader_input_t &rhs)
{
fn = rhs.fn;
li = rhs.li;
own = OWN_FROM_LI;
}
//--------------------------------------------------------------------------
loader_input_t(const loader_input_t &rhs)
{
assign(rhs);
}
public:
// Special attribute that tells the pyvar_to_idcvar how to convert this
// class from and to IDC. The value of this variable must be set to two
int __idc_cvt_id__;
//--------------------------------------------------------------------------
loader_input_t(PyObject *pycobject = NULL): li(NULL), own(OWN_NONE), __idc_cvt_id__(PY_ICID_OPAQUE)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( pycobject != NULL && PyCObject_Check(pycobject) )
_from_cobject(pycobject);
}
//--------------------------------------------------------------------------
void close()
{
if ( li == NULL )
return;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
if ( own == OWN_CREATE )
close_linput(li);
else if ( own == OWN_FROM_FP )
unmake_linput(li);
Py_END_ALLOW_THREADS;
li = NULL;
own = OWN_NONE;
}
//--------------------------------------------------------------------------
~loader_input_t()
{
close();
}
//--------------------------------------------------------------------------
bool open(const char *filename, bool remote = false)
{
close();
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
li = open_linput(filename, remote);
if ( li != NULL )
{
// Save file name
fn = filename;
own = OWN_CREATE;
}
Py_END_ALLOW_THREADS;
return li != NULL;
}
//--------------------------------------------------------------------------
void set_linput(linput_t *linput)
{
close();
own = OWN_FROM_LI;
li = linput;
fn.sprnt("<linput_t * %p>", linput);
}
//--------------------------------------------------------------------------
static loader_input_t *from_linput(linput_t *linput)
{
loader_input_t *l = new loader_input_t();
l->set_linput(linput);
return l;
}
//--------------------------------------------------------------------------
// This method can be used to pass a linput_t* from C code
static loader_input_t *from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyCObject_Check(pycobject) )
return NULL;
loader_input_t *l = new loader_input_t();
l->_from_cobject(pycobject);
return l;
}
//--------------------------------------------------------------------------
static loader_input_t *from_fp(FILE *fp)
{
PYW_GIL_GET;
loader_input_t *l = NULL;
Py_BEGIN_ALLOW_THREADS;
linput_t *fp_li = make_linput(fp);
if ( fp_li != NULL )
{
l = new loader_input_t();
l->own = OWN_FROM_FP;
l->fn.sprnt("<FILE * %p>", fp);
l->li = fp_li;
}
Py_END_ALLOW_THREADS;
return l;
}
//--------------------------------------------------------------------------
linput_t *get_linput()
{
return li;
}
//--------------------------------------------------------------------------
bool open_memory(ea_t start, asize_t size = 0)
{
PYW_GIL_GET;
linput_t *l;
Py_BEGIN_ALLOW_THREADS;
l = create_memory_linput(start, size);
if ( l != NULL )
{
close();
li = l;
fn = "<memory>";
own = OWN_CREATE;
}
Py_END_ALLOW_THREADS;
return l != NULL;
}
//--------------------------------------------------------------------------
int32 seek(int32 pos, int whence = SEEK_SET)
{
int32 r;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
r = qlseek(li, pos, whence);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
int32 tell()
{
int32 r;
PYW_GIL_GET;
Py_BEGIN_ALLOW_THREADS;
r = qltell(li);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
PyObject *getz(size_t sz, int32 fpos = -1)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(sz + 5);
if ( buf == NULL )
break;
Py_BEGIN_ALLOW_THREADS;
qlgetz(li, fpos, buf, sz);
Py_END_ALLOW_THREADS;
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *gets(size_t len)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(len + 5);
if ( buf == NULL )
break;
bool ok;
Py_BEGIN_ALLOW_THREADS;
ok = qlgets(buf, len, li) != NULL;
Py_END_ALLOW_THREADS;
if ( !ok )
{
free(buf);
break;
}
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *read(size_t size)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
ssize_t r;
Py_BEGIN_ALLOW_THREADS;
r = qlread(li, buf, size);
Py_END_ALLOW_THREADS;
if ( r == -1 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
bool opened()
{
return li != NULL;
}
//--------------------------------------------------------------------------
PyObject *readbytes(size_t size, bool big_endian)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
int r;
Py_BEGIN_ALLOW_THREADS;
r = lreadbytes(li, buf, size, big_endian);
Py_END_ALLOW_THREADS;
if ( r == -1 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
int file2base(int32 pos, ea_t ea1, ea_t ea2, int patchable)
{
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = ::file2base(li, pos, ea1, ea2, patchable);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 size()
{
int32 rc;
Py_BEGIN_ALLOW_THREADS;
rc = qlsize(li);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *filename()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(fn.c_str());
}
//--------------------------------------------------------------------------
PyObject *get_char()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int ch;
Py_BEGIN_ALLOW_THREADS;
ch = qlgetc(li);
Py_END_ALLOW_THREADS;
if ( ch == EOF )
Py_RETURN_NONE;
return Py_BuildValue("c", ch);
}
};
//</inline(py_diskio)>
#endif

View File

@@ -1,92 +1,92 @@
#ifndef __PY_LOADER___
#define __PY_LOADER___
//------------------------------------------------------------------------
//<inline(py_loader)>
//------------------------------------------------------------------------
/*
#<pydoc>
def mem2base(mem, ea, fpos):
"""
Load database from the memory.
@param mem: the buffer
@param ea: start linear addresses
@param fpos: position in the input file the data is taken from.
if == -1, then no file position correspond to the data.
@return:
- Returns zero if the passed buffer was not a string
- Otherwise 1 is returned
"""
pass
#</pydoc>
*/
static int py_mem2base(PyObject *py_mem, ea_t ea, long fpos = -1)
{
Py_ssize_t len;
char *buf;
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
return 0;
}
return mem2base((void *)buf, ea, ea+len, fpos);
}
//------------------------------------------------------------------------
/*
#<pydoc>
def load_plugin(name):
"""
Loads a plugin
@return:
- None if plugin could not be loaded
- An opaque object representing the loaded plugin
"""
pass
#</pydoc>
*/
static PyObject *py_load_plugin(const char *name)
{
plugin_t *r = load_plugin(name);
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( r == NULL )
Py_RETURN_NONE;
else
return PyCObject_FromVoidPtr(r, NULL);
}
//------------------------------------------------------------------------
/*
#<pydoc>
def run_plugin(plg):
"""
Runs a plugin
@param plg: A plugin object (returned by load_plugin())
@return: Boolean
"""
pass
#</pydoc>
*/
static bool py_run_plugin(PyObject *plg, int arg)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyCObject_Check(plg) )
{
return false;
}
else
{
plugin_t *p = (plugin_t *)PyCObject_AsVoidPtr(plg);
bool rc;
Py_BEGIN_ALLOW_THREADS;
rc = run_plugin(p, arg);
Py_END_ALLOW_THREADS;
return rc;
}
}
//</inline(py_loader)>
#endif
#ifndef __PY_LOADER___
#define __PY_LOADER___
//------------------------------------------------------------------------
//<inline(py_loader)>
//------------------------------------------------------------------------
/*
#<pydoc>
def mem2base(mem, ea, fpos):
"""
Load database from the memory.
@param mem: the buffer
@param ea: start linear addresses
@param fpos: position in the input file the data is taken from.
if == -1, then no file position correspond to the data.
@return:
- Returns zero if the passed buffer was not a string
- Otherwise 1 is returned
"""
pass
#</pydoc>
*/
static int py_mem2base(PyObject *py_mem, ea_t ea, long fpos = -1)
{
Py_ssize_t len;
char *buf;
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( PyString_AsStringAndSize(py_mem, &buf, &len) == -1 )
return 0;
}
return mem2base((void *)buf, ea, ea+len, fpos);
}
//------------------------------------------------------------------------
/*
#<pydoc>
def load_plugin(name):
"""
Loads a plugin
@return:
- None if plugin could not be loaded
- An opaque object representing the loaded plugin
"""
pass
#</pydoc>
*/
static PyObject *py_load_plugin(const char *name)
{
plugin_t *r = load_plugin(name);
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( r == NULL )
Py_RETURN_NONE;
else
return PyCObject_FromVoidPtr(r, NULL);
}
//------------------------------------------------------------------------
/*
#<pydoc>
def run_plugin(plg):
"""
Runs a plugin
@param plg: A plugin object (returned by load_plugin())
@return: Boolean
"""
pass
#</pydoc>
*/
static bool py_run_plugin(PyObject *plg, int arg)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyCObject_Check(plg) )
{
return false;
}
else
{
plugin_t *p = (plugin_t *)PyCObject_AsVoidPtr(plg);
bool rc;
Py_BEGIN_ALLOW_THREADS;
rc = run_plugin(p, arg);
Py_END_ALLOW_THREADS;
return rc;
}
}
//</inline(py_loader)>
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,191 +1,191 @@
#<pycode(py_nalt)>
SWI_SPARSE = 0x1
"""sparse switch ( value table present ) otherwise lowcase present"""
SWI_V32 = 0x2
"""32-bit values in table"""
SWI_J32 = 0x4
"""32-bit jump offsets"""
SWI_VSPLIT = 0x8
"""value table is split (only for 32-bit values)"""
SWI_DEFAULT = 0x10
"""default case is present"""
SWI_END_IN_TBL = 0x20
"""switchend in table (default entry)"""
SWI_JMP_INV = 0x40
"""jumptable is inversed (last entry is for first entry in values table)"""
SWI_SHIFT_MASK = 0x180
"""use formula (element*shift + elbase) to find jump targets"""
SWI_ELBASE = 0x200
"""elbase is present (if not and shift!=0, endof(jumpea) is used)"""
SWI_JSIZE = 0x400
"""jump offset expansion bit"""
SWI_VSIZE = 0x800
"""value table element size expansion bit"""
SWI_SEPARATE = 0x1000
"""do not create an array of individual dwords"""
SWI_SIGNED = 0x2000
"""jump table entries are signed"""
SWI_CUSTOM = 0x4000
"""custom jump table - ph.create_switch_xrefs will be called to create code xrefs for the table. it must return 2. custom jump table must be created by the module"""
SWI_EXTENDED = 0x8000
"""this is switch_info_ex_t"""
SWI2_INDIRECT = 0x0001
"""value table elements are used as indexes into the jump table"""
SWI2_SUBTRACT = 0x0002
"""table values are subtracted from the elbase instead of being addded"""
# --------------------------------------------------------------------------
class switch_info_ex_t(py_clinked_object_t):
def __init__(self, lnk = None):
py_clinked_object_t.__init__(self, lnk)
def _create_clink(self):
return _idaapi.switch_info_ex_t_create()
def _del_clink(self, lnk):
return _idaapi.switch_info_ex_t_destroy(lnk)
def assign(self, other):
return _idaapi.switch_info_ex_t_assign(self, other)
def is_indirect(self):
return (self.flags & SWI_EXTENDED) != 0 and (self.flags2 & SWI2_INDIRECT) != 0
def is_subtract(self):
return (self.flags & SWI_EXTENDED) != 0 and (self.flags2 & SWI2_SUBTRACT) != 0
def get_jtable_size(self):
return self.jcases if self.is_indirect() else self.ncases
def get_lowcase(self):
return self.ind_lowcase if self.is_indirect() else self.lowcase
def set_expr(self, r, dt):
self.regnum = r
self.regdtyp = dt
def get_shift(self):
return (self.flags & SWI_SHIFT_MASK) >> 7
def set_shift(self, shift):
self.flags &= ~SWI_SHIFT_MASK
self.flags |= ((shift & 3) << 7)
def get_jtable_element_size(self):
code = self.flags & (SWI_J32|SWI_JSIZE)
if code == 0: return 2
elif code == SWI_J32: return 4
elif code == SWI_JSIZE: return 1
else: return 8
def set_jtable_element_size(self, size):
self.flags &= ~(SWI_J32|SWI_JSIZE)
if size == 4: self.flags |= SWI_J32
elif size == 1: self.flags |= SWI_JSIZE
elif size == 8: self.flags |= SWI_J32|SWI_JSIZE
elif size != 2: return False
return True
def get_vtable_element_size(self):
code = self.flags & (SWI_V32|SWI_VSIZE)
if code == 0: return 2
elif code == SWI_V32: return 4
elif code == SWI_VSIZE: return 1
return 8
def set_vtable_element_size(self, size):
self.flags &= ~SWI_V32|SWI_VSIZE
if size == 4: self.flags |= SWI_V32
elif size == 1: self.flags |= SWI_VSIZE
elif size == 8: self.flags |= SWI_V32|SWI_VSIZE
elif size != 2: return False
return True
#
# Autogenerated
#
def __get_regdtyp__(self):
return _idaapi.switch_info_ex_t_get_regdtyp(self)
def __set_regdtyp__(self, v):
_idaapi.switch_info_ex_t_set_regdtyp(self, v)
def __get_flags2__(self):
return _idaapi.switch_info_ex_t_get_flags2(self)
def __set_flags2__(self, v):
_idaapi.switch_info_ex_t_set_flags2(self, v)
def __get_jcases__(self):
return _idaapi.switch_info_ex_t_get_jcases(self)
def __set_jcases__(self, v):
_idaapi.switch_info_ex_t_set_jcases(self, v)
def __get_regnum__(self):
return _idaapi.switch_info_ex_t_get_regnum(self)
def __set_regnum__(self, v):
_idaapi.switch_info_ex_t_set_regnum(self, v)
def __get_flags__(self):
return _idaapi.switch_info_ex_t_get_flags(self)
def __set_flags__(self, v):
_idaapi.switch_info_ex_t_set_flags(self, v)
def __get_ncases__(self):
return _idaapi.switch_info_ex_t_get_ncases(self)
def __set_ncases__(self, v):
_idaapi.switch_info_ex_t_set_ncases(self, v)
def __get_defjump__(self):
return _idaapi.switch_info_ex_t_get_defjump(self)
def __set_defjump__(self, v):
_idaapi.switch_info_ex_t_set_defjump(self, v)
def __get_jumps__(self):
return _idaapi.switch_info_ex_t_get_jumps(self)
def __set_jumps__(self, v):
_idaapi.switch_info_ex_t_set_jumps(self, v)
def __get_elbase__(self):
return _idaapi.switch_info_ex_t_get_elbase(self)
def __set_elbase__(self, v):
_idaapi.switch_info_ex_t_set_elbase(self, v)
def __get_startea__(self):
return _idaapi.switch_info_ex_t_get_startea(self)
def __set_startea__(self, v):
_idaapi.switch_info_ex_t_set_startea(self, v)
def __get_custom__(self):
return _idaapi.switch_info_ex_t_get_custom(self)
def __set_custom__(self, v):
_idaapi.switch_info_ex_t_set_custom(self, v)
def __get_ind_lowcase__(self):
return _idaapi.switch_info_ex_t_get_ind_lowcase(self)
def __set_ind_lowcase__(self, v):
_idaapi.switch_info_ex_t_set_ind_lowcase(self, v)
def __get_values_lowcase__(self):
return _idaapi.switch_info_ex_t_get_values_lowcase(self)
def __set_values_lowcase__(self, v):
_idaapi.switch_info_ex_t_set_values_lowcase(self, v)
regdtyp = property(__get_regdtyp__, __set_regdtyp__)
"""size of the switch expression register as dtyp"""
flags2 = property(__get_flags2__, __set_flags2__)
jcases = property(__get_jcases__, __set_jcases__)
"""number of entries in the jump table (SWI2_INDIRECT)"""
regnum = property(__get_regnum__, __set_regnum__)
"""the switch expression as a register number"""
flags = property(__get_flags__, __set_flags__)
"""the switch expression as a register number"""
ncases = property(__get_ncases__, __set_ncases__)
"""number of cases (excluding default)"""
defjump = property(__get_defjump__, __set_defjump__)
"""default jump address"""
jumps = property(__get_jumps__, __set_jumps__)
"""jump table address"""
elbase = property(__get_elbase__, __set_elbase__)
"""element base"""
startea = property(__get_startea__, __set_startea__)
"""start of switch idiom"""
custom = property(__get_custom__, __set_custom__)
"""information for custom tables (filled and used by modules)"""
ind_lowcase = property(__get_ind_lowcase__, __set_ind_lowcase__)
values = property(__get_values_lowcase__, __set_values_lowcase__)
lowcase = property(__get_values_lowcase__, __set_values_lowcase__)
#<pycode(py_nalt)>
SWI_SPARSE = 0x1
"""sparse switch ( value table present ) otherwise lowcase present"""
SWI_V32 = 0x2
"""32-bit values in table"""
SWI_J32 = 0x4
"""32-bit jump offsets"""
SWI_VSPLIT = 0x8
"""value table is split (only for 32-bit values)"""
SWI_DEFAULT = 0x10
"""default case is present"""
SWI_END_IN_TBL = 0x20
"""switchend in table (default entry)"""
SWI_JMP_INV = 0x40
"""jumptable is inversed (last entry is for first entry in values table)"""
SWI_SHIFT_MASK = 0x180
"""use formula (element*shift + elbase) to find jump targets"""
SWI_ELBASE = 0x200
"""elbase is present (if not and shift!=0, endof(jumpea) is used)"""
SWI_JSIZE = 0x400
"""jump offset expansion bit"""
SWI_VSIZE = 0x800
"""value table element size expansion bit"""
SWI_SEPARATE = 0x1000
"""do not create an array of individual dwords"""
SWI_SIGNED = 0x2000
"""jump table entries are signed"""
SWI_CUSTOM = 0x4000
"""custom jump table - ph.create_switch_xrefs will be called to create code xrefs for the table. it must return 2. custom jump table must be created by the module"""
SWI_EXTENDED = 0x8000
"""this is switch_info_ex_t"""
SWI2_INDIRECT = 0x0001
"""value table elements are used as indexes into the jump table"""
SWI2_SUBTRACT = 0x0002
"""table values are subtracted from the elbase instead of being addded"""
# --------------------------------------------------------------------------
class switch_info_ex_t(py_clinked_object_t):
def __init__(self, lnk = None):
py_clinked_object_t.__init__(self, lnk)
def _create_clink(self):
return _idaapi.switch_info_ex_t_create()
def _del_clink(self, lnk):
return _idaapi.switch_info_ex_t_destroy(lnk)
def assign(self, other):
return _idaapi.switch_info_ex_t_assign(self, other)
def is_indirect(self):
return (self.flags & SWI_EXTENDED) != 0 and (self.flags2 & SWI2_INDIRECT) != 0
def is_subtract(self):
return (self.flags & SWI_EXTENDED) != 0 and (self.flags2 & SWI2_SUBTRACT) != 0
def get_jtable_size(self):
return self.jcases if self.is_indirect() else self.ncases
def get_lowcase(self):
return self.ind_lowcase if self.is_indirect() else self.lowcase
def set_expr(self, r, dt):
self.regnum = r
self.regdtyp = dt
def get_shift(self):
return (self.flags & SWI_SHIFT_MASK) >> 7
def set_shift(self, shift):
self.flags &= ~SWI_SHIFT_MASK
self.flags |= ((shift & 3) << 7)
def get_jtable_element_size(self):
code = self.flags & (SWI_J32|SWI_JSIZE)
if code == 0: return 2
elif code == SWI_J32: return 4
elif code == SWI_JSIZE: return 1
else: return 8
def set_jtable_element_size(self, size):
self.flags &= ~(SWI_J32|SWI_JSIZE)
if size == 4: self.flags |= SWI_J32
elif size == 1: self.flags |= SWI_JSIZE
elif size == 8: self.flags |= SWI_J32|SWI_JSIZE
elif size != 2: return False
return True
def get_vtable_element_size(self):
code = self.flags & (SWI_V32|SWI_VSIZE)
if code == 0: return 2
elif code == SWI_V32: return 4
elif code == SWI_VSIZE: return 1
return 8
def set_vtable_element_size(self, size):
self.flags &= ~SWI_V32|SWI_VSIZE
if size == 4: self.flags |= SWI_V32
elif size == 1: self.flags |= SWI_VSIZE
elif size == 8: self.flags |= SWI_V32|SWI_VSIZE
elif size != 2: return False
return True
#
# Autogenerated
#
def __get_regdtyp__(self):
return _idaapi.switch_info_ex_t_get_regdtyp(self)
def __set_regdtyp__(self, v):
_idaapi.switch_info_ex_t_set_regdtyp(self, v)
def __get_flags2__(self):
return _idaapi.switch_info_ex_t_get_flags2(self)
def __set_flags2__(self, v):
_idaapi.switch_info_ex_t_set_flags2(self, v)
def __get_jcases__(self):
return _idaapi.switch_info_ex_t_get_jcases(self)
def __set_jcases__(self, v):
_idaapi.switch_info_ex_t_set_jcases(self, v)
def __get_regnum__(self):
return _idaapi.switch_info_ex_t_get_regnum(self)
def __set_regnum__(self, v):
_idaapi.switch_info_ex_t_set_regnum(self, v)
def __get_flags__(self):
return _idaapi.switch_info_ex_t_get_flags(self)
def __set_flags__(self, v):
_idaapi.switch_info_ex_t_set_flags(self, v)
def __get_ncases__(self):
return _idaapi.switch_info_ex_t_get_ncases(self)
def __set_ncases__(self, v):
_idaapi.switch_info_ex_t_set_ncases(self, v)
def __get_defjump__(self):
return _idaapi.switch_info_ex_t_get_defjump(self)
def __set_defjump__(self, v):
_idaapi.switch_info_ex_t_set_defjump(self, v)
def __get_jumps__(self):
return _idaapi.switch_info_ex_t_get_jumps(self)
def __set_jumps__(self, v):
_idaapi.switch_info_ex_t_set_jumps(self, v)
def __get_elbase__(self):
return _idaapi.switch_info_ex_t_get_elbase(self)
def __set_elbase__(self, v):
_idaapi.switch_info_ex_t_set_elbase(self, v)
def __get_startea__(self):
return _idaapi.switch_info_ex_t_get_startea(self)
def __set_startea__(self, v):
_idaapi.switch_info_ex_t_set_startea(self, v)
def __get_custom__(self):
return _idaapi.switch_info_ex_t_get_custom(self)
def __set_custom__(self, v):
_idaapi.switch_info_ex_t_set_custom(self, v)
def __get_ind_lowcase__(self):
return _idaapi.switch_info_ex_t_get_ind_lowcase(self)
def __set_ind_lowcase__(self, v):
_idaapi.switch_info_ex_t_set_ind_lowcase(self, v)
def __get_values_lowcase__(self):
return _idaapi.switch_info_ex_t_get_values_lowcase(self)
def __set_values_lowcase__(self, v):
_idaapi.switch_info_ex_t_set_values_lowcase(self, v)
regdtyp = property(__get_regdtyp__, __set_regdtyp__)
"""size of the switch expression register as dtyp"""
flags2 = property(__get_flags2__, __set_flags2__)
jcases = property(__get_jcases__, __set_jcases__)
"""number of entries in the jump table (SWI2_INDIRECT)"""
regnum = property(__get_regnum__, __set_regnum__)
"""the switch expression as a register number"""
flags = property(__get_flags__, __set_flags__)
"""the switch expression as a register number"""
ncases = property(__get_ncases__, __set_ncases__)
"""number of cases (excluding default)"""
defjump = property(__get_defjump__, __set_defjump__)
"""default jump address"""
jumps = property(__get_jumps__, __set_jumps__)
"""jump table address"""
elbase = property(__get_elbase__, __set_elbase__)
"""element base"""
startea = property(__get_startea__, __set_startea__)
"""start of switch idiom"""
custom = property(__get_custom__, __set_custom__)
"""information for custom tables (filled and used by modules)"""
ind_lowcase = property(__get_ind_lowcase__, __set_ind_lowcase__)
values = property(__get_values_lowcase__, __set_values_lowcase__)
lowcase = property(__get_values_lowcase__, __set_values_lowcase__)
#</pycode(py_nalt)>

View File

@@ -1,26 +1,38 @@
//------------------------------------------------------------------------
//<inline(py_name)>
//------------------------------------------------------------------------
PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
{
// Get debug names
ea_name_vec_t names;
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_BEGIN_ALLOW_THREADS;
get_debug_names(ea1, ea2, names);
Py_END_ALLOW_THREADS;
PyObject *dict = Py_BuildValue("{}");
if (dict != NULL)
{
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
{
PyDict_SetItem(dict,
Py_BuildValue(PY_FMT64, it->ea),
PyString_FromString(it->name.c_str()));
}
}
return dict;
}
//------------------------------------------------------------------------
//</inline(py_name)>
//------------------------------------------------------------------------
//-------------------------------------------------------------------------
//<code(py_name)>
//</code(py_name)>
//------------------------------------------------------------------------
//<inline(py_name)>
//------------------------------------------------------------------------
PyObject *py_get_debug_names(ea_t ea1, ea_t ea2)
{
// Get debug names
ea_name_vec_t names;
PYW_GIL_CHECK_LOCKED_SCOPE();
Py_BEGIN_ALLOW_THREADS;
get_debug_names(ea1, ea2, names);
Py_END_ALLOW_THREADS;
PyObject *dict = Py_BuildValue("{}");
if (dict != NULL)
{
for (ea_name_vec_t::iterator it=names.begin();it!=names.end();++it)
{
PyDict_SetItem(dict,
Py_BuildValue(PY_FMT64, it->ea),
PyString_FromString(it->name.c_str()));
}
}
return dict;
}
//-------------------------------------------------------------------------
inline qstring py_get_ea_name(ea_t ea, int gtn_flags=0)
{
qstring out;
get_ea_name(&out, ea, gtn_flags);
return out;
}
//------------------------------------------------------------------------
//</inline(py_name)>
//------------------------------------------------------------------------

View File

@@ -1,52 +1,54 @@
import bisect
#<pycode(py_name)>
class NearestName:
"""
Utility class to help find the nearest name in a given ea/name dictionary
"""
def __init__(self, ea_names):
self.update(ea_names)
def update(self, ea_names):
"""Updates the ea/names map"""
self._names = ea_names
self._addrs = ea_names.keys()
self._addrs.sort()
def find(self, ea):
"""
Returns a tupple (ea, name, pos) that is the nearest to the passed ea
If no name is matched then None is returned
"""
pos = bisect.bisect_left(self._addrs, ea)
# no match
if pos >= len(self._addrs):
return None
# exact match?
if self._addrs[pos] != ea:
pos -= 1 # go to previous element
if pos < 0:
return None
return self[pos]
def _get_item(self, index):
ea = self._addrs[index]
return (ea, self._names[ea], index)
def __iter__(self):
return (self._get_item(index) for index in xrange(0, len(self._addrs)))
def __getitem__(self, index):
"""Returns the tupple (ea, name, index)"""
if index > len(self._addrs):
raise StopIteration
return self._get_item(index)
#</pycode(py_name)>
import bisect
#<pycode(py_name)>
class NearestName:
"""
Utility class to help find the nearest name in a given ea/name dictionary
"""
def __init__(self, ea_names):
self.update(ea_names)
def update(self, ea_names):
"""Updates the ea/names map"""
self._names = ea_names
self._addrs = ea_names.keys()
self._addrs.sort()
def find(self, ea):
"""
Returns a tupple (ea, name, pos) that is the nearest to the passed ea
If no name is matched then None is returned
"""
pos = bisect.bisect_left(self._addrs, ea)
# no match
if pos >= len(self._addrs):
return None
# exact match?
if self._addrs[pos] != ea:
pos -= 1 # go to previous element
if pos < 0:
return None
return self[pos]
def _get_item(self, index):
ea = self._addrs[index]
return (ea, self._names[ea], index)
def __iter__(self):
return (self._get_item(index) for index in xrange(0, len(self._addrs)))
def __getitem__(self, index):
"""Returns the tupple (ea, name, index)"""
if index > len(self._addrs):
raise StopIteration
return self._get_item(index)
extract_name = extract_name2
#</pycode(py_name)>

View File

@@ -1,310 +1,310 @@
#ifndef __PYWRAPS_NOTIFY_WHEN__
#define __PYWRAPS_NOTIFY_WHEN__
//------------------------------------------------------------------------
//<code(py_idaapi)>
//------------------------------------------------------------------------
//------------------------------------------------------------------------
class pywraps_notify_when_t
{
ref_vec_t table[NW_EVENTSCNT];
qstring err;
bool in_notify;
struct notify_when_args_t
{
int when;
PyObject *py_callable;
};
typedef qvector<notify_when_args_t> notify_when_args_vec_t;
notify_when_args_vec_t delayed_notify_when_list;
//------------------------------------------------------------------------
static int idaapi idp_callback(void *ud, int event_id, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
pywraps_notify_when_t *_this = (pywraps_notify_when_t *)ud;
switch ( event_id )
{
case processor_t::newfile:
case processor_t::oldfile:
{
int old = event_id == processor_t::oldfile ? 1 : 0;
char *dbname = va_arg(va, char *);
_this->notify(NW_OPENIDB_SLOT, old);
}
break;
case processor_t::closebase:
_this->notify(NW_CLOSEIDB_SLOT);
break;
}
// event not processed, let other plugins or the processor module handle it
return 0;
}
//------------------------------------------------------------------------
bool unnotify_when(int when, PyObject *py_callable)
{
int cnt = 0;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
// convert index to flag and see
if ( ((1 << slot) & when) != 0 )
{
unregister_callback(slot, py_callable);
++cnt;
}
}
return cnt > 0;
}
//------------------------------------------------------------------------
void register_callback(int slot, PyObject *py_callable)
{
borref_t callable_ref(py_callable);
ref_vec_t &tbl = table[slot];
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
// Already added
if ( it != it_end )
return;
// Insert the element
tbl.push_back(callable_ref);
}
//------------------------------------------------------------------------
void unregister_callback(int slot, PyObject *py_callable)
{
borref_t callable_ref(py_callable);
ref_vec_t &tbl = table[slot];
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
// Not found?
if ( it == it_end )
return;
// Delete the element
tbl.erase(it);
}
public:
//------------------------------------------------------------------------
bool init()
{
return hook_to_notification_point(HT_IDP, idp_callback, this);
}
//------------------------------------------------------------------------
bool deinit()
{
// Uninstall all objects
ref_vec_t::iterator it, it_end;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
for ( it = table[slot].begin(), it_end = table[slot].end(); it!=it_end; ++it )
unregister_callback(slot, it->o);
}
// ...and remove the notification
return unhook_from_notification_point(HT_IDP, idp_callback, this);
}
//------------------------------------------------------------------------
bool notify_when(int when, PyObject *py_callable)
{
// While in notify() do not allow insertion or deletion to happen on the spot
// Instead we will queue them so that notify() will carry the action when it finishes
// dispatching the notification handlers
if ( in_notify )
{
notify_when_args_t &args = delayed_notify_when_list.push_back();
args.when = when;
args.py_callable = py_callable;
return true;
}
// Uninstalling the notification?
if ( (when & NW_REMOVE) != 0 )
return unnotify_when(when & ~NW_REMOVE, py_callable);
int cnt = 0;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
// is this flag set?
if ( ((1 << slot) & when) != 0 )
{
register_callback(slot, py_callable);
++cnt;
}
}
return cnt > 0;
}
//------------------------------------------------------------------------
bool notify(int slot, ...)
{
va_list va;
va_start(va, slot);
bool ok = notify_va(slot, va);
va_end(va);
return ok;
}
//------------------------------------------------------------------------
bool notify_va(int slot, va_list va)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
// Sanity bounds check!
if ( slot < 0 || slot >= NW_EVENTSCNT )
return false;
bool ok = true;
in_notify = true;
int old = slot == NW_OPENIDB_SLOT ? va_arg(va, int) : 0;
{
for (ref_vec_t::iterator it = table[slot].begin(), it_end = table[slot].end();
it != it_end;
++it)
{
// Form the notification code
newref_t py_code(PyInt_FromLong(1 << slot));
ref_t py_result;
switch ( slot )
{
case NW_CLOSEIDB_SLOT:
case NW_INITIDA_SLOT:
case NW_TERMIDA_SLOT:
{
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, NULL));
break;
}
case NW_OPENIDB_SLOT:
{
newref_t py_old(PyInt_FromLong(old));
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, py_old.o, NULL));
}
break;
}
if ( PyW_GetError(&err) || py_result == NULL )
{
PyErr_Clear();
warning("notify_when(): Error occured while notifying object.\n%s", err.c_str());
ok = false;
}
}
}
in_notify = false;
// Process any delayed notify_when() calls that
if ( !delayed_notify_when_list.empty() )
{
for (notify_when_args_vec_t::iterator it = delayed_notify_when_list.begin(), it_end=delayed_notify_when_list.end();
it != it_end;
++it)
{
notify_when(it->when, it->py_callable);
}
delayed_notify_when_list.qclear();
}
return ok;
}
//------------------------------------------------------------------------
pywraps_notify_when_t()
{
in_notify = false;
}
};
static pywraps_notify_when_t *g_nw = NULL;
//------------------------------------------------------------------------
// Initializes the notify_when mechanism
// (Normally called by IDAPython plugin.init())
bool pywraps_nw_init()
{
if ( g_nw != NULL )
return true;
g_nw = new pywraps_notify_when_t();
if ( g_nw->init() )
return true;
// Things went bad, undo!
delete g_nw;
g_nw = NULL;
return false;
}
//------------------------------------------------------------------------
bool pywraps_nw_notify(int slot, ...)
{
if ( g_nw == NULL )
return false;
// Appears to be called from 'driver_notifywhen.cpp', which
// itself is called from possibly non-python code.
// I.e., we must acquire the GIL.
PYW_GIL_GET;
va_list va;
va_start(va, slot);
bool ok = g_nw->notify_va(slot, va);
va_end(va);
return ok;
}
//------------------------------------------------------------------------
// Deinitializes the notify_when mechanism
bool pywraps_nw_term()
{
if ( g_nw == NULL )
return true;
// If could not deinitialize then return w/o stopping nw
if ( !g_nw->deinit() )
return false;
// Cleanup
delete g_nw;
g_nw = NULL;
return true;
}
//</code(py_idaapi)>
//------------------------------------------------------------------------
//<inline(py_idaapi)>
//------------------------------------------------------------------------
/*
#<pydoc>
def notify_when(when, callback):
"""
Register a callback that will be called when an event happens.
@param when: one of NW_XXXX constants
@param callback: This callback prototype varies depending on the 'when' parameter:
The general callback format:
def notify_when_callback(nw_code)
In the case of NW_OPENIDB:
def notify_when_callback(nw_code, is_old_database)
@return: Boolean
"""
pass
#</pydoc>
*/
static bool notify_when(int when, PyObject *py_callable)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( g_nw == NULL || !PyCallable_Check(py_callable) )
return false;
return g_nw->notify_when(when, py_callable);
}
//</inline(py_idaapi)>
//------------------------------------------------------------------------
#endif
#ifndef __PYWRAPS_NOTIFY_WHEN__
#define __PYWRAPS_NOTIFY_WHEN__
//------------------------------------------------------------------------
//<code(py_idaapi)>
//------------------------------------------------------------------------
//------------------------------------------------------------------------
class pywraps_notify_when_t
{
ref_vec_t table[NW_EVENTSCNT];
qstring err;
bool in_notify;
struct notify_when_args_t
{
int when;
PyObject *py_callable;
};
typedef qvector<notify_when_args_t> notify_when_args_vec_t;
notify_when_args_vec_t delayed_notify_when_list;
//------------------------------------------------------------------------
static int idaapi idp_callback(void *ud, int event_id, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
pywraps_notify_when_t *_this = (pywraps_notify_when_t *)ud;
switch ( event_id )
{
case processor_t::newfile:
case processor_t::oldfile:
{
int old = event_id == processor_t::oldfile ? 1 : 0;
char *dbname = va_arg(va, char *);
_this->notify(NW_OPENIDB_SLOT, old);
}
break;
case processor_t::closebase:
_this->notify(NW_CLOSEIDB_SLOT);
break;
}
// event not processed, let other plugins or the processor module handle it
return 0;
}
//------------------------------------------------------------------------
bool unnotify_when(int when, PyObject *py_callable)
{
int cnt = 0;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
// convert index to flag and see
if ( ((1 << slot) & when) != 0 )
{
unregister_callback(slot, py_callable);
++cnt;
}
}
return cnt > 0;
}
//------------------------------------------------------------------------
void register_callback(int slot, PyObject *py_callable)
{
borref_t callable_ref(py_callable);
ref_vec_t &tbl = table[slot];
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
// Already added
if ( it != it_end )
return;
// Insert the element
tbl.push_back(callable_ref);
}
//------------------------------------------------------------------------
void unregister_callback(int slot, PyObject *py_callable)
{
borref_t callable_ref(py_callable);
ref_vec_t &tbl = table[slot];
ref_vec_t::iterator it_end = tbl.end(), it = std::find(tbl.begin(), it_end, callable_ref);
// Not found?
if ( it == it_end )
return;
// Delete the element
tbl.erase(it);
}
public:
//------------------------------------------------------------------------
bool init()
{
return hook_to_notification_point(HT_IDP, idp_callback, this);
}
//------------------------------------------------------------------------
bool deinit()
{
// Uninstall all objects
ref_vec_t::iterator it, it_end;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
for ( it = table[slot].begin(), it_end = table[slot].end(); it!=it_end; ++it )
unregister_callback(slot, it->o);
}
// ...and remove the notification
return unhook_from_notification_point(HT_IDP, idp_callback, this);
}
//------------------------------------------------------------------------
bool notify_when(int when, PyObject *py_callable)
{
// While in notify() do not allow insertion or deletion to happen on the spot
// Instead we will queue them so that notify() will carry the action when it finishes
// dispatching the notification handlers
if ( in_notify )
{
notify_when_args_t &args = delayed_notify_when_list.push_back();
args.when = when;
args.py_callable = py_callable;
return true;
}
// Uninstalling the notification?
if ( (when & NW_REMOVE) != 0 )
return unnotify_when(when & ~NW_REMOVE, py_callable);
int cnt = 0;
for ( int slot=0; slot<NW_EVENTSCNT; slot++ )
{
// is this flag set?
if ( ((1 << slot) & when) != 0 )
{
register_callback(slot, py_callable);
++cnt;
}
}
return cnt > 0;
}
//------------------------------------------------------------------------
bool notify(int slot, ...)
{
va_list va;
va_start(va, slot);
bool ok = notify_va(slot, va);
va_end(va);
return ok;
}
//------------------------------------------------------------------------
bool notify_va(int slot, va_list va)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
// Sanity bounds check!
if ( slot < 0 || slot >= NW_EVENTSCNT )
return false;
bool ok = true;
in_notify = true;
int old = slot == NW_OPENIDB_SLOT ? va_arg(va, int) : 0;
{
for (ref_vec_t::iterator it = table[slot].begin(), it_end = table[slot].end();
it != it_end;
++it)
{
// Form the notification code
newref_t py_code(PyInt_FromLong(1 << slot));
ref_t py_result;
switch ( slot )
{
case NW_CLOSEIDB_SLOT:
case NW_INITIDA_SLOT:
case NW_TERMIDA_SLOT:
{
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, NULL));
break;
}
case NW_OPENIDB_SLOT:
{
newref_t py_old(PyInt_FromLong(old));
py_result = newref_t(PyObject_CallFunctionObjArgs(it->o, py_code.o, py_old.o, NULL));
}
break;
}
if ( PyW_GetError(&err) || py_result == NULL )
{
PyErr_Clear();
warning("notify_when(): Error occured while notifying object.\n%s", err.c_str());
ok = false;
}
}
}
in_notify = false;
// Process any delayed notify_when() calls that
if ( !delayed_notify_when_list.empty() )
{
for (notify_when_args_vec_t::iterator it = delayed_notify_when_list.begin(), it_end=delayed_notify_when_list.end();
it != it_end;
++it)
{
notify_when(it->when, it->py_callable);
}
delayed_notify_when_list.qclear();
}
return ok;
}
//------------------------------------------------------------------------
pywraps_notify_when_t()
{
in_notify = false;
}
};
static pywraps_notify_when_t *g_nw = NULL;
//------------------------------------------------------------------------
// Initializes the notify_when mechanism
// (Normally called by IDAPython plugin.init())
bool pywraps_nw_init()
{
if ( g_nw != NULL )
return true;
g_nw = new pywraps_notify_when_t();
if ( g_nw->init() )
return true;
// Things went bad, undo!
delete g_nw;
g_nw = NULL;
return false;
}
//------------------------------------------------------------------------
bool pywraps_nw_notify(int slot, ...)
{
if ( g_nw == NULL )
return false;
// Appears to be called from 'driver_notifywhen.cpp', which
// itself is called from possibly non-python code.
// I.e., we must acquire the GIL.
PYW_GIL_GET;
va_list va;
va_start(va, slot);
bool ok = g_nw->notify_va(slot, va);
va_end(va);
return ok;
}
//------------------------------------------------------------------------
// Deinitializes the notify_when mechanism
bool pywraps_nw_term()
{
if ( g_nw == NULL )
return true;
// If could not deinitialize then return w/o stopping nw
if ( !g_nw->deinit() )
return false;
// Cleanup
delete g_nw;
g_nw = NULL;
return true;
}
//</code(py_idaapi)>
//------------------------------------------------------------------------
//<inline(py_idaapi)>
//------------------------------------------------------------------------
/*
#<pydoc>
def notify_when(when, callback):
"""
Register a callback that will be called when an event happens.
@param when: one of NW_XXXX constants
@param callback: This callback prototype varies depending on the 'when' parameter:
The general callback format:
def notify_when_callback(nw_code)
In the case of NW_OPENIDB:
def notify_when_callback(nw_code, is_old_database)
@return: Boolean
"""
pass
#</pydoc>
*/
static bool notify_when(int when, PyObject *py_callable)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( g_nw == NULL || !PyCallable_Check(py_callable) )
return false;
return g_nw->notify_when(when, py_callable);
}
//</inline(py_idaapi)>
//------------------------------------------------------------------------
#endif

View File

@@ -1,63 +1,63 @@
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
import struct
if pywraps_there:
_idaapi.notify_when = pywraps.notify_when
# -----------------------------------------------------------------------
#<pycode(py_idaapi)>
# The general callback format of notify_when() is:
# def notify_when_callback(nw_code)
# In the case of NW_OPENIDB, the callback is:
# def notify_when_callback(nw_code, is_old_database)
NW_OPENIDB = 0x0001
"""Notify when the database is opened. Its callback is of the form: def notify_when_callback(nw_code, is_old_database)"""
NW_CLOSEIDB = 0x0002
"""Notify when the database is closed. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_INITIDA = 0x0004
"""Notify when the IDA starts. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_TERMIDA = 0x0008
"""Notify when the IDA terminates. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_REMOVE = 0x0010
"""Use this flag with other flags to uninstall a notifywhen callback"""
#</pycode(py_idaapi)>
# -----------------------------------------------------------------------
def nw_openidb(code, old):
print "Open IDB, old=", old
def nw_closeidb(code):
print "Close IDB"
def nw_openclose(code, old = None):
if code == NW_CLOSEIDB:
print "openclose: Close IDB"
elif code == NW_OPENIDB:
print "openclose: Open IDB, old=", old
def nw_closeida(code):
import ctypes
user32 = ctypes.windll.user32
user32.MessageBoxA(0, "Close IDA", "Info", 0)
print "registering nw_openidb->", _idaapi.notify_when(NW_OPENIDB, nw_openidb)
print "registering nw_closeidb->", _idaapi.notify_when(NW_CLOSEIDB, nw_closeidb)
print "registering nw_openclose->", _idaapi.notify_when(NW_OPENIDB|NW_CLOSEIDB, nw_openclose)
print "registering nw_closeida->", _idaapi.notify_when(NW_TERMIDA, nw_closeida)
# -----------------------------------------------------------------------
# Standalone and testing code
import sys
try:
import pywraps
pywraps_there = True
print "Using pywraps"
except:
pywraps_there = False
print "Not using pywraps"
try:
import _idaapi
except:
print "Please try me from inside IDA"
sys.exit(0)
import struct
if pywraps_there:
_idaapi.notify_when = pywraps.notify_when
# -----------------------------------------------------------------------
#<pycode(py_idaapi)>
# The general callback format of notify_when() is:
# def notify_when_callback(nw_code)
# In the case of NW_OPENIDB, the callback is:
# def notify_when_callback(nw_code, is_old_database)
NW_OPENIDB = 0x0001
"""Notify when the database is opened. Its callback is of the form: def notify_when_callback(nw_code, is_old_database)"""
NW_CLOSEIDB = 0x0002
"""Notify when the database is closed. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_INITIDA = 0x0004
"""Notify when the IDA starts. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_TERMIDA = 0x0008
"""Notify when the IDA terminates. Its callback is of the form: def notify_when_callback(nw_code)"""
NW_REMOVE = 0x0010
"""Use this flag with other flags to uninstall a notifywhen callback"""
#</pycode(py_idaapi)>
# -----------------------------------------------------------------------
def nw_openidb(code, old):
print "Open IDB, old=", old
def nw_closeidb(code):
print "Close IDB"
def nw_openclose(code, old = None):
if code == NW_CLOSEIDB:
print "openclose: Close IDB"
elif code == NW_OPENIDB:
print "openclose: Open IDB, old=", old
def nw_closeida(code):
import ctypes
user32 = ctypes.windll.user32
user32.MessageBoxA(0, "Close IDA", "Info", 0)
print "registering nw_openidb->", _idaapi.notify_when(NW_OPENIDB, nw_openidb)
print "registering nw_closeidb->", _idaapi.notify_when(NW_CLOSEIDB, nw_closeidb)
print "registering nw_openclose->", _idaapi.notify_when(NW_OPENIDB|NW_CLOSEIDB, nw_openclose)
print "registering nw_closeida->", _idaapi.notify_when(NW_TERMIDA, nw_closeida)

View File

@@ -1,157 +1,157 @@
#ifndef __PY_PLGFORM__
#define __PY_PLGFORM__
//<code(py_plgform)>
//---------------------------------------------------------------------------
class plgform_t
{
private:
ref_t py_obj;
TForm *form;
static int idaapi s_callback(void *ud, int notification_code, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
plgform_t *_this = (plgform_t *)ud;
if ( notification_code == ui_tform_visible )
{
TForm *form = va_arg(va, TForm *);
if ( form == _this->form )
{
// Qt: QWidget*
// G: HWND
// We wrap and pass as a CObject in the hope that a Python UI framework
// can unwrap a CObject and get the hwnd/widget back
newref_t py_result(
PyObject_CallMethod(
_this->py_obj.o,
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(form, NULL)));
PyW_ShowCbErr(S_ON_CREATE);
}
}
else if ( notification_code == ui_tform_invisible )
{
TForm *form = va_arg(va, TForm *);
if ( form == _this->form )
{
{
newref_t py_result(
PyObject_CallMethod(
_this->py_obj.o,
(char *)S_ON_CLOSE, "O",
PyCObject_FromVoidPtr(form, NULL)));
PyW_ShowCbErr(S_ON_CLOSE);
}
_this->unhook();
}
}
return 0;
}
void unhook()
{
unhook_from_notification_point(HT_UI, s_callback, this);
form = NULL;
// Call DECREF at last, since it may trigger __del__
PYW_GIL_CHECK_LOCKED_SCOPE();
py_obj = ref_t();
}
public:
plgform_t(): form(NULL)
{
}
bool show(
PyObject *obj,
const char *caption,
int options)
{
// Already displayed?
TForm *f = find_tform(caption);
if ( f != NULL )
{
// Our form?
if ( f == form )
{
// Switch to it
switchto_tform(form, true);
return true;
}
// Fail to create
return false;
}
// Create a form
form = create_tform(caption, NULL);
if ( form == NULL )
return false;
if ( !hook_to_notification_point(HT_UI, s_callback, this) )
{
form = NULL;
return false;
}
py_obj = borref_t(obj);
if ( is_idaq() )
options |= FORM_QWIDGET;
this->form = form;
open_tform(form, options);
return true;
}
void close(int options = 0)
{
if ( form != NULL )
close_tform(form, options);
}
static PyObject *create()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
}
static void destroy(void *obj)
{
delete (plgform_t *)obj;
}
};
//</code(py_plgform)>
//<inline(py_plgform)>
//---------------------------------------------------------------------------
#define DECL_PLGFORM PYW_GIL_CHECK_LOCKED_SCOPE(); plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link);
static PyObject *plgform_new()
{
return plgform_t::create();
}
static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
{
DECL_PLGFORM;
return plgform->show(py_obj, caption, options);
}
static void plgform_close(
PyObject *py_link,
int options)
{
DECL_PLGFORM;
plgform->close(options);
}
#undef DECL_PLGFORM
//</inline(py_plgform)>
#endif // __PY_PLGFORM__
#ifndef __PY_PLGFORM__
#define __PY_PLGFORM__
//<code(py_plgform)>
//---------------------------------------------------------------------------
class plgform_t
{
private:
ref_t py_obj;
TForm *form;
static int idaapi s_callback(void *ud, int notification_code, va_list va)
{
// This hook gets called from the kernel. Ensure we hold the GIL.
PYW_GIL_GET;
plgform_t *_this = (plgform_t *)ud;
if ( notification_code == ui_tform_visible )
{
TForm *form = va_arg(va, TForm *);
if ( form == _this->form )
{
// Qt: QWidget*
// G: HWND
// We wrap and pass as a CObject in the hope that a Python UI framework
// can unwrap a CObject and get the hwnd/widget back
newref_t py_result(
PyObject_CallMethod(
_this->py_obj.o,
(char *)S_ON_CREATE, "O",
PyCObject_FromVoidPtr(form, NULL)));
PyW_ShowCbErr(S_ON_CREATE);
}
}
else if ( notification_code == ui_tform_invisible )
{
TForm *form = va_arg(va, TForm *);
if ( form == _this->form )
{
{
newref_t py_result(
PyObject_CallMethod(
_this->py_obj.o,
(char *)S_ON_CLOSE, "O",
PyCObject_FromVoidPtr(form, NULL)));
PyW_ShowCbErr(S_ON_CLOSE);
}
_this->unhook();
}
}
return 0;
}
void unhook()
{
unhook_from_notification_point(HT_UI, s_callback, this);
form = NULL;
// Call DECREF at last, since it may trigger __del__
PYW_GIL_CHECK_LOCKED_SCOPE();
py_obj = ref_t();
}
public:
plgform_t(): form(NULL)
{
}
bool show(
PyObject *obj,
const char *caption,
int options)
{
// Already displayed?
TForm *f = find_tform(caption);
if ( f != NULL )
{
// Our form?
if ( f == form )
{
// Switch to it
switchto_tform(form, true);
return true;
}
// Fail to create
return false;
}
// Create a form
form = create_tform(caption, NULL);
if ( form == NULL )
return false;
if ( !hook_to_notification_point(HT_UI, s_callback, this) )
{
form = NULL;
return false;
}
py_obj = borref_t(obj);
if ( is_idaq() )
options |= FORM_QWIDGET;
this->form = form;
open_tform(form, options);
return true;
}
void close(int options = 0)
{
if ( form != NULL )
close_tform(form, options);
}
static PyObject *create()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyCObject_FromVoidPtr(new plgform_t(), destroy);
}
static void destroy(void *obj)
{
delete (plgform_t *)obj;
}
};
//</code(py_plgform)>
//<inline(py_plgform)>
//---------------------------------------------------------------------------
#define DECL_PLGFORM PYW_GIL_CHECK_LOCKED_SCOPE(); plgform_t *plgform = (plgform_t *) PyCObject_AsVoidPtr(py_link);
static PyObject *plgform_new()
{
return plgform_t::create();
}
static bool plgform_show(
PyObject *py_link,
PyObject *py_obj,
const char *caption,
int options = FORM_TAB|FORM_MENU|FORM_RESTORE)
{
DECL_PLGFORM;
return plgform->show(py_obj, caption, options);
}
static void plgform_close(
PyObject *py_link,
int options)
{
DECL_PLGFORM;
plgform->close(options);
}
#undef DECL_PLGFORM
//</inline(py_plgform)>
#endif // __PY_PLGFORM__

View File

@@ -1,121 +1,121 @@
import _idaapi
#<pycode(py_plgform)>
class PluginForm(object):
"""
PluginForm class.
This form can be used to host additional controls. Please check the PyQt example.
"""
FORM_MDI = 0x01
"""start by default as MDI (obsolete)"""
FORM_TAB = 0x02
"""attached by default to a tab"""
FORM_RESTORE = 0x04
"""restore state from desktop config"""
FORM_ONTOP = 0x08
"""form should be "ontop"""
FORM_MENU = 0x10
"""form must be listed in the windows menu (automatically set for all plugins)"""
FORM_CENTERED = 0x20
"""form will be centered on the screen"""
FORM_PERSIST = 0x40
"""form will persist until explicitly closed with Close()"""
def __init__(self):
"""
"""
self.__clink__ = _idaapi.plgform_new()
def Show(self, caption, options = 0):
"""
Creates the form if not was not created or brings to front if it was already created
@param caption: The form caption
@param options: One of PluginForm.FORM_ constants
"""
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
return _idaapi.plgform_show(self.__clink__, self, caption, options)
@staticmethod
def FormToPyQtWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TForm* to a QWidget to be used by PyQt
@param ctx: Context. Reference to a module that already imported SIP and QtGui modules
"""
return ctx.sip.wrapinstance(ctx.sip.voidptr(form).__int__(), ctx.QtGui.QWidget)
@staticmethod
def FormToPySideWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TForm* to a QWidget to be used by PySide
@param ctx: Context. Reference to a module that already imported QtGui module
"""
if form is None:
return None
if type(form).__name__ == "SwigPyObject":
# Since 'form' is a SwigPyObject, we first need to convert it to a PyCObject.
# However, there's no easy way of doing it, so we'll use a rather brutal approach:
# converting the SwigPyObject to a 'long' (will go through 'SwigPyObject_long',
# that will return the pointer's value as a long), and then convert that value
# back to a pointer into a PyCObject.
ptr_l = long(form)
from ctypes import pythonapi, c_void_p, py_object
pythonapi.PyCObject_FromVoidPtr.restype = py_object
pythonapi.PyCObject_AsVoidPtr.argtypes = [c_void_p, c_void_p]
form = pythonapi.PyCObject_FromVoidPtr(ptr_l, 0)
return ctx.QtGui.QWidget.FromCObject(form)
def OnCreate(self, form):
"""
This event is called when the plugin form is created.
The programmer should populate the form when this event is triggered.
@return: None
"""
pass
def OnClose(self, form):
"""
Called when the plugin form is closed
@return: None
"""
pass
def Close(self, options):
"""
Closes the form.
@param options: Close options (FORM_SAVE, FORM_NO_CONTEXT, ...)
@return: None
"""
return _idaapi.plgform_close(self.__clink__, options)
FORM_SAVE = 0x1
"""Save state in desktop config"""
FORM_NO_CONTEXT = 0x2
"""Don't change the current context (useful for toolbars)"""
FORM_DONT_SAVE_SIZE = 0x4
"""Don't save size of the window"""
FORM_CLOSE_LATER = 0x8
"""This flag should be used when Close() is called from an event handler"""
#</pycode(py_plgform)>
plg = PluginForm()
plg.Show("This is it")
import _idaapi
#<pycode(py_plgform)>
class PluginForm(object):
"""
PluginForm class.
This form can be used to host additional controls. Please check the PyQt example.
"""
FORM_MDI = 0x01
"""start by default as MDI (obsolete)"""
FORM_TAB = 0x02
"""attached by default to a tab"""
FORM_RESTORE = 0x04
"""restore state from desktop config"""
FORM_ONTOP = 0x08
"""form should be "ontop"""
FORM_MENU = 0x10
"""form must be listed in the windows menu (automatically set for all plugins)"""
FORM_CENTERED = 0x20
"""form will be centered on the screen"""
FORM_PERSIST = 0x40
"""form will persist until explicitly closed with Close()"""
def __init__(self):
"""
"""
self.__clink__ = _idaapi.plgform_new()
def Show(self, caption, options = 0):
"""
Creates the form if not was not created or brings to front if it was already created
@param caption: The form caption
@param options: One of PluginForm.FORM_ constants
"""
options |= PluginForm.FORM_TAB|PluginForm.FORM_MENU|PluginForm.FORM_RESTORE
return _idaapi.plgform_show(self.__clink__, self, caption, options)
@staticmethod
def FormToPyQtWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TForm* to a QWidget to be used by PyQt
@param ctx: Context. Reference to a module that already imported SIP and QtGui modules
"""
return ctx.sip.wrapinstance(ctx.sip.voidptr(form).__int__(), ctx.QtGui.QWidget)
@staticmethod
def FormToPySideWidget(form, ctx = sys.modules['__main__']):
"""
Use this method to convert a TForm* to a QWidget to be used by PySide
@param ctx: Context. Reference to a module that already imported QtGui module
"""
if form is None:
return None
if type(form).__name__ == "SwigPyObject":
# Since 'form' is a SwigPyObject, we first need to convert it to a PyCObject.
# However, there's no easy way of doing it, so we'll use a rather brutal approach:
# converting the SwigPyObject to a 'long' (will go through 'SwigPyObject_long',
# that will return the pointer's value as a long), and then convert that value
# back to a pointer into a PyCObject.
ptr_l = long(form)
from ctypes import pythonapi, c_void_p, py_object
pythonapi.PyCObject_FromVoidPtr.restype = py_object
pythonapi.PyCObject_AsVoidPtr.argtypes = [c_void_p, c_void_p]
form = pythonapi.PyCObject_FromVoidPtr(ptr_l, 0)
return ctx.QtGui.QWidget.FromCObject(form)
def OnCreate(self, form):
"""
This event is called when the plugin form is created.
The programmer should populate the form when this event is triggered.
@return: None
"""
pass
def OnClose(self, form):
"""
Called when the plugin form is closed
@return: None
"""
pass
def Close(self, options):
"""
Closes the form.
@param options: Close options (FORM_SAVE, FORM_NO_CONTEXT, ...)
@return: None
"""
return _idaapi.plgform_close(self.__clink__, options)
FORM_SAVE = 0x1
"""Save state in desktop config"""
FORM_NO_CONTEXT = 0x2
"""Don't change the current context (useful for toolbars)"""
FORM_DONT_SAVE_SIZE = 0x4
"""Don't save size of the window"""
FORM_CLOSE_LATER = 0x8
"""This flag should be used when Close() is called from an event handler"""
#</pycode(py_plgform)>
plg = PluginForm()
plg.Show("This is it")

View File

@@ -1,407 +1,407 @@
#ifndef __PY_IDA_QFILE__
#define __PY_IDA_QFILE__
//<inline(py_qfile)>
/*
#<pydoc>
class qfile_t(pyidc_opaque_object_t):
"""A helper class to work with FILE related functions."""
def __init__(self):
pass
def close(self):
"""Closes the file"""
pass
def open(self, filename, mode):
"""Opens a file
@param filename: the file name
@param mode: The mode string, ala fopen() style
@return: Boolean
"""
pass
def set_linput(self, linput):
"""Links the current loader_input_t instance to a linput_t instance"""
pass
@staticmethod
def tmpfile():
"""A static method to construct an instance using a temporary file"""
pass
def seek(self, pos, whence = SEEK_SET):
"""Set input source position
@return: the new position (not 0 as fseek!)
"""
pass
def tell(self):
"""Returns the current position"""
pass
def gets(self, len):
"""Reads a line from the input file. Returns the read line or None"""
pass
def read(self, size):
"""Reads from the file. Returns the buffer or None"""
pass
def write(self, buf):
"""Writes to the file. Returns 0 or the number of bytes written"""
pass
def readbytes(self, size, big_endian):
"""Similar to read() but it respect the endianness"""
pass
def writebytes(self, size, big_endian):
"""Similar to write() but it respect the endianness"""
pass
def flush(self):
pass
def get_char(self):
"""Reads a single character from the file. Returns None if EOF or the read character"""
pass
def put_char(self):
"""Writes a single character to the file"""
pass
def opened(self):
"""Checks if the file is opened or not"""
pass
#</pydoc>
*/
class qfile_t
{
private:
FILE *fp;
bool own;
qstring fn;
//--------------------------------------------------------------------------
void assign(const qfile_t &rhs)
{
fn = rhs.fn;
fp = rhs.fp;
own = false;
}
//--------------------------------------------------------------------------
bool _from_fp(FILE *fp)
{
if ( fp == NULL )
return false;
own = false;
fn.sprnt("<FILE * %p>", fp);
this->fp = fp;
return true;
}
inline void _from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
_from_fp((FILE *)PyCObject_AsVoidPtr(pycobject));
}
public:
int __idc_cvt_id__;
//--------------------------------------------------------------------------
qfile_t(const qfile_t &rhs)
{
assign(rhs);
}
//--------------------------------------------------------------------------
qfile_t(PyObject *pycobject = NULL)
{
fp = NULL;
own = true;
fn.qclear();
__idc_cvt_id__ = PY_ICID_OPAQUE;
bool ok;
{
PYW_GIL_CHECK_LOCKED_SCOPE();
ok = pycobject != NULL && PyCObject_Check(pycobject);
}
if ( ok )
_from_cobject(pycobject);
}
//--------------------------------------------------------------------------
bool opened()
{
return fp != NULL;
}
//--------------------------------------------------------------------------
void close()
{
if ( fp == NULL )
return;
if ( own )
{
Py_BEGIN_ALLOW_THREADS;
qfclose(fp);
Py_END_ALLOW_THREADS;
}
fp = NULL;
own = true;
}
//--------------------------------------------------------------------------
~qfile_t()
{
close();
}
//--------------------------------------------------------------------------
bool open(const char *filename, const char *mode)
{
close();
Py_BEGIN_ALLOW_THREADS;
fp = qfopen(filename, mode);
Py_END_ALLOW_THREADS;
if ( fp == NULL )
return false;
// Save file name
fn = filename;
own = true;
return true;
}
//--------------------------------------------------------------------------
static qfile_t *from_fp(FILE *fp)
{
if ( fp == NULL )
return NULL;
qfile_t *qf = new qfile_t();
qf->own = false;
qf->fn.sprnt("<FILE * %p>", fp);
qf->fp = fp;
return qf;
}
//--------------------------------------------------------------------------
// This method can be used to pass a FILE* from C code
static qfile_t *from_cobject(PyObject *pycobject)
{
return PyCObject_Check(pycobject) ? from_fp((FILE *)PyCObject_AsVoidPtr(pycobject)) : NULL;
}
//--------------------------------------------------------------------------
static qfile_t *tmpfile()
{
FILE *fp;
Py_BEGIN_ALLOW_THREADS;
fp = qtmpfile();
Py_END_ALLOW_THREADS;
return from_fp(fp);
}
//--------------------------------------------------------------------------
FILE *get_fp()
{
return fp;
}
//--------------------------------------------------------------------------
int seek(int32 offset, int whence = SEEK_SET)
{
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfseek(fp, offset, whence);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 tell()
{
int32 rc;
Py_BEGIN_ALLOW_THREADS;
rc = qftell(fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *readbytes(int size, bool big_endian)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
int r;
Py_BEGIN_ALLOW_THREADS;
r = freadbytes(fp, buf, size, big_endian);
Py_END_ALLOW_THREADS;
if ( r != 0 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *read(int size)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
int r;
Py_BEGIN_ALLOW_THREADS;
r = qfread(fp, buf, size);
Py_END_ALLOW_THREADS;
if ( r <= 0 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *gets(int size)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
char *p;
Py_BEGIN_ALLOW_THREADS;
p = qfgets(buf, size, fp);
Py_END_ALLOW_THREADS;
if ( p == NULL )
{
free(buf);
break;
}
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
int writebytes(PyObject *py_buf, bool big_endian)
{
Py_ssize_t sz;
void *buf;
PYW_GIL_CHECK_LOCKED_SCOPE();
sz = PyString_GET_SIZE(py_buf);
buf = (void *)PyString_AS_STRING(py_buf);
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = fwritebytes(fp, buf, int(sz), big_endian);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int write(PyObject *py_buf)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyString_Check(py_buf) )
return 0;
// Just so that there is no risk that the buffer returned by
// 'PyString_AS_STRING' gets deallocated within the
// Py_BEGIN|END_ALLOW_THREADS section.
borref_t py_buf_ref(py_buf);
void *p = (void *)PyString_AS_STRING(py_buf);
Py_ssize_t sz = PyString_GET_SIZE(py_buf);
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfwrite(fp, p, sz);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int puts(const char *str)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfputs(str, fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 size()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int32 r;
Py_BEGIN_ALLOW_THREADS;
int pos = qfseek(fp, 0, SEEK_END);
r = qftell(fp);
qfseek(fp, pos, SEEK_SET);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
int flush()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qflush(fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *filename()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(fn.c_str());
}
//--------------------------------------------------------------------------
PyObject *get_char()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int ch;
Py_BEGIN_ALLOW_THREADS;
ch = qfgetc(fp);
Py_END_ALLOW_THREADS;
if ( ch == EOF )
Py_RETURN_NONE;
return Py_BuildValue("c", ch);
}
//--------------------------------------------------------------------------
int put_char(char chr)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfputc(chr, fp);
Py_END_ALLOW_THREADS;
return rc;
}
};
//</inline(py_qfile)>
#endif
#ifndef __PY_IDA_QFILE__
#define __PY_IDA_QFILE__
//<inline(py_qfile)>
/*
#<pydoc>
class qfile_t(pyidc_opaque_object_t):
"""A helper class to work with FILE related functions."""
def __init__(self):
pass
def close(self):
"""Closes the file"""
pass
def open(self, filename, mode):
"""Opens a file
@param filename: the file name
@param mode: The mode string, ala fopen() style
@return: Boolean
"""
pass
def set_linput(self, linput):
"""Links the current loader_input_t instance to a linput_t instance"""
pass
@staticmethod
def tmpfile():
"""A static method to construct an instance using a temporary file"""
pass
def seek(self, pos, whence = SEEK_SET):
"""Set input source position
@return: the new position (not 0 as fseek!)
"""
pass
def tell(self):
"""Returns the current position"""
pass
def gets(self, len):
"""Reads a line from the input file. Returns the read line or None"""
pass
def read(self, size):
"""Reads from the file. Returns the buffer or None"""
pass
def write(self, buf):
"""Writes to the file. Returns 0 or the number of bytes written"""
pass
def readbytes(self, size, big_endian):
"""Similar to read() but it respect the endianness"""
pass
def writebytes(self, size, big_endian):
"""Similar to write() but it respect the endianness"""
pass
def flush(self):
pass
def get_char(self):
"""Reads a single character from the file. Returns None if EOF or the read character"""
pass
def put_char(self):
"""Writes a single character to the file"""
pass
def opened(self):
"""Checks if the file is opened or not"""
pass
#</pydoc>
*/
class qfile_t
{
private:
FILE *fp;
bool own;
qstring fn;
//--------------------------------------------------------------------------
void assign(const qfile_t &rhs)
{
fn = rhs.fn;
fp = rhs.fp;
own = false;
}
//--------------------------------------------------------------------------
bool _from_fp(FILE *fp)
{
if ( fp == NULL )
return false;
own = false;
fn.sprnt("<FILE * %p>", fp);
this->fp = fp;
return true;
}
inline void _from_cobject(PyObject *pycobject)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
_from_fp((FILE *)PyCObject_AsVoidPtr(pycobject));
}
public:
int __idc_cvt_id__;
//--------------------------------------------------------------------------
qfile_t(const qfile_t &rhs)
{
assign(rhs);
}
//--------------------------------------------------------------------------
qfile_t(PyObject *pycobject = NULL)
{
fp = NULL;
own = true;
fn.qclear();
__idc_cvt_id__ = PY_ICID_OPAQUE;
bool ok;
{
PYW_GIL_CHECK_LOCKED_SCOPE();
ok = pycobject != NULL && PyCObject_Check(pycobject);
}
if ( ok )
_from_cobject(pycobject);
}
//--------------------------------------------------------------------------
bool opened()
{
return fp != NULL;
}
//--------------------------------------------------------------------------
void close()
{
if ( fp == NULL )
return;
if ( own )
{
Py_BEGIN_ALLOW_THREADS;
qfclose(fp);
Py_END_ALLOW_THREADS;
}
fp = NULL;
own = true;
}
//--------------------------------------------------------------------------
~qfile_t()
{
close();
}
//--------------------------------------------------------------------------
bool open(const char *filename, const char *mode)
{
close();
Py_BEGIN_ALLOW_THREADS;
fp = qfopen(filename, mode);
Py_END_ALLOW_THREADS;
if ( fp == NULL )
return false;
// Save file name
fn = filename;
own = true;
return true;
}
//--------------------------------------------------------------------------
static qfile_t *from_fp(FILE *fp)
{
if ( fp == NULL )
return NULL;
qfile_t *qf = new qfile_t();
qf->own = false;
qf->fn.sprnt("<FILE * %p>", fp);
qf->fp = fp;
return qf;
}
//--------------------------------------------------------------------------
// This method can be used to pass a FILE* from C code
static qfile_t *from_cobject(PyObject *pycobject)
{
return PyCObject_Check(pycobject) ? from_fp((FILE *)PyCObject_AsVoidPtr(pycobject)) : NULL;
}
//--------------------------------------------------------------------------
static qfile_t *tmpfile()
{
FILE *fp;
Py_BEGIN_ALLOW_THREADS;
fp = qtmpfile();
Py_END_ALLOW_THREADS;
return from_fp(fp);
}
//--------------------------------------------------------------------------
FILE *get_fp()
{
return fp;
}
//--------------------------------------------------------------------------
int seek(int32 offset, int whence = SEEK_SET)
{
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfseek(fp, offset, whence);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 tell()
{
int32 rc;
Py_BEGIN_ALLOW_THREADS;
rc = qftell(fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *readbytes(int size, bool big_endian)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
int r;
Py_BEGIN_ALLOW_THREADS;
r = freadbytes(fp, buf, size, big_endian);
Py_END_ALLOW_THREADS;
if ( r != 0 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *read(int size)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
int r;
Py_BEGIN_ALLOW_THREADS;
r = qfread(fp, buf, size);
Py_END_ALLOW_THREADS;
if ( r <= 0 )
{
free(buf);
break;
}
PyObject *ret = PyString_FromStringAndSize(buf, r);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
PyObject *gets(int size)
{
do
{
char *buf = (char *) malloc(size + 5);
if ( buf == NULL )
break;
PYW_GIL_CHECK_LOCKED_SCOPE();
char *p;
Py_BEGIN_ALLOW_THREADS;
p = qfgets(buf, size, fp);
Py_END_ALLOW_THREADS;
if ( p == NULL )
{
free(buf);
break;
}
PyObject *ret = PyString_FromString(buf);
free(buf);
return ret;
} while ( false );
Py_RETURN_NONE;
}
//--------------------------------------------------------------------------
int writebytes(PyObject *py_buf, bool big_endian)
{
Py_ssize_t sz;
void *buf;
PYW_GIL_CHECK_LOCKED_SCOPE();
sz = PyString_GET_SIZE(py_buf);
buf = (void *)PyString_AS_STRING(py_buf);
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = fwritebytes(fp, buf, int(sz), big_endian);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int write(PyObject *py_buf)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
if ( !PyString_Check(py_buf) )
return 0;
// Just so that there is no risk that the buffer returned by
// 'PyString_AS_STRING' gets deallocated within the
// Py_BEGIN|END_ALLOW_THREADS section.
borref_t py_buf_ref(py_buf);
void *p = (void *)PyString_AS_STRING(py_buf);
Py_ssize_t sz = PyString_GET_SIZE(py_buf);
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfwrite(fp, p, sz);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int puts(const char *str)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfputs(str, fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
int32 size()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int32 r;
Py_BEGIN_ALLOW_THREADS;
int pos = qfseek(fp, 0, SEEK_END);
r = qftell(fp);
qfseek(fp, pos, SEEK_SET);
Py_END_ALLOW_THREADS;
return r;
}
//--------------------------------------------------------------------------
int flush()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qflush(fp);
Py_END_ALLOW_THREADS;
return rc;
}
//--------------------------------------------------------------------------
PyObject *filename()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
return PyString_FromString(fn.c_str());
}
//--------------------------------------------------------------------------
PyObject *get_char()
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int ch;
Py_BEGIN_ALLOW_THREADS;
ch = qfgetc(fp);
Py_END_ALLOW_THREADS;
if ( ch == EOF )
Py_RETURN_NONE;
return Py_BuildValue("c", ch);
}
//--------------------------------------------------------------------------
int put_char(char chr)
{
PYW_GIL_CHECK_LOCKED_SCOPE();
int rc;
Py_BEGIN_ALLOW_THREADS;
rc = qfputc(chr, fp);
Py_END_ALLOW_THREADS;
return rc;
}
};
//</inline(py_qfile)>
#endif

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More