Commit 66408145 by devttys0

Added ctypes wrapper and custom libmagic module.

parent 53c2cb29
import os
import sys
import glob
import ctypes
import ctypes.util
from binwalk.core.compat import *
class Function(object):
PY2CTYPES = {
bytes : ctypes.c_char_p,
str : ctypes.c_char_p,
int : ctypes.c_int,
float : ctypes.c_float,
None : ctypes.c_int,
}
RETVAL_CONVERTERS = {
int : int,
float : float,
str : bytes2str,
bytes : str2bytes,
}
def __init__(self, library, name, retype):
self.function = getattr(library, name)
self.retype = retype
if has_key(self.PY2CTYPES, self.retype):
self.function.restype = self.PY2CTYPES[self.retype]
self.retval_converter = self.RETVAL_CONVERTERS[self.retype]
else:
raise Exception("Unknown return type: '%s'" % retype)
def run(self, *args):
args = list(args)
for i in range(0, len(args)):
if isinstance(args[i], str):
args[i] = str2bytes(args[i])
return self.retval_converter(self.function(*args))
class Library(object):
def __init__(self, library, functions):
self.library = ctypes.cdll.LoadLibrary(self.find_library(library))
if not self.library:
raise Exception("Failed to load library '%s'" % library)
for (function, restype) in iterator(functions):
f = Function(self.library, function, restype)
setattr(self, function, f.run)
def find_library(self, library):
lib_path = None
system_paths = {
'linux' : ['/usr/local/lib/lib%s.so' % library],
'darwin' : ['/opt/local/lib/lib%s.dylib' % library,
'/usr/local/lib/lib%s.dylib' % library,
] + glob.glob('/usr/local/Cellar/lib%s/*/lib/lib%s.dylib' % (library, library)),
'win32' : ['%s.dll' % library]
}
lib_path = ctypes.util.find_library(library)
if not lib_path:
for path in system_paths[sys.platform]:
if os.path.exists(path):
lib_path = path
break
if not lib_path:
raise Exception("Failed to locate library '%s'" % library)
return lib_path
import ctypes
import ctypes.util
import binwalk.core.C
from binwalk.core.compat import *
class Magic(object):
LIBMAGIC_FUNCTIONS = {
"magic_open" : int,
"magic_load" : int,
"magic_buffer" : str,
}
MAGIC_NO_CHECK_TEXT = 0x020000
MAGIC_NO_CHECK_APPTYPE = 0x008000
MAGIC_NO_CHECK_TOKENS = 0x100000
MAGIC_NO_CHECK_ENCODING = 0x200000
MAGIC_FLAGS = MAGIC_NO_CHECK_TEXT | MAGIC_NO_CHECK_ENCODING | MAGIC_NO_CHECK_APPTYPE | MAGIC_NO_CHECK_TOKENS
def __init__(self, magic_file=None):
if magic_file:
self.magic_file = str2bytes(magic_file)
self.libmagic = binwalk.core.C.Library('magic', self.LIBMAGIC_FUNCTIONS)
self.magic_cookie = self.libmagic.magic_open(self.MAGIC_FLAGS)
self.libmagic.magic_load(self.magic_cookie, self.magic_file)
def buffer(self, data):
return self.libmagic.magic_buffer(self.magic_cookie, str2bytes(data), len(data))
if __name__ == "__main__":
magic = Magic()
print (magic.buffer("This is my voice on TV."))
import magic import binwalk.core.magic
import binwalk.core.parser
import binwalk.core.smart import binwalk.core.smart
from binwalk.core.compat import * import binwalk.core.parser
from binwalk.core.module import Module, Option, Kwarg from binwalk.core.module import Module, Option, Kwarg
class Signature(Module): class Signature(Module):
...@@ -43,8 +42,6 @@ class Signature(Module): ...@@ -43,8 +42,6 @@ class Signature(Module):
Kwarg(name='magic_files', default=[]), Kwarg(name='magic_files', default=[]),
] ]
MAGIC_FLAGS = magic.MAGIC_NO_CHECK_TEXT | magic.MAGIC_NO_CHECK_ENCODING | magic.MAGIC_NO_CHECK_APPTYPE | magic.MAGIC_NO_CHECK_TOKENS
VERBOSE_FORMAT = "%s %d" VERBOSE_FORMAT = "%s %d"
def init(self): def init(self):
...@@ -72,8 +69,7 @@ class Signature(Module): ...@@ -72,8 +69,7 @@ class Signature(Module):
# Parse the magic file(s) and initialize libmagic # Parse the magic file(s) and initialize libmagic
self.mfile = self.parser.parse(self.magic_files) self.mfile = self.parser.parse(self.magic_files)
self.magic = magic.open(self.MAGIC_FLAGS) self.magic = binwalk.core.magic.Magic(self.mfile)
self.magic.load(str2bytes(self.mfile))
# Once the temporary magic files are loaded into libmagic, we don't need them anymore; delete the temp files # Once the temporary magic files are loaded into libmagic, we don't need them anymore; delete the temp files
self.parser.rm_magic_files() self.parser.rm_magic_files()
...@@ -114,11 +110,8 @@ class Signature(Module): ...@@ -114,11 +110,8 @@ class Signature(Module):
if candidate_offset < current_block_offset: if candidate_offset < current_block_offset:
continue continue
# In python3 we need a bytes object to pass to magic.buffer
candidate_data = str2bytes(data[candidate_offset:candidate_offset+fp.block_peek_size])
# Pass the data to libmagic for parsing # Pass the data to libmagic for parsing
magic_result = self.magic.buffer(candidate_data) magic_result = self.magic.buffer(data[candidate_offset:candidate_offset+fp.block_peek_size])
if not magic_result: if not magic_result:
continue continue
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment