From 00cf4ad3809a5619010ee355647b8c9b301a475a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Milkovi=C4=8D?= Date: Fri, 9 Sep 2022 01:27:46 +0200 Subject: [PATCH] Add printing of analysis time to retdec-fileinfo output --- .../file_information/file_information.cpp | 18 ++++++++++++++++++ .../file_information/file_information.h | 3 +++ .../file_presentation/json_presentation.cpp | 10 +++++++--- .../file_presentation/json_presentation.h | 5 +++-- .../file_presentation/plain_presentation.cpp | 9 +++++++-- .../file_presentation/plain_presentation.h | 7 ++++--- src/fileinfo/fileinfo.cpp | 19 +++++++++++++++---- 7 files changed, 57 insertions(+), 14 deletions(-) diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index de4409bda..bb21e095a 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -106,6 +106,15 @@ std::string FileInformation::getPathToFile() const return filePath; } +/** + * Get time when the analysis was done + * @return Analysis time + */ +std::string FileInformation::getAnalysisTime() const +{ + return analysisTime; +} + std::string FileInformation::getTelfhash() const { return telfhash; @@ -3307,6 +3316,15 @@ void FileInformation::setPathToFile(const std::string &filepath) filePath = filepath; } +/** + * Set when the analysis was done + * @param filepath Analysis time + */ +void FileInformation::setAnalysisTime(const std::string &analysistime) +{ + analysisTime = analysistime; +} + void FileInformation::setTelfhash(const std::string &hash) { telfhash = hash; diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 09d2c7030..ce157ef39 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -26,6 +26,7 @@ class FileInformation private: retdec::cpdetect::ReturnCode status = retdec::cpdetect::ReturnCode::OK; std::string filePath; ///< path to input file + std::string analysisTime; ///< time when the analysis was done std::string telfhash; ///< telfhash of ELF input file std::string crc32; ///< CRC32 of input file std::string md5; ///< MD5 of input file @@ -78,6 +79,7 @@ class FileInformation /// @{ retdec::cpdetect::ReturnCode getStatus() const; std::string getPathToFile() const; + std::string getAnalysisTime() const; std::string getTelfhash() const; std::string getCrc32() const; std::string getMd5() const; @@ -504,6 +506,7 @@ class FileInformation /// @{ void setStatus(retdec::cpdetect::ReturnCode state); void setPathToFile(const std::string &filepath); + void setAnalysisTime(const std::string &analysistime); void setTelfhash(const std::string &telfhash); void setCrc32(const std::string &fileCrc32); void setMd5(const std::string &fileMd5); diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index c16a769d2..e6b519614 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -97,9 +97,8 @@ bool presentSimple( /** * Constructor */ -JsonPresentation::JsonPresentation(FileInformation &fileinfo_, bool verbose_) - : FilePresentation(fileinfo_) - , verbose(verbose_) +JsonPresentation::JsonPresentation(FileInformation &fileinfo_, bool verbose_, bool analysisTime_) + : FilePresentation(fileinfo_), verbose(verbose_), analysisTime(analysisTime_) { } @@ -1322,6 +1321,11 @@ bool JsonPresentation::present() presentFileinfoVersion(writer); } + if(analysisTime) + { + serializeString(writer, "analysisTime", fileinfo.getAnalysisTime()); + } + serializeString(writer, "inputFile", fileinfo.getPathToFile()); serializeString(writer, "dllName", fileinfo.getExportDllName()); diff --git a/src/fileinfo/file_presentation/json_presentation.h b/src/fileinfo/file_presentation/json_presentation.h index ab0b5856c..a42e9f137 100644 --- a/src/fileinfo/file_presentation/json_presentation.h +++ b/src/fileinfo/file_presentation/json_presentation.h @@ -28,7 +28,8 @@ class JsonPresentation : public FilePresentation rapidjson::ASCII<>>; private: - bool verbose; ///< @c true - print all information about file + bool verbose; ///< @c true - print all information about file + bool analysisTime; ///< @c true - print when the analysis was done /// @name Auxiliary presentation methods /// @{ @@ -63,7 +64,7 @@ class JsonPresentation : public FilePresentation const IterativeSubtitleGetter &getter) const; /// @} public: - JsonPresentation(FileInformation &fileinfo_, bool verbose_); + JsonPresentation(FileInformation &fileinfo_, bool verbose_, bool analysisTime_); virtual bool present() override; }; diff --git a/src/fileinfo/file_presentation/plain_presentation.cpp b/src/fileinfo/file_presentation/plain_presentation.cpp index bec2ae6a1..890cd10f5 100644 --- a/src/fileinfo/file_presentation/plain_presentation.cpp +++ b/src/fileinfo/file_presentation/plain_presentation.cpp @@ -348,8 +348,8 @@ void presentIterativeSimple(const IterativeSimpleGetter &getter) /** * Constructor */ -PlainPresentation::PlainPresentation(FileInformation &fileinfo_, bool verbose_, bool explanatory_) : - FilePresentation(fileinfo_), verbose(verbose_), explanatory(explanatory_) +PlainPresentation::PlainPresentation(FileInformation &fileinfo_, bool verbose_, bool explanatory_, bool analysisTime_) : + FilePresentation(fileinfo_), verbose(verbose_), explanatory(explanatory_), analysisTime(analysisTime_) { } @@ -828,6 +828,11 @@ bool PlainPresentation::present() Log::info() << "RetDec Fileinfo version : " << utils::version::getVersionStringShort() << "\n"; } + if(analysisTime) + { + Log::info() << "Analysis time : " + << fileinfo.getAnalysisTime() << "\n"; + } Log::info() << "Input file : " << fileinfo.getPathToFile() << "\n"; const std::string& dllName = fileinfo.getExportDllName(); diff --git a/src/fileinfo/file_presentation/plain_presentation.h b/src/fileinfo/file_presentation/plain_presentation.h index 005674874..0c1cf648d 100644 --- a/src/fileinfo/file_presentation/plain_presentation.h +++ b/src/fileinfo/file_presentation/plain_presentation.h @@ -18,8 +18,9 @@ namespace fileinfo { class PlainPresentation : public FilePresentation { private: - bool verbose; ///< @c true - print all information about file - bool explanatory; ///< @c true - print explanatory notes + bool verbose; ///< @c true - print all information about file + bool explanatory; ///< @c true - print explanatory notes + bool analysisTime; ///< @c true - print when the analysis was done /// @name Auxiliary presentation methods /// @{ @@ -37,7 +38,7 @@ class PlainPresentation : public FilePresentation void presentSignatures() const; /// @} public: - PlainPresentation(FileInformation &fileinfo_, bool verbose_, bool explanatory_); + PlainPresentation(FileInformation &fileinfo_, bool verbose_, bool explanatory_, bool analysisTime_); virtual bool present() override; }; diff --git a/src/fileinfo/fileinfo.cpp b/src/fileinfo/fileinfo.cpp index edaf112e5..5dc9d8488 100644 --- a/src/fileinfo/fileinfo.cpp +++ b/src/fileinfo/fileinfo.cpp @@ -14,6 +14,7 @@ #include "retdec/utils/memory.h" #include "retdec/utils/io/log.h" #include "retdec/utils/string.h" +#include "retdec/utils/time.h" #include "retdec/utils/version.h" #include "retdec/ar-extractor/detection.h" #include "retdec/cpdetect/errors.h" @@ -76,6 +77,8 @@ struct ProgParams std::size_t epBytesCount = EP_BYTES_SIZE; /// load flags for `fileformat` LoadFlags loadFlags = LoadFlags::NONE; + /// flag whether to include analysis time into the output + bool analysisTime = false; friend std::ostream& operator<<(std::ostream& os, const ProgParams& pp); }; @@ -96,6 +99,7 @@ std::ostream& operator<<(std::ostream& os, const ProgParams& pp) os << "max half memory : " << pp.maxMemoryHalfRAM << "\n"; os << "ep bytes count : " << pp.epBytesCount << "\n"; os << "load flags : " << pp.loadFlags << "\n"; + os << "analysis time : " << pp.analysisTime << "\n"; os << "yara malware rules : " << "\n"; for (auto& r : pp.yaraMalwarePaths) @@ -134,11 +138,11 @@ void fatalErrorHandler(void *user_data, const std::string& /*reason*/, bool /*ge if(params->plainText) { - PlainPresentation(*fileinfo, params->verbose, params->explanatory).present(); + PlainPresentation(*fileinfo, params->verbose, params->explanatory, params->analysisTime).present(); } else { - JsonPresentation(*fileinfo, params->verbose).present(); + JsonPresentation(*fileinfo, params->verbose, params->analysisTime).present(); } exit(static_cast(ReturnCode::FORMAT_PARSER_PROBLEM)); @@ -206,6 +210,7 @@ void printHelp() << " Without this parameter program print only\n" << " basic information.\n" << " --explanatory, -X Print explanatory notes (only in plain text output).\n" + << " --analysis-time Print also analysis time into output.\n" << "\n" << "Options for specifying configuration file:\n" << " --config=file, -c=file\n" @@ -390,6 +395,7 @@ bool doConfigString( params.verbose = retdec::serdes::deserializeBool(root, "verbose", params.verbose); params.explanatory = retdec::serdes::deserializeBool(root, "explanatory", params.explanatory); params.maxMemoryHalfRAM = retdec::serdes::deserializeBool(root, "maxMemoryHalf", params.maxMemoryHalfRAM); + params.analysisTime = retdec::serdes::deserializeBool(root, "analysisTime", params.analysisTime); if (root.HasMember("loadStrings")) { @@ -604,6 +610,10 @@ bool doParams(int argc, char **_argv, ProgParams ¶ms) { params.explanatory = true; } + else if (c == "--analysis-time") + { + params.analysisTime = true; + } else if (c == "-S" || c == "--strings") { params.loadFlags = static_cast(params.loadFlags @@ -773,6 +783,7 @@ int main(int argc, char* argv[]) FileInformation fileinfo; FileDetector *fileDetector = nullptr; fileinfo.setPathToFile(params.filePath); + fileinfo.setAnalysisTime(timestampToDate(getCurrentTimestamp())); fileinfo.setFileFormatEnum(fileFormat); ErrorHandlerInfo hInfo { ¶ms, &fileinfo }; llvm::install_fatal_error_handler(fatalErrorHandler, &hInfo); @@ -833,11 +844,11 @@ int main(int argc, char* argv[]) // print results on standard output if(params.plainText) { - PlainPresentation(fileinfo, params.verbose, params.explanatory).present(); + PlainPresentation(fileinfo, params.verbose, params.explanatory, params.analysisTime).present(); } else { - JsonPresentation(fileinfo, params.verbose).present(); + JsonPresentation(fileinfo, params.verbose, params.analysisTime).present(); } // generate configuration file