/** * Sets the location of the module given an absolute or relative location. * For relative paths we look for the * module first in PROG_DIR, then MODULE_DIR, then the * current directory, and * finally the system path. Will throw an exception if the module cannot * be found. * @param location Absolute or relative path string for module. */ void TskModule::setPath(const std::string& location) { if (location.empty()) { throw TskException("TskModule::setPath: location is empty or missing."); } Poco::Path tempPath = location; if (!tempPath.isAbsolute()) { // If this is a relative path, then see if we can find the // executable either in PROG_DIR, in MODULE_DIR, in the current directory, // or on the system path. std::string pathsToSearch = GetSystemProperty(TskSystemProperties::PROG_DIR); if (!pathsToSearch.empty()) pathsToSearch += Poco::Path::pathSeparator(); pathsToSearch += GetSystemProperty(TskSystemProperties::MODULE_DIR); if (!pathsToSearch.empty()) pathsToSearch += Poco::Path::pathSeparator(); pathsToSearch += "."; if (!Poco::Path::find(pathsToSearch, location, tempPath)) { // if we didn't find them in the above paths, check on the path. if (Poco::Environment::has("Path")) { std::string systemPath = Poco::Environment::get("Path"); if (!systemPath.empty()) { Poco::Path::find(systemPath, location, tempPath); } } } } // Confirm existence of file at location. Poco::File moduleFile(tempPath); if (!moduleFile.exists()) { std::stringstream msg; msg << "TskModule::setPath - Module not found: " << tempPath.toString().c_str(); throw TskException(msg.str()); } else { std::wstringstream msg; msg << L"TskModule::setPath - Module found at: " << tempPath.toString().c_str(); LOGINFO(msg.str()); } m_modulePath = tempPath.toString(); }
void TskCarveExtractScalpel::processCarvedFiles(const std::string &outputFolderPath, const std::vector<TskCarveExtractScalpel::CarvedFile> &carvedFiles) const { try { TskImgDB& imgDB = TskServices::Instance().getImgDB(); const uint64_t sectorSize = 512; for (std::vector<CarvedFile>::const_iterator file = carvedFiles.begin(); file != carvedFiles.end(); ++file) { std::stringstream filePath; filePath << outputFolderPath << Poco::Path::separator() << (*file).name; // Convert the starting offset (in bytes) of the carved file in the unallocated image file the and length of the carved file (in bytes) // into a range of "sectors." int fileStartSectorOffset = static_cast<int>((*file).offset / sectorSize); int fileEndSectorOffset = static_cast<int>(((*file).offset + (*file).length) / sectorSize); // Get the unallocated sectors run corresponding to the unallocated image file and map the file sector offsets to image sector offset and length. std::auto_ptr<UnallocRun> run(imgDB.getUnallocRun((*file).id, fileStartSectorOffset)); int numberOfRuns = 1; uint64_t sectorRunStart[] = { run->getAllocStart() + fileStartSectorOffset - run->getUnallocStart() }; uint64_t sectorRunLength[] = { run->getAllocStart() + fileEndSectorOffset - run->getUnallocStart() - sectorRunStart[0] }; // Add the mapping to the image database. uint64_t fileId; if (imgDB.addCarvedFileInfo(run->getVolId(), const_cast<wchar_t*>(TskUtilities::toUTF16((*file).name).c_str()), (*file).length, §orRunStart[0], §orRunLength[0], numberOfRuns, fileId) == -1) { std::stringstream msg; msg << "TskCarveExtractScalpel::processCarvedFiles : unable to save carved file info for '" << filePath.str() << "'"; throw TskException(msg.str()); } TskServices::Instance().getFileManager().addFile(fileId, TskUtilities::toUTF16(filePath.str())); // Delete output (carved) files by default. std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_OUTPUT_FILES"); std::transform(option.begin(), option.end(), option.begin(), ::toupper); bool deleteOutputFiles = (option != "TRUE"); if (deleteOutputFiles) { Poco::File file(filePath.str()); file.remove(); } if (imgDB.updateFileStatus(fileId, TskImgDB::IMGDB_FILES_STATUS_READY_FOR_ANALYSIS) == 1) { std::stringstream msg; msg << "TskCarveExtractScalpel::processCarvedFiles : unable to update file status for '" << filePath.str() << "'"; throw TskException(msg.str()); } } } catch (Poco::Exception &ex) { std::stringstream msg; msg << "TskCarveExtractScalpel::processCarvedFiles : Poco exception: " << ex.displayText(); throw TskException(msg.str()); } }
/** * Module initialization function. Optionally receives an output folder * path as the location for saving the files corresponding to interesting * file set hits. The default output folder path is a folder named for the * module in #MODULE_OUT_DIR#. * * @param args Optional output folder path. * @return TskModule::OK if an output folder is created, TskModule::FAIL * otherwise. */ TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments) { TskModule::Status status = TskModule::OK; const std::string MSG_PREFIX = "SaveInterestingFilesModule::initialize : "; try { Poco::Path outputDirPath; if (strlen(arguments) != 0) { outputDirPath = Poco::Path::forDirectory(arguments); } else { outputDirPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR)); outputDirPath.pushDirectory(name()); } outputFolderPath = outputDirPath.toString(); Poco::File(outputDirPath).createDirectory(); } catch (TskException &ex) { status = TskModule::FAIL; outputFolderPath.clear(); std::stringstream msg; msg << MSG_PREFIX << "TskException: " << ex.message(); LOGERROR(msg.str()); } catch (Poco::Exception &ex) { status = TskModule::FAIL; outputFolderPath.clear(); std::stringstream msg; msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText(); LOGERROR(msg.str()); } catch (std::exception &ex) { status = TskModule::FAIL; outputFolderPath.clear(); std::stringstream msg; msg << MSG_PREFIX << "std::exception: " << ex.what(); LOGERROR(msg.str()); } catch (...) { status = TskModule::FAIL; outputFolderPath.clear(); LOGERROR(MSG_PREFIX + "unrecognized exception"); } return status; }
void TskCarvePrepSectorConcat::setUpForCarvePrep(std::string &outputFolderPath, std::string &outputFileName, size_t &maxOutputFileSize) const { try { // Create the output folder. Since multiple calls to processSectors() and/or processFiles() are possible, check to see if the folder already exists. outputFolderPath = GetSystemProperty("CARVE_DIR"); Poco::File folder(outputFolderPath); if (!folder.exists()) { folder.createDirectory(); } outputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME"); maxOutputFileSize = strtoul(GetSystemProperty("MAX_UNALLOC_SECTORS_IMG_FILE_SIZE").c_str(), NULL, 10); } catch (Poco::Exception &ex) { std::stringstream msg; msg << "TskCarvePrepSectorConcat::createFolder : Poco exception: " << ex.displayText(); throw TskException(msg.str()); } }
/** * Module cleanup function. This is where the module should free any resources * allocated during initialization or execution. * * @returns TskModule::OK on success and TskModule::FAIL on error. */ TskModule::Status TSK_MODULE_EXPORT finalize() { std::ostringstream msgPrefix; msgPrefix << MODULE_NAME << "::finalize : "; try { #if !defined(_DEBUG) // Delete the output folder if it's empty. Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR)); outputFolderPath.pushDirectory(MODULE_NAME); Poco::File outputFolder(outputFolderPath); std::vector<Poco::File> filesList; outputFolder.list(filesList); if (filesList.empty()) { outputFolder.remove(true); } #endif return TskModule::OK; } catch (TskException &ex) { std::ostringstream msg; msg << msgPrefix.str() << "TskException: " << ex.message(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (Poco::Exception &ex) { std::ostringstream msg; msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (std::exception &ex) { std::ostringstream msg; msg << msgPrefix.str() << "std::exception: " << ex.what(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (...) { LOGERROR(msgPrefix.str() + "unrecognized exception"); return TskModule::FAIL; } }
/** * Module initialization function. Takes a string as input that allows * arguments to be passed into the module. * @param arguments Tells the module which */ TskModule::Status TSK_MODULE_EXPORT initialize(const char* arguments) { magicHandle = magic_open(MAGIC_NONE); if (magicHandle == NULL) { LOGERROR("FileTypeSigModule: Error allocating magic cookie."); return TskModule::FAIL; } //Attempt to load magic database from default places on Linux. //Don't bother trying magic_load() for defaults on win32 because it will always cause an exception instead of gracefully returning. #ifndef TSK_WIN32 /* Load the default magic database, which is found in this order: 1. MAGIC env variable 2. $HOME/.magic.mgc (or $HOME/.magic dir) 3. /usr/share/misc/magic.mgc (or /usr/share/misc/magic dir) (unless libmagic was build configured abnormally) */ if (magic_load(magicHandle, NULL)) { std::stringstream msg; msg << "FileTypeSigModule: Error loading default magic file: " << magic_error(magicHandle); LOGERROR(msg.str()); //don't return, just fall through to the default loading below } else { return TskModule::OK; } #endif //Load the magic database file in the repo std::string path = GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR) + Poco::Path::separator() + MODULE_NAME + Poco::Path::separator() + "magic.mgc"; Poco::File magicFile = Poco::File(path); if (magicFile.exists() == false) { std::stringstream msg; msg << "FileTypeSigModule: Magic file not found: " << path; LOGERROR(msg.str()); return TskModule::FAIL; } if (magic_load(magicHandle, path.c_str())) { std::stringstream msg; msg << "FileTypeSigModule: Error loading magic file: " << magic_error(magicHandle) << GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR); LOGERROR(msg.str()); return TskModule::FAIL; } return TskModule::OK; }
/** * Module execution function. * * @returns TskModule::OK on success, TskModule::FAIL on error, or TskModule::STOP. */ TskModule::Status TSK_MODULE_EXPORT report() { std::ostringstream msgPrefix; msgPrefix << MODULE_NAME << "::report : "; try { // Create an output folder. Poco::Path outputFolderPath = Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_OUT_DIR)); outputFolderPath.pushDirectory(MODULE_NAME); Poco::File(outputFolderPath).createDirectories(); // Generate the report. outputFolderPath.setFileName("SummaryReport.htm"); TskSummaryReport::generateReport(outputFolderPath.toString()); return TskModule::OK; } catch (TskException &ex) { std::ostringstream msg; msg << msgPrefix.str() << "TskException: " << ex.message(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (Poco::Exception &ex) { std::ostringstream msg; msg << msgPrefix.str() << "Poco::Exception: " << ex.displayText(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (std::exception &ex) { std::ostringstream msg; msg << msgPrefix.str() << "std::exception: " << ex.what(); LOGERROR(msg.str()); return TskModule::FAIL; } catch (...) { LOGERROR(msgPrefix.str() + "unrecognized exception"); return TskModule::FAIL; } }
/*! * \brief TLogManager constructor. * \param env [in] JNI environment object. * \param info [in] JVM running performance information. */ TLogManager::TLogManager(JNIEnv *env, TJvmInfo *info) { /* Sanity check. */ if (unlikely(info == NULL)) { throw "TJvmInfo is NULL."; } jvmInfo = info; jvmCmd = NULL; arcMaker = NULL; jniArchiver = NULL; char *tempdirPath = NULL; /* Get temporary path of java */ tempdirPath = GetSystemProperty(env, "java.io.tmpdir"); try { /* Create JVM socket commander. */ jvmCmd = new TJVMSockCmd(tempdirPath); /* Archive file maker. */ arcMaker = new TCmdArchiver(); /* Archive file maker to use zip library in java. */ jniArchiver = new TJniZipArchiver(); /* Get GC log filename pointer. */ gcLogFilename = (char **)symFinder->findSymbol(GCLOG_FILENAME_SYMBOL); if (unlikely(gcLogFilename == NULL)) { throw 1; } } catch (...) { free(tempdirPath); delete jvmCmd; delete arcMaker; delete jniArchiver; throw "TLogManager initialize failed!"; } free(tempdirPath); }
int TskCarveExtractScalpel::processFile(int unallocImgId) { TskImgDB *imgDB = NULL; try { imgDB = &TskServices::Instance().getImgDB(); // Get the input folder path. The file to carve resides in a subdirectory of the carve prep output folder. The name of the subdirectory is the unallocated image file id. std::string carvePrepOutputPath = GetSystemProperty("CARVE_DIR"); if (!Poco::File(carvePrepOutputPath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::processFile : specified carve prep output folder '" << carvePrepOutputPath << "' does not exist"; throw TskException(msg.str()); } std::stringstream inputFolderPathBuilder; inputFolderPathBuilder << carvePrepOutputPath << Poco::Path::separator() << unallocImgId; // Get the input file name and construct the input file path. All of the files to carve have the same name. std::string carvePrepOutputFileName = GetSystemProperty("UNALLOC_SECTORS_IMG_FILE_NAME"); std::stringstream unallocImgFilePathBuilder; unallocImgFilePathBuilder << inputFolderPathBuilder.str() << Poco::Path::separator() << carvePrepOutputFileName; Poco::File unallocImgFile(unallocImgFilePathBuilder.str()); if (!unallocImgFile.exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::processFile : did not find unalloc img file number " << unallocImgId << " at '" << unallocImgFilePathBuilder.str() << "'"; throw TskException(msg.str()); } if (unallocImgFile.getSize() > static_cast<Poco::File::FileSize>(0)) { // Attempt to carve the file, storing the carved files in a subdirectory of the input folder and the Scalpel console output in the input folder. // The console output is placed in the input folder rather than the output folder because Scalpel will only write to an empty directory. std::stringstream outputFolderPath; outputFolderPath << inputFolderPathBuilder.str() << Poco::Path::separator() << CARVED_FILES_FOLDER; std::stringstream stdOutFilePath; stdOutFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_OUT_DUMP_FILE_NAME; std::stringstream stdErrFilePath; stdErrFilePath << inputFolderPathBuilder.str() << Poco::Path::separator() << STD_ERR_DUMP_FILE_NAME; carveFile(unallocImgFilePathBuilder.str(), outputFolderPath.str(), stdOutFilePath.str(), stdErrFilePath.str()); // Scalpel lists any files it carves out in a results file. Use the file list to add the files to the image DB and copy them to file storage. std::stringstream resultsFilePath; resultsFilePath << outputFolderPath.str() << Poco::Path::separator() << SCALPEL_RESULTS_FILE_NAME; processCarvedFiles(outputFolderPath.str(), parseCarvingResultsFile(unallocImgId, resultsFilePath.str())); // Update the unused sector info in the image database so it is known which of the unallocated sectors just carved did not go into a carved file. if (m_createUnusedSectorFiles) { std::vector<TskUnusedSectorsRecord> unusedSectorsList; imgDB->addUnusedSectors(unallocImgId, unusedSectorsList); } } else { // There is nothing to do if the file to be carved is of length zero. imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_NOT_NEEDED); } return 0; } catch (TskException &ex) { LOGERROR(TskUtilities::toUTF16(ex.message())); if (imgDB) { imgDB->setUnallocImgStatus(unallocImgId, TskImgDB::IMGDB_UNALLOC_IMG_STATUS_CARVED_ERR); } return 1; } }
void TskCarveExtractScalpel::carveFile(const std::string &unallocImgPath, const std::string &outputFolderPath, const std::string &stdOutFilePath, const std::string &stdErrFilePath) const { try { // Find out where Scalpel is installed. std::string scalpelDirPath = GetSystemProperty("SCALPEL_DIR"); if (scalpelDirPath.empty()) { throw TskException("TskCarveExtractScalpel::configure : Scalpel directory not set"); } if (!Poco::File(scalpelDirPath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::configure : specified Scalpel directory '" << scalpelDirPath << "' does not exist"; throw TskException(msg.str()); } // Get the path to the Scalpel executable. std::stringstream pathBuilder; pathBuilder << scalpelDirPath << Poco::Path::separator() << SCALPEL_EXE_FILE_NAME; std::string scalpelExePath = pathBuilder.str(); if (!Poco::File(scalpelExePath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::configure : Scalpel executable '" << scalpelExePath << "' does not exist"; throw TskException(msg.str()); } // Get the path to the Scalpel config file. std::string scalpelConfigFilePath = GetSystemProperty("SCALPEL_CONFIG_FILE"); if (!Poco::File(scalpelConfigFilePath).exists()) { std::stringstream msg; msg << "TskCarveExtractScalpel::TskCarveExtractScalpel : Scalpel config file '" << scalpelConfigFilePath << "' does not exist"; throw TskException(msg.str()); } // Set the Scalpel command line: specify the Scalpel config file. Poco::Process::Args args; args.push_back("-c"); args.push_back(scalpelConfigFilePath); // Set the Scalpel command line: allow for nested headers and footers. args.push_back("-e"); // Set the Scalpel command line: put any carved files directly into the output folder. args.push_back("-o"); args.push_back(outputFolderPath); args.push_back("-O"); // Set the Scalpel command line: specify the file to carve. args.push_back(unallocImgPath); // Launch Scalpel with console output redirects. Poco::Pipe outPipe; Poco::Pipe errPipe; Poco::ProcessHandle handle = Poco::Process::launch(scalpelExePath, args, NULL, &outPipe, &errPipe); // Capture the console output. Note that Scalpel may block at times as it waits for this loop to empty the stream buffers. Poco::PipeInputStream stdOutInputStream(outPipe); Poco::FileOutputStream stdOutOutputStream(stdOutFilePath); Poco::PipeInputStream stdErrInputStream(errPipe); Poco::FileOutputStream stdErrOutputStream(stdErrFilePath); while (stdOutInputStream || stdErrInputStream) { if (stdOutInputStream) { Poco::StreamCopier::copyStream(stdOutInputStream, stdOutOutputStream); } if (stdErrInputStream) { Poco::StreamCopier::copyStream(stdErrInputStream, stdErrOutputStream); } } // Scalpel should be finished since the console output streams are closed. int exitCode = Poco::Process::wait(handle); stdOutOutputStream.flush(); stdErrOutputStream.flush(); // On the first invocation of Scalpel, record its use in the image database. static bool toolInfoRecorded = false; if (!toolInfoRecorded) { std::ifstream stdOutStream(stdOutFilePath.c_str()); if (stdOutStream) { std::string versionString; std::getline(stdOutStream, versionString); Poco::StringTokenizer tokenizer(versionString, "\t ", Poco::StringTokenizer::TOK_IGNORE_EMPTY | Poco::StringTokenizer::TOK_TRIM); if (tokenizer[0] == "Scalpel" && tokenizer[1] == "version") { TskServices::Instance().getImgDB().addToolInfo("Scalpel", tokenizer[2].c_str()); toolInfoRecorded = true; } else { LOGWARN("TskCarveExtractScalpel::carveFile : Scalpel stdout output format changed, cannot record tool info"); } } else { LOGWARN("TskCarveExtractScalpel::carveFile : failed to open stdout stream, cannot record tool info"); } } // Delete input files by default. std::string option = GetSystemProperty("CARVE_EXTRACT_KEEP_INPUT_FILES"); std::transform(option.begin(), option.end(), option.begin(), ::toupper); bool deleteInputFiles = (option != "TRUE"); if (deleteInputFiles) { Poco::File file(unallocImgPath); file.remove(); } if (exitCode != 0) { std::stringstream msg; msg << "TskCarveExtractScalpel::carveFile : Scalpel exited with error exit code " << exitCode << " when carving '" << unallocImgPath.c_str() << "'"; throw TskException(msg.str()); } } catch (Poco::Exception &ex) { std::stringstream msg; msg << "TskCarveExtractScalpel::carveFile : Poco exception: " << ex.displayText(); throw TskException(msg.str()); } }
/** * Module initialization function. The initialization arguments string should * provide the path of a module configuration file that defines what files * are interesting. If the empty string is passed to this function, the module * assumes a default config file is present in the output directory. * * @param args Path of the configuration file that defines what files are * interesting, may be set to the empty string. * @return TskModule::OK on success, TskModule::FAIL otherwise. */ TSK_MODULE_EXPORT TskModule::Status initialize(const char* arguments) { TskModule::Status status = TskModule::OK; const std::string MSG_PREFIX = "InterestingFilesModule::initialize : "; try { // Make sure the file sets are cleared in case initialize() is called more than once. fileSets.clear(); configFilePath.assign(arguments); if (configFilePath.empty()) { // Use the default config file path. Poco::Path configurationFilePath(Poco::Path::forDirectory(GetSystemProperty(TskSystemProperties::MODULE_CONFIG_DIR))); configurationFilePath.pushDirectory(MODULE_NAME); configurationFilePath.setFileName(DEFAULT_CONFIG_FILE_NAME); configFilePath = configurationFilePath.toString(); } // Compile the contents of the config file into interesting file set definitions. Poco::File configFile = Poco::File(configFilePath); if (configFile.exists()) { std::ifstream configStream(configFile.path().c_str()); if (configStream) { Poco::XML::InputSource inputSource(configStream); Poco::AutoPtr<Poco::XML::Document> configDoc = Poco::XML::DOMParser().parse(&inputSource); Poco::XML::Element * rootElement = configDoc->documentElement(); if (rootElement == NULL) { std::ostringstream msg; msg << MSG_PREFIX << "Root element of config file is NULL."; throw TskException(msg.str()); } const std::string& ignoreKnownValue = Poco::XML::fromXMLString(rootElement->getAttribute(IGNORE_KNOWN_TAG)); if (!ignoreKnownValue.empty()) { knownType = parseKnownType(ignoreKnownValue); ignoreKnown = true; } Poco::AutoPtr<Poco::XML::NodeList> fileSetDefinitions = configDoc->getElementsByTagName(INTERESTING_FILE_SET_ELEMENT_TAG); for (unsigned long i = 0; i < fileSetDefinitions->length(); ++i) { compileInterestingFilesSet(fileSetDefinitions->item(i)); } } else { std::ostringstream msg; msg << MSG_PREFIX << "failed to open config file '" << configFilePath << "'"; throw TskException(msg.str()); } } else { std::ostringstream msg; msg << MSG_PREFIX << "config file'" << configFilePath << "' does not exist"; LOGERROR(msg.str()); } // Log the configuration. std::ostringstream msg; msg << MSG_PREFIX << "configured with " << fileSets.size() << " interesting file set definitions from '" << configFilePath << "'"; LOGINFO(msg.str()); } catch (TskException &ex) { status = TskModule::FAIL; configFilePath.clear(); std::ostringstream msg; msg << MSG_PREFIX << "TskException: " << ex.message(); LOGERROR(msg.str()); } catch (Poco::Exception &ex) { status = TskModule::FAIL; configFilePath.clear(); std::ostringstream msg; msg << MSG_PREFIX << "Poco::Exception: " << ex.displayText(); LOGERROR(msg.str()); } catch (std::exception &ex) { status = TskModule::FAIL; configFilePath.clear(); std::ostringstream msg; msg << MSG_PREFIX << "std::exception: " << ex.what(); LOGERROR(msg.str()); } catch (...) { status = TskModule::FAIL; configFilePath.clear(); LOGERROR(MSG_PREFIX + "unrecognized exception"); } return status; }