Example #1
0
 def pull(self, remote, local):
     cmd = " ".join(["pull", remote, local])
     data = self.adb(cmd)
     if "pulled." not in data:
         log.warning("%s pull %s Failed." % (self.serial, remote))
     else:
         log.success("%s pull %s succeed." % (self.serial, remote))
Example #2
0
def _compile(code, werror, flags, libs):
    digest = md5sumhex(code + str(werror) + str(flags) + str(libs))
    if digest in __cache:
        return __cache[digest]
    sopath = os.path.join(__tempdir, digest + '.so')
    try:
        if os.path.exists(sopath):
            return CDDL(sopath)
    except:
        pass
    cpath = os.path.join(__tempdir, digest + '.c')
    with open(cpath, 'w') as f:
        f.write(code)
    flags += [
        '-fPIC', '-shared', '-O3', '-march=native', '-mtune=native', '-Wall'
    ]
    if werror:
        flags.append('-Werror')
    cmd = ['gcc'] + flags + ['-o', sopath, cpath] + libs
    p = Popen(cmd, stderr=PIPE)
    _, s = p.communicate()
    s = s.replace(cpath + ':', '').replace(cpath, '')
    if p.returncode <> 0:
        log.error('GCC error (%s):' % cpath)
        log.trace(s)
        sys.exit(p.returncode)
    elif s <> '':
        log.warning('GCC warning (%s):' % cpath)
        log.trace(s)
    return CDLL(sopath)
Example #3
0
    def RunJohn(self, filenName, algoType):
        isSuccess = False
        progress = log.progress("Cracking hash from file: " +
                                highlightRed(filenName))
        process = subprocess.run((self.johnPath, filenName, algoType,
                                  "--wordlist=" + self.wordlistPath),
                                 check=True,
                                 stdout=subprocess.PIPE,
                                 stderr=subprocess.DEVNULL)

        if ('krb5asrep' in algoType):
            regexHashUser = r"(.*[^\s-])\s+\(\$krb5\w+\$23\$(\w+-?\w+)@.+\.\w+\)"
        elif ('krb5tgs' in algoType):
            regexHashUser = r"(.*[^\s-])\s+\(\?\)"
        else:
            log.warning('Fail to detect hash !')
            return isSuccess
        output = process.stdout.decode()
        for output in output.splitlines():
            x = re.search(regexHashUser, output)
            if (x is not None):
                if ('krb5asrep' in algoType):
                    print("", end='\t')
                    log.success("Cread Found: '" + highlightGreen(x.group(2)) +
                                ":" + highlightGreen(x.group(1)) + "'")
                    isSuccess = True
                elif ('krb5tgs' in algoType):
                    print("", end='\t')
                    log.success("Cread Found: '" + highlightGreen(x.group(1)) +
                                "'")
                    isSuccess = True
                else:
                    log.warning('Fail get hash !')
        progress.success(status='Done')
        return isSuccess
    def encrypt(plain_text: bytes,
                key: bytes,
                skip_first_round: bool = False) -> bytes:

        # Check key parameter length
        key_length = len(key)
        if (key_length != KEY_LENGTH):
            log.warning(
                "Key does not have the correct length: {} != {}".format(
                    KEY_LENGTH, key_length))
            exit()
        else:
            log.success("Key have the correct length: {} == {}".format(
                KEY_LENGTH, key_length))

        # Check plain text parameter length
        plain_length = len(plain_text)
        if (plain_length % CHUNK_LENGTH != 0):
            log.warning(
                "Text to encrypt does not have the correct length: {} % {} != 0"
                .format(plain_length, CHUNK_LENGTH))
            exit()
        else:
            log.success(
                "Text to encrypt has the correct length: {} % {} == 0".format(
                    plain_length, CHUNK_LENGTH))
            log.info("Text to encrypt is: {}".format(
                Converter.bytes_to_hex(plain_text)))

        # Get keys used for encryption
        keys = BC4Worker._generate_keys(key, plain_length // CHUNK_LENGTH,
                                        skip_first_round)

        # Split text in chunks and encrypt
        encrypted_text: bytes = bytes()
        for i in range(0, plain_length, CHUNK_LENGTH):

            # Get parts that will be XORed
            plain_part = plain_text[i:i + CHUNK_LENGTH]
            key_part = keys[i:i + CHUNK_LENGTH]

            # Encrypt with XOR
            ciphertext_part = Converter.bytes_to_int(
                plain_part) ^ Converter.bytes_to_int(key_part)
            encrypted_text += Converter.int_to_bytes(ciphertext_part)

            # Log
            if VERBOSE:
                log.info("The #{} encryption is {} (meaning {} ^ {})".format(
                    i // CHUNK_LENGTH, Converter.int_to_hex(ciphertext_part),
                    Converter.bytes_to_hex(plain_part),
                    Converter.bytes_to_hex(key_part)))

        # Log
        if VERBOSE:
            log.info("Ciphertext is: {}".format(
                Converter.bytes_to_hex(encrypted_text)))

        # Encode encrypted text and return
        return encrypted_text
Example #5
0
    def UserOldPassword(self):
        printTitle("[-] Users with old password")

        passwordMinAge = 100
        timeFilter = "(pwdLastSet<=%s)" % self.__datetime_to_mstimestamp(
            datetime.datetime.now() - datetime.timedelta(days=passwordMinAge))
        OBJECT_TO_SEARCH = '(&(objectCategory=user)' + timeFilter + ')'
        ATTRIBUTES_TO_SEARCH = ['pwdLastSet', 'sAMAccountName']

        result = self.__SearchServerLdap(OBJECT_TO_SEARCH,
                                         ATTRIBUTES_TO_SEARCH)
        for info in result:
            timestamp = int(info[1]['pwdLastSet'][0].decode())
            username = info[1]['sAMAccountName'][0].decode()
            if (timestamp != 0):
                value = datetime.datetime(1601, 1, 1) + datetime.timedelta(
                    seconds=timestamp / 10000000)
                now = datetime.datetime.now()
                lastChange = now - value
                if (lastChange.days > 100):
                    log.warning("Username: "******"Password last change: " +
                                highlightRed(str((now - value).days)) +
                                " days ago " +
                                value.strftime('%Y-%m-%d %H:%M:%S'))
Example #6
0
    def one(cls, word, code, timing, size, color, words, lines, word_present):
        """ Display an entry in the table

            :param word: The word found
            :param code: The HTTP status code from the response
            :param timing: The time of the request execution
            :param size: Byte size of the response
            :param color: The HTTP status code to apply
            :param words: The words count in the response content
            :param lines: The lines count in the response content
            :param word_present: Is the word present in the response content
        """

        timing += "ms"
        out = ("|{}|{}{}{}|{}|{}|{}|{}|{}|".format(
            ' ' + word[:33] + ((33 - len(word)) * " "),
            ' ' + fg(color),
            code[:8] + ((8 - len(code)) * " "),
            attr('reset'),
            ' ' + timing[:23] + ((23 - len(timing)) * " "),
            ' ' + size[:15] + ((15 - len(size)) * " "),
            ' ' + words[:15] + ((15 - len(words)) * " "),
            ' ' + lines[:15] + ((15 - len(lines)) * " "),
            ' ' + word_present[:19] + ((19 - len(word_present)) * " "),
        ))
        log.warning(out)
Example #7
0
def _compile(code, werror, flags, libs):
    digest = md5sumhex(code + str(werror) + str(flags) + str(libs))
    if digest in __cache:
        return __cache[digest]
    sopath = os.path.join(__tempdir, digest + '.so')
    try:
        if os.path.exists(sopath):
            return CDDL(sopath)
    except:
        pass
    cpath = os.path.join(__tempdir, digest + '.c')
    with open(cpath, 'w') as f:
        f.write(code)
    flags += ['-fPIC', '-shared', '-O3', '-march=native', '-mtune=native',
              '-Wall']
    if werror:
        flags.append('-Werror')
    cmd = ['gcc'] + flags + ['-o', sopath, cpath] + libs
    p = Popen(cmd, stderr = PIPE)
    _, s = p.communicate()
    s = s.replace(cpath + ':', '').replace(cpath, '')
    if p.returncode <> 0:
        log.error('GCC error (%s):' % cpath)
        log.trace(s)
        sys.exit(p.returncode)
    elif s <> '':
        log.warning('GCC warning (%s):' % cpath)
        log.trace(s)
    return CDLL(sopath)
Example #8
0
 def sync_device_to_host(self, device_dir, host_dir):
     cmd = "adb-sync -s %s --reverse %s %s" % (self.serial, device_dir,
                                               host_dir)
     result = exeute_cmd(cmd)
     if "Total: " not in result:
         log.warning("%s sync %s Failed." % (self.serial, device_dir))
     else:
         log.success("%s sync %s succeed." % (self.serial, device_dir))
Example #9
0
def ResovelIpAddress(ServerName):
    try:
        data = socket.gethostbyname_ex(ServerName)
        ipAddres = data[2][0]
    except Exception:
        log.warning("Fail to resolve ServerName: " + ServerName)
        return None
    return ipAddres
Example #10
0
 def kill_process(self, location, process_name):
     if location == "host":
         self.kill_host_process(process_name)
     elif location == "device":
         self.kill_device_process(process_name)
     else:
         log.warning("The location should be either host or device.")
         return None
Example #11
0
def prompt_for_match(matches):
    log.warning('SELECT LIBC VERSION')
    for i, m in enumerate(matches):
        log.info('%d: %s' % (i+1, m))

    sel = int(input('> '))
    print('')

    return matches[sel-1]
Example #12
0
 def get_process_list(self, location, process_name):
     if location == "host":
         pids = self.get_host_process_list(process_name)
     elif location == "device":
         pids = self.get_device_process_list(process_name)
     else:
         log.warning("The location should be either host or device.")
         return None
     log.debug("pids: %s" % str(pids))
     return pids
def on_message(message, data):
    if message['type'] == 'send':
        info = json.loads(str(message['payload']).encode('string-escape'),
                          strict=False)
        filename = PATH + info["name"] + ".dat"
        with open(filename, "a+") as f:
            json.dump(info, f)
            f.write("\n")
        log.info("stored call to " + info["name"])
    else:
        log.warning("Could not parse: " + str(message))
Example #14
0
 def connect(self):
     if self.connected():
         log.warning('Already connected to %s on port %d' % self.target)
         return
     log.waitfor('Opening connection to %s on port %d' % self.target)
     self.sock = socket.socket(self.family, self.type, self.proto)
     self.sock.settimeout(self.timeout)
     self.sock.connect(self.target)
     self.lhost = self.sock.getsockname()[0]
     self.lport = self.sock.getsockname()[1]
     log.succeeded()
Example #15
0
 def push(self, local, remote):
     cmd = " ".join(["push", local, remote])
     data = self.adb(cmd)
     if "pushed." in data:
         log.success("%s push %s succeed." % (self.serial, remote))
     else:
         log.warning("%s push %s Failed." % (self.serial, local))
         log.info("  retry push..")
         while self.get_device_state() != "device":
             sleep(10)
         self.reset()
         self.push(local, remote)
Example #16
0
def tricky_sha_inputs():
    # Hand-crafted to succeed on the first try:
    block = "0000000000000000014a6c756a385603e2b1eccafbdf974e11ee851072d54303"
    while True:
        req = requests.get(f"https://blockchain.info/rawblock/{block}?format=hex")
        header = bytes.fromhex(req.text[: 80 * 2])
        base = sha256(header).digest()
        if sha256(base).digest().endswith(b"\0\0\0\0\0\0\0\0"):
            yield block, base
        else:
            log.warning("Block not sufficient")
        block = header[4:][:32][::-1].hex()
def generate_payload_aligned(rop):
    payload1 = OFFSET + rop
    if (len(payload1) % 16) == 0:
        return payload1

    else:
        payload2 = OFFSET + p64(RET) + rop
        if (len(payload2) % 16) == 0:
            log.info("Payload aligned successfully")
            return payload2
        else:
            log.warning(f"I couldn't align the payload! Len: {len(payload1)}")
            return payload1
Example #18
0
 def connect(self):
     if self.connected():
         log.warning('Already connected to %s on port %d' % self.target)
         return
     if not self.silent:
         log.waitfor('Opening connection to %s on port %d' % self.target)
     self.sock = socket.socket(self.family, self.type, self.proto)
     self.sock.settimeout(self.timeout)
     self.sock.connect(self.target)
     self.lhost = self.sock.getsockname()[0]
     self.lport = self.sock.getsockname()[1]
     if not self.silent:
         log.succeeded()
Example #19
0
    def __init__(self, serial, cfg: dict):
        self.serial = serial
        self.cfg = cfg

        self.host_fuzzer_path = cfg["host_fuzzer_path"]
        self.fuzzer_name = os.path.basename(self.host_fuzzer_path)

        self.host_model_dir = cfg["host_model_dir"]
        self.host_seed_dir = cfg["host_seed_dir"]
        self.device_work_dir = cfg["device_work_dir"]

        self.device_fuzzer_path = os.path.join(self.device_work_dir,
                                               self.fuzzer_name)

        self.max_instance_number = cfg["max_instance_number"]

        # count how many fuzzers ever run, as some may be died.
        self.accumulated_fuzzer_num = 0

        # how many logcat, as logcat may be died?
        self.accumulated_logcat_num = 0

        # how many dmesg, as dmesg may be died.
        self.accumulated_dmesg_num = 0
        self.dmesg_pid = -1

        # device dir
        self.host_log_dir = os.path.join(self.cfg["current_log_dir"],
                                         self.serial)
        if os.path.exists(self.host_log_dir):
            if os.path.isdir(self.host_log_dir):
                pass
            else:
                log.warning("The log %s dir must not be an existing file!" %
                            self.host_log_dir)
                exit(0)
        else:
            os.makedirs(self.host_log_dir)

        self.flash_count = 0
        self.flash_cfg = json.load(open("flash.cfg"))
        self.flasher = Flasher(self.serial, self.flash_cfg)

        # restart device script on device
        self.device_restart_device_script_path = os.path.join(
            self.device_work_dir,
            os.path.basename(self.cfg["restart_device_script_path"]))
        self.max_tombstone_count = self.cfg["max_tombstone_count"]

        self.device_manager_log_path = os.path.join(self.host_log_dir,
                                                    "device_manager.log")
Example #20
0
def pause(n=None):
    """Waits for either user input or a specific number of seconds."""
    try:
        if n is None:
            log.info('Paused (press enter to continue)')
            raw_input('')
        else:
            log.waitfor('Continueing in')
            for i in range(n, 0, -1):
                log.status('%d... ' % i)
                pwn.sleep(1)
            log.succeeded('Now')
    except KeyboardInterrupt:
        log.warning('Interrupted')
        sys.exit(1)
Example #21
0
def pause(n = None):
    """Waits for either user input or a specific number of seconds."""
    try:
        if n is None:
            log.info('Paused (press enter to continue)')
            raw_input('')
        else:
            log.waitfor('Continueing in')
            for i in range(n, 0, -1):
                log.status('%d... ' % i)
                pwn.sleep(1)
            log.succeeded('Now')
    except KeyboardInterrupt:
        log.warning('Interrupted')
        sys.exit(1)
Example #22
0
 def _on_message(self, message, data):
     """Process the method call messages"""
     if message['type'] == 'send':
         #info = json.loads(str(message['payload']).encode('string-escape'), strict=False)
         info = message['payload']
         
         if self.print_calls:
             pretty_print(info, log.info)
             
         if self.write_results:
             filename = os.path.join(self.path, info["name"] + ".dat")
             with open(filename, "a+") as f:
                 json.dump(info, f)
                 f.write("\n")    
     else:
         log.warning(str(message).encode('string-escape'))
Example #23
0
    def start(self, cmd, args, env):
        if self.connected():
            log.warning('Program "%s" already started' % cmd)
            return
        log.waitfor('Starting program "%s"' % cmd)

        self.proc = Popen(
                tuple(cmd.split()) + args,
                stdin=PIPE, stdout=PIPE, stderr=PIPE,
                env = env,
                bufsize = 0)
        fd = self.proc.stdout.fileno()
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        self.stdout = fd
        log.succeeded()
Example #24
0
def find_libc(*args):
    find_argv = [os.path.join(LIBCDB_DIR, 'find')] + list(args)
    proc = subprocess.Popen(find_argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    matches = proc.stdout.readlines()

    if not matches:
        log.warning('No matches found for "%s" in libc db!' % ' '.join(args))
        exit(1)

    if len(matches) > 1:
        selection = prompt_for_match(matches)
    else:
        selection = matches[0]

    lib_id = extract_id(selection)
    return lib_id
Example #25
0
def run_new_remote_gdbserver(host, port):
    gdbserver_pid = None

    log.info("Attempting to connect to remote debugging gdbserver")
    try:
        remote_telnet = remote(host, PORTS["DEBUG_TELNET_PORT"])
    except KeyboardInterrupt:
        raise SystemExit(log.warning("SIGINT received, exiting gracefully..."))
    else:
        remote_telnet.sendline("pidof gdbserver.i686"), time.sleep(1)  # Have to sleep because of polling delay
        recv_data = remote_telnet.recv_raw(2048).decode('ascii', errors="ignore")

    for line in recv_data.split("\n"):
        newline = line.strip("\n")
        if newline.isdigit():
            gdbserver_pid = newline
            break

    if gdbserver_pid:
        log.info("killing stale gdbserver...")
        remote_telnet.sendline("kill -9 {}".format(gdbserver_pid)), time.sleep(1)

    log.info("starting new remote gdbserver and attaching...")
    remote_telnet.sendline("/flash/bin/gdbserver.i686 {}:{} --attach $(pidof www) &".format(host, port)), time.sleep(1)

    return True
Example #26
0
def libc_resolve(dict_sym_addr, choice=0):
    if len(dict_sym_addr) <= 1:
        log.warning_once(
            "[libc-resolver]: No reliable result is guaranteed without at least two symbols"
        )
    result = libcdb_wrapper.find(dict_sym_addr)
    log.info("Found:\n%s" % result)
    regex_lib_names = r"\((.*)\)"
    libs = re.findall(regex_lib_names, result, re.MULTILINE)
    if len(libs) > 1:
        log.warning(
            "[libc-resolver]: %d libraries are compatible, default choice is %d"
            % (len(libs), choice + 1))
    libc = ELF(config.db_path + libs[choice] + ".so")
    libc.address = list(dict_sym_addr.values())[0] - libc.symbols[list(
        dict_sym_addr.keys())[0]]
    return (libc)
Example #27
0
    async def handle_request_exceptions(self, request):
        """ Handle the given requests errors !

            :param request: The request to handle
        """

        data = None
        try:
            data = await request.process()
        except aiohttp.InvalidURL as e:
            log.warning("Invalid URL, exiting ..")
            await self.stop()
        except aiohttp.ClientConnectionError as e:
            self.status(0, request._word, "Request failed !")
            color = Printer.get_code_color("ERROR")
            Printer.one("'" + request._word + "'", "ERROR", "0", "0", color,
                        "0", "0", "N/A")
        return data
Example #28
0
    def loop(self):
        """ Launch the main fuzzy loop """

        self.loop = asyncio.get_event_loop()
        # self.loop.set_debug(True)
        self.loop.set_exception_handler(exception_handler)
        try:
            self.loop.run_until_complete(self.process())
        except KeyboardInterrupt as e:
            Printer.end()
            log.warning("Interrupted !")
            if self._verbose:
                print_exceptions()
            exit()
        Printer.end()
        log.warning("Ending !")
        if self._verbose:
            print_exceptions()
Example #29
0
def get_offsets(symbol, addr, libc_id=None, run_oneg=False):
    if not libc_id:
        libc_id = find_libc(symbol, hex(addr))
    
    offsets = dump_libc(libc_id, symbol)
    offsets.update(dump_libc(libc_id))

    libc_base = addr - offsets[symbol]
    addrs = {'base': libc_base}

    for symbol in offsets.keys():
        addrs[symbol] = libc_base + offsets[symbol]

    if run_oneg:
        log.warning('Fetching one_gadget results...')
        print_oneg_results(libc_id)

    return addrs
Example #30
0
    def start(self, cmd, args, env):
        if self.connected():
            log.warning('Program "%s" already started' % cmd)
            return
        if not self.silent:
            log.waitfor('Starting program "%s"' % cmd)

        self.proc = Popen(
                tuple(cmd.split()) + args,
                stdin=PIPE, stdout=PIPE, stderr=PIPE,
                env = env,
                bufsize = 0)
        fd = self.proc.stdout.fileno()
        fl = fcntl.fcntl(fd, fcntl.F_GETFL)
        fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
        self.stdout = fd
        if not self.silent:
            log.succeeded()
Example #31
0
 def wipe_userdata_and_cache(self):
     log.info("start wiping userdata and cache.")
     cmd = [
         "/usr/bin/adb -s %s reboot bootloader" % self.serial,
         "sleep 5",
         "/usr/bin/fastboot -s %s boot %s" %
         (self.serial, self.cfg["twrp_img_path"]),
         "sleep 25",
         "/usr/bin/adb -s %s shell recovery --wipe_data" % self.serial,
     ]
     cmd = "\n".join(cmd)
     result = exeute_cmd(cmd)
     log.info(result)
     if "I:AB_OTA_UPDATER := true" in result:
         log.success("wiping userdata and cache succeed.")
     else:
         log.warning("wiping userdata and cache failed.")
     # wait until boot completed
     sleep(30)
Example #32
0
    def leak(self, close=True, trim=True):
        """

        :param close:
        :param trim:
        :return:
        """
        current_round = 0
        total_leak_counter = 0
        leak_adjust_switch = False

        while True:
            log.info("Round: {}".format(current_round))
            round_hits = 0
            for _ in range(self.leak_attempts):
                leaked = self.leak_pointer(close=close, trim=trim)
                if leaked is not None:
                    for pointer in leaked:
                        log.info("-> 0x{}".format(pointer))
                        self.leakedlist.append(pointer)
                        round_hits += 1

            if round_hits == 0:
                log.warning("unable to leak valid pointers during round, "
                            "trying again after {} seconds".format(
                                self.leak_wait_time))
                time.sleep(self.leak_wait_time)
                if leak_adjust_switch:
                    leak_adjust_switch = False
                    self.leak_attempts -= 10
                else:
                    leak_adjust_switch = True
                    self.leak_attempts += 10
            else:
                total_leak_counter += round_hits
                if current_round != self.leak_rounds:
                    current_round += 1
                else:
                    break

        log.success("leaked {} possible pointers!".format(total_leak_counter))

        return self.leakedlist
Example #33
0
    def __SearchServerLdap(self, OBJECT_TO_SEARCH, ATTRIBUTES_TO_SEARCH):
        resultSearch = []

        try:
            result = self.ldapCon.search_s(self.baseDn, ldap.SCOPE_SUBTREE,
                                           OBJECT_TO_SEARCH,
                                           ATTRIBUTES_TO_SEARCH)
            for info in result:
                if (info[0] != None):
                    resultSearch.append([info[0], info[1]])
            if (len(resultSearch) == 0):
                log.warning("No entry found !")
        except ldap.OPERATIONS_ERROR as error:
            log.failure("OPERATIONS_ERROR: " + str(error))
            exit(0)
        except ldap.LDAPError as error:
            log.failure("LDAPError: " + str(error))
            exit(0)

        return resultSearch
Example #34
0
    def analyze_leaks(self, leakedlist=None):
        """

        :param leakedlist:
        :return:
        """

        sortedlist = list()

        if isinstance(leakedlist, list):
            if len(leakedlist) > 1:
                self.leakedlist = leakedlist
        elif len(self.leakedlist) < 2:
            log.warning("not enough pointers to analyse from leaked list")
            return False

        log.info("analyzing pointers from leaked list...")

        for pointer in self.leakedlist:
            sortedlist.append(int("0x{}".format(pointer), 16))

        log.info("sorting pointers: ")
        sortedlist = sorted(sortedlist)

        for pointer in sortedlist:
            log.info("-> {}".format(hex(pointer)))

        duplicates = Counter(sortedlist)

        log.info("attempting to locate duplicates...")

        counter = 0
        for key, value in duplicates.items():
            if value > 1:
                log.info("found duplicate pointer: {}".format(hex(key)))
                counter += 1

        if counter == 0:
            log.warning("could not locate any duplicates")

        return True
Example #35
0
import os, tempfile
from pwn import decoutils as _decoutils
from pwn import log, md5sumhex
from cPickle import load, dump

__tempdir = os.path.join(tempfile.gettempdir(), 'pwn-memoize')

if not os.path.exists(__tempdir):
    try:
        os.mkdir(__tempdir)
    except:
        log.warning('Could not create memoization dir: %s\n' % __tempdir)
        __tempdir = None
elif not os.path.isdir(__tempdir):
    log.warning('Memoization path is not a dir: %s\n' % __tempdir)
    __tempdir = None

def memoize(*args, **kwargs):
    '''Function memoization decorator.
    Args:
    use_mem (default True):   Cache results in memory.
    use_file (default True):  Cache results in files under /tmp/pwn-memoize.

    Used with no arguments is the same as setting mem = True and file = True.'''
    if len(args) == 1 and kwargs == {}:
        return _internal_memoize()(args[0])
    else:
        return _internal_memoize(*args, **kwargs)

_TYPE_VALUE     = 0
_TYPE_EXCEPTION = 1