Edit File: tools.py
from ctypes import sizeof from ptrace.ctypes_tools import formatUintHex16, formatUintHex32, formatWordHex from datetime import datetime, timedelta from os import getenv, access, X_OK, pathsep, getcwd from os.path import join as path_join, isabs, dirname, normpath def dumpRegs(log, regs): """ Dump all registers using log callback (write one line). """ width = max(len(name) for name, type in regs._fields_) name_format = "%% %us" % width for name, type in regs._fields_: value = getattr(regs, name) name = name_format % name if sizeof(type) == 32: value = formatUintHex32(value) elif sizeof(type) == 16: value = formatUintHex16(value) else: value = formatWordHex(value) log("%s = %s" % (name, value)) def readBits(value, bitmasks): """ Extract bits from the integer value using a list of bit masks. bitmasks is a list of tuple (mask, text). >>> bitmask = ( ... (1, "exec"), ... (2, "write"), ... (4, "read")) ... >>> readBits(5, bitmask) ['exec', 'read'] >>> readBits(12, bitmask) ['read', '8'] """ bitset = [] for mask, item in bitmasks: if not value & mask: continue bitset.append(item) value = value & ~mask if value: bitset.append(str(value)) return bitset def formatBits(value, bitmasks, empty_text=None, format_value=str): """ Format a value using a bitmask: see readBits() functions. >>> bitmask = ( ... (1, "exec"), ... (2, "write"), ... (4, "read")) ... >>> formatBits(5, bitmask, empty_text="no permission") '<exec|read> (5)' >>> formatBits(0, bitmask, empty_text="no permission") 'no permission' """ orig_value = value text = readBits(value, bitmasks) if text: text = "%s" % ("|".join(text)) if value: text = "<%s> (%s)" % (text, format_value(orig_value)) return text else: if empty_text: return empty_text else: return str(value) LOCAL_TIMEZONE_OFFSET = datetime.fromtimestamp( 0) - datetime.utcfromtimestamp(0) # Start of UNIX timestamp (Epoch): 1st January 1970 at 00:00 UNIX_TIMESTAMP_T0 = datetime(1970, 1, 1) def timestampUNIX(value, is_local): """ Convert an UNIX (32-bit) timestamp to datetime object. Timestamp value is the number of seconds since the 1st January 1970 at 00:00. Maximum value is 2147483647: 19 january 2038 at 03:14:07. May raise ValueError for invalid value: value have to be in 0..2147483647. >>> timestampUNIX(0, False) datetime.datetime(1970, 1, 1, 0, 0) >>> timestampUNIX(1154175644.37, False) datetime.datetime(2006, 7, 29, 12, 20, 44, 370000) """ timestamp = UNIX_TIMESTAMP_T0 + timedelta(seconds=value) if is_local: timestamp += LOCAL_TIMEZONE_OFFSET return timestamp def locateProgram(program): """ Locate a program using the PATH environment variable. Return the unchanged program value if it's not possible to get the full program path. """ if isabs(program): return program if dirname(program): # ./test => $PWD/./test # ../python => $PWD/../python program = path_join(getcwd(), program) program = normpath(program) return program paths = getenv('PATH') if not paths: return program for path in paths.split(pathsep): filename = path_join(path, program) if access(filename, X_OK): return filename return program def minmax(min_value, value, max_value): """ Restrict value to [min_value; max_value] >>> minmax(-2, -3, 10) -2 >>> minmax(-2, 27, 10) 10 >>> minmax(-2, 0, 10) 0 """ return min(max(min_value, value), max_value) def inverseDict(data): """ Inverse a dictionary. >>> inverseDict({"0x10": 16, "0x20": 32}) == {32: '0x20', 16: '0x10'} True """ result = {} for key, value in data.items(): result[value] = key return result def signal_to_exitcode(signum): """ Converts a signal number to an exit code. UNIX: https://www.gnu.org/software/bash/manual/html_node/Exit-Status.html >>> import signal >>> signal_to_exitcode(signal.SIGQUIT) 131 """ return 128 + signum