summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2018-05-30 15:41:10 -0400
committerRyan Snyder <ryan@vector35.com>2018-07-10 18:11:09 -0400
commit5cff3bf3cc5aa11875569a6aeddf88ef867411f1 (patch)
tree95d57658dae88fef66196cf8c8ac52e771d73f3d /python
parent1c03ac08aa94f5bedf21ec8f48ee1ec998e0e50c (diff)
Various Python 3 support changes
Diffstat (limited to 'python')
-rw-r--r--python/__init__.py6
-rw-r--r--python/architecture.py13
-rw-r--r--python/binaryview.py9
-rw-r--r--python/databuffer.py28
-rw-r--r--python/demangle.py4
-rw-r--r--python/generator.cpp179
-rw-r--r--python/log.py1
-rw-r--r--python/lowlevelil.py1
-rw-r--r--python/mediumlevelil.py54
-rw-r--r--python/metadata.py9
-rw-r--r--python/setting.py6
-rw-r--r--python/types.py2
12 files changed, 202 insertions, 110 deletions
diff --git a/python/__init__.py b/python/__init__.py
index a3ba0453..2f7cc5a0 100644
--- a/python/__init__.py
+++ b/python/__init__.py
@@ -118,10 +118,8 @@ class PluginManagerLoadPluginCallback(object):
def __init__(self):
self.cb = ctypes.CFUNCTYPE(
ctypes.c_bool,
- core.compatstring,
- core.compatstring,
- # ctypes.c_char_p,
- # ctypes.c_char_p,
+ ctypes.c_char_p,
+ ctypes.c_char_p,
ctypes.c_void_p)(self._load_plugin)
def _load_plugin(self, repo_path, plugin_path, ctx):
diff --git a/python/architecture.py b/python/architecture.py
index b99da184..521c750a 100644
--- a/python/architecture.py
+++ b/python/architecture.py
@@ -1073,7 +1073,6 @@ class Architecture(with_metaclass(_ArchitectureMetaClass, object)):
errors[0] = core.BNAllocString(str(error_str))
if data is None:
return False
- data = str(data)
buf = ctypes.create_string_buffer(len(data))
ctypes.memmove(buf, data, len(data))
core.BNSetDataBufferContents(result, buf, len(data))
@@ -2294,7 +2293,6 @@ class CoreArchitecture(Architecture):
:rtype: InstructionInfo
"""
info = core.BNInstructionInfo()
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNGetInstructionInfo(self.handle, buf, addr, len(data), info):
@@ -2322,7 +2320,6 @@ class CoreArchitecture(Architecture):
:return: an InstructionTextToken list for the current instruction
:rtype: list(InstructionTextToken)
"""
- data = str(data)
count = ctypes.c_ulonglong()
length = ctypes.c_ulonglong()
length.value = len(data)
@@ -2359,7 +2356,6 @@ class CoreArchitecture(Architecture):
:return: the length of the current instruction
:rtype: int
"""
- data = str(data)
length = ctypes.c_ulonglong()
length.value = len(data)
buf = (ctypes.c_ubyte * len(data))()
@@ -2449,7 +2445,6 @@ class CoreArchitecture(Architecture):
False
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureNeverBranchPatchAvailable(self.handle, buf, addr, len(data))
@@ -2471,7 +2466,6 @@ class CoreArchitecture(Architecture):
False
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureAlwaysBranchPatchAvailable(self.handle, buf, addr, len(data))
@@ -2492,7 +2486,6 @@ class CoreArchitecture(Architecture):
False
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureInvertBranchPatchAvailable(self.handle, buf, addr, len(data))
@@ -2516,7 +2509,6 @@ class CoreArchitecture(Architecture):
False
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureSkipAndReturnZeroPatchAvailable(self.handle, buf, addr, len(data))
@@ -2538,7 +2530,6 @@ class CoreArchitecture(Architecture):
False
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
return core.BNIsArchitectureSkipAndReturnValuePatchAvailable(self.handle, buf, addr, len(data))
@@ -2558,7 +2549,6 @@ class CoreArchitecture(Architecture):
'\\x90\\x90'
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNArchitectureConvertToNop(self.handle, buf, addr, len(data)):
@@ -2585,7 +2575,6 @@ class CoreArchitecture(Architecture):
(['jmp ', '0x9'], 5L)
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNArchitectureAlwaysBranch(self.handle, buf, addr, len(data)):
@@ -2613,7 +2602,6 @@ class CoreArchitecture(Architecture):
(['jl ', '0xa'], 6L)
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNArchitectureInvertBranch(self.handle, buf, addr, len(data)):
@@ -2637,7 +2625,6 @@ class CoreArchitecture(Architecture):
(['mov ', 'eax', ', ', '0x0'], 5L)
>>>
"""
- data = str(data)
buf = (ctypes.c_ubyte * len(data))()
ctypes.memmove(buf, data, len(data))
if not core.BNArchitectureSkipAndReturnValue(self.handle, buf, addr, len(data), value):
diff --git a/python/binaryview.py b/python/binaryview.py
index ac08ad76..b1bc4822 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -372,12 +372,12 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
@property
def name(self):
"""BinaryView name (read-only)"""
- return core.BNGetBinaryViewTypeName(self.handle).decode('utf8')
+ return core.BNGetBinaryViewTypeName(self.handle)
@property
def long_name(self):
"""BinaryView long name (read-only)"""
- return core.BNGetBinaryViewTypeLongName(self.handle).decode('utf8')
+ return core.BNGetBinaryViewTypeLongName(self.handle)
def __repr__(self):
return "<view type: '%s'>" % self.name
@@ -423,6 +423,9 @@ class BinaryViewType(with_metaclass(_BinaryViewTypeMetaclass, object)):
else:
bv = cls[available.name].open(filename)
+ if bv is None:
+ raise Exception("Unknown Architecture/Architecture Not Found (check plugins folder)")
+
if update_analysis:
bv.update_analysis_and_wait()
return bv
@@ -1740,7 +1743,7 @@ class BinaryView(object):
\'\\xcf\\xfa\\xed\\xfe\'
"""
buf = databuffer.DataBuffer(handle=core.BNReadViewBuffer(self.handle, addr, length))
- return str(buf)
+ return bytes(buf)
def write(self, addr, data):
"""
diff --git a/python/databuffer.py b/python/databuffer.py
index bf366750..1b29a7eb 100644
--- a/python/databuffer.py
+++ b/python/databuffer.py
@@ -26,6 +26,13 @@ from binaryninja import _binaryninjacore as core
class DataBuffer(object):
def __init__(self, contents="", handle=None):
+
+ # python3 no longer has longs
+ try:
+ long
+ except NameError:
+ long = int
+
if handle is not None:
self.handle = core.handle_of_type(handle, core.BNDataBuffer)
elif isinstance(contents, int) or isinstance(contents, long):
@@ -44,7 +51,7 @@ class DataBuffer(object):
def __getitem__(self, i):
if isinstance(i, tuple):
result = ""
- source = str(self)
+ source = bytes(self)
for s in i:
result += source[s]
return result
@@ -59,7 +66,7 @@ class DataBuffer(object):
ctypes.memmove(buf, core.BNGetDataBufferContentsAt(self.handle, start), stop - start)
return buf.raw
else:
- return str(self)[i]
+ return bytes(self)[i]
elif i < 0:
if i >= -len(self):
return chr(core.BNGetDataBufferByte(self.handle, int(len(self) + i)))
@@ -79,7 +86,7 @@ class DataBuffer(object):
if stop < start:
stop = start
if len(value) != (stop - start):
- data = str(self)
+ data = bytes(self)
data = data[0:start] + value + data[stop:]
core.BNSetDataBufferContents(self.handle, data, len(data))
else:
@@ -107,22 +114,27 @@ class DataBuffer(object):
def __str__(self):
buf = ctypes.create_string_buffer(len(self))
ctypes.memmove(buf, core.BNGetDataBufferContents(self.handle), len(self))
- return buf.raw
+ if type(buf.raw) is str:
+ return buf.raw
+ else:
+ return buf.raw.decode("charmap")
- def __repr__(self):
- return repr(str(self))
+ def __bytes__(self):
+ buf = ctypes.create_string_buffer(len(self))
+ ctypes.memmove(buf, core.BNGetDataBufferContents(self.handle), len(self))
+ return buf.raw
def escape(self):
return core.BNDataBufferToEscapedString(self.handle)
def unescape(self):
- return DataBuffer(handle=core.BNDecodeEscapedString(str(self)))
+ return DataBuffer(handle=core.BNDecodeEscapedString(bytes(self)))
def base64_encode(self):
return core.BNDataBufferToBase64(self.handle)
def base64_decode(self):
- return DataBuffer(handle = core.BNDecodeBase64(str(self)))
+ return DataBuffer(handle = core.BNDecodeBase64(bytes(self)))
def zlib_compress(self):
buf = core.BNZlibCompress(self.handle)
diff --git a/python/demangle.py b/python/demangle.py
index ceb1e48b..90a19761 100644
--- a/python/demangle.py
+++ b/python/demangle.py
@@ -65,7 +65,7 @@ def demangle_ms(arch, mangled_name):
names = []
if core.BNDemangleMS(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize)):
for i in range(outSize.value):
- names.append(outName[i])
+ names.append(outName[i].decode('charmap'))
core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
return (types.Type(handle), names)
return (None, mangled_name)
@@ -79,7 +79,7 @@ def demangle_gnu3(arch, mangled_name):
names = []
if core.BNDemangleGNU3(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize)):
for i in range(outSize.value):
- names.append(outName[i])
+ names.append(outName[i].decode('charmap'))
core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
if not handle:
return (None, names)
diff --git a/python/generator.cpp b/python/generator.cpp
index 8fc415b0..2da856ff 100644
--- a/python/generator.cpp
+++ b/python/generator.cpp
@@ -121,10 +121,8 @@ void OutputType(FILE* out, Type* type, bool isReturnType = false, bool isCallbac
{
if (isReturnType)
fprintf(out, "ctypes.POINTER(ctypes.c_byte)");
- else {
- //fprintf(out, "compatstring");
+ else
fprintf(out, "ctypes.c_char_p");
- }
break;
}
else if (type->GetChildType()->GetClass() == FunctionTypeClass)
@@ -175,7 +173,7 @@ int main(int argc, char* argv[])
}
bool ok = arch->GetStandalonePlatform()->ParseTypesFromSourceFile(argv[1], types, vars, funcs, errors);
- fprintf(stderr, "Errors: %s", errors.c_str());
+ fprintf(stderr, "Errors: %s\n", errors.c_str());
if (!ok)
return 1;
@@ -190,7 +188,6 @@ int main(int argc, char* argv[])
fprintf(out, "import platform\n");
fprintf(out, "core = None\n");
fprintf(out, "_base_path = None\n");
- fprintf(out, "ctypes.set_conversion_mode('utf-8', 'strict')\n");
fprintf(out, "if platform.system() == \"Darwin\":\n");
fprintf(out, "\t_base_path = os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"..\", \"MacOS\")\n");
fprintf(out, "\tcore = ctypes.CDLL(os.path.join(_base_path, \"libbinaryninjacore.dylib\"))\n\n");
@@ -202,40 +199,12 @@ int main(int argc, char* argv[])
fprintf(out, "\tcore = ctypes.CDLL(os.path.join(_base_path, \"binaryninjacore.dll\"))\n");
fprintf(out, "else:\n");
fprintf(out, "\traise Exception(\"OS not supported\")\n\n");
- // fprintf(out, "class compatstring(ctypes.c_char_p):\n");
- // fprintf(out, "\tdef __init__(self, value=None):\n");
- // fprintf(out, "\t\tsuper(compatstring, self).__init__()\n");
- // fprintf(out, "\t\tif value is not None:\n");
- // fprintf(out, "\t\t\tself.value = value\n");
- // fprintf(out, "\t@classmethod\n");
- // fprintf(out, "\tdef from_param(cls, value):\n");
- // fprintf(out, "\t\tif not isinstance(value, bytes):\n");
- // fprintf(out, "\t\t\treturn super(compatstring, cls).from_param(value.encode('utf8'))\n");
- // fprintf(out, "\t\treturn super(compatstring, cls).from_param(value)\n\n");
- // fprintf(out, "\t@property\n");
- // fprintf(out, "\tdef value(self, value):\n");
- // fprintf(out, "\t\tif not isinstance(value, bytes):\n");
- // fprintf(out, "\t\t\treturn super(compatstring, cls).from_param(value.encode('utf8'))\n");
- // fprintf(out, "\t\treturn super(compatstring, cls).from_param(value)\n\n");
- fprintf(out, "class compatstring(ctypes.c_char_p):\n");
- fprintf(out, " @classmethod\n");
- fprintf(out, " def from_param(cls, obj):\n");
- fprintf(out, " if (obj is not None) and (not isinstance(obj, cls)):\n");
- fprintf(out, " if not isinstance(obj, basestring):\n");
- fprintf(out, " raise TypeError('parameter must be a string type instance')\n");
- fprintf(out, " if not isinstance(obj, unicode):\n");
- fprintf(out, " obj = unicode(obj)\n");
- fprintf(out, " obj = obj.encode('utf-8')\n");
- fprintf(out, " return ctypes.c_char_p.from_param(obj)\n");
- fprintf(out, "\n");
- fprintf(out, " def decode(self):\n");
- fprintf(out, " if self.value is None:\n");
- fprintf(out, " return None\n");
- fprintf(out, " return self.value.decode('utf-8')\n");
- fprintf(out, " @property\n");
- fprintf(out, " def value(self, c_void_p=ctypes.c_void_p):\n");
- fprintf(out, " addr = c_void_p.from_buffer(self).value\n");
- fprintf(out, " return \n");
+
+ fprintf(out, "def cstr(arg):\n");
+ fprintf(out, "\tif isinstance(arg, str):\n");
+ fprintf(out, "\t\treturn arg.encode('charmap')\n");
+ fprintf(out, "\telse:\n");
+ fprintf(out, "\t\treturn arg\n\n");
// Create type objects
fprintf(out, "# Type definitions\n");
@@ -248,7 +217,23 @@ int main(int argc, char* argv[])
if (i.second->GetClass() == StructureTypeClass)
{
fprintf(out, "class %s(ctypes.Structure):\n", name.c_str());
- fprintf(out, "\tpass\n");
+
+ // python uses str's, C uses byte-arrays
+ bool stringField = false;
+ for (auto& arg : i.second->GetStructure()->GetMembers())
+ {
+ if ((arg.type->GetClass() == PointerTypeClass) &&
+ (arg.type->GetChildType()->GetWidth() == 1) &&
+ (arg.type->GetChildType()->IsSigned()))
+ {
+ fprintf(out, "\t@property\n\tdef %s(self):\n\t\treturn self._%s.decode('charmap')\n", arg.name.c_str(), arg.name.c_str());
+ fprintf(out, "\t@%s.setter\n\tdef %s(self, value):\n\t\tself._%s = value.encode('charmap')\n", arg.name.c_str(), arg.name.c_str(), arg.name.c_str());
+ stringField = true;
+ }
+ }
+
+ if (!stringField)
+ fprintf(out, "\tpass\n");
}
else if (i.second->GetClass() == EnumerationTypeClass)
{
@@ -313,7 +298,15 @@ int main(int argc, char* argv[])
fprintf(out, "%s._fields_ = [\n", name.c_str());
for (auto& j : type->GetStructure()->GetMembers())
{
- fprintf(out, "\t\t(\"%s\", ", j.name.c_str());
+ // To help the python->C wrappers
+ if ((j.type->GetClass() == PointerTypeClass) &&
+ (j.type->GetChildType()->GetWidth() == 1) &&
+ (j.type->GetChildType()->IsSigned()))
+ {
+ fprintf(out, "\t\t(\"_%s\", ", j.name.c_str());
+ }
+ else
+ fprintf(out, "\t\t(\"%s\", ", j.name.c_str());
OutputType(out, j.type);
fprintf(out, "),\n");
}
@@ -347,6 +340,22 @@ int main(int argc, char* argv[])
(i.second->GetChildType()->GetChildType()->IsSigned());
// Pointer returns will be automatically wrapped to return None on null pointer
bool pointerResult = (i.second->GetChildType()->GetClass() == PointerTypeClass);
+
+ // From python -> C python3 requires str -> str.encode('charmap')
+ bool stringArgument = false;
+ for (auto& arg : i.second->GetParameters())
+ {
+ if ((arg.type->GetClass() == PointerTypeClass) &&
+ (arg.type->GetChildType()->GetWidth() == 1) &&
+ (arg.type->GetChildType()->IsSigned()))
+ {
+ stringArgument = true;
+ break;
+ }
+ }
+ if (name == "BNFreeString")
+ stringArgument = false;
+
bool callbackConvention = false;
if (name == "BNAllocString")
{
@@ -358,7 +367,7 @@ int main(int argc, char* argv[])
}
string funcName = name;
- if (stringResult || pointerResult)
+ if (stringResult || pointerResult || stringArgument)
funcName = string("_") + funcName;
fprintf(out, "%s = core.%s\n", funcName.c_str(), name.c_str());
@@ -391,8 +400,30 @@ int main(int argc, char* argv[])
{
// Emit wrapper to get Python string and free native memory
fprintf(out, "def %s(*args):\n", name.c_str());
- fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
- fprintf(out, "\tstring = ctypes.cast(result, ctypes.c_char_p).value\n");
+ if (stringArgument)
+ {
+ fprintf(out, "\tresult = %s(", funcName.c_str());
+ string stringArgFuncCall = "";
+ size_t argN = 0;
+ for (auto& arg : i.second->GetParameters())
+ {
+ if ((arg.type->GetClass() == PointerTypeClass) &&
+ (arg.type->GetChildType()->GetWidth() == 1) &&
+ (arg.type->GetChildType()->IsSigned()))
+ {
+ stringArgFuncCall += "cstr(args[" + to_string(argN) + "]), ";
+ }
+ else
+ stringArgFuncCall += "args[" + to_string(argN) + "], ";
+ argN++;
+ }
+ stringArgFuncCall = stringArgFuncCall.substr(0, stringArgFuncCall.size()-2);
+ stringArgFuncCall += ")\n";
+ fprintf(out, "%s", stringArgFuncCall.c_str());
+ }
+ else
+ fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
+ fprintf(out, "\tstring = str(ctypes.cast(result, ctypes.c_char_p).value.decode('charmap'))\n");
fprintf(out, "\tBNFreeString(result)\n");
fprintf(out, "\treturn string\n");
}
@@ -400,11 +431,58 @@ int main(int argc, char* argv[])
{
// Emit wrapper to return None on null pointer
fprintf(out, "def %s(*args):\n", name.c_str());
- fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
+ if (stringArgument)
+ {
+ fprintf(out, "\tresult = %s(", funcName.c_str());
+ string stringArgFuncCall = "";
+ size_t argN = 0;
+ for (auto& arg : i.second->GetParameters())
+ {
+ if ((arg.type->GetClass() == PointerTypeClass) &&
+ (arg.type->GetChildType()->GetWidth() == 1) &&
+ (arg.type->GetChildType()->IsSigned()))
+ {
+ stringArgFuncCall += "cstr(args[" + to_string(argN) + "]), ";
+ }
+ else
+ stringArgFuncCall += "args[" + to_string(argN) + "], ";
+ argN++;
+ }
+ stringArgFuncCall = stringArgFuncCall.substr(0, stringArgFuncCall.size()-2);
+ stringArgFuncCall += ")\n";
+ fprintf(out, "%s", stringArgFuncCall.c_str());
+ }
+ else
+ fprintf(out, "\tresult = %s(*args)\n", funcName.c_str());
fprintf(out, "\tif not result:\n");
fprintf(out, "\t\treturn None\n");
fprintf(out, "\treturn result\n");
}
+ else if (stringArgument)
+ {
+ fprintf(out, "def %s(*args):\n", name.c_str());
+ {
+ fprintf(out, "\treturn %s(", funcName.c_str());
+ string stringArgFuncCall = "";
+ size_t argN = 0;
+ for (auto& arg : i.second->GetParameters())
+ {
+ if ((arg.type->GetClass() == PointerTypeClass) &&
+ (arg.type->GetChildType()->GetWidth() == 1) &&
+ (arg.type->GetChildType()->IsSigned()))
+ {
+ stringArgFuncCall += "cstr(args[" + to_string(argN) + "]), ";
+ }
+ else
+ stringArgFuncCall += "args[" + to_string(argN) + "], ";
+ argN++;
+ }
+ stringArgFuncCall = stringArgFuncCall.substr(0, stringArgFuncCall.size()-2);
+ stringArgFuncCall += ")\n";
+ fprintf(out, "%s", stringArgFuncCall.c_str());
+ }
+ }
+ fprintf(out, "\n");
}
fprintf(out, "\n# Helper functions\n");
@@ -413,6 +491,17 @@ int main(int argc, char* argv[])
fprintf(out, "\t\treturn ctypes.cast(value, ctypes.POINTER(handle_type))\n");
fprintf(out, "\traise ValueError('expected pointer to %%s' %% str(handle_type))\n");
+ // The following method is addapted from python/enum/__init__.py, lines 25-36
+ fprintf(out, "\ntry:\n");
+ fprintf(out, "\tbasestring\n");
+ fprintf(out, "\tunicode\n");
+ fprintf(out, "except NameError:\n");
+ fprintf(out, "\t# In Python 2 basestring is the ancestor of both str and unicode\n");
+ fprintf(out, "\t# in Python 3 it's just str, but was missing in 3.1\n");
+ fprintf(out, "\t# In Python 3 unicode no longer exists (it's just str)\n");
+ fprintf(out, "\tbasestring = str\n");
+ fprintf(out, "\tunicode = str\n");
+
fprintf(out, "\n# Set path for core plugins\n");
fprintf(out, "BNSetBundledPluginDirectory(os.path.join(_base_path, \"plugins\"))\n");
diff --git a/python/log.py b/python/log.py
index e7cd956d..d4d87019 100644
--- a/python/log.py
+++ b/python/log.py
@@ -21,6 +21,7 @@
# Binary Ninja components -- additional imports belong in the appropriate class
from binaryninja import _binaryninjacore as core
+from binaryninja.enums import LogLevel
_output_to_log = False
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 333bb5a1..272b2474 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -722,7 +722,6 @@ class LowLevelILFunction(object):
LLFC_NO !overflow No overflow
======================= ========== ===============================
"""
- from binaryninja import mediumlevelil
def __init__(self, arch, handle = None, source_func = None):
self.arch = arch
self.source_function = source_func
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 707915d7..f7e9951a 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -21,10 +21,13 @@
import ctypes
import struct
-# Binary Ninja components -- additional imports belong in the appropriate class
+# Binary Ninja components
from binaryninja import _binaryninjacore as core
from binaryninja.enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDependence
from binaryninja import basicblock #required for MediumLevelILBasicBlock argument
+from binaryninja import function
+from binaryninja import types
+from binaryninja import lowlevelil
# 2-3 compatibility
from six.moves import range
@@ -208,9 +211,6 @@ class MediumLevelILInstruction(object):
}
def __init__(self, func, expr_index, instr_index=None):
- from binaryninja import function
- from binaryninja import types
- from binaryninja import lowlevelil
instr = core.BNGetMediumLevelILByIndex(func.handle, expr_index)
self.function = func
self.expr_index = expr_index
@@ -241,14 +241,14 @@ class MediumLevelILInstruction(object):
elif operand_type == "intrinsic":
value = lowlevelil.ILIntrinsic(func.arch, instr.operands[i])
elif operand_type == "var":
- value = binaryninja.function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ value = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
elif operand_type == "var_ssa":
- var = binaryninja.function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ var = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
version = instr.operands[i + 1]
i += 1
value = SSAVariable(var, version)
elif operand_type == "var_ssa_dest_and_src":
- var = binaryninja.function.Variable.from_identifier(self.function.source_function, instr.operands[i])
+ var = function.Variable.from_identifier(self.function.source_function, instr.operands[i])
dest_version = instr.operands[i + 1]
src_version = instr.operands[i + 2]
i += 2
@@ -349,14 +349,14 @@ class MediumLevelILInstruction(object):
def value(self):
"""Value of expression if constant or a known value (read-only)"""
value = core.BNGetMediumLevelILExprValue(self.function.handle, self.expr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
@property
def possible_values(self):
"""Possible values of expression using path-sensitive static data flow analysis (read-only)"""
value = core.BNGetMediumLevelILPossibleExprValues(self.function.handle, self.expr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -454,7 +454,7 @@ class MediumLevelILInstruction(object):
return []
result = []
for operand in self.operands:
- if (isinstance(operand, binaryninja.function.Variable)) or (isinstance(operand, SSAVariable)):
+ if (isinstance(operand, function.Variable)) or (isinstance(operand, SSAVariable)):
result.append(operand)
elif isinstance(operand, MediumLevelILInstruction):
result += operand.vars_read
@@ -477,7 +477,7 @@ class MediumLevelILInstruction(object):
var_data.index = ssa_var.var.index
var_data.storage = ssa_var.var.storage
value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, ssa_var.version, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -491,88 +491,88 @@ class MediumLevelILInstruction(object):
def get_var_for_reg(self, reg):
reg = self.function.arch.get_reg_index(reg)
result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index)
- return binaryninja.function.Variable(self.function.source_function, result.type, result.index, result.storage)
+ return function.Variable(self.function.source_function, result.type, result.index, result.storage)
def get_var_for_flag(self, flag):
flag = self.function.arch.get_flag_index(flag)
result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index)
- return binaryninja.function.Variable(self.function.source_function, result.type, result.index, result.storage)
+ return function.Variable(self.function.source_function, result.type, result.index, result.storage)
def get_var_for_stack_location(self, offset):
result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index)
- return binaryninja.function.Variable(self.function.source_function, result.type, result.index, result.storage)
+ return function.Variable(self.function.source_function, result.type, result.index, result.storage)
def get_reg_value(self, reg):
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAtInstruction(self.function.handle, reg, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_reg_value_after(self, reg):
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILRegisterValueAfterInstruction(self.function.handle, reg, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_reg_values(self, reg):
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILPossibleRegisterValuesAtInstruction(self.function.handle, reg, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_reg_values_after(self, reg):
reg = self.function.arch.get_reg_index(reg)
value = core.BNGetMediumLevelILPossibleRegisterValuesAfterInstruction(self.function.handle, reg, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_flag_value(self, flag):
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAtInstruction(self.function.handle, flag, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_flag_value_after(self, flag):
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILFlagValueAfterInstruction(self.function.handle, flag, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_flag_values(self, flag):
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILPossibleFlagValuesAtInstruction(self.function.handle, flag, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_flag_values_after(self, flag):
flag = self.function.arch.get_flag_index(flag)
value = core.BNGetMediumLevelILPossibleFlagValuesAfterInstruction(self.function.handle, flag, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_stack_contents(self, offset, size):
value = core.BNGetMediumLevelILStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_stack_contents_after(self, offset, size):
value = core.BNGetMediumLevelILStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index)
- result = binaryninja.function.RegisterValue(self.function.arch, value)
+ result = function.RegisterValue(self.function.arch, value)
return result
def get_possible_stack_contents(self, offset, size):
value = core.BNGetMediumLevelILPossibleStackContentsAtInstruction(self.function.handle, offset, size, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
def get_possible_stack_contents_after(self, offset, size):
value = core.BNGetMediumLevelILPossibleStackContentsAfterInstruction(self.function.handle, offset, size, self.instr_index)
- result = binaryninja.function.PossibleValueSet(self.function.arch, value)
+ result = function.PossibleValueSet(self.function.arch, value)
core.BNFreePossibleValueSet(value)
return result
@@ -905,7 +905,7 @@ class MediumLevelILFunction(object):
var_data.index = ssa_var.var.index
var_data.storage = ssa_var.var.storage
value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, ssa_var.version)
- result = binaryninja.function.RegisterValue(self.arch, value)
+ result = function.RegisterValue(self.arch, value)
return result
def get_low_level_il_instruction_index(self, instr):
diff --git a/python/metadata.py b/python/metadata.py
index 64080060..fed8bdaa 100644
--- a/python/metadata.py
+++ b/python/metadata.py
@@ -43,7 +43,7 @@ class Metadata(object):
self.handle = core.BNCreateMetadataBooleanData(value)
elif isinstance(value, str):
if raw:
- buffer = (ctypes.c_ubyte * len(value)).from_buffer_copy(value)
+ buffer = (ctypes.c_ubyte * len(value)).from_buffer_copy(value.encode('charmap'))
self.handle = core.BNCreateMetadataRawData(buffer, len(value))
else:
self.handle = core.BNCreateMetadataStringData(value)
@@ -147,7 +147,10 @@ class Metadata(object):
result = core.BNMetadataGetValueStore(self.handle)
try:
for i in range(result.contents.size):
- yield result.contents.keys[i]
+ if type(result.contents.keys[i]) is bytes:
+ yield str(result.contents.keys[i].decode('charmap'))
+ else:
+ yield result.contents.keys[i]
finally:
core.BNFreeMetadataValueStore(result)
else:
@@ -172,7 +175,7 @@ class Metadata(object):
def __str__(self):
if self.is_string:
- return core.BNMetadataGetString(self.handle)
+ return str(core.BNMetadataGetString(self.handle))
if self.is_raw:
length = ctypes.c_ulonglong()
length.value = 0
diff --git a/python/setting.py b/python/setting.py
index 16d943e7..fea06140 100644
--- a/python/setting.py
+++ b/python/setting.py
@@ -58,11 +58,11 @@ class Setting(object):
length.value = len(default_value)
default_list = (ctypes.c_char_p * len(default_value))()
for i in range(len(default_value)):
- default_list[i] = default_value[i]
+ default_list[i] = default_value[i].encode('charmap')
result = core.BNSettingGetStringList(self.plugin_name, name, default_list, ctypes.byref(length))
out_list = []
for i in range(length.value):
- out_list.append(result[i])
+ out_list.append(result[i].decode('charmap'))
core.BNFreeStringList(result, length)
return out_list
@@ -113,7 +113,7 @@ class Setting(object):
length.value = len(value)
default_list = (ctypes.c_char_p * len(value))()
for i in range(len(value)):
- default_list[i] = str(value[i])
+ default_list[i] = value[i].encode('utf-8')
return core.BNSettingSetStringList(self.plugin_name, name, default_list, length, auto_flush)
diff --git a/python/types.py b/python/types.py
index 857f67e6..2ad8d2c2 100644
--- a/python/types.py
+++ b/python/types.py
@@ -39,7 +39,7 @@ class QualifiedName(object):
elif isinstance(name, QualifiedName):
self.name = name.name
else:
- self.name = name
+ self.name = [i.decode('utf-8') for i in name]
def __str__(self):
return "::".join(self.name)