main.cpp

Go to the documentation of this file.
00001 /*------------------------------------------------------------------------------
00002     This file is part of PHP-AST Project by Romain Gaucher (http://rgaucher.info).
00003 
00004     PHP-AST is free software: you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation, either version 3 of the License, or
00007     (at your option) any later version.
00008 
00009     PHP-AST/ORACLE is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with PHP-AST.  If not, see <http://www.gnu.org/licenses/>.
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 += "&amp;"; break;
00068             case '<' : ret += "&lt;"; break;
00069             case '>' : ret += "&gt;"; break;
00070             case '"' : ret += "&quot;"; 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     // return all.
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') // cpp
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         // php-oracle --obf:control-flow     input.xml output.xml obfuscation-pattern_1.xml obfuscation-pattern_2.xml ...
00203         // php-oracle --obf:data-flow        ...
00204         // php-oracle --obf:data             ...
00205         // php-oracle --obf:mixed     | analyze the name of the obfuscation pattern path
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 }

Generated on Wed Feb 27 20:31:06 2008 for php.ast.svn.src. by  doxygen 1.5.3