├── .gitignore ├── AUTHORS ├── GVolSchema.sql ├── LICENSE ├── README.md ├── build.xml ├── docs └── GVol-User Guide.pdf ├── manifest.mf ├── nbproject ├── project.properties └── project.xml ├── sqlite-jdbc-3.8.10.2.jar └── src ├── database ├── BatchFile.java ├── DatabaseConn.java ├── Option.java ├── OptionValueType.java ├── Plugin.java └── Profile.java ├── dialog ├── BatchFileDialog.java ├── BatchFileWizardDialog.java ├── OptionsDialog.java ├── PluginsDialog.java └── ProfilesDialog.java ├── diff ├── JDiff.java └── Line.java ├── iface ├── ComLayerWithOutputPanel.java ├── ComLayerWithPluginPanel.java └── ComLayerWithThread.java └── main ├── ComboBoxItem.java ├── CommandExecuter.java ├── MFileChooser.java ├── MainClass.java ├── MainFrame.java ├── OSType.java ├── OptionsPanel.java ├── OutputPanel.java └── PluginsPanel.java /.gitignore: -------------------------------------------------------------------------------- 1 | *.exe 2 | *.db 3 | *.jar 4 | dist/ 5 | build/ 6 | 7 | #netbeans specific 8 | core 9 | nbproject/ 10 | !nbproject/project.properties 11 | !nbproject/project.xml 12 | 13 | #java specific 14 | *.class 15 | 16 | #general swap/backup files 17 | *.so 18 | *.log 19 | *.out 20 | *~ 21 | *.swp 22 | *.DS_Store 23 | *.lock 24 | 25 | *.jar 26 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Mohamad Shawkey 2 | May Medhat 3 | 4 | -------------------------------------------------------------------------------- /GVolSchema.sql: -------------------------------------------------------------------------------- 1 | CREATE TABLE VolCommand 2 | ( 3 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 4 | Cmd VARCHAR(1000) NOT NULL 5 | ); 6 | 7 | CREATE TABLE PROFILE 8 | ( 9 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 10 | Name VARCHAR(100) NOT NULL, 11 | [Desc] VARCHAR(300) NOT NULL 12 | ); 13 | 14 | CREATE TABLE Plugin 15 | ( 16 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 17 | Name VARCHAR(100) NOT NULL, 18 | [Desc] VARCHAR(300) 19 | ); 20 | 21 | CREATE TABLE [Option] 22 | ( 23 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 24 | Name VARCHAR(100) NOT NULL, 25 | [Desc] VARCHAR(300) NOT NULL, 26 | [Type] VARCHAR(50) NOT NULL 27 | ); 28 | 29 | CREATE TABLE PluginOption 30 | ( 31 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 32 | PluginID INTEGER NOT NULL, 33 | OptionID INTEGER NOT NULL, 34 | Required BIT, 35 | CONSTRAINT FK_PluginOption_Plugin FOREIGN KEY (PluginID) REFERENCES Plugin(ID), 36 | CONSTRAINT FK_PluginOption_Option FOREIGN KEY (OptionID) REFERENCES [Option](ID) 37 | ); 38 | 39 | CREATE TABLE BatchFile 40 | ( 41 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 42 | Name VARCHAR(300) NOT NULL 43 | ); 44 | 45 | CREATE TABLE BatchFilePlugin 46 | ( 47 | ID INTEGER PRIMARY KEY AUTOINCREMENT, 48 | BatchFileID INTEGER NOT NULL, 49 | PluginID INTEGER NOT NULL, 50 | CONSTRAINT FK_BatchFilePlugin_BatchFile FOREIGN KEY (BatchFileID) REFERENCES BatchFile(ID), 51 | CONSTRAINT FK_BatchFilePlugin_Plugin FOREIGN KEY (PluginID) REFERENCES Plugin(ID) 52 | 53 | ); 54 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 EG-CERT 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

GVol

2 | 3 | GVol is a lightweight GUI application built in Java designed to automate the usage of volatility toolkit for the purpose of malware analysis. The application includes various volatility plugins with their predefined options. In addition to that, users can create batch files to run multiple plugins at once to scan a memory image. Furthermore, GVol includes pre-configured batch files to simplify the usage of volatility for malware analysis process. Furthermore, user can compare the output of Volatility for two images. 4 | 5 |

GVol Features

6 | 25 |

Download

26 | You can get a copy of the latest release from 27 |
28 | https://github.com/eg-cert/GVol/releases 29 |

Building

30 | Building should be very simple 31 | 32 | ``` 33 | cd GVol 34 | ant 35 | ``` 36 |
37 | the target jar file shall be under the dist directory 38 | 39 |

Running

40 | ``` 41 | java -jar GVol.jar 42 | ``` 43 | 44 | 45 |

Configuration

46 | 47 | Download the latest version from releases. You need the Java runtime environment to run GVol. Run the file GVol.jar. 48 |
49 | The first time you run GVol, you should tell it how to run Volatility.
50 | 1- Menu bar > Configuration > Cmd & profiles
51 | 2- Enter the command to run volatility in your system like "python vol.py" or the path of the standalone executable if you use it.
52 | 53 | For more details about the tool and how to use it, read the user guide. 54 | -------------------------------------------------------------------------------- /build.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Builds, tests, and runs the project GVol. 12 | 13 | 73 | 74 | -------------------------------------------------------------------------------- /docs/GVol-User Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eg-cert/GVol/226924e6ef7dc878e7d5191b0549b91b52b12c24/docs/GVol-User Guide.pdf -------------------------------------------------------------------------------- /manifest.mf: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | X-COMMENT: Main-Class will be added automatically by build 3 | 4 | -------------------------------------------------------------------------------- /nbproject/project.properties: -------------------------------------------------------------------------------- 1 | annotation.processing.enabled=true 2 | annotation.processing.enabled.in.editor=false 3 | annotation.processing.processors.list= 4 | annotation.processing.run.all.processors=true 5 | annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output 6 | application.title=GVol 7 | application.vendor=User 8 | build.classes.dir=${build.dir}/classes 9 | build.classes.excludes=**/*.java,**/*.form 10 | # This directory is removed when the project is cleaned: 11 | build.dir=build 12 | build.generated.dir=${build.dir}/generated 13 | build.generated.sources.dir=${build.dir}/generated-sources 14 | # Only compile against the classpath explicitly listed here: 15 | build.sysclasspath=ignore 16 | build.test.classes.dir=${build.dir}/test/classes 17 | build.test.results.dir=${build.dir}/test/results 18 | # Uncomment to specify the preferred debugger connection transport: 19 | #debug.transport=dt_socket 20 | debug.classpath=\ 21 | ${run.classpath} 22 | debug.test.classpath=\ 23 | ${run.test.classpath} 24 | # Files in build.classes.dir which should be excluded from distribution jar 25 | dist.archive.excludes= 26 | # This directory is removed when the project is cleaned: 27 | dist.dir=dist 28 | dist.jar=${dist.dir}/GVol.jar 29 | dist.javadoc.dir=${dist.dir}/javadoc 30 | endorsed.classpath= 31 | excludes= 32 | file.reference.sqlite-jdbc-3.8.10.2.jar=sqlite-jdbc-3.8.10.2.jar 33 | includes=** 34 | jar.compress=false 35 | javac.classpath=\ 36 | ${file.reference.sqlite-jdbc-3.8.10.2.jar} 37 | # Space-separated list of extra javac options 38 | javac.compilerargs= 39 | javac.deprecation=false 40 | javac.processorpath=\ 41 | ${javac.classpath} 42 | javac.source=1.6 43 | javac.target=1.6 44 | javac.test.classpath=\ 45 | ${javac.classpath}:\ 46 | ${build.classes.dir} 47 | javac.test.processorpath=\ 48 | ${javac.test.classpath} 49 | javadoc.additionalparam= 50 | javadoc.author=false 51 | javadoc.encoding=${source.encoding} 52 | javadoc.noindex=false 53 | javadoc.nonavbar=false 54 | javadoc.notree=false 55 | javadoc.private=false 56 | javadoc.splitindex=true 57 | javadoc.use=true 58 | javadoc.version=false 59 | javadoc.windowtitle= 60 | main.class=main.MainClass 61 | manifest.file=manifest.mf 62 | meta.inf.dir=${src.dir}/META-INF 63 | mkdist.disabled=false 64 | platform.active=default_platform 65 | run.classpath=\ 66 | ${javac.classpath}:\ 67 | ${build.classes.dir} 68 | # Space-separated list of JVM arguments used when running the project. 69 | # You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. 70 | # To set system properties for unit tests define test-sys-prop.name=value: 71 | run.jvmargs= 72 | run.test.classpath=\ 73 | ${javac.test.classpath}:\ 74 | ${build.test.classes.dir} 75 | source.encoding=UTF-8 76 | src.dir=src 77 | test.src.dir=test 78 | -------------------------------------------------------------------------------- /nbproject/project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | org.netbeans.modules.java.j2seproject 4 | 5 | 6 | GVol 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /sqlite-jdbc-3.8.10.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/eg-cert/GVol/226924e6ef7dc878e7d5191b0549b91b52b12c24/sqlite-jdbc-3.8.10.2.jar -------------------------------------------------------------------------------- /src/database/BatchFile.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | /** 4 | * 5 | * @author Moahamd Shawkey 6 | */ 7 | public class BatchFile { 8 | private final int ID; 9 | private final String Name; 10 | 11 | public BatchFile(int ID, String Name){ 12 | this.ID = ID; 13 | this.Name = Name; 14 | } 15 | 16 | public String getName(){ 17 | return Name; 18 | } 19 | 20 | public int getID(){ 21 | return ID; 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /src/database/DatabaseConn.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | import java.sql.Connection; 4 | import java.sql.DriverManager; 5 | import java.sql.ResultSet; 6 | import java.sql.Statement; 7 | import org.sqlite.SQLiteConfig; 8 | 9 | public class DatabaseConn { 10 | 11 | private static Connection c; 12 | 13 | public static boolean init() { 14 | try { 15 | Class.forName("org.sqlite.JDBC"); 16 | SQLiteConfig config = new SQLiteConfig(); 17 | config.enforceForeignKeys(true); 18 | c = DriverManager.getConnection("jdbc:sqlite:GVol.db", config.toProperties()); 19 | } catch (Exception ex) { 20 | return false; 21 | } 22 | return true; 23 | } 24 | 25 | public static int profilesCount() { 26 | return getCount("profile", null); 27 | } 28 | 29 | public static int batchFileCount() { 30 | return getCount("batchfile", null); 31 | } 32 | 33 | public static int optionsCount() { 34 | return getCount("option", null); 35 | } 36 | 37 | private static int pluginsCount() { 38 | return getCount("plugin", null); 39 | } 40 | 41 | private static int pluginOptionsCount(int pluginID) { 42 | return getCount("pluginOption", "where pluginID = " + pluginID); 43 | } 44 | 45 | public static int batchFilePluginCount(int batchFileID) { 46 | return getCount("batchFilePlugin", "where batchFileID = " + batchFileID); 47 | } 48 | 49 | private static int getCount(String tableName, String where) { 50 | String sql = "select count(*) from " + tableName + " " + ((where == null) ? "" : where) + ";"; 51 | 52 | try { 53 | Statement stmt = c.createStatement(); 54 | ResultSet rs = stmt.executeQuery(sql); 55 | if (rs.next()) { 56 | return rs.getInt("count(*)"); 57 | } 58 | stmt.close(); 59 | } catch (Exception ex) { 60 | } 61 | return 0; 62 | } 63 | 64 | public static BatchFile[] getBatchFiles() { 65 | BatchFile[] batchFiles = new BatchFile[batchFileCount()]; 66 | String sql = "select * from batchfile order by name;"; 67 | try { 68 | Statement stmt = c.createStatement(); 69 | ResultSet rs = stmt.executeQuery(sql); 70 | int i = 0; 71 | while (rs.next()) { 72 | batchFiles[i] = new BatchFile(rs.getInt("id"), rs.getString("name")); 73 | i++; 74 | } 75 | stmt.close(); 76 | } catch (Exception ex) { 77 | System.err.println(ex.getMessage()); 78 | } 79 | return batchFiles; 80 | } 81 | 82 | public static BatchFile getBatchFile(int batchFileID) { 83 | String sql = "select * from batchfile where id = "+batchFileID+";"; 84 | try { 85 | Statement stmt = c.createStatement(); 86 | ResultSet rs = stmt.executeQuery(sql); 87 | 88 | if (rs.next()) { 89 | return new BatchFile(rs.getInt("id"), rs.getString("name")); 90 | } 91 | stmt.close(); 92 | } catch (Exception ex) { 93 | System.err.println(ex.getMessage()); 94 | } 95 | return null; 96 | } 97 | 98 | public static Profile[] getProfiles() { 99 | Profile[] profiles = new Profile[profilesCount()]; 100 | String sql = "select * from profile order by name;"; 101 | int ID; 102 | String name; 103 | String desc; 104 | try { 105 | Statement stmt = c.createStatement(); 106 | ResultSet rs = stmt.executeQuery(sql); 107 | int i = 0; 108 | while (rs.next()) { 109 | ID = rs.getInt("id"); 110 | name = rs.getString("name"); 111 | desc = rs.getString("desc"); 112 | profiles[i] = new Profile(ID, name, desc); 113 | i++; 114 | } 115 | stmt.close(); 116 | } catch (Exception ex) { 117 | System.err.println(ex.getMessage()); 118 | } 119 | return profiles; 120 | } 121 | 122 | public static String getVolCommand() { 123 | String volCommand = null; 124 | String sql = "select * from volcommand limit 1;"; 125 | try { 126 | Statement stmt = c.createStatement(); 127 | ResultSet rs = stmt.executeQuery(sql); 128 | if (rs.next()) { 129 | volCommand = rs.getString("cmd"); 130 | } else { 131 | stmt.close(); 132 | throw new Exception("Couldn't read vol command from database."); 133 | } 134 | stmt.close(); 135 | } catch (Exception ex) { 136 | System.err.println(ex.getMessage()); 137 | } 138 | return volCommand; 139 | 140 | } 141 | 142 | public static Option[] getOptions() { 143 | Option[] options = new Option[optionsCount()]; 144 | String sql = "select * from option order by name;"; 145 | int ID; 146 | String name; 147 | String desc; 148 | String type; 149 | try { 150 | Statement stmt = c.createStatement(); 151 | ResultSet rs = stmt.executeQuery(sql); 152 | int i = 0; 153 | while (rs.next()) { 154 | ID = rs.getInt("id"); 155 | name = rs.getString("name"); 156 | desc = rs.getString("desc"); 157 | type = rs.getString("type"); 158 | options[i] = new Option(ID, OptionValueType.valueOf(type), name, desc); 159 | i++; 160 | } 161 | stmt.close(); 162 | } catch (Exception ex) { 163 | System.err.println(ex.getMessage()); 164 | } 165 | return options; 166 | } 167 | 168 | private static Option getOption(int optionID) { 169 | Option option = null; 170 | String sql = "select * from option where ID = "; 171 | sql += ((Integer) optionID).toString() + " order by name;"; 172 | int ID; 173 | String name; 174 | String desc; 175 | String type; 176 | try { 177 | Statement stmt = c.createStatement(); 178 | ResultSet rs = stmt.executeQuery(sql); 179 | if (rs.next()) { 180 | ID = rs.getInt("id"); 181 | name = rs.getString("name"); 182 | desc = rs.getString("desc"); 183 | type = rs.getString("type"); 184 | option = new Option(ID, OptionValueType.valueOf(type), name, desc); 185 | 186 | } 187 | stmt.close(); 188 | } catch (Exception ex) { 189 | System.err.println(ex.getMessage()); 190 | } 191 | return option; 192 | } 193 | 194 | public static Option[] getPluginOptions(int PluginID) { 195 | Option[] options = new Option[pluginOptionsCount(PluginID)]; 196 | String sql = "select * from pluginoption "; 197 | sql += "where pluginID = " + ((Integer) PluginID).toString() + ";"; 198 | 199 | int optionID; 200 | try { 201 | Statement stmt = c.createStatement(); 202 | ResultSet rs = stmt.executeQuery(sql); 203 | int i = 0; 204 | while (rs.next()) { 205 | optionID = rs.getInt("optionID"); 206 | options[i] = getOption(optionID); 207 | i++; 208 | } 209 | stmt.close(); 210 | } catch (Exception ex) { 211 | System.err.println(ex.getMessage()); 212 | } 213 | return options; 214 | } 215 | 216 | public static Plugin[] getBatchFilePlugins(int batchFileID) { 217 | Plugin[] plugins = new Plugin[batchFilePluginCount(batchFileID)]; 218 | String sql = "select * from batchFilePlugin "; 219 | sql += "where batchFileID = " + batchFileID + ";"; 220 | 221 | int pluginID; 222 | try { 223 | Statement stmt = c.createStatement(); 224 | ResultSet rs = stmt.executeQuery(sql); 225 | int i = 0; 226 | while (rs.next()) { 227 | pluginID = rs.getInt("pluginID"); 228 | plugins[i] = getPlugin(pluginID); 229 | i++; 230 | } 231 | stmt.close(); 232 | } catch (Exception ex) { 233 | System.err.println(ex.getMessage()); 234 | } 235 | return plugins; 236 | } 237 | 238 | public static Plugin[] getPlugins() { 239 | Plugin[] plugins = new Plugin[pluginsCount()]; 240 | String sql = "select * from plugin order by name;"; 241 | int ID; 242 | String name, desc; 243 | try { 244 | Statement stmt = c.createStatement(); 245 | ResultSet rs = stmt.executeQuery(sql); 246 | int i = 0; 247 | while (rs.next()) { 248 | ID = rs.getInt("id"); 249 | name = rs.getString("name"); 250 | desc = rs.getString("desc"); 251 | plugins[i] = new Plugin(ID, name, desc); 252 | i++; 253 | } 254 | stmt.close(); 255 | } catch (Exception ex) { 256 | System.err.println(ex.getMessage()); 257 | } 258 | return plugins; 259 | } 260 | 261 | public static Profile getProfile(int id) { 262 | Profile[] profiles = getProfiles(); 263 | for (Profile p : profiles) { 264 | if (p.getID() == id) { 265 | return p; 266 | } 267 | } 268 | return null; 269 | } 270 | 271 | public static Plugin getPlugin(int id) { 272 | Plugin[] plugins = getPlugins(); 273 | for (Plugin p : plugins) { 274 | if (id == p.getID()) { 275 | return p; 276 | } 277 | } 278 | return null; 279 | } 280 | 281 | public static void setVolCommand(String newCmd) { 282 | String sql = "delete from volcommand;"; 283 | try { 284 | Statement stmt = c.createStatement(); 285 | stmt.executeUpdate(sql); 286 | sql = "insert into volcommand (cmd) values('" + newCmd + "');"; 287 | stmt.executeUpdate(sql); 288 | stmt.close(); 289 | } catch (Exception ex) { 290 | System.err.println(ex.getMessage()); 291 | } 292 | } 293 | 294 | public static void addProfile(Profile p) { 295 | String sql = "insert into profile (name,[desc]) values('" + p.getName() + "'"; 296 | sql = sql + ",'" + p.getDescription() + "');"; 297 | try { 298 | Statement stmt = c.createStatement(); 299 | stmt.executeUpdate(sql); 300 | 301 | stmt.close(); 302 | } catch (Exception ex) { 303 | System.err.println(ex.getMessage()); 304 | } 305 | } 306 | 307 | public static void addOption(Option op) { 308 | String sql = "insert into option (name,[desc],[type]) values('" + op.getCmd() + "'"; 309 | sql = sql + ",'" + op.getDesc() + "','" + op.getValueType().toString() + "');"; 310 | try { 311 | Statement stmt = c.createStatement(); 312 | stmt.executeUpdate(sql); 313 | 314 | stmt.close(); 315 | } catch (Exception ex) { 316 | System.err.println(ex.getMessage()); 317 | } 318 | } 319 | 320 | public static void addPlugin(Plugin p) { 321 | String sql = "insert into plugin (name,desc) values('" + p.getName() + "','"+p.getDesc().replace("'", "''")+"');"; 322 | 323 | try { 324 | Statement stmt = c.createStatement(); 325 | stmt.executeUpdate(sql); 326 | 327 | stmt.close(); 328 | } catch (Exception ex) { 329 | System.err.println(ex.getMessage()); 330 | } 331 | } 332 | 333 | public static void addPluginOption(int pluginID, int optionID) { 334 | String sql = "insert into pluginOption (pluginID,optionID) values(" + ((Integer) pluginID).toString() + ","; 335 | sql += ((Integer) optionID).toString() + ");"; 336 | try { 337 | Statement stmt = c.createStatement(); 338 | stmt.executeUpdate(sql); 339 | 340 | stmt.close(); 341 | } catch (Exception ex) { 342 | System.err.println(ex.getMessage()); 343 | } 344 | } 345 | 346 | public static void addBatchFile(BatchFile batchFile) { 347 | String sql = "insert into batchFile (name) values('" + batchFile.getName() + "');"; 348 | try { 349 | Statement stmt = c.createStatement(); 350 | stmt.executeUpdate(sql); 351 | 352 | stmt.close(); 353 | } catch (Exception ex) { 354 | System.err.println(ex.getMessage()); 355 | } 356 | } 357 | 358 | public static void addBatchFilePlugin(int batchFileID, int pluginID) { 359 | String sql = "insert into batchFilePlugin (pluginID,batchFileID) values(" + pluginID + ","; 360 | sql += batchFileID + ");"; 361 | try { 362 | Statement stmt = c.createStatement(); 363 | stmt.executeUpdate(sql); 364 | 365 | stmt.close(); 366 | } catch (Exception ex) { 367 | System.err.println(ex.getMessage()); 368 | } 369 | } 370 | 371 | public static void deleteProfile(int ID) { 372 | String sql = "delete from profile where id =" + ((Integer) ID).toString(); 373 | try { 374 | Statement stmt = c.createStatement(); 375 | stmt.executeUpdate(sql); 376 | 377 | stmt.close(); 378 | } catch (Exception ex) { 379 | System.err.println(ex.getMessage()); 380 | } 381 | } 382 | 383 | public static void deleteOption(int ID) { 384 | String sql = "delete from option where id =" + ((Integer) ID).toString(); 385 | try { 386 | Statement stmt = c.createStatement(); 387 | stmt.executeUpdate(sql); 388 | 389 | stmt.close(); 390 | } catch (Exception ex) { 391 | System.err.println(ex.getMessage()); 392 | } 393 | } 394 | 395 | public static void deletePlugin(int pluginID) { 396 | String[] sql = new String[2]; 397 | sql[0] = "delete from plugin where id = " + ((Integer) pluginID).toString(); 398 | sql[1] = "delete from PluginOption where PluginID = " + ((Integer) pluginID).toString(); 399 | 400 | for (int i = 1; i >= 0; i--) { 401 | try { 402 | Statement stmt = c.createStatement(); 403 | stmt.executeUpdate(sql[i]); 404 | 405 | stmt.close(); 406 | } catch (Exception ex) { 407 | System.err.println("delete Plugin: " + ex.getMessage()); 408 | } 409 | } 410 | } 411 | 412 | public static void deletePluginOption(int pluginID, int optionID) { 413 | String sql = "delete from PluginOption where PluginID ="; 414 | sql += ((Integer) pluginID).toString(); 415 | sql += " and optionID = " + ((Integer) optionID).toString(); 416 | try { 417 | Statement stmt = c.createStatement(); 418 | stmt.executeUpdate(sql); 419 | 420 | stmt.close(); 421 | } catch (Exception ex) { 422 | System.err.println(ex.getMessage()); 423 | } 424 | } 425 | 426 | public static void deleteBatchFile(int batchFileID) { 427 | String [] sql = new String[2]; 428 | sql[0] = "delete from BatchFilePlugin where batchFileID = "+batchFileID; 429 | sql[1] = "delete from batchFile where ID = "+batchFileID; 430 | for(int i=0;i<2;i++){ 431 | try { 432 | Statement stmt = c.createStatement(); 433 | stmt.executeUpdate(sql[i]); 434 | 435 | stmt.close(); 436 | } catch (Exception ex) { 437 | System.err.println(ex.getMessage()); 438 | } 439 | } 440 | } 441 | 442 | public static void deleteBatchFilePlugin(int batchFileID, int pluginID) { 443 | String sql = "delete from batchFilePlugin where batchFileID ="; 444 | sql += batchFileID; 445 | sql += " and pluginID = " + pluginID; 446 | try { 447 | Statement stmt = c.createStatement(); 448 | stmt.executeUpdate(sql); 449 | stmt.close(); 450 | } catch (Exception ex) { 451 | System.err.println(ex.getMessage()); 452 | } 453 | } 454 | 455 | public static boolean profileExists(String profileName) { 456 | String sql = "select * from profile where name ='" + profileName.trim() + "';"; 457 | try { 458 | Statement stmt = c.createStatement(); 459 | ResultSet rs = stmt.executeQuery(sql); 460 | return rs.next(); 461 | } catch (Exception ex) { 462 | System.err.println(ex.getMessage()); 463 | } 464 | return false; 465 | } 466 | 467 | public static boolean pluginExists(String pluginName) { 468 | String sql = "select * from plugin where name ='" + pluginName.trim() + "';"; 469 | try { 470 | Statement stmt = c.createStatement(); 471 | ResultSet rs = stmt.executeQuery(sql); 472 | return rs.next(); 473 | } catch (Exception ex) { 474 | System.err.println(ex.getMessage()); 475 | } 476 | return false; 477 | } 478 | 479 | public static boolean pluginOptionExists(int pluginID, int optionID) { 480 | String sql = "select * from pluginOption where pluginID ="; 481 | sql += ((Integer) pluginID).toString(); 482 | sql += " and optionID = " + ((Integer) optionID).toString(); 483 | try { 484 | Statement stmt = c.createStatement(); 485 | ResultSet rs = stmt.executeQuery(sql); 486 | return rs.next(); 487 | } catch (Exception ex) { 488 | System.err.println(ex.getMessage()); 489 | } 490 | return false; 491 | } 492 | 493 | public static boolean batchFileExists(String batchFileName) { 494 | String sql = "select * from batchFile where name ='" + batchFileName.trim() + "';"; 495 | try { 496 | Statement stmt = c.createStatement(); 497 | ResultSet rs = stmt.executeQuery(sql); 498 | return rs.next(); 499 | } catch (Exception ex) { 500 | System.err.println(ex.getMessage()); 501 | } 502 | return false; 503 | } 504 | 505 | public static boolean optionUsed(int optionID) { 506 | String sql = "select * from pluginOption where optionID = " + ((Integer) optionID).toString(); 507 | try { 508 | Statement stmt = c.createStatement(); 509 | ResultSet rs = stmt.executeQuery(sql); 510 | return rs.next(); 511 | } catch (Exception ex) { 512 | System.err.println(ex.getMessage()); 513 | } 514 | return false; 515 | } 516 | 517 | public static boolean batchFilePluginExists(int batchFileID, int pluginID) { 518 | String sql = "select * from batchFilePlugin where pluginID ="; 519 | sql += pluginID; 520 | sql += " and batchFileID = " + batchFileID; 521 | try { 522 | Statement stmt = c.createStatement(); 523 | ResultSet rs = stmt.executeQuery(sql); 524 | return rs.next(); 525 | } catch (Exception ex) { 526 | System.err.println(ex.getMessage()); 527 | } 528 | return false; 529 | } 530 | 531 | public static boolean pluginUsed(int pluginID) { 532 | String sql = "select * from batchFilePlugin where pluginID = " + pluginID; 533 | try { 534 | Statement stmt = c.createStatement(); 535 | ResultSet rs = stmt.executeQuery(sql); 536 | return rs.next(); 537 | } catch (Exception ex) { 538 | System.err.println(ex.getMessage()); 539 | } 540 | return false; 541 | } 542 | 543 | public static void updatePluginDesc(String name, String desc) { 544 | desc=desc.replace("'", "''"); 545 | String sql = "update plugin set [desc] = '"+desc+"' where name = '"+name.trim()+"';"; 546 | 547 | try { 548 | Statement stmt = c.createStatement(); 549 | stmt.executeUpdate(sql); 550 | 551 | stmt.close(); 552 | } catch (Exception ex) { 553 | System.err.println(ex.getMessage()); 554 | } 555 | } 556 | 557 | } -------------------------------------------------------------------------------- /src/database/Option.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | public class Option { 4 | final private OptionValueType valType; 5 | final private String cmd; 6 | final private String desc; 7 | final private int ID; 8 | 9 | 10 | public Option(int ID, OptionValueType valType,String cmd,String desc) { 11 | this.valType = valType; 12 | this.cmd = cmd; 13 | this.desc = desc; 14 | this.ID = ID; 15 | } 16 | public OptionValueType getValueType(){ 17 | return valType; 18 | } 19 | 20 | public String getCmd(){ 21 | return cmd; 22 | } 23 | 24 | public String getDesc(){ 25 | return desc; 26 | } 27 | 28 | public int getID(){ 29 | return ID; 30 | } 31 | 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/database/OptionValueType.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | public enum OptionValueType { 4 | NOVALUE,NUMBER,STRING,FILE,DIRECTORY 5 | } 6 | -------------------------------------------------------------------------------- /src/database/Plugin.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | public class Plugin { 4 | 5 | private final String name; 6 | private final int ID; 7 | private final String desc; 8 | 9 | public Plugin(int id, String name, String desc){ 10 | this.name = name; 11 | this.ID = id; 12 | this.desc = desc; 13 | } 14 | 15 | 16 | public String getName(){ 17 | return name; 18 | } 19 | 20 | public int getID() { 21 | return ID; 22 | } 23 | 24 | public String getDesc(){ 25 | return desc; 26 | } 27 | 28 | public String getTooltip(){ 29 | 30 | String tip = "" + name + "
"; 31 | tip = tip + String.format("
%s
", 400,((desc==null)?"":desc) + ""); 32 | 33 | return tip; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/database/Profile.java: -------------------------------------------------------------------------------- 1 | package database; 2 | 3 | 4 | public class Profile { 5 | 6 | private final String desc; 7 | private final String name; 8 | private final int ID; 9 | 10 | public Profile(String name, String desc) { 11 | this.name = name; 12 | this.desc = desc; 13 | ID = 0; 14 | } 15 | 16 | public Profile(int ID, String name, String desc){ 17 | this.name = name; 18 | this.desc = desc; 19 | this.ID = ID; 20 | } 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public String getDescription() { 26 | return desc; 27 | } 28 | 29 | public int getID(){ 30 | return ID; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/dialog/BatchFileDialog.java: -------------------------------------------------------------------------------- 1 | 2 | package dialog; 3 | 4 | import database.*; 5 | import java.awt.Component; 6 | import java.awt.Dimension; 7 | import java.awt.FlowLayout; 8 | import java.awt.Insets; 9 | import java.awt.event.ActionEvent; 10 | import java.awt.event.ActionListener; 11 | import java.awt.event.MouseAdapter; 12 | import java.awt.event.MouseEvent; 13 | import javax.swing.BorderFactory; 14 | import javax.swing.JButton; 15 | import javax.swing.JComboBox; 16 | import javax.swing.JDialog; 17 | import javax.swing.JFrame; 18 | import javax.swing.JLabel; 19 | import javax.swing.JMenuItem; 20 | import javax.swing.JOptionPane; 21 | import javax.swing.JPanel; 22 | import javax.swing.JPopupMenu; 23 | import javax.swing.JScrollPane; 24 | import javax.swing.JTable; 25 | import javax.swing.JTextField; 26 | import javax.swing.ListSelectionModel; 27 | import javax.swing.SwingUtilities; 28 | import javax.swing.event.ListSelectionEvent; 29 | import javax.swing.event.ListSelectionListener; 30 | import javax.swing.table.DefaultTableModel; 31 | import main.ComboBoxItem; 32 | 33 | public class BatchFileDialog extends JDialog implements ActionListener { 34 | 35 | private JTable batchTable; 36 | private JPopupMenu batchPopup; 37 | private JMenuItem deleteBatchItem; 38 | 39 | private JTable pluginTable; 40 | private JPopupMenu pluginPopup; 41 | private JMenuItem removePluginItem; 42 | 43 | final private JPanel addBatchPanel; 44 | final private JLabel nameLabel; 45 | final private JTextField nameTextField; 46 | final private JButton addBatchButton; 47 | 48 | final private JPanel addPluginPanel; 49 | final private JLabel addPluginLabel; 50 | final private JComboBox pluginsComboBox; 51 | final private JButton addPluginButton; 52 | 53 | final private JButton doneButton; 54 | private int selectedFileID = 0; 55 | 56 | public BatchFileDialog(JFrame parent) { 57 | super(parent, true); 58 | setSize(new Dimension(620, 580)); 59 | setLayout(null); 60 | setLocationRelativeTo(parent); 61 | 62 | 63 | addBatchPanel = new JPanel(); 64 | nameLabel = new JLabel("Name: "); 65 | nameTextField = new JTextField(15); 66 | addBatchButton = new JButton("Add"); 67 | selectedFileID = 0; 68 | 69 | 70 | addPluginPanel = new JPanel(); 71 | addPluginLabel = new JLabel("Select Plugin"); 72 | pluginsComboBox = new JComboBox(); 73 | addPluginButton = new JButton("Add"); 74 | 75 | initBatchTable(); 76 | initAddBatchPanel(); 77 | initPluginsTable(); 78 | initAddPluginPanel(); 79 | doneButton = new JButton("Done"); 80 | doneButton.addActionListener(this); 81 | Insets insets = this.getInsets(); 82 | doneButton.setBounds(insets.left + 500, insets.top + 500, 80, 25); 83 | add(doneButton); 84 | 85 | } 86 | 87 | private void initBatchTable() { 88 | Insets insets = this.getInsets(); 89 | batchTable = new JTable(){ 90 | @Override 91 | public boolean isCellEditable(int rowIndex, int vColIndex) { 92 | return false; 93 | } 94 | }; 95 | batchTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 96 | batchTable.getSelectionModel().addListSelectionListener(new TableSelectionListener()); 97 | 98 | batchPopup = new JPopupMenu(); 99 | deleteBatchItem = new JMenuItem("Delete Batch File"); 100 | deleteBatchItem.addActionListener(this); 101 | batchPopup.add(deleteBatchItem); 102 | batchTable.addMouseListener(new TableMouseListener(batchTable,batchPopup)); 103 | 104 | JScrollPane scrollPane = new JScrollPane(batchTable); 105 | scrollPane.setBounds(insets.left + 5, insets.top + 5, 590, 175); 106 | scrollPane.setBorder(BorderFactory.createTitledBorder("Batch Files")); 107 | 108 | add(scrollPane); 109 | 110 | selectedFileID = 0; 111 | updateBatches(); 112 | } 113 | 114 | private void initAddBatchPanel() { 115 | Insets insets = this.getInsets(); 116 | addBatchPanel.setBounds(insets.left+5,insets.top+185,590,60); 117 | addBatchPanel.setLayout(new FlowLayout()); 118 | addBatchPanel.setBorder(BorderFactory.createTitledBorder("Add new batch file")); 119 | add(addBatchPanel); 120 | 121 | addBatchButton.addActionListener(this); 122 | 123 | addBatchPanel.add(nameLabel); 124 | addBatchPanel.add(nameTextField); 125 | addBatchPanel.add(addBatchButton); 126 | } 127 | 128 | private void initPluginsTable() { 129 | Insets insets = this.getInsets(); 130 | pluginTable = new JTable(){ 131 | @Override 132 | public boolean isCellEditable(int rowIndex, int vColIndex) { 133 | return false; 134 | } 135 | 136 | @Override 137 | public String getToolTipText(MouseEvent e) { 138 | java.awt.Point p = e.getPoint(); 139 | int row = rowAtPoint(p); 140 | ComboBoxItem cbi = (ComboBoxItem) pluginTable.getModel().getValueAt(row, 0); 141 | int id = cbi.getID(); 142 | Plugin plugin = DatabaseConn.getPlugin(id); 143 | return plugin.getTooltip(); 144 | } 145 | 146 | }; 147 | pluginTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 148 | 149 | pluginPopup = new JPopupMenu(); 150 | removePluginItem = new JMenuItem("Remove Plugin"); 151 | removePluginItem.addActionListener(this); 152 | pluginPopup.add(removePluginItem); 153 | pluginTable.addMouseListener(new TableMouseListener(pluginTable,pluginPopup)); 154 | 155 | 156 | JScrollPane scrollPane = new JScrollPane(pluginTable); 157 | scrollPane.setBounds(insets.left + 5, insets.top + 250, 590, 175); 158 | scrollPane.setBorder(BorderFactory.createTitledBorder("Selected batch file plugins")); 159 | add(scrollPane); 160 | 161 | updatePlugins(); 162 | 163 | } 164 | 165 | private void initAddPluginPanel() { 166 | Insets insets = this.getInsets(); 167 | addPluginPanel.setBounds(insets.left+5,insets.top+435,590,60); 168 | addPluginPanel.setLayout(new FlowLayout()); 169 | addPluginPanel.setBorder(BorderFactory.createTitledBorder("Add Plugin to The Selected Batch File")); 170 | 171 | addPluginButton.addActionListener(this); 172 | add(addPluginPanel); 173 | updateComboBox(); 174 | addPluginPanel.add(addPluginLabel); 175 | addPluginPanel.add(pluginsComboBox); 176 | addPluginPanel.add(addPluginButton); 177 | } 178 | 179 | private void updateBatches() { 180 | batchTable.removeAll(); 181 | String [] columnNames = {"Batch File Name"}; 182 | BatchFile[] batches = DatabaseConn.getBatchFiles(); 183 | if(batches == null ) return; 184 | ComboBoxItem [][] data = new ComboBoxItem[batches.length][1]; 185 | for(int i=0;i If the options needs an equal sign, add the equal sign." 119 | + "
For example \"output=\""); 120 | typeLabel.setText("Type: "); 121 | descLabel.setText("Description: "); 122 | 123 | for (OptionValueType ovt : OptionValueType.values()) { 124 | typeComboBox.addItem(ovt.name()); 125 | } 126 | 127 | addButton.setText("Add"); 128 | addButton.addActionListener(this); 129 | 130 | addOptionPanel.add(nameLabel); 131 | addOptionPanel.add(nameTextField); 132 | addOptionPanel.add(typeLabel); 133 | addOptionPanel.add(typeComboBox); 134 | addOptionPanel.add(descLabel); 135 | addOptionPanel.add(descTextField); 136 | addOptionPanel.add(addButton); 137 | } 138 | 139 | private void updateOptions() { 140 | optionTable.removeAll(); 141 | String [] columnNames = {"Option","Type","Description"}; 142 | Option [] options = DatabaseConn.getOptions(); 143 | if(options==null || options.length==0) return; 144 | ComboBoxItem [][] data = new ComboBoxItem[options.length][3]; 145 | for(int i=0;i= 0 && r < table.getRowCount()) { 213 | table.setRowSelectionInterval(r, r); 214 | if(SwingUtilities.isRightMouseButton( e )){ 215 | popup.show(table, e.getX(), e.getY()); 216 | } 217 | } 218 | } 219 | 220 | } 221 | } 222 | -------------------------------------------------------------------------------- /src/dialog/PluginsDialog.java: -------------------------------------------------------------------------------- 1 | 2 | package dialog; 3 | 4 | import database.*; 5 | import java.awt.Dimension; 6 | import java.awt.FlowLayout; 7 | import java.awt.Insets; 8 | import java.awt.event.ActionEvent; 9 | import java.awt.event.ActionListener; 10 | import java.awt.event.MouseAdapter; 11 | import java.awt.event.MouseEvent; 12 | import javax.swing.BorderFactory; 13 | import javax.swing.JButton; 14 | import javax.swing.JComboBox; 15 | import javax.swing.JDialog; 16 | import javax.swing.JFrame; 17 | import javax.swing.JLabel; 18 | import javax.swing.JMenuItem; 19 | import javax.swing.JOptionPane; 20 | import javax.swing.JPanel; 21 | import javax.swing.JPopupMenu; 22 | import javax.swing.JScrollPane; 23 | import javax.swing.JTable; 24 | import javax.swing.JTextField; 25 | import javax.swing.ListSelectionModel; 26 | import javax.swing.SwingUtilities; 27 | import javax.swing.event.ListSelectionEvent; 28 | import javax.swing.event.ListSelectionListener; 29 | import javax.swing.table.DefaultTableModel; 30 | import main.ComboBoxItem; 31 | 32 | public class PluginsDialog extends JDialog implements ActionListener{ 33 | 34 | 35 | final private JPanel addPluginPanel; 36 | private JTable pluginTable; 37 | private JPopupMenu pluginPopup; 38 | private JMenuItem deletePluginItem; 39 | 40 | final private JLabel pluginNameLabel; 41 | final private JTextField pluginNameTextField; 42 | final private JLabel descLabel; 43 | final private JTextField descTextField; 44 | final private JButton addPluginButton; 45 | 46 | private JTable optionTable; 47 | private JPopupMenu optionPopup; 48 | private JMenuItem removeOptionItem; 49 | 50 | final private JPanel addOptionPanel; 51 | final private JLabel addOptionLabel; 52 | final private JComboBox optionsComboBox; 53 | final private JButton addOptionButton; 54 | final private JButton doneButton; 55 | 56 | private int selectedPluginID=0; 57 | 58 | public PluginsDialog(JFrame parent){ 59 | super(parent, true); 60 | setSize(new Dimension(620, 580)); 61 | setLayout(null); 62 | setLocationRelativeTo(parent); 63 | 64 | addPluginPanel = new JPanel(); 65 | pluginNameLabel=new JLabel("Plugin Name:"); 66 | descLabel = new JLabel("Description:"); 67 | pluginNameTextField= new JTextField(12); 68 | descTextField = new JTextField(15); 69 | 70 | addPluginButton= new JButton(); 71 | 72 | addOptionPanel = new JPanel(); 73 | addOptionLabel = new JLabel("Select Option"); 74 | optionsComboBox = new JComboBox(); 75 | addOptionButton = new JButton("Add"); 76 | doneButton = new JButton(); 77 | 78 | 79 | initPluginsTable(); 80 | initAddPluginPanel(); 81 | initOptionsTable(); 82 | initAddOptionPanel(); 83 | 84 | doneButton.setText("Done"); 85 | doneButton.addActionListener(this); 86 | doneButton.setBounds(getInsets().left + 500, getInsets().top + 520, 80, 25); 87 | add(doneButton); 88 | } 89 | 90 | private void initPluginsTable() { 91 | Insets insets = this.getInsets(); 92 | pluginTable = new JTable(){ 93 | @Override 94 | public boolean isCellEditable(int rowIndex, int vColIndex) { 95 | return false; 96 | } 97 | 98 | @Override 99 | public String getToolTipText(MouseEvent e) { 100 | try { 101 | String tip = null; 102 | java.awt.Point p = e.getPoint(); 103 | int row = rowAtPoint(p); 104 | ComboBoxItem cbi = (ComboBoxItem) pluginTable.getModel().getValueAt(row, 0); 105 | if (cbi == null) { 106 | return null; 107 | } 108 | Plugin plugin = DatabaseConn.getPlugin(cbi.getID()); 109 | return plugin.getTooltip(); 110 | } catch (Exception ex) { 111 | return null; 112 | } 113 | } 114 | 115 | }; 116 | pluginTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 117 | pluginTable.getSelectionModel().addListSelectionListener(new TableSelectionListener()); 118 | 119 | pluginPopup = new JPopupMenu(); 120 | deletePluginItem = new JMenuItem("Delete Plugin"); 121 | deletePluginItem.addActionListener(this); 122 | pluginPopup.add(deletePluginItem); 123 | pluginTable.addMouseListener(new TableMouseListener(pluginTable,pluginPopup)); 124 | 125 | JScrollPane scrollPane = new JScrollPane(pluginTable); 126 | scrollPane.setBounds(insets.left + 5, insets.top + 5, 590, 175); 127 | scrollPane.setBorder(BorderFactory.createTitledBorder("Plugins")); 128 | 129 | add(scrollPane); 130 | 131 | updatePlugins(); 132 | } 133 | 134 | private void initAddPluginPanel() { 135 | Insets insets = this.getInsets(); 136 | addPluginPanel.setBounds(insets.left+5,insets.top+185,590,80); 137 | addPluginPanel.setLayout(new FlowLayout()); 138 | addPluginPanel.setBorder(BorderFactory.createTitledBorder("Add new plugin")); 139 | add(addPluginPanel); 140 | 141 | addPluginButton.setText("Add Plugin"); 142 | addPluginButton.addActionListener(this); 143 | 144 | addPluginPanel.add(pluginNameLabel); 145 | addPluginPanel.add(pluginNameTextField); 146 | addPluginPanel.add(descLabel); 147 | addPluginPanel.add(descTextField); 148 | addPluginPanel.add(addPluginButton); 149 | } 150 | 151 | private void initOptionsTable() { 152 | Insets insets = this.getInsets(); 153 | optionTable = new JTable(){ 154 | @Override 155 | public boolean isCellEditable(int rowIndex, int vColIndex) { 156 | return false; 157 | } 158 | }; 159 | optionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 160 | 161 | optionPopup = new JPopupMenu(); 162 | removeOptionItem = new JMenuItem("Remove Option"); 163 | removeOptionItem.addActionListener(this); 164 | optionPopup.add(removeOptionItem); 165 | optionTable.addMouseListener(new TableMouseListener(optionTable,optionPopup)); 166 | 167 | 168 | JScrollPane scrollPane = new JScrollPane(optionTable); 169 | scrollPane.setBounds(insets.left + 5, insets.top + 270, 590, 175); 170 | scrollPane.setBorder(BorderFactory.createTitledBorder("Options")); 171 | add(scrollPane); 172 | 173 | updateOptions(); 174 | } 175 | 176 | private void initAddOptionPanel() { 177 | Insets insets = this.getInsets(); 178 | addOptionPanel.setBounds(insets.left+5,insets.top+455,590,60); 179 | addOptionPanel.setLayout(new FlowLayout()); 180 | addOptionPanel.setBorder(BorderFactory.createTitledBorder("Add Option to The Selected Plugin")); 181 | 182 | addOptionButton.addActionListener(this); 183 | add(addOptionPanel); 184 | updateComboBox(); 185 | addOptionPanel.add(addOptionLabel); 186 | addOptionPanel.add(optionsComboBox); 187 | addOptionPanel.add(addOptionButton); 188 | 189 | } 190 | 191 | @Override 192 | public void actionPerformed(ActionEvent ae) { 193 | Object source = ae.getSource(); 194 | 195 | if(source == doneButton){ 196 | doneButtonAction(); 197 | } 198 | else if(source == addPluginButton){ 199 | addPluginButtonAction(); 200 | } 201 | else if(source == addOptionButton){ 202 | addOptionButtonAction(); 203 | } 204 | else if(source == deletePluginItem){ 205 | int row = pluginTable.getSelectedRow(); 206 | ComboBoxItem cbi = (ComboBoxItem) pluginTable.getModel().getValueAt(row, 0); 207 | deleteButtonAction(cbi.getID()); 208 | } 209 | else if (source == removeOptionItem){ 210 | int row = optionTable.getSelectedRow(); 211 | ComboBoxItem cbi = (ComboBoxItem) optionTable.getModel().getValueAt(row, 0); 212 | removeButtonAction(cbi.getID()); 213 | } 214 | } 215 | 216 | private void updatePlugins() { 217 | pluginTable.removeAll(); 218 | String [] columnNames = {"Plugin Name"}; 219 | Plugin [] plugins = DatabaseConn.getPlugins(); 220 | ComboBoxItem [][] data = new ComboBoxItem[plugins.length][1]; 221 | for(int i=0;i= 0 && r < table.getRowCount()) { 245 | table.setRowSelectionInterval(r, r); 246 | if(SwingUtilities.isRightMouseButton( e )){ 247 | popup.show(table, e.getX(), e.getY()); 248 | } 249 | } 250 | } 251 | 252 | } 253 | 254 | } 255 | -------------------------------------------------------------------------------- /src/diff/JDiff.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @author Mohamad Shawkey 4 | * @since Sept, 15th, 2015 5 | */ 6 | package diff; 7 | 8 | import java.io.BufferedWriter; 9 | import java.io.File; 10 | import java.io.FileNotFoundException; 11 | import java.io.FileOutputStream; 12 | import java.io.IOException; 13 | import java.io.OutputStreamWriter; 14 | import java.io.Writer; 15 | import java.nio.charset.Charset; 16 | import java.nio.file.Files; 17 | import java.util.ArrayList; 18 | import java.util.HashMap; 19 | import java.util.List; 20 | 21 | public class JDiff { 22 | 23 | enum LineState { 24 | NOCHANGE, DELETED, ADDED, MODIFIED 25 | } 26 | 27 | class Res { 28 | 29 | public int ind; 30 | public LineState state; 31 | public int ind2; 32 | } 33 | 34 | public static void main(String[] args) { 35 | if (args.length != 3) { 36 | System.err.println("Usage: JDiff.jar first.txt second.txt output.txt"); 37 | System.err.println(args[0] + " " + args[1] + " length = " + args.length); 38 | } 39 | try { 40 | JDiff jDiff = new JDiff(args[0], args[1]); 41 | jDiff.getSimpleOutputSep(args[2]); 42 | jDiff.getFormattedOutputSep(args[2] + ".html"); 43 | System.out.println("Done :)"); 44 | } catch (Exception ex) { 45 | System.err.println("Error happened!"); 46 | System.err.println(ex.getMessage()); 47 | } 48 | } 49 | 50 | private final List beforeLines; 51 | private final List afterLines; 52 | private final List output; 53 | private boolean resultsReady; 54 | 55 | public JDiff(String beforeFile, String afterFile) throws IOException { 56 | File f = new File(beforeFile); 57 | beforeLines = Files.readAllLines(f.toPath(), Charset.defaultCharset()); 58 | 59 | f = new File(afterFile); 60 | afterLines = Files.readAllLines(f.toPath(), Charset.defaultCharset()); 61 | 62 | 63 | 64 | output = new ArrayList(); 65 | resultsReady = false; 66 | } 67 | 68 | // this function needs to be refactored and split into several smaller functions 69 | private void getDiff() { 70 | if(resultsReady) return; 71 | List before = preFormatLines(beforeLines); 72 | List after = preFormatLines(afterLines); 73 | List orig = new ArrayList(); 74 | // this map maps a line in the first file to its index 75 | // or indicies if it exists more than once 76 | HashMap > mp = new HashMap >(); 77 | ArrayList al ; 78 | // a list of the new added lines in the second file 79 | // which doesn't exist in the first line 80 | List added = new ArrayList(); 81 | 82 | // initialize the map 83 | for (int i = 0; i < before.size(); i++) { 84 | Line li = new Line(before.get(i)); 85 | li.setRemoved(true); 86 | li.setIndex(i); 87 | orig.add(li); 88 | if(mp.containsKey(before.get(i))){ 89 | al = mp.get(before.get(i)); 90 | al.add(i); 91 | } 92 | else{ 93 | al = new ArrayList(); 94 | al.add(i); 95 | mp.put(before.get(i), al); 96 | } 97 | } 98 | 99 | processDiff(after, before, orig, added, mp); 100 | 101 | resultsReady = true; 102 | 103 | prepareResult(orig, added); 104 | } 105 | 106 | private void processDiff(List after, List before, Listorig, List added, HashMap > mp){ 107 | 108 | // determine what lines exist in the second files, 109 | // the deleted lines, and the added lines 110 | ArrayList al ; 111 | for (int i = 0; i < after.size(); i++) { 112 | Line li; 113 | if (mp.containsKey(after.get(i))) { 114 | al = mp.get(after.get(i)); 115 | int index = -1; 116 | for(int j=0;jorig,List added){ 148 | // create a list of lines for the output 149 | // to handle the order of lines 150 | int i, j; 151 | i = j = 0; 152 | Res res; 153 | while (i < orig.size() || j < added.size()) { 154 | res = new Res(); 155 | if (i >= orig.size() || (j< added.size() && orig.get(i).getIndex() > added.get(j).getIndex())) { 156 | res.state = LineState.ADDED; 157 | res.ind = added.get(j).getIndex(); 158 | j++; 159 | } else{ 160 | if(orig.get(i).getModified() >=0) { 161 | res.state = LineState.MODIFIED; 162 | res.ind2 = orig.get(i).getModified(); 163 | } 164 | else res.state = (orig.get(i).getRemoved() ? LineState.DELETED : LineState.NOCHANGE); 165 | res.ind = orig.get(i).getIndex(); 166 | i++; 167 | } 168 | output.add(res); 169 | } 170 | } 171 | 172 | public void getSimpleOutputSep(String outputFile)throws FileNotFoundException, IOException { 173 | if (!resultsReady) { 174 | getDiff(); 175 | } 176 | LineState [] states = {LineState.NOCHANGE, LineState.DELETED, LineState.MODIFIED, LineState.ADDED}; 177 | Writer fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile))); 178 | for(int j=0;j"); 237 | fout.write(beforeLines.get(output.get(i).ind)+ "\n"); 238 | } 239 | else if(output.get(i).state == LineState.DELETED){ 240 | fout.write("
"); 241 | fout.write(beforeLines.get(output.get(i).ind) +"
\n"); 242 | } 243 | else if(output.get(i).state == LineState.ADDED){ 244 | fout.write("
"); 245 | fout.write(afterLines.get(output.get(i).ind)+ "
\n"); 246 | } 247 | else if(output.get(i).state == LineState.MODIFIED){ 248 | fout.write("
"); 249 | fout.write(beforeLines.get(output.get(i).ind) +"
\n"); 250 | fout.write("
"); 251 | fout.write(afterLines.get(output.get(i).ind2)+ "
\n"); 252 | } 253 | } 254 | } 255 | fout.flush(); 256 | fout.close(); 257 | } 258 | 259 | public void getFormattedOutput(String outputFile) throws FileNotFoundException, IOException { 260 | if (!resultsReady) { 261 | getDiff(); 262 | } 263 | Writer fout = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(outputFile))); 264 | for (int i = 0; i < output.size(); i++) { 265 | if(output.get(i).state == LineState.NOCHANGE ){ 266 | fout.write("
"); 267 | fout.write(beforeLines.get(output.get(i).ind)+ "
\n"); 268 | } 269 | else if(output.get(i).state == LineState.DELETED){ 270 | fout.write("
"); 271 | fout.write(beforeLines.get(output.get(i).ind) +"
\n"); 272 | } 273 | else if(output.get(i).state == LineState.ADDED){ 274 | fout.write("
"); 275 | fout.write(afterLines.get(output.get(i).ind)+ "
\n"); 276 | } 277 | else if(output.get(i).state == LineState.MODIFIED){ 278 | fout.write("
"); 279 | fout.write(beforeLines.get(output.get(i).ind) +"
\n"); 280 | fout.write("
"); 281 | fout.write(afterLines.get(output.get(i).ind2)+ "
\n"); 282 | } 283 | } 284 | fout.flush(); 285 | fout.close(); 286 | } 287 | 288 | private List preFormatLines(List lines) { 289 | List res = new ArrayList(); 290 | for (int i = 0; i < lines.size(); i++) { 291 | StringBuilder sb = new StringBuilder(lines.get(i).trim()); 292 | if (isNullOrWhitespace(lines.get(i))) { 293 | lines.remove(i); 294 | i--; 295 | } else { 296 | for (int j = 0; j < sb.length() - 1; j++) { 297 | if (Character.isWhitespace(sb.charAt(j))) { 298 | sb.setCharAt(j, ' '); 299 | } 300 | 301 | if (Character.isWhitespace(sb.charAt(j)) && Character.isWhitespace(sb.charAt(j + 1))) { 302 | sb.deleteCharAt(j); 303 | j--; 304 | } 305 | } 306 | res.add(sb.toString()); 307 | } 308 | } 309 | return res; 310 | } 311 | 312 | private boolean isNullOrWhitespace(String str) { 313 | return (str == null || str.isEmpty() || str.trim().isEmpty()); 314 | } 315 | 316 | private boolean isModified(String bLine, String aLine){ 317 | if(bLine == null || aLine == null){ 318 | return false; 319 | } 320 | 321 | int pre, post; 322 | pre = 0; 323 | post = 0; 324 | 325 | for(int i =0 ;i=pre; i--){ 331 | if(bLine.charAt(i) == aLine.charAt(i)) post++; 332 | else break; 333 | } 334 | 335 | int mod = Math.max(bLine.length()-pre-post, aLine.length()-pre-post); 336 | return (mod <= (pre+post)/3); 337 | } 338 | 339 | } 340 | -------------------------------------------------------------------------------- /src/diff/Line.java: -------------------------------------------------------------------------------- 1 | 2 | package diff; 3 | 4 | 5 | public class Line { 6 | private int index; 7 | private boolean removed; 8 | final private String txt; 9 | private int modified; 10 | 11 | public Line(String txt){ 12 | this.txt = txt ; 13 | this.modified = -1; 14 | } 15 | 16 | public int getModified(){ 17 | return modified; 18 | } 19 | 20 | public void setModified(int m){ 21 | modified = m; 22 | } 23 | 24 | public boolean getRemoved(){ 25 | return removed; 26 | } 27 | 28 | public void setRemoved(boolean b){ 29 | removed = b; 30 | } 31 | 32 | public int getIndex(){ 33 | return index; 34 | } 35 | 36 | public void setIndex(int ind){ 37 | index = ind; 38 | } 39 | 40 | public String getLine(){ 41 | return txt; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/iface/ComLayerWithOutputPanel.java: -------------------------------------------------------------------------------- 1 | 2 | package iface; 3 | 4 | public interface ComLayerWithOutputPanel { 5 | public boolean tabClosed(int id); 6 | } 7 | -------------------------------------------------------------------------------- /src/iface/ComLayerWithPluginPanel.java: -------------------------------------------------------------------------------- 1 | package iface; 2 | 3 | public interface ComLayerWithPluginPanel { 4 | 5 | public void buttonClicked(); 6 | 7 | public void listIndexChanged(int ind); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /src/iface/ComLayerWithThread.java: -------------------------------------------------------------------------------- 1 | 2 | package iface; 3 | 4 | public interface ComLayerWithThread { 5 | public void addToConsole(String line,int id, int ind); 6 | public void threadClosed(int id); 7 | } 8 | -------------------------------------------------------------------------------- /src/main/ComboBoxItem.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | public class ComboBoxItem { 4 | 5 | final private int ID; 6 | final private String text; 7 | 8 | public ComboBoxItem(int ID, String text) { 9 | this.ID = ID; 10 | this.text = text; 11 | } 12 | 13 | @Override 14 | public String toString() { 15 | return text; 16 | } 17 | 18 | public int getID() { 19 | return ID; 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /src/main/CommandExecuter.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import diff.JDiff; 4 | import java.io.BufferedReader; 5 | import java.io.InputStreamReader; 6 | import java.text.SimpleDateFormat; 7 | import java.util.Calendar; 8 | import iface.*; 9 | 10 | public class CommandExecuter implements Runnable { 11 | 12 | private final ComLayerWithThread comLayer; 13 | private final String [][] cmd; 14 | private final String [][] diff; 15 | private volatile boolean isStopped; 16 | private final int id; 17 | public CommandExecuter(String [][] cmd, ComLayerWithThread comLayer,int id, String [][] diff){ 18 | this.cmd = cmd; 19 | this.comLayer = comLayer; 20 | this.id = id; 21 | this.diff = diff; 22 | } 23 | 24 | @Override 25 | public void run() { 26 | Process p; 27 | long st,end; 28 | st = System.currentTimeMillis()/1000; 29 | String timeStamp = new SimpleDateFormat("HH:mm:ss").format(Calendar.getInstance().getTime()); 30 | comLayer.addToConsole("Execution Started at: "+ timeStamp+"\r\n\r\n", id,-1); 31 | for(int i=0;i= 0; i--) { 110 | if (filePath.charAt(i) == '\\' || filePath.charAt(i) == '/') { 111 | break; 112 | } else { 113 | fileName = filePath.charAt(i) + fileName; 114 | } 115 | } 116 | return fileName; 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /src/main/MainClass.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import javax.swing.JFrame; 4 | import javax.swing.SwingUtilities; 5 | import database.DatabaseConn; 6 | 7 | public class MainClass { 8 | 9 | 10 | 11 | public static void main(String[] args) { 12 | 13 | DatabaseConn.init(); 14 | 15 | SwingUtilities.invokeLater(new Runnable(){ 16 | 17 | @Override 18 | public void run() { 19 | JFrame frame = new MainFrame(); 20 | frame.setVisible(true); 21 | } 22 | 23 | }); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/MainFrame.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import java.awt.Insets; 4 | import java.awt.event.ActionEvent; 5 | import java.awt.event.ActionListener; 6 | import java.awt.event.WindowAdapter; 7 | import java.io.File; 8 | import java.io.FileOutputStream; 9 | import java.io.OutputStreamWriter; 10 | import java.nio.file.Files; 11 | import java.nio.file.Paths; 12 | import java.util.ArrayList; 13 | import javax.swing.JFrame; 14 | import javax.swing.JMenu; 15 | import javax.swing.JMenuBar; 16 | import javax.swing.JMenuItem; 17 | import javax.swing.JOptionPane; 18 | import javax.swing.JPanel; 19 | import iface.*; 20 | import dialog.*; 21 | import database.*; 22 | import javax.swing.ToolTipManager; 23 | 24 | public class MainFrame extends JFrame implements ActionListener { 25 | 26 | private String [] volCommand; 27 | private final ArrayList commandExecuter; 28 | private final ArrayList outputFiles; 29 | private int ids; 30 | final JFrame frame; 31 | private PluginsPanel pluginsPanel; 32 | private OptionsPanel optionsPanel; 33 | private OutputPanel outputPanel; 34 | private final JPanel mainPanel; 35 | 36 | private final BatchFileDialog batchFileDialog; 37 | private final PluginsDialog pluginsDialog; 38 | private final OptionsDialog optionsDialog; 39 | private final ProfilesDialog profilesDialog; 40 | 41 | private final JMenuBar menuBar; 42 | private final JMenu fileMenu; 43 | private final JMenuItem batchMenuItem; 44 | private final JMenuItem exitMenuItem; 45 | private final JMenu configMenu; 46 | private final JMenuItem cmdAndProfilesMenuItem; 47 | private final JMenuItem optionsMenuItem; 48 | private final JMenuItem pluginsMenuItem; 49 | private final SubWindowAdapter windowAdapter; 50 | 51 | public MainFrame() { 52 | super("GVol - A GUI for Volatility Memory Forensics Framework"); 53 | this.volCommand = updateVolCommand();//DatabaseConn.getVolCommand(); 54 | 55 | this.ids = 0; 56 | this.commandExecuter = new ArrayList(); 57 | this.outputFiles = new ArrayList(); 58 | setSize(920, 720); 59 | this.setResizable(false); 60 | setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 61 | 62 | frame = this; 63 | windowAdapter = new SubWindowAdapter(); 64 | addWindowListener(windowAdapter); 65 | 66 | mainPanel = new JPanel(); 67 | setContentPane(mainPanel); 68 | mainPanel.setLayout(null); 69 | 70 | menuBar = new JMenuBar(); 71 | fileMenu = new JMenu(); 72 | configMenu = new JMenu(); 73 | 74 | batchMenuItem = new JMenuItem(); 75 | exitMenuItem = new JMenuItem(); 76 | cmdAndProfilesMenuItem = new JMenuItem(); 77 | optionsMenuItem = new JMenuItem(); 78 | pluginsMenuItem = new JMenuItem(); 79 | 80 | batchFileDialog = new BatchFileDialog(this); 81 | optionsDialog = new OptionsDialog(this); 82 | pluginsDialog = new PluginsDialog(this); 83 | profilesDialog = new ProfilesDialog(this); 84 | 85 | ToolTipManager.sharedInstance().setDismissDelay(600000); 86 | 87 | initOptionsPanel(); 88 | initPluginsPanel(); 89 | initOutputPanel(); 90 | initMenuBar(); 91 | setJMenuBar(menuBar); 92 | setLocationRelativeTo(null); 93 | } 94 | 95 | private void initPluginsPanel() { 96 | pluginsPanel = new PluginsPanel(new PluginPanelCom()); 97 | Insets insets = mainPanel.getInsets(); 98 | pluginsPanel.setBounds(insets.left + 5, insets.top + 5, 450, 450); 99 | mainPanel.add(pluginsPanel); 100 | } 101 | 102 | private void initOptionsPanel() { 103 | optionsPanel = new OptionsPanel(); 104 | Insets insets = mainPanel.getInsets(); 105 | optionsPanel.setBounds(insets.left + 460, insets.top + 5, 450, 450); 106 | mainPanel.add(optionsPanel); 107 | } 108 | 109 | private void initOutputPanel() { 110 | outputPanel = new OutputPanel(new OutputPanelCom()); 111 | Insets insets = mainPanel.getInsets(); 112 | outputPanel.setBounds(insets.left + 5, insets.top + 460, 905, 200); 113 | mainPanel.add(outputPanel); 114 | } 115 | 116 | private void showMessage(String msg) { 117 | JOptionPane.showMessageDialog(this, msg); 118 | } 119 | 120 | private void initMenuBar() { 121 | fileMenu.setText("File"); 122 | batchMenuItem.setText("Manage Batch Files..."); 123 | batchMenuItem.addActionListener(this); 124 | exitMenuItem.setText("Exit"); 125 | exitMenuItem.addActionListener(this); 126 | fileMenu.add(batchMenuItem); 127 | fileMenu.add(exitMenuItem); 128 | 129 | configMenu.setText("Configuration"); 130 | 131 | cmdAndProfilesMenuItem.setText("Command & Profiles..."); 132 | cmdAndProfilesMenuItem.addActionListener(this); 133 | optionsMenuItem.setText("Volatility Options..."); 134 | optionsMenuItem.addActionListener(this); 135 | pluginsMenuItem.setText("Plugins..."); 136 | pluginsMenuItem.addActionListener(this); 137 | configMenu.add(cmdAndProfilesMenuItem); 138 | configMenu.add(optionsMenuItem); 139 | configMenu.add(pluginsMenuItem); 140 | 141 | menuBar.add(fileMenu); 142 | menuBar.add(configMenu); 143 | } 144 | 145 | @Override 146 | public void actionPerformed(ActionEvent ae) { 147 | Object source = ae.getSource(); 148 | if (source == exitMenuItem) { 149 | windowAdapter.windowClosing(null); 150 | return; 151 | } else if (source == batchMenuItem) { 152 | batchFileDialog.setVisible(true); 153 | } else if (source == cmdAndProfilesMenuItem) { 154 | profilesDialog.setVisible(true); 155 | } else if (source == optionsMenuItem) { 156 | optionsDialog.setVisible(true); 157 | } else if (source == pluginsMenuItem) { 158 | pluginsDialog.setVisible(true); 159 | } 160 | pluginsPanel.updateComponents(); 161 | volCommand = updateVolCommand(); 162 | } 163 | 164 | private String[] updateVolCommand() { 165 | String [] newCmd = null; 166 | String cmd = DatabaseConn.getVolCommand(); 167 | if(cmd.length()>7){ 168 | String st = cmd.substring(0, 7); 169 | st = st.toLowerCase(); 170 | File f = new File(cmd); 171 | 172 | if(st.compareTo("python ")==0 && !f.exists()){ 173 | newCmd = new String[2]; 174 | newCmd[0] = "python"; 175 | newCmd[1] = cmd.substring(7); 176 | } 177 | else{ 178 | newCmd = new String[1]; 179 | newCmd[0] = cmd; 180 | } 181 | } 182 | else{ 183 | newCmd = new String[1]; 184 | newCmd[0] = cmd; 185 | } 186 | return newCmd; 187 | } 188 | 189 | class PluginPanelCom implements ComLayerWithPluginPanel { 190 | 191 | @Override 192 | public void buttonClicked() { 193 | if (!optionsPanel.hasValidValues()) { 194 | showMessage("you must enter values for all selected options."); 195 | return; 196 | } else if (!pluginsPanel.hasValidValues()) { 197 | String msg = "you must specify an input image file or output directory.\n"; 198 | msg += "If you selected a second memory image, you have to choose an output directory."; 199 | showMessage(msg); 200 | return; 201 | } else if (pluginsPanel.runBatchFile() > 0 && DatabaseConn.batchFilePluginCount(pluginsPanel.runBatchFile()) < 1) { 202 | showMessage("this batch file has no commands."); 203 | return; 204 | } 205 | 206 | if (pluginsPanel.runBatchFile() > 0) { 207 | if(!runBatchFile()) return; 208 | } else { 209 | runCommand(); 210 | } 211 | 212 | Thread t = new Thread(commandExecuter.get(commandExecuter.size() - 1)); 213 | t.start(); 214 | } 215 | 216 | @Override 217 | public void listIndexChanged(int pluginID) { 218 | 219 | optionsPanel.updateVisibleOptions(pluginID); 220 | revalidate(); 221 | repaint(); 222 | 223 | } 224 | 225 | private String getNewFileName(String dir, String name){ 226 | try { 227 | String fPath = dir + File.separator + name; 228 | Integer i = 0; 229 | while (Files.exists(Paths.get(fPath + i.toString() + ".txt"))) { 230 | i++; 231 | } 232 | fPath = fPath + i.toString() + ".txt"; 233 | return fPath; 234 | } catch (Exception ex) { 235 | return null; 236 | } 237 | } 238 | 239 | private OutputStreamWriter getOutputStream(String filePath) { 240 | try { 241 | OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(filePath)); 242 | return out; 243 | } catch (Exception ex) { 244 | System.err.println("failed to getOutputStream fpath = "+filePath); 245 | return null; 246 | } 247 | } 248 | 249 | private void runCommand() { 250 | 251 | OutputStreamWriter[] out = null; 252 | 253 | int count; 254 | String [][] diff = null; 255 | if(pluginsPanel.shouldWriteToFile()){ 256 | out = new OutputStreamWriter[1]; 257 | } 258 | if(pluginsPanel.shouldRunDiff()){ 259 | count = 2; 260 | diff = new String[1][2]; 261 | out = new OutputStreamWriter[2]; 262 | } 263 | else count=1; 264 | 265 | String [][] cmd = new String[count][];//[1+volCommand.length+pluginCommands.length+optionCommands.length]; 266 | 267 | for(int j=0;j
%s
", 150, options[ind].getDesc())); 65 | checkBoxes[ind].setMaximumSize(new Dimension(200, 0)); 66 | checkBoxes[ind].addActionListener(this); 67 | 68 | switch (options[ind].getValueType()) { 69 | case STRING: 70 | jField = new JTextField(14); 71 | jField.setPreferredSize(new Dimension(250, 25)); 72 | components[ind] = jField; 73 | break; 74 | case NUMBER: 75 | jField = new JTextField(14); 76 | jField.addKeyListener(new NumberValidator()); 77 | jField.setPreferredSize(new Dimension(250, 25)); 78 | components[ind] = jField; 79 | break; 80 | case FILE: 81 | fileChooser = new MFileChooser(false); 82 | components[ind] = fileChooser; 83 | break; 84 | case DIRECTORY: 85 | fileChooser = new MFileChooser(true); 86 | components[ind] = fileChooser; 87 | break; 88 | case NOVALUE: 89 | components[ind] = new JLabel(); 90 | break; 91 | 92 | } 93 | components[ind].setEnabled(false); 94 | 95 | } 96 | 97 | @Override 98 | public void actionPerformed(ActionEvent ae) { 99 | JCheckBox checkBox = (JCheckBox) ae.getSource(); 100 | for (int i = 0; i < checkBoxes.length; i++) { 101 | if (checkBox == checkBoxes[i]) { 102 | 103 | components[i].setEnabled(checkBox.isSelected()); 104 | break; 105 | } 106 | } 107 | } 108 | 109 | class NumberValidator extends KeyAdapter { 110 | 111 | @Override 112 | public void keyReleased(KeyEvent e) { 113 | JTextField textField = (JTextField) e.getSource(); 114 | String text = textField.getText(); 115 | 116 | if (text.length() >= 2 && text.charAt(0) == '0' && text.charAt(1) == 'x') { 117 | text = validateHex(text); 118 | } else { 119 | text = validateDec(text); 120 | } 121 | 122 | textField.setText(text); 123 | } 124 | 125 | private String validateHex(String text) { 126 | String newText = "" + text.charAt(0) + text.charAt(1); 127 | for (int i = 2; i < text.length(); i++) { 128 | if ((text.charAt(i) <= '9' && text.charAt(i) >= '0') 129 | || (text.charAt(i) <= 'f' && text.charAt(i) >= 'a') 130 | || (text.charAt(i) <= 'F' && text.charAt(i) >= 'A')) { 131 | 132 | newText = newText + text.charAt(i); 133 | } 134 | } 135 | return newText; 136 | } 137 | 138 | private String validateDec(String text) { 139 | String newText = ""; 140 | for (int i = 0; i < text.length(); i++) { 141 | if (text.charAt(i) <= '9' && text.charAt(i) >= '0') { 142 | newText = newText + text.charAt(i); 143 | } 144 | } 145 | return newText; 146 | } 147 | 148 | } 149 | 150 | public String [] getCommand() { 151 | 152 | ArrayList str = new ArrayList(); 153 | 154 | for (int i = 0; i < checkBoxes.length; i++) { 155 | if (checkBoxes[i].isSelected()) { 156 | str.add(options[i].getCmd()); 157 | switch (options[i].getValueType()) { 158 | case STRING: 159 | case NUMBER: 160 | JTextField jField = (JTextField) components[i]; 161 | str.add(jField.getText()); 162 | break; 163 | case FILE: 164 | case DIRECTORY: 165 | MFileChooser fileChooser = (MFileChooser) components[i]; 166 | str.add(fileChooser.getSelectedFile()); 167 | break; 168 | } 169 | } 170 | } 171 | String [] cmd = new String[str.size()]; 172 | for(int i=0;i consoleTextArea; 22 | private final JTabbedPane tabsPane; 23 | private final JButton closeButton; 24 | private final ComLayerWithOutputPanel comLayer; 25 | 26 | public OutputPanel(ComLayerWithOutputPanel comLayer) { 27 | 28 | super(); 29 | this.comLayer = comLayer; 30 | setBorder(BorderFactory.createTitledBorder("Console Output")); 31 | setLayout(new BorderLayout()); 32 | tabsPane = new JTabbedPane(); 33 | consoleTextArea = new ArrayList(); 34 | add(tabsPane, BorderLayout.CENTER); 35 | closeButton = new JButton(); 36 | closeButton.setText("Close Current Tab"); 37 | closeButton.addActionListener(this); 38 | 39 | JPanel panel = new JPanel(); 40 | panel.setLayout(new FlowLayout()); 41 | panel.add(closeButton); 42 | JLabel lb = new JLabel(); 43 | lb.setPreferredSize(new Dimension(600,25)); 44 | panel.add(lb); 45 | add(panel, BorderLayout.PAGE_END); 46 | 47 | 48 | } 49 | 50 | private JTextArea createTextArea() { 51 | JTextArea textArea = new JTextArea(); 52 | textArea.setLineWrap(true); 53 | textArea.setEditable(false); 54 | return textArea; 55 | } 56 | 57 | public void appendText(String txt, int id) { 58 | consoleTextArea.get(id).append(txt); 59 | 60 | 61 | } 62 | 63 | public void clearText(int id) { 64 | consoleTextArea.get(id).setText(""); 65 | 66 | } 67 | 68 | public void addNewTextArea() { 69 | JTextArea textArea = createTextArea(); 70 | consoleTextArea.add(textArea); 71 | DefaultCaret caret = (DefaultCaret)textArea.getCaret(); 72 | caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE); 73 | tabsPane.addTab("Tab " + consoleTextArea.size(), new JScrollPane(textArea)); 74 | tabsPane.setSelectedIndex(tabsPane.getTabCount()- 1); 75 | } 76 | 77 | @Override 78 | public void actionPerformed(ActionEvent ae) { 79 | int ind = tabsPane.getSelectedIndex(); 80 | if(ind >=0) 81 | { 82 | String str = tabsPane.getTitleAt(ind); 83 | str = str.substring(4); 84 | int id = Integer.parseInt(str)-1; 85 | if (comLayer.tabClosed(id)) { 86 | tabsPane.remove(ind); 87 | } 88 | 89 | } 90 | 91 | } 92 | 93 | } -------------------------------------------------------------------------------- /src/main/PluginsPanel.java: -------------------------------------------------------------------------------- 1 | package main; 2 | 3 | import java.awt.GridBagConstraints; 4 | import java.awt.GridBagLayout; 5 | import java.awt.event.ActionEvent; 6 | import java.awt.event.ActionListener; 7 | import javax.swing.BorderFactory; 8 | import javax.swing.JButton; 9 | import javax.swing.JCheckBox; 10 | import javax.swing.JComboBox; 11 | import javax.swing.JLabel; 12 | import javax.swing.JPanel; 13 | import database.*; 14 | import iface.*; 15 | import java.awt.event.MouseEvent; 16 | 17 | class PluginsPanel extends JPanel implements ActionListener { 18 | 19 | private final JLabel imageLabel; 20 | private final JLabel image2Label; 21 | private final JLabel profileLabel; 22 | private final JLabel pluginLabel; 23 | private final JLabel outputDirLabel; 24 | private final JLabel batchFileLabel; 25 | 26 | private final JButton executeButton; 27 | 28 | private final JComboBox profilesList; 29 | private final JComboBox pluginsList; 30 | private final JComboBox batchFilesList; 31 | 32 | private Plugin[] plugins; 33 | private Profile[] profiles; 34 | private BatchFile [] batchFiles; 35 | 36 | private final MFileChooser inputFileChooser; 37 | private final MFileChooser inputFile2Chooser; 38 | private final MFileChooser outputDirChooser; 39 | 40 | private final JCheckBox writeFileBox; 41 | private final JCheckBox runBatchBox; 42 | 43 | private final ComLayerWithPluginPanel comLayer; 44 | 45 | public PluginsPanel(ComLayerWithPluginPanel comLayer) { 46 | super(); 47 | setBorder(BorderFactory.createTitledBorder("Plugins")); 48 | 49 | this.comLayer = comLayer; 50 | imageLabel = new JLabel(); 51 | image2Label = new JLabel(); 52 | profileLabel = new JLabel(); 53 | pluginLabel = new JLabel(); 54 | outputDirLabel = new JLabel(); 55 | batchFileLabel = new JLabel(); 56 | 57 | inputFileChooser = new MFileChooser(false); 58 | inputFile2Chooser = new MFileChooser(false); 59 | executeButton = new JButton(); 60 | profilesList = new JComboBox(); 61 | pluginsList = new JComboBox() { 62 | @Override 63 | public String getToolTipText(MouseEvent e) { 64 | try { 65 | //System.err.println("called"); 66 | ComboBoxItem cbi = (ComboBoxItem) this.getSelectedItem(); 67 | if (cbi == null) { 68 | return null; 69 | } 70 | Plugin plugin = DatabaseConn.getPlugin(cbi.getID()); 71 | 72 | return plugin.getTooltip(); 73 | } catch (Exception ex) { 74 | // System.err.println("Failed to get ToolTip"); 75 | } 76 | return null; 77 | 78 | } 79 | }; 80 | pluginsList.setToolTipText("select a plugin"); 81 | batchFilesList = new JComboBox(); 82 | writeFileBox = new JCheckBox(String.format("
%s
", 150,"Write the output to a file.")); 83 | runBatchBox = new JCheckBox("Run batch file."); 84 | outputDirChooser = new MFileChooser(true); 85 | 86 | initComponents(); 87 | } 88 | 89 | private void initComponents() { 90 | 91 | imageLabel.setText("Memory image: "); 92 | image2Label.setText("Diff with this image: "); 93 | profileLabel.setText("Profile: "); 94 | pluginLabel.setText("Plugin: "); 95 | outputDirLabel.setText("Choose output directory: "); 96 | batchFileLabel.setText("Choose batch file: "); 97 | outputDirChooser.setEnabled(false); 98 | writeFileBox.addActionListener(this); 99 | runBatchBox.addActionListener(this); 100 | 101 | executeButton.addActionListener(this); 102 | executeButton.setText("Run Command"); 103 | batchFilesList.setEnabled(false); 104 | setLayout(new GridBagLayout()); 105 | GridBagConstraints gc = new GridBagConstraints(); 106 | 107 | gc.gridx = 0; 108 | gc.gridy = 0; 109 | gc.fill = GridBagConstraints.NONE; 110 | gc.anchor = GridBagConstraints.WEST; 111 | gc.weightx = gc.weighty = 1; 112 | 113 | //labels column 114 | add(imageLabel,gc); 115 | gc.gridy++; 116 | add(image2Label,gc); 117 | gc.gridy++; 118 | add(profileLabel,gc); 119 | gc.gridy++; 120 | add(pluginLabel,gc); 121 | gc.gridy++; 122 | add(writeFileBox,gc); 123 | gc.gridy++; 124 | add(outputDirLabel,gc); 125 | gc.gridy++; add(runBatchBox,gc); 126 | gc.gridy++; add(batchFileLabel,gc); 127 | 128 | //second column 129 | gc.gridy=0; 130 | gc.gridx=1; 131 | 132 | add(inputFileChooser,gc); 133 | gc.gridy++; 134 | add(inputFile2Chooser,gc); 135 | gc.gridy++; 136 | add(profilesList,gc); 137 | gc.gridy++; 138 | add(pluginsList,gc); 139 | gc.gridy+=2; 140 | add(outputDirChooser,gc); 141 | gc.gridy+=3; 142 | add(batchFilesList,gc); 143 | gc.gridy++; 144 | gc.weighty = 3; 145 | gc.anchor = GridBagConstraints.NORTH; 146 | add(executeButton,gc); 147 | 148 | updateComponents(); 149 | } 150 | 151 | public void updateComponents(){ 152 | plugins = DatabaseConn.getPlugins(); 153 | profiles = DatabaseConn.getProfiles(); 154 | batchFiles = DatabaseConn.getBatchFiles(); 155 | 156 | pluginsList.removeAllItems(); 157 | profilesList.removeAllItems(); 158 | batchFilesList.removeAllItems(); 159 | 160 | for (Profile profile : profiles) { 161 | profilesList.addItem(new ComboBoxItem(profile.getID(), profile.getDescription())); 162 | } 163 | int first = -1; 164 | for(Plugin plugin : plugins){ 165 | if(first == -1) first = plugin.getID(); 166 | 167 | pluginsList.addItem(new ComboBoxItem(plugin.getID(), plugin.getName())); 168 | } 169 | pluginsList.addActionListener(this); 170 | comLayer.listIndexChanged(first); 171 | 172 | for(BatchFile batchFile:batchFiles){ 173 | batchFilesList.addItem(new ComboBoxItem(batchFile.getID(), batchFile.getName())); 174 | } 175 | revalidate(); 176 | } 177 | 178 | public boolean hasValidValues(){ 179 | String txt; 180 | 181 | txt = inputFileChooser.getSelectedFile(); 182 | if(txt==null || txt.isEmpty() || txt.trim().isEmpty()) 183 | return false; 184 | 185 | txt = inputFile2Chooser.getSelectedFile(); 186 | if(txt!=null && !txt.trim().isEmpty() && !writeFileBox.isSelected()){ 187 | return false; 188 | } 189 | if(writeFileBox.isSelected()){ 190 | txt = outputDirChooser.getSelectedFile(); 191 | if(txt==null || txt.isEmpty() || txt.trim().isEmpty()) 192 | return false; 193 | } 194 | return true; 195 | } 196 | 197 | /** 198 | * @return the first part of the command which contains the input file 199 | * and the profile 200 | */ 201 | 202 | public String [] getCommand(int ind){ 203 | //input image 204 | String [] cmd = new String[3]; 205 | cmd[0] = "-f"; 206 | if(ind ==0) cmd[1] = inputFileChooser.getSelectedFile(); 207 | else cmd[1] = inputFile2Chooser.getSelectedFile(); 208 | //profile 209 | ComboBoxItem cbi = (ComboBoxItem) profilesList.getSelectedItem(); 210 | Profile p = DatabaseConn.getProfile(cbi.getID()); 211 | cmd[2] = "--profile="+p.getName(); 212 | return cmd; 213 | } 214 | 215 | public boolean shouldRunDiff(){ 216 | String txt = inputFile2Chooser.getSelectedFile(); 217 | return !(txt == null || txt.isEmpty() || txt.trim().isEmpty()); 218 | } 219 | 220 | public boolean shouldWriteToFile(){ 221 | return writeFileBox.isSelected(); 222 | } 223 | 224 | public int runBatchFile(){ 225 | if(runBatchBox.isSelected()){ 226 | ComboBoxItem cbi = (ComboBoxItem)batchFilesList.getSelectedItem(); 227 | if(cbi==null) return -1; 228 | return cbi.getID(); 229 | } 230 | else return -1; 231 | } 232 | 233 | public String getPluginName(){ 234 | //plugin 235 | ComboBoxItem cbi = (ComboBoxItem) pluginsList.getSelectedItem(); 236 | Plugin pl = DatabaseConn.getPlugin(cbi.getID()); 237 | return pl.getName(); 238 | } 239 | 240 | public String getFileName(int ind){ 241 | if(ind==0) return inputFileChooser.getFileName(); 242 | else return inputFile2Chooser.getFileName(); 243 | } 244 | 245 | public String getOutputDir(){ 246 | String str = outputDirChooser.getSelectedFile(); 247 | if(str!=null && str.charAt(str.length()-1)=='/' || str.charAt(str.length()-1)=='\\'){ 248 | str = str.substring(0,str.length()-1); 249 | } 250 | return str; 251 | } 252 | 253 | @Override 254 | public void actionPerformed(ActionEvent e) { 255 | Object source = e.getSource(); 256 | if(pluginsList == source){ 257 | if(pluginsList.getItemCount()<1) return ; 258 | ComboBoxItem cbi = (ComboBoxItem) pluginsList.getSelectedItem(); 259 | comLayer.listIndexChanged(cbi.getID()); 260 | } 261 | else if(executeButton == source){ 262 | executeButtonAction(); 263 | } 264 | else if(writeFileBox == source){ 265 | writeFileBoxAction(); 266 | 267 | } 268 | else if(runBatchBox == source){ 269 | runBatchBoxAction(); 270 | } 271 | 272 | } 273 | 274 | private void executeButtonAction() { 275 | comLayer.buttonClicked(); 276 | } 277 | 278 | private void writeFileBoxAction() { 279 | outputDirChooser.setEnabled(writeFileBox.isSelected()); 280 | } 281 | 282 | private void runBatchBoxAction() { 283 | boolean selected = runBatchBox.isSelected(); 284 | batchFilesList.setEnabled(selected); 285 | pluginsList.setEnabled(!selected); 286 | comLayer.listIndexChanged(-1); 287 | executeButton.setText(selected?"Run Batch":"Run Command"); 288 | } 289 | 290 | } 291 | --------------------------------------------------------------------------------