Browse Source

Updates

master
Ben Kurtovic 10 years ago
parent
commit
1eb8648388
1 changed files with 61 additions and 27 deletions
  1. +61
    -27
      func_smash.py

+ 61
- 27
func_smash.py View File

@@ -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")


Loading…
Cancel
Save