Skip to content

Commit cee55c4

Browse files
committed
Add files via upload
1 parent 09fd191 commit cee55c4

File tree

1 file changed

+103
-0
lines changed

1 file changed

+103
-0
lines changed
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
"""
2+
Obtain matchups between a constant name and the standard enum IDA Pro uses.
3+
4+
Moved here from https://github.com/fireeye/flare-ida/tree/master/MSDN_crawler
5+
6+
Original Authors: William Ballenthin, Moritz Raabe
7+
Copyright 2014 Mandiant, A FireEye Company
8+
9+
Mandiant licenses this file to you under the Apache License, Version
10+
2.0 (the "License"); you may not use this file except in compliance with the
11+
License. You may obtain a copy of the License at:
12+
13+
http://www.apache.org/licenses/LICENSE-2.0
14+
15+
Unless required by applicable law or agreed to in writing, software
16+
distributed under the License is distributed on an "AS IS" BASIS,
17+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
18+
implied. See the License for the specific language governing
19+
permissions and limitations under the License.
20+
"""
21+
22+
import re
23+
import sys
24+
import os
25+
import logging
26+
import subprocess
27+
28+
g_logger = logging.getLogger("til_extractor")
29+
30+
31+
def show_usage():
32+
print 'Usage:',
33+
print sys.argv[0] + ' <path to tilib> <til directory>'
34+
35+
36+
def main(tilib_exe, til_dir):
37+
logging.basicConfig(level=logging.WARN)
38+
39+
if not os.path.isfile(tilib_exe):
40+
g_logger.warn(tilib_exe + ' is not a file')
41+
return False
42+
if not os.path.isdir(til_dir):
43+
g_logger.warn(til_dir + ' is not a directory')
44+
return False
45+
46+
const_pattern = re.compile("([0-9A-Fa-f]{8}) ([0-9A-Fa-f]{8}) +([A-Za-z0-9_]+) ([A-Za-z0-9_]+)")
47+
ignored_enum_names = set(["int", "unsigned", "const", "UINT", "void", "struct", "__int16", "char"])
48+
49+
for til_file in os.listdir(til_dir):
50+
til_file = os.path.join(til_dir, til_file)
51+
g_logger.debug("Will process til file: %s", til_file)
52+
if not os.path.isfile(til_file):
53+
continue
54+
55+
try:
56+
output = subprocess.check_output([tilib_exe, "-l", til_file],
57+
shell=True,
58+
stderr=subprocess.STDOUT)
59+
except subprocess.CalledProcessError as e:
60+
g_logger.warn("Error calling tilib.exe with %s -- %s", til_file, e)
61+
# Not all files can be parsed correctly
62+
continue
63+
64+
enums = {} # dict of (enum_name:string, enum_def:dict of (constant_name:string, constant_value:int))
65+
for line in output.split("\n"):
66+
if "__stdcall" in line:
67+
continue
68+
if "__cdecl" in line:
69+
continue
70+
if "__fastcall" in line:
71+
continue
72+
73+
m = const_pattern.match(line)
74+
if not m:
75+
continue
76+
77+
constant_value = int(m.group(2), 0x10)
78+
enum_name = m.group(3)
79+
constant_name = m.group(4)
80+
81+
# our simple parsing of the text output isn't very smart, so we get
82+
# some typedefs, too try to ignore those, on a best effort basis
83+
if enum_name in ignored_enum_names:
84+
continue
85+
86+
g_logger.debug("%s", line)
87+
g_logger.debug(" value: %s", hex(constant_value))
88+
g_logger.debug(" enum_name: %s", enum_name)
89+
g_logger.debug(" constant_name: %s", constant_name)
90+
91+
enum = enums.get(enum_name, {})
92+
if constant_name not in enum:
93+
enum[constant_name] = constant_value
94+
enums[enum_name] = enum
95+
96+
return_data = {} # dict of (constant_name:string, enum_name:string)
97+
for enum_name, enum in enums.iteritems():
98+
for constant_name, constant_value in enum.iteritems():
99+
return_data[constant_name] = enum_name
100+
return return_data
101+
102+
if __name__ == '__main__':
103+
main()

0 commit comments

Comments
 (0)