-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathenum_missing.py
More file actions
75 lines (62 loc) · 2.33 KB
/
enum_missing.py
File metadata and controls
75 lines (62 loc) · 2.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# Copyright (c) 2011 The Native Client Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import re
import subprocess
import generator
# This script attempts to list instructions that generator.py does not
# know about (whether whitelisted or not).
#
# It generates instructions by enumerating prefix/opcode combinations
# and feeding them through objdump to see which are valid.
def GetExamples():
for p_twobyte in [[], [0x0f]]:
for byte in xrange(256):
for p_data16 in [[], [0x66]]:
for p_rep in [[], [0xf2], [0xf3]]:
yield p_data16 + p_rep + p_twobyte + [byte]
# Attempt to enumerate possible AMD 3DNow instructions.
for byte in xrange(256):
yield [0x0f, 0x0f, 0xff, byte]
# Returns whether the prefix sequence "bytes" appears in the trie
# "node". This cheats: it just checks whether the trie contains a
# subtree, but it does not check whether the subtree contains any
# accepting nodes.
def TrieContainsPrefix(node, bytes):
for byte in bytes:
node = node.children.get(byte)
if node is None:
return False
return True
def Main():
pad_to = 16
fh = open('tmp.S', 'w')
for bytes in GetExamples():
bytes = bytes + [0x90] * (pad_to - len(bytes))
fh.write('.ascii "%s"\n' % ''.join('\\x%02x' % byte for byte in bytes))
fh.close()
subprocess.check_call(['gcc', '-m32', '-c', 'tmp.S', '-o', 'tmp.o'])
def GetInstrs():
proc = subprocess.Popen(['objdump', '-d', 'tmp.o', '-M', 'intel'],
stdout=subprocess.PIPE)
regexp = re.compile('\s*([0-9a-f]+):\s*((\S\S )+)\s*(.*)')
for line in proc.stdout:
match = regexp.match(line)
if match is not None:
addr = int(match.group(1), 16)
if addr % pad_to == 0:
bytes = match.group(2).split()
instr = match.group(4)
yield instr
root_node = generator.ExpandWildcards(generator.ConvertToDfa(
generator.GetRoot(nacl_mode=False)))
for bytes, instr in zip(GetExamples(), GetInstrs()):
if '(bad)' in instr:
continue
if any(x in instr for x in ('repz ', 'repnz ', 'data16')):
continue
bytes = ['%02x' % byte for byte in bytes]
if not TrieContainsPrefix(root_node, bytes):
print '%s:%s' % (' '.join(bytes), instr)
if __name__ == '__main__':
Main()