Skip to content

Commit 3196528

Browse files
authored
Merge pull request diffblue#291 from diffblue/feature/include_libs
SEC-16: Preparation steps for load analysed web apps with libraries included.
2 parents a0f4421 + ad20aeb commit 3196528

File tree

4 files changed

+115
-2
lines changed

4 files changed

+115
-2
lines changed
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import os
2+
import shutil
3+
import argparse
4+
import tempfile
5+
import contextlib
6+
7+
8+
@contextlib.contextmanager
9+
def _working_dir(new_dir):
10+
previous_dir = os.getcwd()
11+
if not os.path.isdir(new_dir):
12+
os.makedirs(new_dir)
13+
os.chdir(new_dir)
14+
yield
15+
os.chdir(previous_dir)
16+
17+
18+
def _parse_cmd_line():
19+
parser = argparse.ArgumentParser(
20+
description="Creates a JAR file consisting of modelled class files and "
21+
"other class files in the passed 'rt.jar'.")
22+
parser.add_argument("rt", type=str,
23+
help="A path-name of the 'rt.jar' file.")
24+
parser.add_argument("--output-name", type=str, default="rtm.jar",
25+
help="A name of the final JAR file (without path).")
26+
cmdline = parser.parse_args()
27+
if not os.path.isfile(cmdline.rt):
28+
print("ERROR: The passed file '" + cmdline.rt + "' does not exist.")
29+
exit(1)
30+
if os.path.splitext(cmdline.rt)[1].lower() != ".jar":
31+
print("ERROR: The passed file '" + cmdline.rt + "' does not have '.jar' extension.")
32+
exit(1)
33+
cmdline.rt = os.path.abspath(cmdline.rt)
34+
return cmdline
35+
36+
37+
def _mkrtm(cmdline):
38+
model_classes_root_dir = os.path.abspath(os.path.join("target", "classes"))
39+
temp_root_dir = tempfile.mkdtemp()
40+
classes_root_dir = os.path.join(temp_root_dir, "classes")
41+
rt_unpack_root_dir = os.path.join(temp_root_dir, "RT_UNPACK")
42+
dst_jar_pathname = os.path.abspath(os.path.join("target", cmdline.output_name))
43+
44+
shutil.copytree(model_classes_root_dir, classes_root_dir)
45+
with _working_dir(rt_unpack_root_dir):
46+
os.system("jar -xvf '" + cmdline.rt + "'")
47+
for root, _, file_names in os.walk(rt_unpack_root_dir):
48+
for filename in file_names:
49+
if os.path.splitext(filename)[1].lower() == ".class":
50+
src_pathname = os.path.abspath(os.path.join(root, filename))
51+
rel_pathname = os.path.relpath(src_pathname, rt_unpack_root_dir)
52+
dst_pathname = os.path.join(classes_root_dir, rel_pathname)
53+
if not os.path.isfile(dst_pathname):
54+
if not os.path.isdir(os.path.dirname(dst_pathname)):
55+
os.makedirs(os.path.dirname(dst_pathname))
56+
shutil.copy(src_pathname, dst_pathname)
57+
with _working_dir(classes_root_dir):
58+
os.system("jar cvfm " + os.path.basename(dst_jar_pathname) + " " +
59+
os.path.join(rt_unpack_root_dir, "META-INF", "MANIFEST.MF") +
60+
" .")
61+
shutil.copy(os.path.join(classes_root_dir, os.path.basename(dst_jar_pathname)),
62+
dst_jar_pathname)
63+
64+
65+
if __name__ == '__main__':
66+
_mkrtm(_parse_cmd_line())

driver/mkbench.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ def _read_info_of_class_files(class_files, temp_dir, verbosity):
7070
return classes_info, java_class_info_call_duration
7171

7272

73-
def collect_java_binaries(app_binary_dirs, temp_dir, output_json, verbosity):
73+
def collect_java_binaries(app_binary_dirs, list_of_classpaths, temp_dir, output_json, verbosity):
7474
prof_start_time = time.time()
7575
prof = dict()
7676

@@ -164,7 +164,10 @@ def collect_java_binaries(app_binary_dirs, temp_dir, output_json, verbosity):
164164
if not os.path.isdir(os.path.dirname(output_json)):
165165
os.makedirs(os.path.dirname(output_json))
166166
with open(output_json, "w") as ofile:
167-
ofile.write(json.dumps({"jar": java_binaries.jar_files}, sort_keys=True, indent=4))
167+
ofile.write(json.dumps({
168+
"jar": sorted(java_binaries.jar_files),
169+
"classpath": sorted([p for p in list_of_classpaths if os.path.exists(p)])
170+
}, sort_keys=True, indent=4))
168171

169172
# Lastly, we complete and return statistics from this stage.
170173
prof["num_jars_final"] = len(java_binaries.jar_files)

driver/run.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ def __parse_cmd_line():
2828
help="The install directory of the Java web application to be analysed. Under that "
2929
"directory (directly or indirectly) there should be all binaries files "
3030
"(WAR/JAR/CLASS files) of that wab application.")
31+
parser.add_argument("-L", "--libraries", nargs='+', default=[],
32+
help="A list of disk paths to libraries you want to include into class path. A path "
33+
"can either be a path-name of a JAR file, or a directory.")
3134
parser.add_argument("-R", "--results-dir", type=str,
3235
help="A directory into which all results from the analysis of the given Java web applicaton "
3336
"will be written.")
@@ -104,6 +107,7 @@ def evaluate(cmdline):
104107
classes_jar_pathname = os.path.abspath(os.path.join(cmdline.results_dir, "program.json"))
105108
prof["collect_java_binaries"] = mkbench.collect_java_binaries(
106109
input_search_dirs,
110+
cmdline.libraries,
107111
cmdline.temp_dir,
108112
classes_jar_pathname,
109113
cmdline.verbosity

src/taint-analysis/taint_config.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,39 @@ bool taint_configt::load(message_handlert &handler)
191191
return false;
192192
}
193193

194+
struct cmdline_updatert : public cmdlinet
195+
{
196+
void add_to_classpaths(const std::vector<std::string> &classpaths)
197+
{
198+
PRECONDITION(!classpaths.empty());
199+
int idx=getoptnr("classpath");
200+
if(idx==-1)
201+
{
202+
options.push_back({});
203+
idx=int(options.size()-1UL);
204+
}
205+
if(options.at(idx).isset==false)
206+
{
207+
options.at(idx).isset=true;
208+
if(options.at(idx).values.empty())
209+
options.at(idx).values.push_back("");
210+
}
211+
std::string &dst_classpaths = options.at(idx).values.front();
212+
for(const auto &classpath : classpaths)
213+
{
214+
if(!dst_classpaths.empty())
215+
dst_classpaths+=
216+
#ifdef _WIN32
217+
';'
218+
#else
219+
':'
220+
#endif
221+
;
222+
dst_classpaths+=classpath;
223+
}
224+
}
225+
};
226+
194227
void taint_build_cmdline_from_config(
195228
const std::string &cfg_file_path,
196229
messaget * const logger,
@@ -213,5 +246,12 @@ void taint_build_cmdline_from_config(
213246
return;
214247
for(auto const &jar : cfg["jar"].array)
215248
cmdline.args.push_back(jar.value);
249+
if(!cfg["classpath"].array.empty())
250+
{
251+
std::vector<std::string> classpaths;
252+
for(auto const &classpath : cfg["classpath"].array)
253+
classpaths.push_back(classpath.value);
254+
static_cast<cmdline_updatert*>(&cmdline)->add_to_classpaths(classpaths);
255+
}
216256
cmdline.set("lazy-methods");
217257
}

0 commit comments

Comments
 (0)