This commit is contained in:
adam-m 2012-08-16 14:45:06 -04:00
commit e193ecc99a
5 changed files with 147 additions and 33 deletions

View File

@ -18,9 +18,6 @@
*/
package org.sleuthkit.autopsy.hashdatabase;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JOptionPane;
import org.openide.nodes.Node;
import org.openide.util.HelpCtx;
@ -108,22 +105,8 @@ public class HashDbSearchAction extends CallableSystemAction implements HashSear
}
private void doSearch() {
// Get the map of hashes to FsContent and send it to the manager
List<FsContent> files = HashDbSearcher.findFilesByMd5(fsContent.getMd5Hash());
for(int i=0; i<files.size(); i++) {
// If they are the same file, remove it from the list
if(files.get(i).equals(fsContent)) {
files.remove(i);
}
}
if(!files.isEmpty()) {
Map<String, List<FsContent>> map = new LinkedHashMap<String, List<FsContent>>();
map.put(fsContent.getMd5Hash(), files);
HashDbSearchManager man = new HashDbSearchManager(map);
man.execute();
} else {
JOptionPane.showMessageDialog(null, "No other files with the same MD5 hash were found.");
}
HashDbSearchThread hashThread = new HashDbSearchThread(fsContent);
hashThread.execute();
}
@Override

View File

@ -37,16 +37,16 @@
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="saveBox" min="-2" max="-2" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="errorField" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace min="0" pref="0" max="32767" attributes="0"/>
</Group>
<Group type="102" alignment="0" attributes="0">
<Component id="errorField" min="-2" max="-2" attributes="0"/>
<EmptySpace type="separate" max="-2" attributes="0"/>
<Component id="searchButton" min="-2" max="-2" attributes="0"/>
<EmptySpace type="unrelated" max="-2" attributes="0"/>
<Component id="cancelButton" min="-2" max="-2" attributes="0"/>
</Group>
</Group>
<EmptySpace max="-2" attributes="0"/>
</Group>

View File

@ -24,15 +24,12 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.table.DefaultTableModel;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;
import org.sleuthkit.datamodel.FsContent;
/**
* Searches for files by md5 hash, based off the hash given in this panel.
@ -328,10 +325,9 @@ public class HashDbSearchPanel extends javax.swing.JPanel implements ActionListe
for(int i=0; i<numRows; i++) {
hashes.add((String) hashTable.getValueAt(i, 0));
}
// Get the map of hashes to FsContent and send it to the manager
Map<String, List<FsContent>> map = HashDbSearcher.findFilesBymd5(hashes);
HashDbSearchManager man = new HashDbSearchManager(map);
man.execute();
// Start a new thread and find the hashes
HashDbSearchThread hashThread = new HashDbSearchThread(hashes);
hashThread.execute();
return true;
}

View File

@ -0,0 +1,111 @@
/*
* Autopsy Forensic Browser
*
* Copyright 2011 Basis Technology Corp.
* Contact: carrier <at> sleuthkit <dot> org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.sleuthkit.autopsy.hashdatabase;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CancellationException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.openide.util.Cancellable;
import org.sleuthkit.datamodel.FsContent;
class HashDbSearchThread extends SwingWorker<Object,Void> {
private Logger logger = Logger.getLogger(HashDbSearchThread.class.getName());
private ProgressHandle progress;
Map<String, List<FsContent>> map;
ArrayList<String> hashes = new ArrayList<String>();
FsContent fsContent;
HashDbSearchThread(FsContent fsContent) {
this.hashes.add(fsContent.getMd5Hash());
this.fsContent = fsContent;
}
HashDbSearchThread(ArrayList<String> hashes) {
this.hashes = hashes;
}
@Override
protected Object doInBackground() throws Exception {
logger.log(Level.INFO, "Starting background processing for file search by MD5 hash.");
// Setup progress bar
final String displayName = "Searching";
progress = ProgressHandleFactory.createHandle(displayName, new Cancellable() {
@Override
public boolean cancel() {
if (progress != null)
progress.setDisplayName(displayName + " (Cancelling...)");
return HashDbSearchThread.this.cancel(true);
}
});
// Start the progress bar as indeterminate
progress.start();
progress.switchToIndeterminate();
// Do the querying
map = HashDbSearcher.findFilesBymd5(hashes, progress, this);
logger.log(Level.INFO, "Done background processing");
return null;
}
@Override
protected void done() {
try {
super.get(); //block and get all exceptions thrown while doInBackground()
} catch (CancellationException ex) {
logger.log(Level.INFO, "File search by MD5 hash was canceled.");
} catch (InterruptedException ex) {
logger.log(Level.INFO, "File search by MD5 hash was interrupted.");
} catch (Exception ex) {
logger.log(Level.SEVERE, "Fatal error during file search by MD5 hash.", ex);
} finally {
progress.finish();
if (!this.isCancelled()) {
logger.log(Level.INFO, "File search by MD5 hash completed without cancellation.");
// If its a right click action, we are given an FsContent which
// is the file right clicked, so we can remove that from the search
if(fsContent!=null) {
boolean quit = true;
for(List<FsContent> files: map.values()) {
files.remove(fsContent);
if(!files.isEmpty()) {
quit = false;
}
}
if(quit) {
JOptionPane.showMessageDialog(null, "No other files with the same MD5 hash were found.");
return;
}
}
HashDbSearchManager man = new HashDbSearchManager(map);
man.execute();
} else {
logger.log(Level.INFO, "File search by MD5 hash was canceled.");
}
}
}
}

View File

@ -22,6 +22,8 @@ import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.SwingWorker;
import org.netbeans.api.progress.ProgressHandle;
import org.sleuthkit.autopsy.casemodule.Case;
import org.sleuthkit.datamodel.FsContent;
import org.sleuthkit.datamodel.SleuthkitCase;
@ -59,6 +61,28 @@ public class HashDbSearcher {
}
return map;
}
// Same as above, but with a given ProgressHandle to accumulate and StringWorker to check if cancelled
static Map<String, List<FsContent>> findFilesBymd5(List<String> md5Hash, ProgressHandle progress, SwingWorker worker) {
Map<String, List<FsContent>> map = new LinkedHashMap<String, List<FsContent>>();
if(!worker.isCancelled()) {
progress.switchToDeterminate(md5Hash.size());
int size = 0;
for(String md5 : md5Hash) {
if(worker.isCancelled()) {
break;
}
List<FsContent> files = findFilesByMd5(md5);
if(!files.isEmpty()) {
map.put(md5, files);
}
size++;
if(!worker.isCancelled()) {
progress.progress(size);
}
}
}
return map;
}
/**
* Given a file, returns a list of all files with the same