---
tags: comp-decomp
title: Design Reasons
---
# To do:
- Meta-data matching is bad. See something else.
-
# Why use partial matching (Flexible)
## Partial matching (Flexible)
Partial matching is using a statement whose bytecode doesn't exactly match the one used in target binary.
## Problem
We find set of instructions that do not exist in database. See example below.

Offset 0~6 maps to instruction `from ctypes import *`. However such an instruction does not exist in the database.
## Solution
We find that we can leverage statements that use if not exact then similar instructions. We use `LOAD_CONST`, `IMPORT_NAME`, and `IMPORT_STAR`. See matches listed as follows.
```
import traceback
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
from itertools import chain, repeat
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
from multiprocessing import Pool
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
import os, time, sys
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
from winreg import OpenKey, EnumKey, CloseKey, HKEY_LOCAL_MACHINE
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
import sys, getopt
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
from subprocess import Popen, PIPE, STDOUT
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
import xml.etree.ElementTree as ET
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'ROT_TWO', 'POP_TOP', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
if not re: import re
['LOAD_NAME', 'POP_JUMP_IF_TRUE', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
import gc, os, sys, _testcapi
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
from ctypes.wintypes import BOOL, UINT, BYTE, WCHAR, UINT, DWORD
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
import apples, sys, crumbs, larry, atexit # Pleasant comments
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME', 'LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'STORE_NAME']
from ctypes import c_short, c_uint, c_int, c_long, pointer, POINTER, byref
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
from ctypes import c_short, c_uint, c_int, c_long, POINTER
['LOAD_CONST', 'LOAD_CONST', 'IMPORT_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'IMPORT_FROM', 'STORE_NAME', 'POP_TOP']
```
Note that, none of them include `IMPORT_STAR`. However, most of them are very close to `from ctypes import *` (e.g., `from multiprocessing import Pool`). We can perturb such instructions to get to the solution!
## Additional questions
Q1. Why not synthesize directly?
-> Random synthesis will have larger search space.
Q2. Why not pattern match?
-> Our goal is to synthesize source to find resultant binary that matches target binary. Reverse-engineering binary is decompilation which has its own limitations as listed XXX.
# Why use partial matching (Strict)
## Partial matching (Strict)
Partial matching is using a statement whose bytecode doesn't exactly match the one used in target binary.
## Problem
We find set of instructions that do not exist exactly in database. See example below.

Offset 196~224 maps to instruction:
```
VirtualProtect(memorywithshell, ctypes.c_int(len(shellcode)),0x40,ctypes.byref(old))
```
However such an instruction does not exist in the database. Atleast not the exact combination of it.
## Solution
We find that we can find combinations of the available instructions.
```
data.extend(_pack_uint32(0))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
domain_literal.append(ValueTerminal('[', 'domain-literal-start'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
section.append(ValueTerminal(digits, 'digits'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(list(arr), list(range(10)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
b.extend(list(range(5)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(next(it), 100)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(join(0), None)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(join(), None)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(len(set(fd_counts)), 1, fd_counts)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_CONST', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(queue_full(queue, MAXSIZE), False)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(acquire(False, None), False)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(acquire(False, TIMEOUT1), False)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
f.write(struct.pack('B', len(s)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
super(F, self).__init__(123)
['LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
print(repr(int(byteyears)).rjust(8))
['LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
print("OSError:", html.escape(str(msg)))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
error('bad filter {!r}: {}'.format(raw, e))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
error('unsupported column {!r}'.format(column))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
connection.putheader("Content-Length", str(len(request_body)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
print('??? new object created while tearing down:', line.rstrip())
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
self.assertEqual(dt.__format__(''), str(dt))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(dt.date(), date(2002, 3, 4))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(dt.time(), time(18, 45, 3, 1234))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(str(tz), tz.tzname(None))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
self.assertEqual('UTC', timezone(ZERO).tzname(None))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
self.assertEqual('\ud800', timezone(ZERO, '\ud800').tzname(None))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
self.assertEqual('UTC+01:06:40', timezone(timedelta(0, 4000)).tzname(None))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
super().feed(data.decode('ascii', 'surrogateescape'))
['LOAD_NAME', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
print("open", openfilename.encode(enc))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
self.add_kwarg(l_args, "sep", String(repr(sep)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
print('{:40s} {:<32s} {:<9s}'.format('File', 'MD5', 'Size'))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
print('{:40s} {:>32s} {:>9s}'.format(f, h, s))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
parts.append(_formatparam(k.replace('_', '-'), v))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
print('Origin: {}'.format(getsourcefile(module)))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
Bunch(f, 1).wait_for_finished()
['LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_METHOD', 'CALL_METHOD', 'POP_TOP']
Array("index1", index1).dump(fp, trace)
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
self.msg(2, "ImportError:", str(msg))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
print("?", name, "imported from", ', '.join(mods))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
self.assertEqual(self.loads(dumped), bytearray(b'xxx'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(unpickled, range(1, 7))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
object.__setattr__(self, 'header_factory', HeaderRegistry())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
p.runctx('f(m)', globals(), locals())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEquals(type(000), type(0))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
info_add('locale.encoding', locale.getpreferredencoding(False))
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
self.processed_file(str(tree), "<stdin>", input)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(self.type2test(LyingTuple((2,))), self.type2test((1,)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(len(self.type2test()), 0)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(next(iter(T((1,2)))), 1)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
join(os.getenv('HOME'), '/Library/Frameworks')
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_CONST', 'CALL_FUNCTION', 'POP_TOP']
self.checkequal('abc', 'abc', '__getitem__', slice(0, 3))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.checkequal('w x y z', ' ', 'join', Sequence())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.fixtype(' ').join(f())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.checkraises(TypeError, 'abc', '__mod__', X())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
data.insert(0, int(m))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
stn(info.get("prefix", ""), 155, encoding, errors)
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'POP_TOP']
offsets.append(int(match.group(1)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(read_written(x, 'float'), x)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
self.assertFalse(isinstance(ast.Num(42), N))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(repr(ast.literal_eval('-0.0')), '-0.0')
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
gen().__anext__().send(100)
['LOAD_NAME', 'CALL_FUNCTION', 'LOAD_METHOD', 'CALL_METHOD', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
eq(base64.encodebytes(bytearray(b'abc')), b'YWJj\n')
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'LOAD_CONST', 'CALL_FUNCTION', 'POP_TOP']
eq(base64.encodebytes(array('B', b'abc')), b'YWJj\n')
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'LOAD_CONST', 'CALL_FUNCTION', 'POP_TOP']
eq(base64.b64decode(data.decode('ascii')), res)
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'POP_TOP']
self.assertEqual(func(bstr.decode('ascii')), res)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'CALL_FUNCTION', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
eq(base64.b32decode(data, True), res)
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'POP_TOP']
eq(base64.b32decode(data.decode('ascii'), True), res)
['LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_CONST', 'CALL_METHOD', 'LOAD_NAME', 'CALL_FUNCTION', 'POP_TOP']
tracer.run(compile(textwrap.dedent(code), '<string>', 'exec'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'CALL_METHOD', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertTrue(hasattr(getattr(binascii, name), '__call__'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(a2b_qp(type2test(b"=")), b"")
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(TypeError, getattr(binascii, func), "test")
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(nd.tolist(), farray(items, (3, 4)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(TypeError, eval, "1 in nd", locals())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(ValueError, slice_indices, slice(0,1,0), 4)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(abs(AbsClass()), -5)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(ValueError, compile, chr(0), 'f', 'exec')
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_CONST', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertIn('local_var', dir())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(eval('a', globals, locals), 1)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(eval('dir()', g, m), list('xyz'))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(eval('globals()', g, m), g)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'CALL_METHOD', 'POP_TOP']
eval('[locals() for i in (2,3)]', g, collections.UserDict())
['LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_METHOD', 'CALL_METHOD', 'CALL_FUNCTION', 'POP_TOP']
self.assertRaises(TypeError, eval, 'dir()', globals(), C())
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_NAME', 'CALL_FUNCTION', 'LOAD_NAME', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(TypeError, list, filter(badfunc, range(5)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertRaises(TypeError, list, filter(42, (1, 2)))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(hash(Z(42)), hash(42))
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_FUNCTION', 'LOAD_NAME', 'LOAD_CONST', 'CALL_FUNCTION', 'CALL_METHOD', 'POP_TOP']
self.assertEqual(max(1, 2, 3), 3)
['LOAD_NAME', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_CONST', 'LOAD_CONST', 'LOAD_CONST', 'CALL_FUNCTION', 'LOAD_CONST', 'CALL_METHOD', 'POP_TOP']
```
By perturbing any of the above combinations we can work with a better seed!
## Additional questions
Q1. Why not synthesize directly?
-> Random synthesis will have larger search space.
Q2. Why not pattern match?
-> Our goal is to synthesize source to find resultant binary that matches target binary. Reverse-engineering binary is decompilation which has its own limitations as listed XXX.
Q3. Why not flexible partial match?
-> Search space is larger in there since we allow the flexibility of having instruction not already present here. We quantify the search space as XXX.
Q4. How do you choose?
-> Currently random. Our rules ensure that whatever we choose, it converges to the target sequence of bytecode.