/* <Author: Gabriele Martini Description: This Software is a A Command-Line Program written in Java to check what Framework it's been used to build the APK> Copyright (C) <2014> <Gabriele Martini> This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.apkcategorychecker.analyzer; import java.io.File; import java.io.IOException; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import javax.xml.parsers.ParserConfigurationException; import org.xml.sax.SAXException; import brut.androlib.AndrolibException; import com.apkcategorychecker.cli.CommandLineInterface; import com.apkcategorychecker.json.FactoryJsCSVBuilder; import com.apkcategorychecker.json.JsCSVBuilder; import com.apkcategorychecker.tool.ToolDecoder; import com.apkcategorychecker.tool.ToolDeleteDirectory; import com.apkcategorychecker.writer.FactoryWriter; import com.apkcategorychecker.writer.Writer; /** * This class analyze a given path: if the path point to an APK file will be called a istance of APKAnalyzer, * if the path point a directory, the directory will be scanned and the APKs contained will be analyzed * * @author Gabriele Martini * */ public class PathAnalyzer { /*--Attributes--*/ /** * Counter */ private int counter = 0; /** * The Arraylist of JsonElement */ private final ArrayList<JsElement> jsonList = new ArrayList<JsElement>(); /** * The istance of APKAnalyzer */ private APKAnalyzer apkAnalyzer; /** * Istance of JsonElement containing the list of js files */ private JsElement _jsonElement; /*--Methods--*/ /** * Method to analyze the given path * * @throws IOException * @throws AndrolibException */ public void Analyze() throws IOException, AndrolibException{ /*--Get the path to analyze from the command-line--*/ String givenPath = CommandLineInterface.getInstance().getPath(); /*--Get the boolean keep--*/ boolean keepDecodedPath = CommandLineInterface.getInstance().getKeep(); /*--Get the path of decoded APK--*/ String _outDecoded = CommandLineInterface.getInstance().getDecodedPath(); /*--Get the output directory pf result file--*/ String _outDir = CommandLineInterface.getInstance().getOutDir(); /*--Get the current time*/ String time = this.GetTime(); /*Create the CSV file*/ String csvPath = this.createCSV(_outDir, time); /*--Analyze the Path--*/ try { this.AnalyzePath(givenPath, keepDecodedPath, _outDecoded, csvPath); } catch (ParserConfigurationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SAXException e) { // TODO Auto-generated catch block e.printStackTrace(); } /*--Build a json file containing the name of all javascript files--*/ this.BuildJson(_outDir, time); } /** * Build the json file containing the list of js files * * @param outDir * @param time */ private void BuildJson(String outDir, String time){ /*--Instance of JsonBuilder--*/ JsCSVBuilder builder; /*--Choose the correct builder--*/ builder = FactoryJsCSVBuilder.getInstance().getJsCSVBuilder(); /*--Build the json file--*/ builder.BuildJs(this.jsonList, outDir, time); } private String GetTime(){ DateFormat dateFormat = new SimpleDateFormat("yyyy.MM.dd HH.mm.ss"); Date date = new Date(); return dateFormat.format(date); } /** * Recursive method to find through a directory * * @param _givenPath Path to analyze * @param _keepDecodedPath If "true" the directory containing the decoded APK will be maintained * @throws IOException * @throws AndrolibException * @throws SAXException * @throws ParserConfigurationException */ private void AnalyzePath(String _givenPath, boolean _keepDecodedPath, String _outDecoded, String _csvPath) throws IOException, AndrolibException, ParserConfigurationException, SAXException { /*--Create a new file from given path--*/ File file_path = new File(_givenPath); /*--Recursive method to find an APK file from the given path--*/ if(file_path.isFile()){ if(file_path.getAbsolutePath().contains(".apk")){ /*Instance of ToolDecoder; decode an APK file in a Directory with the same name of APK*/ ToolDecoder tooldecoder = new ToolDecoder(); String _decodedApkPath = tooldecoder.DecodeApk(_givenPath, _outDecoded); apkAnalyzer = new APKAnalyzer(); apkAnalyzer.Analyze(_givenPath, _decodedApkPath, file_path.getName(), _outDecoded, System.currentTimeMillis(), _csvPath, counter); this._jsonElement = apkAnalyzer.AnalyzeJsFiles(_decodedApkPath); this.jsonList.add(this._jsonElement); this.deleteDirectory(_decodedApkPath, _keepDecodedPath); this.counter = this.counter + 1; } }else if(file_path.isDirectory()){ File[] listOfFiles = file_path.listFiles(); int length = listOfFiles.length; for (int i = 0; i < length; i++) { if (listOfFiles[i].isFile()) { //Decode this.AnalyzePath(listOfFiles[i].getPath(), _keepDecodedPath, _outDecoded, _csvPath); } else if (listOfFiles[i].isDirectory()) { this.AnalyzePath(listOfFiles[i].getPath(), _keepDecodedPath, _outDecoded, _csvPath); } } } } private void deleteDirectory(String _decodedApkPath, boolean _keepDecodedPath) throws IOException { /*If _keepDecodedPath is true do nothing, if false remove the directory * containing the decoded APK*/ if(_keepDecodedPath == false){ ToolDeleteDirectory.getInstance().DeleteDirectory(_decodedApkPath); } } private String createCSV(String _destinationPath, String time){ String format = CommandLineInterface.getInstance().getWriterFormat(); /*--Instance of Writer--*/ Writer writer; /*--Choose the correct writer--*/ writer = FactoryWriter.getInstance().getWriter(format); String _pathCSV = ""; /*Check if _destinationPath is an APK or a Directory in order to *get the right destination path */ File Destination = new File(_destinationPath); if(!Destination.exists()){ Destination.mkdir(); } if(Destination.isDirectory()){ _pathCSV = _destinationPath; }else if(Destination.isFile()){ _pathCSV = _destinationPath.substring(0, _destinationPath.length() - 4); } File _fileCSV = new File(_pathCSV+"/Results_"+time+".csv"); /*--Write the results--*/ try { writer.createHeader(_fileCSV.getAbsolutePath()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return _fileCSV.getAbsolutePath(); } }