mirror of
https://github.com/cemu-project/idapython.git
synced 2026-01-31 01:15:17 +01:00
@@ -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)
|
||||
@@ -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()
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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!"
|
||||
@@ -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"
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
4
build.py
4
build.py
@@ -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])
|
||||
|
||||
106
docs/notes.txt
106
docs/notes.txt
@@ -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.
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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!"
|
||||
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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()
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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..."
|
||||
@@ -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()
|
||||
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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')
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
|
||||
@@ -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
3614
python.cpp
File diff suppressed because it is too large
Load Diff
1660
python/idautils.py
1660
python/idautils.py
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
23
pywraps.hpp
23
pywraps.hpp
@@ -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
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
@echo off
|
||||
deploy_all.py
|
||||
@echo off
|
||||
deploy_all.py
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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, ¬ags) )
|
||||
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, ¬ags) )
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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)>
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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
@@ -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
@@ -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)>
|
||||
|
||||
1514
pywraps/py_cvt.hpp
1514
pywraps/py_cvt.hpp
File diff suppressed because it is too large
Load Diff
1570
pywraps/py_dbg.hpp
1570
pywraps/py_dbg.hpp
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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)>
|
||||
|
||||
1632
pywraps/py_graph.hpp
1632
pywraps/py_graph.hpp
File diff suppressed because it is too large
Load Diff
@@ -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
1210
pywraps/py_idaapi.py
1210
pywraps/py_idaapi.py
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 ®vals[i];
|
||||
}
|
||||
static regval_t rv;
|
||||
|
||||
@@ -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!"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
1092
pywraps/py_nalt.hpp
1092
pywraps/py_nalt.hpp
File diff suppressed because it is too large
Load Diff
@@ -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)>
|
||||
@@ -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)>
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
@@ -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)>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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__
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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
1826
pywraps/py_ua.hpp
1826
pywraps/py_ua.hpp
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
Reference in New Issue
Block a user