From 1eb86483880ceb48e10c45c109eccc31d6b646b6 Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Tue, 17 Apr 2012 12:34:00 -0400 Subject: [PATCH] Updates --- func_smash.py | 88 +++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 27 deletions(-) diff --git a/func_smash.py b/func_smash.py index 9159de1..d9b4958 100644 --- a/func_smash.py +++ b/func_smash.py @@ -11,28 +11,7 @@ MARKOV_END = -2 def make_chain(funcs): chain = {} for func in funcs: - co = func.__code__ - code = co.co_code - n = len(code) - i = 0 - lastop = MARKOV_START - while i < n: - op = ord(code[i]) - i += 1 - if op >= opcode.HAVE_ARGUMENT: - oparg = ord(code[i]) + ord(code[i + 1]) * 256 - i += 2 - if op in opcode.hasconst: - arg = co.co_consts[oparg] - elif op in opcode.haslocal: - arg = co.co_varnames[oparg] - else: - raise NotImplementedError(op, opcode.opname[op]) - else: - arg = None - _chain_append(chain, lastop, (op, arg)) - lastop = op - _chain_append(chain, op, MARKOV_END) + _disassemble_func(func, chain) return chain def make_function(chain, name, argcount=1): @@ -52,6 +31,51 @@ def make_function(chain, name, argcount=1): func = types.FunctionType(code, globals(), name) return func +def print_chain(chain): + print "{" + for key in sorted(chain.keys()): + op = _int_to_opname(key) + targets = {} + for op2 in chain[key]: + target = _int_to_opname(op2[0]) + if op2[0] >= opcode.HAVE_ARGUMENT: + target = "{0}({1})".format(target, op2[1]) + try: + targets[target] += 1 + except KeyError: + targets[target] = 1 + targs = [t if targets[t] == 1 else "{0}x {1}".format(targets[t], t) for t in targets] + targs.sort() + tstring = ", ".join(targs) + print op.rjust(20), "=> [{0}]".format(tstring) + print "}" + +def _disassemble_func(func, chain): + co = func.__code__ + code = co.co_code + n = len(code) + i = 0 + lastop = MARKOV_START + while i < n: + op = ord(code[i]) + i += 1 + if op >= opcode.HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i + 1]) * 256 + i += 2 + if op in opcode.hasconst: + arg = co.co_consts[oparg] + elif op in opcode.haslocal: + arg = co.co_varnames[oparg] + elif op in opcode.hascompare: + arg = opcode.cmp_op[oparg] + else: + raise NotImplementedError(op, opcode.opname[op]) + else: + arg = None + _chain_append(chain, lastop, (op, arg)) + lastop = op + _chain_append(chain, op, (MARKOV_END, None)) + def _chain_append(chain, first, second): try: chain[first].append(second) @@ -63,24 +87,35 @@ def _make_codes(chain): code = random.choice(chain[MARKOV_START]) constants, varnames = [], [] while 1: - if code == MARKOV_END: - break op, arg = code + if op == MARKOV_END: + break codes.append(op) if op >= opcode.HAVE_ARGUMENT: if op in opcode.hasconst: + if arg not in constants: + constants.append(arg) args = constants elif op in opcode.haslocal: + if arg not in varnames: + varnames.append(arg) args = varnames + elif op in opcode.hascompare: + args = opcode.cmp_op else: raise NotImplementedError(op, opcode.opname[op]) - if arg not in args: - args.append(arg) codes.append(args.index(arg)) codes.append(0) code = random.choice(chain[op]) return codes, tuple(constants), tuple(varnames) +def _int_to_opname(op): + if op == MARKOV_START: + return "START" + elif op == MARKOV_END: + return "END" + return opcode.opname[op] + ############## FUNCTION CORPUS ################################################ def f1(a): @@ -106,7 +141,6 @@ corpus = [f1, f2, f3, f4] if __name__ == "__main__": print "USING FUNCTION CORPUS:", [func.__name__ for func in corpus] chain = make_chain(corpus) - print "OPCODE MARKOV CHAIN:", chain print func = make_function(chain, "func")