summaryrefslogtreecommitdiff
path: root/python/databuffer.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/databuffer.py')
-rw-r--r--python/databuffer.py145
1 files changed, 145 insertions, 0 deletions
diff --git a/python/databuffer.py b/python/databuffer.py
new file mode 100644
index 00000000..6b3423da
--- /dev/null
+++ b/python/databuffer.py
@@ -0,0 +1,145 @@
+# Copyright (c) 2015-2016 Vector 35 LLC
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+import ctypes
+
+# Binary Ninja components
+import _binaryninjacore as core
+
+
+class DataBuffer(object):
+ def __init__(self, contents="", handle=None):
+ if handle is not None:
+ self.handle = core.handle_of_type(handle, core.BNDataBuffer)
+ elif isinstance(contents, int) or isinstance(contents, long):
+ self.handle = core.BNCreateDataBuffer(None, contents)
+ elif isinstance(contents, DataBuffer):
+ self.handle = core.BNDuplicateDataBuffer(contents.handle)
+ else:
+ self.handle = core.BNCreateDataBuffer(contents, len(contents))
+
+ def __del__(self):
+ core.BNFreeDataBuffer(self.handle)
+
+ def __len__(self):
+ return int(core.BNGetDataBufferLength(self.handle))
+
+ def __getitem__(self, i):
+ if isinstance(i, tuple):
+ result = ""
+ source = str(self)
+ for s in i:
+ result += source[s]
+ return result
+ elif isinstance(i, slice):
+ if i.step is not None:
+ i = i.indices(len(self))
+ start = i[0]
+ stop = i[1]
+ if stop <= start:
+ return ""
+ buf = ctypes.create_string_buffer(stop - start)
+ ctypes.memmove(buf, core.BNGetDataBufferContentsAt(self.handle, start), stop - start)
+ return buf.raw
+ else:
+ return str(self)[i]
+ elif i < 0:
+ if i >= -len(self):
+ return chr(core.BNGetDataBufferByte(self.handle, int(len(self) + i)))
+ raise IndexError("index out of range")
+ elif i < len(self):
+ return chr(core.BNGetDataBufferByte(self.handle, int(i)))
+ else:
+ raise IndexError("index out of range")
+
+ def __setitem__(self, i, value):
+ if isinstance(i, slice):
+ if i.step is not None:
+ raise IndexError("step not supported on assignment")
+ i = i.indices(len(self))
+ start = i[0]
+ stop = i[1]
+ if stop < start:
+ stop = start
+ if len(value) != (stop - start):
+ data = str(self)
+ data = data[0:start] + value + data[stop:]
+ core.BNSetDataBufferContents(self.handle, data, len(data))
+ else:
+ value = str(value)
+ buf = ctypes.create_string_buffer(value)
+ ctypes.memmove(core.BNGetDataBufferContentsAt(self.handle, start), buf, len(value))
+ elif i < 0:
+ if i >= -len(self):
+ if len(value) != 1:
+ raise ValueError("expected single byte for assignment")
+ value = str(value)
+ buf = ctypes.create_string_buffer(value)
+ ctypes.memmove(core.BNGetDataBufferContentsAt(self.handle, int(len(self) + i)), buf, 1)
+ else:
+ raise IndexError("index out of range")
+ elif i < len(self):
+ if len(value) != 1:
+ raise ValueError("expected single byte for assignment")
+ value = str(value)
+ buf = ctypes.create_string_buffer(value)
+ ctypes.memmove(core.BNGetDataBufferContentsAt(self.handle, int(i)), buf, 1)
+ else:
+ raise IndexError("index out of range")
+
+ def __str__(self):
+ buf = ctypes.create_string_buffer(len(self))
+ ctypes.memmove(buf, core.BNGetDataBufferContents(self.handle), len(self))
+ return buf.raw
+
+ def __repr__(self):
+ return repr(str(self))
+
+ def escape(self):
+ return core.BNDataBufferToEscapedString(self.handle)
+
+ def unescape(self):
+ return DataBuffer(handle=core.BNDecodeEscapedString(str(self)))
+
+ def base64_encode(self):
+ return core.BNDataBufferToBase64(self.handle)
+
+ def base64_decode(self):
+ return DataBuffer(handle = core.BNDecodeBase64(str(self)))
+
+ def zlib_compress(self):
+ buf = core.BNZlibCompress(self.handle)
+ if buf is None:
+ return None
+ return DataBuffer(handle = buf)
+
+ def zlib_decompress(self):
+ buf = core.BNZlibDecompress(self.handle)
+ if buf is None:
+ return None
+ return DataBuffer(handle = buf)
+
+
+def escape_string(text):
+ return DataBuffer(text).escape()
+
+
+def unescape_string(text):
+ return DataBuffer(text).unescape()