forked from wmkhoo/taintgrind
-
Notifications
You must be signed in to change notification settings - Fork 4
/
make_capstone_options.py
203 lines (146 loc) · 5.54 KB
/
make_capstone_options.py
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
from optparse import OptionParser
import os, sys, traceback
import errno
import time
import re
USER_DELAY = 0.0
def get_options(parser):
# http://docs.python.org/2/library/optparse.html
#usage = "usage: %prog [options] arg"
#parser = OptionParser(usage)
#parser.add_option('-n', "--nsamples", action="store", dest="nsamples", type="int", help='number of samples in FILENAME')
parser.add_option("--vginstdir",
action='store',
dest='vginstdir',
default = None,
help='the Valgrind installation directory to use to configure Capstone')
parser.add_option("--capstonedir",
action='store',
dest='capstonedir',
default = None,
help='the Capstone directory containing the source code')
parser.add_option("--outmakefile",
action='store',
dest='outmakefile',
default = None,
help='the Capstone makefile to output')
parser.add_option("-v", "--verbose",
action="store_true",
dest="verbose")
return parser.parse_args()
def check_options(parser, options, args):
if options.vginstdir == None:
parser.error("VGINSTDIR not supplied")
if options.capstonedir == None:
parser.error("CAPSTONEDIR not supplied")
if options.outmakefile == None:
parser.error("OUTMAKEFILE not supplied")
def silentremove(filename):
try:
os.remove(filename)
except OSError as e: # this would be "except OSError, e:" before Python 2.6
if e.errno != errno.ENOENT: # errno.ENOENT = no such file or directory
raise # re-raise exception if a different error occured
def append_tailing_slash(indir):
if indir[-1] != '/':
indir += '/'
return indir
def get_flags(infile):
flags = "" # "VGO_linux=1 VGA_amd64=1"
flagstable = dict()
# read content
content = readfromfile(infile)
# get VGO flags = OS flags
vgoList = re.findall(r'-DVGO_[a-z,A-Z,0-9]*=\d', content) # eg -DVGO_linux=1
for vgo in vgoList:
flagstable[ vgo[2:] ] = 1
# get VGA flags = architecture flags
vgaList = re.findall(r'-DVGA_[a-z,A-Z,0-9]*=\d', content) # eg -DVGA_amd64=1
for vga in vgaList:
flagstable[ vga[2:] ] = 1
# get VGP flags. Not sure what they are. We don't really need them at the moment anyway since the compilation works wihtout them
# I put them anyway...
vgpList = re.findall(r'-DVGP_[a-z,A-Z,0-9,_]*=\d', content) # eg -DVGP_amd64_linux=1
for vgp in vgpList:
flagstable[ vgp[2:] ] = 1
for key in flagstable:
flags += key + " "
return flags
def readfromfile(filename):
with open(filename, "r") as f:
return f.read()
def save2file(content, filename):
with open(filename, "w") as f:
f.write(content)
def print_progress_ok(s):
print s.ljust(60) + "[OK]"
time.sleep(USER_DELAY)
def main(options):
vginstdir = os.path.realpath(options.vginstdir)
capstonedir = os.path.realpath(options.capstonedir)
outmakefile = options.outmakefile
# folders exists?
if not os.path.isdir(vginstdir):
raise Exception("folder '%s' does not exist" % vginstdir)
if not os.path.isdir(capstonedir):
raise Exception("folder '%s' does not exist" % capstonedir)
# add tailing slash if need be
vginstdir = append_tailing_slash(vginstdir)
capstonedir = append_tailing_slash(capstonedir)
# folder looks like valgrind installation folder?
vginstdir_incval = vginstdir + "include/valgrind/"
if not os.path.isdir(vginstdir_incval):
raise Exception("'include/valgrind/' missing from folder '%s'. Was Valgrind compiled and installed in this folder?" % vginstdir)
print_progress_ok("Validity of Valgrind's installation directory")
# read the Makefile of Valgrind and extract
# - the relevant options to pass to valgrind's headers
# - platform flags :VGA_x86, VGA_amd64, VGA_ppc32, VGA_ppc64be, VGA_ppc64le, VGA_arm, VGA_arm64, VGA_s390x, VGA_mips32, VGA_mips64
# - OS flags: ...
# - the relevant options for capstone itself, so we compile only the platforms we need
# (arm, aarch64, mips, powerpc, sparc, systemz, x86, xcore)
# Well, I've decided it's just simpler to compile it all... TODO
# I extract any flags that looks like -DVGO_***=1, eg -DVGO_linux=1 and -DVGA_***=1
flags = get_flags("../Makefile")
print_progress_ok("Flags recovery")
# file content.
# originally I used this to install. I've changed to a simple copy so it does not require root
# sudo %s CAPSTONE_BUILD_CORE_ONLY=yes CAPTSTONE_SECRETGRIND_HEADER_DIR=%s CAPSTONE_STATIC=yes CAPSTONE_SHARED=no ./make.sh install
# no longer copy the lib*.a
# no longer copy the header files
content = """
#!/bin/sh
# WARNING: this was auto-generated. Do not change!!!
# build static libs only
%s CAPSTONE_BUILD_CORE_ONLY=yes CAPTSTONE_SECRETGRIND_HEADER_DIR=%s CAPSTONE_STATIC=yes CAPSTONE_SHARED=no ./make.sh
""" % (flags, vginstdir_incval)
#print content
# save the file
outmakefile = capstonedir + outmakefile
silentremove(outmakefile)
save2file(content, outmakefile)
print_progress_ok("File creation")
# create the symbolic link
silentremove("../include/capstone")
os.symlink(capstonedir + "include/", "../include/capstone")
print_progress_ok("Include dir creation")
# create the file that we'll use for building capstone with the correct options
# CAPSTONE_ARCHS="arm aarch64 x86" TODO
# CAPSTONE_COMPILE_TEMPLATE
if __name__ == '__main__':
parser = OptionParser()
(options, args) = get_options(parser)
check_options(parser, options, args)
ret = 0
try:
main(options)
print "SUCCESS"
except Exception, e:
ret = -1
print "Exception: " + str(e)
#except:
# print "Exception caught"
# traceback.print_exc(file=sys.stdout)
#finally:
#print 'finally'
sys.exit(ret)
#print 'Done ...'