mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-17 02:07:42 +00:00
Merge pull request #1315 from sidheshenator/python_module_reload_and_logging
Python module reload and logging
This commit is contained in:
commit
fd70adfc55
@ -70,6 +70,7 @@ public final class JythonModuleLoader {
|
||||
private static <T> List<T> getInterfaceImplementations(LineFilter filter, Class<T> interfaceClass) {
|
||||
List<T> objects = new ArrayList<>();
|
||||
Set<File> pythonModuleDirs = new HashSet<>();
|
||||
PythonInterpreter interpreter = new PythonInterpreter();
|
||||
|
||||
// add python modules from 'autospy/build/cluster/InternalPythonModules' folder
|
||||
// which are copied from 'autopsy/*/release/InternalPythonModules' folders.
|
||||
@ -90,7 +91,7 @@ public final class JythonModuleLoader {
|
||||
if (line.startsWith("class ") && filter.accept(line)) { //NON-NLS
|
||||
String className = line.substring(6, line.indexOf("("));
|
||||
try {
|
||||
objects.add( createObjectFromScript(script, className, interfaceClass));
|
||||
objects.add( createObjectFromScript(interpreter, script, className, interfaceClass));
|
||||
} catch (Exception ex) {
|
||||
logger.log(Level.SEVERE, String.format("Failed to load %s from %s", className, script.getAbsolutePath()), ex); //NON-NLS
|
||||
// NOTE: using ex.toString() because the current version is always returning null for ex.getMessage().
|
||||
@ -112,23 +113,23 @@ public final class JythonModuleLoader {
|
||||
return objects;
|
||||
}
|
||||
|
||||
private static <T> T createObjectFromScript(File script, String className, Class<T> interfaceClass) {
|
||||
// Make a "fresh" interpreter every time to avoid name collisions, etc.
|
||||
PythonInterpreter interpreter = new PythonInterpreter();
|
||||
|
||||
private static <T> T createObjectFromScript(PythonInterpreter interpreter, File script, String className, Class<T> interfaceClass) {
|
||||
// Add the directory where the Python script resides to the Python
|
||||
// module search path to allow the script to use other scripts bundled
|
||||
// with it.
|
||||
interpreter.exec("import sys"); //NON-NLS
|
||||
String path = Matcher.quoteReplacement(script.getParent());
|
||||
interpreter.exec("sys.path.append('" + path + "')"); //NON-NLS
|
||||
String moduleName = script.getName().replaceAll(".py", ""); //NON-NLS
|
||||
|
||||
// reload the module so that the changes made to it can be loaded.
|
||||
interpreter.exec("import " + moduleName); //NON-NLS
|
||||
interpreter.exec("reload(" + moduleName + ")"); //NON-NLS
|
||||
|
||||
// Execute the script and create an instance of the desired class.
|
||||
interpreter.execfile(script.getAbsolutePath());
|
||||
// Importing the appropriate class from the Py Script which contains multiple classes.
|
||||
interpreter.exec("from " + script.getName().replaceAll(".py", "") + " import " + className);
|
||||
interpreter.exec("from " + moduleName + " import " + className);
|
||||
interpreter.exec("obj = " + className + "()"); //NON-NLS
|
||||
|
||||
|
||||
T obj = interpreter.get("obj", interfaceClass); //NON-NLS
|
||||
|
||||
// Remove the directory where the Python script resides from the Python
|
||||
|
@ -32,6 +32,7 @@
|
||||
# See http://sleuthkit.org/autopsy/docs/api-docs/3.1/index.html for documentation
|
||||
|
||||
import jarray
|
||||
import inspect
|
||||
from java.lang import System
|
||||
from java.util.logging import Level
|
||||
from org.sleuthkit.datamodel import SleuthkitCase
|
||||
@ -58,11 +59,11 @@ from org.sleuthkit.autopsy.casemodule.services import FileManager
|
||||
class SampleJythonDataSourceIngestModuleFactory(IngestModuleFactoryAdapter):
|
||||
|
||||
# TODO: give it a unique name. Will be shown in module list, logs, etc.
|
||||
moduleName = "Sample Data Source Module"
|
||||
|
||||
moduleName = "Sample Data Source Module"
|
||||
|
||||
def getModuleDisplayName(self):
|
||||
return self.moduleName
|
||||
|
||||
|
||||
# TODO: Give it a description
|
||||
def getModuleDescription(self):
|
||||
return "Sample module that does X, Y, and Z."
|
||||
@ -82,6 +83,11 @@ class SampleJythonDataSourceIngestModuleFactory(IngestModuleFactoryAdapter):
|
||||
# TODO: Rename this to something more specific. Could just remove "Factory" from above name.
|
||||
class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
|
||||
_logger = Logger.getLogger(SampleJythonDataSourceIngestModuleFactory.moduleName)
|
||||
|
||||
def log(self, level, msg):
|
||||
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
|
||||
|
||||
def __init__(self):
|
||||
self.context = None
|
||||
|
||||
@ -93,8 +99,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
self.context = context
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException(IngestModule(), "Oh No!")
|
||||
|
||||
|
||||
|
||||
# Where the analysis is done.
|
||||
# The 'dataSource' object being passed in is of type org.sleuthkit.datamodel.Content.
|
||||
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/interfaceorg_1_1sleuthkit_1_1datamodel_1_1_content.html
|
||||
@ -104,8 +109,6 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
def process(self, dataSource, progressBar):
|
||||
if self.context.isJobCancelled():
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
logger = Logger.getLogger(SampleJythonDataSourceIngestModuleFactory.moduleName)
|
||||
|
||||
# we don't know how much work there is yet
|
||||
progressBar.switchToIndeterminate()
|
||||
@ -115,13 +118,13 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
services = Services(sleuthkitCase)
|
||||
fileManager = services.getFileManager()
|
||||
|
||||
# For our example, we will use FileManager to get all
|
||||
# For our example, we will use FileManager to get all
|
||||
# files with the word "test"
|
||||
# in the name and then count and read them
|
||||
files = fileManager.findFiles(dataSource, "%test%")
|
||||
|
||||
numFiles = len(files)
|
||||
logger.logp(Level.INFO, SampleJythonDataSourceIngestModule.__name__, "process", "found " + str(numFiles) + " files")
|
||||
self.log(Level.INFO, "found " + str(numFiles) + " files")
|
||||
progressBar.switchToDeterminate(numFiles)
|
||||
fileCount = 0;
|
||||
for file in files:
|
||||
@ -130,7 +133,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
if self.context.isJobCancelled():
|
||||
return IngestModule.ProcessResult.OK
|
||||
|
||||
logger.logp(Level.INFO, SampleJythonDataSourceIngestModule.__name__, "process", "Processing file: " + file.getName())
|
||||
self.log(Level.INFO, "Processing file: " + file.getName())
|
||||
fileCount += 1
|
||||
|
||||
# Make an artifact on the blackboard. TSK_INTERESTING_FILE_HIT is a generic type of
|
||||
@ -139,7 +142,7 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
att = BlackboardAttribute(BlackboardAttribute.ATTRIBUTE_TYPE.TSK_SET_NAME.getTypeID(), SampleJythonDataSourceIngestModuleFactory.moduleName, "Test file")
|
||||
art.addAttribute(att)
|
||||
|
||||
|
||||
|
||||
# To further the example, this code will read the contents of the file and count the number of bytes
|
||||
inputStream = ReadContentInputStream(file)
|
||||
buffer = jarray.zeros(1024, "b")
|
||||
@ -159,4 +162,4 @@ class SampleJythonDataSourceIngestModule(DataSourceIngestModule):
|
||||
"Sample Jython Data Source Ingest Module", "Found %d files" % fileCount)
|
||||
IngestServices.getInstance().postMessage(message)
|
||||
|
||||
return IngestModule.ProcessResult.OK;
|
||||
return IngestModule.ProcessResult.OK;
|
@ -32,6 +32,7 @@
|
||||
# See http://sleuthkit.org/autopsy/docs/api-docs/3.1/index.html for documentation
|
||||
|
||||
import jarray
|
||||
import inspect
|
||||
from java.lang import System
|
||||
from java.util.logging import Level
|
||||
from org.sleuthkit.datamodel import SleuthkitCase
|
||||
@ -84,12 +85,16 @@ class SampleJythonFileIngestModuleFactory(IngestModuleFactoryAdapter):
|
||||
# Looks at the attributes of the passed in file.
|
||||
class SampleJythonFileIngestModule(FileIngestModule):
|
||||
|
||||
_logger = Logger.getLogger(SampleJythonFileIngestModuleFactory.moduleName)
|
||||
|
||||
def log(self, level, msg):
|
||||
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
|
||||
|
||||
# Where any setup and configuration is done
|
||||
# 'context' is an instance of org.sleuthkit.autopsy.ingest.IngestJobContext.
|
||||
# See: http://sleuthkit.org/autopsy/docs/api-docs/3.1/classorg_1_1sleuthkit_1_1autopsy_1_1ingest_1_1_ingest_job_context.html
|
||||
# TODO: Add any setup code that you need here.
|
||||
def startUp(self, context):
|
||||
self.logger = Logger.getLogger(SampleJythonFileIngestModuleFactory.moduleName)
|
||||
self.filesFound = 0
|
||||
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
@ -101,7 +106,6 @@ class SampleJythonFileIngestModule(FileIngestModule):
|
||||
# See: http://www.sleuthkit.org/sleuthkit/docs/jni-docs/classorg_1_1sleuthkit_1_1datamodel_1_1_abstract_file.html
|
||||
# TODO: Add your analysis code in here.
|
||||
def process(self, file):
|
||||
|
||||
# Skip non-files
|
||||
if ((file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNALLOC_BLOCKS) or (file.getType() == TskData.TSK_DB_FILES_TYPE_ENUM.UNUSED_BLOCKS) or (file.isFile() == False)):
|
||||
return IngestModule.ProcessResult.OK
|
||||
@ -109,7 +113,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
|
||||
# For an example, we will flag files with .txt in the name and make a blackboard artifact.
|
||||
if file.getName().find(".txt") != -1:
|
||||
|
||||
self.logger.logp(Level.INFO, SampleJythonFileIngestModule.__name__, "process", "Found a text file: " + file.getName())
|
||||
self.log(Level.INFO, "Found a text file: " + file.getName())
|
||||
self.filesFound+=1
|
||||
|
||||
# Make an artifact on the blackboard. TSK_INTERESTING_FILE_HIT is a generic type of
|
||||
@ -125,7 +129,7 @@ class SampleJythonFileIngestModule(FileIngestModule):
|
||||
for artifact in artifactList:
|
||||
attributeList = artifact.getAttributes();
|
||||
for attrib in attributeList:
|
||||
self.logger.logp(Level.INFO, SampleJythonFileIngestModule.__name__, "process", attrib.toString())
|
||||
self.log(Level.INFO, attrib.toString())
|
||||
|
||||
# To further the example, this code will read the contents of the file and count the number of bytes
|
||||
inputStream = ReadContentInputStream(file)
|
||||
@ -143,4 +147,4 @@ class SampleJythonFileIngestModule(FileIngestModule):
|
||||
def shutDown(self):
|
||||
# As a final part of this example, we'll send a message to the ingest inbox with the number of files found (in this thread)
|
||||
message = IngestMessage.createMessage(IngestMessage.MessageType.DATA, SampleJythonFileIngestModuleFactory.moduleName, str(self.filesFound) + " files found")
|
||||
ingestServices = IngestServices.getInstance().postMessage(message)
|
||||
ingestServices = IngestServices.getInstance().postMessage(message)
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
|
||||
import jarray
|
||||
import inspect
|
||||
from java.lang import System
|
||||
from java.util.logging import Level
|
||||
from javax.swing import JCheckBox
|
||||
@ -68,10 +69,10 @@ class SampleFileIngestModuleWithUIFactory(IngestModuleFactoryAdapter):
|
||||
|
||||
# TODO: give it a unique name. Will be shown in module list, logs, etc.
|
||||
moduleName = "Sample Data Source Module with UI"
|
||||
|
||||
|
||||
def getModuleDisplayName(self):
|
||||
return self.moduleName
|
||||
|
||||
|
||||
# TODO: Give it a description
|
||||
def getModuleDescription(self):
|
||||
return "Sample module that does X, Y, and Z."
|
||||
@ -109,6 +110,11 @@ class SampleFileIngestModuleWithUIFactory(IngestModuleFactoryAdapter):
|
||||
# Looks at the attributes of the passed in file.
|
||||
class SampleFileIngestModuleWithUI(FileIngestModule):
|
||||
|
||||
_logger = Logger.getLogger(SampleFileIngestModuleWithUIFactory.moduleName)
|
||||
|
||||
def log(self, level, msg):
|
||||
self._logger.logp(level, self.__class__.__name__, inspect.stack()[1][3], msg)
|
||||
|
||||
# Autopsy will pass in the settings from the UI panel
|
||||
def __init__(self, settings):
|
||||
self.local_settings = settings
|
||||
@ -117,14 +123,12 @@ class SampleFileIngestModuleWithUI(FileIngestModule):
|
||||
# Where any setup and configuration is done
|
||||
# TODO: Add any setup code that you need here.
|
||||
def startUp(self, context):
|
||||
self.logger = Logger.getLogger(SampleFileIngestModuleWithUIFactory.moduleName)
|
||||
|
||||
# As an example, determine if user configured a flag in UI
|
||||
if self.local_settings.getFlag():
|
||||
self.logger.logp(Level.INFO, SampleFileIngestModuleWithUI.__name__, "startUp", "flag is set")
|
||||
self.log(Level.INFO, "flag is set")
|
||||
else:
|
||||
self.logger.logp(Level.INFO, SampleFileIngestModuleWithUI.__name__, "startUp", "flag is not set")
|
||||
|
||||
self.log(Level.INFO, "flag is not set")
|
||||
|
||||
# Throw an IngestModule.IngestModuleException exception if there was a problem setting up
|
||||
# raise IngestModuleException(IngestModule(), "Oh No!")
|
||||
pass
|
||||
@ -171,7 +175,7 @@ class SampleFileIngestModuleWithUISettingsPanel(IngestModuleIngestJobSettingsPan
|
||||
# is present, it creates a read-only 'settings' property. This auto-
|
||||
# generated read-only property overshadows the instance-variable -
|
||||
# 'settings'
|
||||
|
||||
|
||||
# We get passed in a previous version of the settings so that we can
|
||||
# prepopulate the UI
|
||||
# TODO: Update this for your UI
|
||||
@ -179,7 +183,7 @@ class SampleFileIngestModuleWithUISettingsPanel(IngestModuleIngestJobSettingsPan
|
||||
self.local_settings = settings
|
||||
self.initComponents()
|
||||
self.customizeComponents()
|
||||
|
||||
|
||||
# TODO: Update this for your UI
|
||||
def checkBoxEvent(self, event):
|
||||
if self.checkbox.isSelected():
|
||||
@ -201,4 +205,3 @@ class SampleFileIngestModuleWithUISettingsPanel(IngestModuleIngestJobSettingsPan
|
||||
def getSettings(self):
|
||||
return self.local_settings
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user