00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <fstream>
00020 #include <iostream>
00021 #include <list>
00022 #include <string>
00023 #include <map>
00024 #include "AstContainer.h"
00025 #include "AstPath.h"
00026 #include "tree_util.h"
00027 #include "Metric.h"
00028 #include "Translation.h"
00029 #include "Obfuscator.h"
00030 #include "Utils.h"
00031
00032 using namespace std;
00033
00034 list<string> loadConf(const string& fname)
00035 {
00036 ifstream file(fname.c_str());
00037 string s;
00038 list<string> ret;
00039 if (!file) {
00040 cerr << "Cannot opent the file..." << endl;
00041 }
00042 while(getline(file, s))
00043 {
00044 ret.push_back(s);
00045 }
00046 return ret;
00047 }
00048
00049 unsigned loc(const string& fname)
00050 {
00051 ifstream file(fname.c_str());
00052 string s;
00053 unsigned ret = 0;
00054 if (!file) {
00055 cerr << "Cannot opent the file..." << endl;
00056 }
00057 while(getline(file, s))
00058 ++ret;
00059 return ret;
00060 }
00061
00062 string xmlentities(const string& str)
00063 {
00064 string ret;
00065 for(string::const_iterator iter=str.begin();iter!=str.end();++iter) {
00066 switch (*iter) {
00067 case '&' : ret += "&"; break;
00068 case '<' : ret += "<"; break;
00069 case '>' : ret += ">"; break;
00070 case '"' : ret += """; break;
00071 default: ret += *iter; break;
00072 }
00073 }
00074 return ret;
00075 }
00076
00077 string txt_out(const string& fname, map<string, MetricResult>& m)
00078 {
00079 string ret = "";
00080 ret += "---------------------\n" ;
00081 ret += "Analysis of '" + fname + "' [loc=" + to_string<unsigned>(loc(fname)) + "]" + "\n";
00082 ret += "---------------------\n" ;
00083 ret += ("Variables: " + m["NumberVariables"].main.toString() + "\n");
00084 ret += ("Functions: " + m["NumberFunctions"].main.toString() + "\n");
00085 ret += ("Sinks: " + m["NumberSinks"].main.toString() + "\n");
00086 ret += ("Classes: " + m["NumberClasses"].main.toString() + "\n");
00087 ret += ("Resources: " + m["NumberResources"].main.toString() + "\n");
00088 ret += ("Inputs: " + m["NumberInput"].main.toString() + "\n");
00089 ret += ("dInputs: " + m["NumberDiffuseInputs"].main.toString() + "\n");
00090 ret += ("dInputs2Sink: " + m["NumberSunkDiffuseInputs"].main.toString() + "\n");
00091 return ret;
00092 }
00093
00094 string xml_out(const string& fname, map<string, MetricResult>& m)
00095 {
00096 string ret = "";
00097 ret += "<instance>\n";
00098 ret += ("\t<file loc=\"" + to_string<unsigned>(loc(fname)) + "\" >" + xmlentities(fname) + "</file>\n" );
00099 ret += ("\t<results>\n");
00100 ret += ("\t\t<variables>" + m["NumberVariables"].main.toString() + "</variables>\n");
00101 ret += ("\t\t<functions>" + m["NumberFunctions"].main.toString() + "</functions>\n");
00102 ret += ("\t\t<sinks>" + m["NumberSinks"].main.toString() + "</sinks>\n");
00103 ret += ("\t\t<classes >" + m["NumberClasses"].main.toString() + "</classes >\n");
00104 ret += ("\t\t<resources>" + m["NumberResources"].main.toString() + "</resources >\n");
00105 ret += ("\t\t<nbInputs>" + m["NumberInput"].main.toString() + "</nbInputs>\n");
00106 ret += ("\t\t<nbDiffInputs>" + m["NumberDiffuseInputs"].main.toString() + "</nbDiffInputs>\n");
00107 ret += ("\t\t<nbDiffInputsSunked>" + m["NumberSunkDiffuseInputs"].main.toString() + "</nbDiffInputsSunked>\n");
00108 ret += ("\t</results>\n");
00109 ret += "</instance>\n";
00110 return ret;
00111 }
00112
00113
00114 map<string, MetricResult> computeMetrics(const Ast& ast)
00115 {
00116 NumberFunctions numbFunctions;
00117 list<string> sinkList = loadConf("./defs/php/sensitive_sinks.pds");
00118 list<string> taintList= loadConf("./defs/php/tainted_data_sources.pds");
00119 list<string> sanitList= loadConf("./defs/php/untainting_data.pds");
00120
00121 NumberSunkDiffuseInputs numSinks(&ast, "./defs/php.xml", sinkList);
00122 NumberDiffuseInputs numIntrinsicInputs("./defs/php.xml");
00123 NumberInput numInputs("./defs/php.xml");
00124 NumberVariables numVariable;
00125 NumberFunctions numFunctions;
00126 NumberClasses numClasses;
00127 NumberSinks sinks(sinkList,&ast);
00128 NumberResources resources(taintList,&ast);
00129
00130 MetricResult inputs, intrisics, nsinked, sink;
00131 MetricResult vars, func, classes, resource;
00132
00133 vars = ast.compute(&numVariable);
00134 func = ast.compute(&numFunctions);
00135 classes = ast.compute(&numClasses);
00136 inputs = ast.compute(&numInputs);
00137 intrisics = ast.compute(&numIntrinsicInputs);
00138 nsinked = ast.compute(&numSinks);
00139 sink = ast.compute(&sinks);
00140 resource = ast.compute(&resources);
00141
00142
00143 map<string, MetricResult> ret;
00144 ret["NumberSunkDiffuseInputs"] = nsinked;
00145 ret["NumberDiffuseInputs"] = intrisics;
00146 ret["NumberInput"] = inputs;
00147 ret["NumberVariables"] = vars;
00148 ret["NumberFunctions"] = func;
00149 ret["NumberClasses"] = classes;
00150 ret["NumberSinks"] = sink;
00151 ret["NumberResources"] = resource;
00152
00153 return ret;
00154 }
00155
00156
00157
00158 int main(int argc, char *argv[])
00159 {
00160 if (argc == 2)
00161 {
00162 string fname(argv[1]);
00163 Ast ast(fname);
00164 utils::replace(fname, ".xml", ".php");
00165 ast.printInfo(cout);
00166 map<string, MetricResult> metrics = computeMetrics(ast);
00167 cout << txt_out(fname, metrics) << endl;
00168 }
00169 else if (argc == 4)
00170 {
00171 string opt(argv[1]);
00172 string fname(argv[2]);
00173 string oput(argv[3]);
00174 Ast ast(fname);
00175 if (opt == "--out:cpp" || opt == "--out:php") {
00176 Translation *trans = 0;
00177 if (opt[6] == 'c')
00178 trans = new Ast2Cpp;
00179 else
00180 trans = new Ast2Php;
00181 StringBuffer o = ast.convert(trans);
00182 o.write(oput);
00183 }
00184 else if (opt == "--out:xml" || opt == "--out:text") {
00185 map<string, MetricResult> metrics = computeMetrics(ast);
00186 if (opt[6] == 'x')
00187 cout << xml_out(fname, metrics) << endl;
00188 else
00189 cout << txt_out(fname, metrics) << endl;
00190 }
00191 else {
00192 ofstream fout;
00193 fout.open(oput.c_str(), ofstream::app);
00194 map<string, MetricResult> metrics = computeMetrics(ast);
00195 utils::replace(fname, ".xml", ".php");
00196 fout << txt_out(fname, metrics) << endl;
00197 fout.close();
00198 }
00199 }
00200 else if (argc >= 5)
00201 {
00202
00203
00204
00205
00206 vector<string> obf;
00207 Ast2Cpp ast2cpp;
00208 Ast2Php ast2php;
00209 for (unsigned i=4;i<argc;i++)
00210 obf.push_back(string(argv[i]));
00211 string fname(argv[2]);
00212 string output(argv[3]);
00213 if (string(argv[1]) == "--obf:control-flow")
00214 {
00215 Ast ast(fname);
00216 for (vector<string>::const_iterator iter=obf.begin();iter!=obf.end();++iter) {
00217 ControlFlow cf(*iter);
00218 ast.apply(&cf);
00219 }
00220 StringBuffer o = ast.convert(&ast2php);
00221 o.write(output);
00222 }
00223 }
00224 return 0;
00225 }