From 79ca498f0b4861ffdad91a4d9fa987cc7f624c4c Mon Sep 17 00:00:00 2001 From: Oleksii Shevchuk Date: Mon, 12 Mar 2018 17:08:23 +0200 Subject: [PATCH] Add shadowing by path feature + example --- client/build_library_zip.py | 28 ++-- .../library_patches/Crypto/Util/_raw_api.py | 136 ++++++++++++++++++ 2 files changed, 155 insertions(+), 9 deletions(-) create mode 100644 client/library_patches/Crypto/Util/_raw_api.py diff --git a/client/build_library_zip.py b/client/build_library_zip.py index 7dd3396e..14d6ea91 100644 --- a/client/build_library_zip.py +++ b/client/build_library_zip.py @@ -106,7 +106,6 @@ if 'win' in sys.platform: try: content = set(ignore) - for dep in all_dependencies: mdep = __import__(dep) print "DEPENDENCY: ", dep, mdep @@ -116,15 +115,19 @@ try: for root, dirs, files in os.walk(mdep.__path__[0]): for f in list(set([x.rsplit('.',1)[0] for x in files])): found=False + need_compile=True for ext in ('.dll', '.so', '.pyd', '.py', '.pyc', '.pyo'): if ( ext == '.pyc' or ext == '.pyo' ) and found: continue pypath = os.path.join(root,f+ext) if os.path.exists(pypath): - zipname = '/'.join([root[len(path)+1:], f.split('.', 1)[0] + ext]) - zipname = zipname.replace('\\', '/') - found=True + ziproot = root[len(path)+1:].replace('\\', '/') + zipname = '/'.join([ziproot, f.split('.', 1)[0] + ext]) + found = True + + if ziproot.startswith('site-packages'): + ziproot = ziproot[14:] if zipname.startswith('network/transports/') and \ not zipname.startswith('network/transports/__init__.py'): @@ -141,21 +144,28 @@ try: if zipname in content: continue + file_root = root + if os.path.exists(os.path.join(PATCHES, f+'.py')): print('found [PATCH] for {}'.format(f)) - root = PATCHES + file_root = PATCHES + ext = '.py' + elif os.path.exists(os.path.sep.join([PATCHES] + zipname.split('/'))): + print('found [PATCH ZROOT] for {}'.format(f)) + file_root = os.path.sep.join([PATCHES] + ziproot.split('/')) ext = '.py' - break print('adding file : {}'.format(zipname)) content.add(zipname) - if ext == '.py': + if ext == '.py' and need_compile: zf.writestr( zipname+'o', - compile_py(os.path.join(root,f+ext))) + compile_py(os.path.join(file_root,f+ext))) else: - zf.write(os.path.join(root,f+ext), zipname) + zf.write(os.path.join(file_root,f+ext), zipname) + + break else: if '' in mdep.__file__: continue diff --git a/client/library_patches/Crypto/Util/_raw_api.py b/client/library_patches/Crypto/Util/_raw_api.py new file mode 100644 index 00000000..cf793738 --- /dev/null +++ b/client/library_patches/Crypto/Util/_raw_api.py @@ -0,0 +1,136 @@ +# =================================================================== +# +# Copyright (c) 2014, Legrandin +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# =================================================================== + +import sys +from Crypto.Util.py3compat import byte_string +from Crypto.Util._file_system import pycryptodome_filename + +import imp +extension_suffixes = [] +for ext, mod, typ in imp.get_suffixes(): + if typ == imp.C_EXTENSION: + extension_suffixes.append(ext) + +from ctypes import (CDLL, c_void_p, byref, c_ulong, c_ulonglong, c_size_t, + create_string_buffer, c_ubyte) +from ctypes.util import find_library +from _ctypes import Array + +null_pointer = None + +def load_lib(name, cdecl): + import platform + bits, linkage = platform.architecture() + if "." not in name and not linkage.startswith("Win"): + full_name = find_library(name) + if full_name is None: + raise OSError("Cannot load library '%s'" % name) + name = full_name + return CDLL(name) + +def get_c_string(c_string): + return c_string.value + +def get_raw_buffer(buf): + return buf.raw + +def c_uint8_ptr(data): + if byte_string(data) or isinstance(data, Array): + return data + elif isinstance(data, bytearray): + local_type = c_ubyte * len(data) + return local_type.from_buffer(data) + else: + raise TypeError("Object type %s cannot be passed to C code" % type(data)) + +class VoidPointer(object): + """Model a newly allocated pointer to void""" + + __slots__ = [ '_p' ] + + def __init__(self): + self._p = c_void_p() + + def get(self): + return self._p + + def address_of(self): + return byref(self._p) + +backend = "ctypes" + +class SmartPointer(object): + """Class to hold a non-managed piece of memory""" + + __slots__ = ( '_raw_pointer', '_destructor' ) + + def __init__(self, raw_pointer, destructor): + self._raw_pointer = raw_pointer + self._destructor = destructor + + def get(self): + return self._raw_pointer + + def release(self): + rp, self._raw_pointer = self._raw_pointer, None + return rp + + def __del__(self): + try: + if self._raw_pointer is not None: + self._destructor(self._raw_pointer) + self._raw_pointer = None + + self._destructor = None + except AttributeError: + pass + +def load_pycryptodome_raw_lib(name, cdecl): + """Load a shared library and return a handle to it. + + @name, the name of the library expressed as a PyCryptodome module, + for instance Crypto.Cipher._raw_cbc. + + @cdecl, the C function declarations. + """ + + attempts = [] + basename = '/'.join(name.split('.')) + for ext in extension_suffixes: + try: + filename = basename + ext + return CDLL(filename) + except OSError, exp: + attempts.append("Trying '%s': %s" % (filename, str(exp))) + + raise OSError("Cannot load native module '%s': %s (%s)" % (name, ", ".join(attempts), exp)) + +def expect_byte_string(data): + raise NotImplementedError("To be removed")