2021-12-07 22:47:41 +01:00
|
|
|
#include "content/views/view_information.hpp"
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2022-02-01 18:09:40 +01:00
|
|
|
#include <hex/api/content_registry.hpp>
|
2023-08-06 21:33:15 +02:00
|
|
|
#include <hex/api/achievement_manager.hpp>
|
2022-02-01 18:09:40 +01:00
|
|
|
|
2021-01-13 17:28:27 +01:00
|
|
|
#include <hex/providers/provider.hpp>
|
2022-07-31 16:57:35 +02:00
|
|
|
#include <hex/providers/buffered_reader.hpp>
|
2022-08-17 16:15:36 +02:00
|
|
|
|
2022-03-04 11:36:37 +01:00
|
|
|
#include <hex/helpers/fs.hpp>
|
2022-08-17 16:15:36 +02:00
|
|
|
#include <hex/helpers/magic.hpp>
|
2020-11-12 09:38:52 +01:00
|
|
|
|
|
|
|
#include <cmath>
|
2020-11-12 21:21:11 +01:00
|
|
|
#include <filesystem>
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2021-03-02 13:49:45 +01:00
|
|
|
#include <implot.h>
|
2021-02-22 13:08:06 +01:00
|
|
|
|
2023-12-26 00:22:47 +01:00
|
|
|
#include <toasts/toast_notification.hpp>
|
2023-04-08 00:58:53 +02:00
|
|
|
|
2021-12-07 22:47:41 +01:00
|
|
|
namespace hex::plugin::builtin {
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2021-09-06 16:15:05 +02:00
|
|
|
using namespace hex::literals;
|
|
|
|
|
2024-01-08 21:51:48 +01:00
|
|
|
ViewInformation::ViewInformation() : View::Window("hex.builtin.view.information.name", ICON_VS_GRAPH_LINE) {
|
2024-01-25 22:49:56 +01:00
|
|
|
EventDataChanged::subscribe(this, [this](prv::Provider *provider) {
|
|
|
|
auto &analysis = m_analysis.get(provider);
|
|
|
|
|
|
|
|
analysis.dataValid = false;
|
|
|
|
analysis.plainTextCharacterPercentage = -1.0;
|
|
|
|
analysis.averageEntropy = -1.0;
|
|
|
|
analysis.highestBlockEntropy = -1.0;
|
|
|
|
analysis.blockSize = 0;
|
|
|
|
analysis.dataMimeType.clear();
|
|
|
|
analysis.dataDescription.clear();
|
|
|
|
analysis.dataAppleCreatorType.clear();
|
|
|
|
analysis.dataExtensions.clear();
|
|
|
|
analysis.analyzedRegion = { 0, 0 };
|
2020-11-12 09:38:52 +01:00
|
|
|
});
|
2021-04-12 22:20:05 +02:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
EventRegionSelected::subscribe(this, [this](ImHexApi::HexEditor::ProviderRegion region) {
|
|
|
|
auto &analysis = m_analysis.get(region.getProvider());
|
|
|
|
|
2023-03-10 16:06:18 +01:00
|
|
|
// Set the position of the diagram relative to the place where
|
|
|
|
// the user clicked inside the hex editor view
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.blockSize != 0) {
|
|
|
|
analysis.byteTypesDistribution->setHandlePosition(region.getStartAddress());
|
|
|
|
analysis.chunkBasedEntropy->setHandlePosition(region.getStartAddress());
|
2023-03-10 16:06:18 +01:00
|
|
|
}
|
2021-04-12 22:20:05 +02:00
|
|
|
});
|
2021-12-05 22:09:43 +01:00
|
|
|
|
2022-01-13 14:34:19 +01:00
|
|
|
ContentRegistry::FileHandler::add({ ".mgc" }, [](const auto &path) {
|
2022-03-04 11:36:37 +01:00
|
|
|
for (const auto &destPath : fs::getDefaultPaths(fs::ImHexPath::Magic)) {
|
2023-03-12 18:27:29 +01:00
|
|
|
if (wolv::io::fs::copyFile(path, destPath / path.filename(), std::fs::copy_options::overwrite_existing)) {
|
2023-12-26 00:22:47 +01:00
|
|
|
ui::ToastInfo::open("hex.builtin.view.information.magic_db_added"_lang);
|
2022-01-13 14:34:19 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2024-01-25 22:49:56 +01:00
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
m_analysis.setOnCreateCallback([](prv::Provider *provider, AnalysisData &analysis) {
|
|
|
|
analysis.dataValid = false;
|
|
|
|
analysis.blockSize = 0;
|
|
|
|
analysis.averageEntropy = -1.0;
|
|
|
|
|
|
|
|
analysis.lowestBlockEntropy = -1.0;
|
|
|
|
analysis.highestBlockEntropy = -1.0;
|
|
|
|
analysis.lowestBlockEntropyAddress = 0x00;
|
|
|
|
analysis.highestBlockEntropyAddress = 0x00;
|
|
|
|
|
|
|
|
analysis.plainTextCharacterPercentage = -1.0;
|
|
|
|
|
|
|
|
analysis.analysisRegion = { 0, 0 };
|
|
|
|
analysis.analyzedRegion = { 0, 0 };
|
|
|
|
analysis.analyzedProvider = provider;
|
|
|
|
|
|
|
|
analysis.inputChunkSize = 0;
|
|
|
|
analysis.selectionType = ui::RegionType::EntireData;
|
|
|
|
|
|
|
|
analysis.digram = std::make_shared<DiagramDigram>();
|
|
|
|
analysis.layeredDistribution = std::make_shared<DiagramLayeredDistribution>();
|
|
|
|
analysis.byteDistribution = std::make_shared<DiagramByteDistribution>();
|
|
|
|
analysis.byteTypesDistribution = std::make_shared<DiagramByteTypesDistribution>();
|
|
|
|
analysis.chunkBasedEntropy = std::make_shared<DiagramChunkBasedEntropyAnalysis>();
|
2022-01-13 14:34:19 +01:00
|
|
|
});
|
2020-11-12 09:38:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ViewInformation::~ViewInformation() {
|
2023-12-08 10:29:44 +01:00
|
|
|
EventDataChanged::unsubscribe(this);
|
|
|
|
EventRegionSelected::unsubscribe(this);
|
2024-01-25 22:49:56 +01:00
|
|
|
EventProviderOpened::unsubscribe(this);
|
2020-11-12 09:38:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-22 13:08:06 +01:00
|
|
|
void ViewInformation::analyze() {
|
2023-08-06 21:33:15 +02:00
|
|
|
AchievementManager::unlockAchievement("hex.builtin.achievement.misc", "hex.builtin.achievement.misc.analyze_file.name");
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
auto provider = ImHexApi::Provider::get();
|
|
|
|
|
|
|
|
m_analysis.get(provider).analyzerTask = TaskManager::createTask("hex.builtin.view.information.analyzing", 0, [this, provider](auto &task) {
|
|
|
|
auto &analysis = m_analysis.get(provider);
|
|
|
|
const auto ®ion = analysis.analysisRegion;
|
2020-12-27 15:39:06 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.analyzedProvider = provider;
|
2024-01-09 16:48:49 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if ((region.getStartAddress() >= region.getEndAddress()) || (region.getEndAddress() > provider->getActualSize())) {
|
|
|
|
analysis.analyzedRegion = { provider->getBaseAddress(), provider->getActualSize() };
|
2023-03-10 16:06:18 +01:00
|
|
|
}
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.inputChunkSize == 0) {
|
|
|
|
analysis.inputChunkSize = 256;
|
2023-07-06 00:00:56 +02:00
|
|
|
}
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
task.setMaxValue(analysis.analyzedRegion.getSize());
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2021-12-16 23:48:52 +01:00
|
|
|
{
|
|
|
|
magic::compile();
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.dataDescription = magic::getDescription(provider);
|
|
|
|
analysis.dataMimeType = magic::getMIMEType(provider);
|
|
|
|
analysis.dataAppleCreatorType = magic::getAppleCreatorType(provider);
|
|
|
|
analysis.dataExtensions = magic::getExtensions(provider);
|
2021-12-16 23:48:52 +01:00
|
|
|
}
|
|
|
|
|
2021-02-22 13:08:06 +01:00
|
|
|
{
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.blockSize = std::max<u32>(std::ceil(provider->getActualSize() / 2048.0F), 256);
|
2022-07-31 16:57:35 +02:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.averageEntropy = -1.0;
|
|
|
|
analysis.highestBlockEntropy = -1.0;
|
|
|
|
analysis.plainTextCharacterPercentage = -1.0;
|
2022-12-27 22:50:37 +01:00
|
|
|
|
2023-03-10 16:06:18 +01:00
|
|
|
// Setup / start each analysis
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.byteDistribution->reset();
|
|
|
|
analysis.digram->reset(region.getSize());
|
|
|
|
analysis.layeredDistribution->reset(region.getSize());
|
|
|
|
analysis.byteTypesDistribution->reset(region.getStartAddress(), region.getEndAddress(), provider->getBaseAddress(), provider->getActualSize());
|
|
|
|
analysis.chunkBasedEntropy->reset(analysis.inputChunkSize, region.getStartAddress(), region.getEndAddress(),
|
2023-03-18 10:52:50 +01:00
|
|
|
provider->getBaseAddress(), provider->getActualSize());
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2023-03-10 16:06:18 +01:00
|
|
|
// Create a handle to the file
|
2023-03-12 18:27:29 +01:00
|
|
|
auto reader = prv::ProviderReader(provider);
|
2024-01-25 22:49:56 +01:00
|
|
|
reader.seek(region.getStartAddress());
|
|
|
|
reader.setEndAddress(region.getEndAddress());
|
2023-04-10 14:08:21 +02:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.analyzedRegion = region;
|
2020-11-12 21:21:11 +01:00
|
|
|
|
2022-07-31 16:57:35 +02:00
|
|
|
u64 count = 0;
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2023-10-04 12:00:32 +02:00
|
|
|
// Loop over each byte of the selection and update each analysis
|
2023-11-07 00:46:17 +01:00
|
|
|
// one byte at a time to process the file only once
|
2022-07-31 16:57:35 +02:00
|
|
|
for (u8 byte : reader) {
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.byteDistribution->update(byte);
|
|
|
|
analysis.byteTypesDistribution->update(byte);
|
|
|
|
analysis.chunkBasedEntropy->update(byte);
|
|
|
|
analysis.layeredDistribution->update(byte);
|
|
|
|
analysis.digram->update(byte);
|
2023-03-10 16:06:18 +01:00
|
|
|
++count;
|
|
|
|
task.update(count);
|
2021-02-22 13:08:06 +01:00
|
|
|
}
|
2020-11-12 21:21:11 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.averageEntropy = analysis.chunkBasedEntropy->calculateEntropy(analysis.byteDistribution->get(), analysis.analyzedRegion.getSize());
|
|
|
|
analysis.highestBlockEntropy = analysis.chunkBasedEntropy->getHighestEntropyBlockValue();
|
|
|
|
analysis.highestBlockEntropyAddress = analysis.chunkBasedEntropy->getHighestEntropyBlockAddress();
|
|
|
|
analysis.lowestBlockEntropy = analysis.chunkBasedEntropy->getLowestEntropyBlockValue();
|
|
|
|
analysis.lowestBlockEntropyAddress = analysis.chunkBasedEntropy->getLowestEntropyBlockAddress();
|
|
|
|
analysis.plainTextCharacterPercentage = analysis.byteTypesDistribution->getPlainTextCharacterPercentage();
|
2021-02-22 13:08:06 +01:00
|
|
|
}
|
2024-01-25 22:49:56 +01:00
|
|
|
|
|
|
|
analysis.dataValid = true;
|
2022-08-17 16:15:36 +02:00
|
|
|
});
|
2023-03-10 16:06:18 +01:00
|
|
|
}
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2021-02-22 13:08:06 +01:00
|
|
|
void ViewInformation::drawContent() {
|
2023-11-21 13:47:50 +01:00
|
|
|
if (ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav)) {
|
2020-11-15 16:06:10 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
auto provider = ImHexApi::Provider::get();
|
|
|
|
if (ImHexApi::Provider::isValid() && provider->isReadable()) {
|
2024-01-25 22:49:56 +01:00
|
|
|
auto &analysis = m_analysis.get(provider);
|
|
|
|
|
|
|
|
ImGui::BeginDisabled(analysis.analyzerTask.isRunning());
|
2023-12-23 21:09:41 +01:00
|
|
|
ImGuiExt::BeginSubWindow("hex.ui.common.settings"_lang);
|
2023-11-21 13:47:50 +01:00
|
|
|
{
|
2023-12-12 12:15:20 +01:00
|
|
|
if (ImGui::BeginTable("SettingsTable", 2, ImGuiTableFlags_BordersInner | ImGuiTableFlags_SizingFixedSame, ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
|
2023-12-12 13:20:51 +01:00
|
|
|
ImGui::TableSetupColumn("Left", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
|
|
|
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::TableNextRow();
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ui::regionSelectionPicker(&analysis.analysisRegion, provider, &analysis.selectionType, false);
|
2023-03-10 16:06:18 +01:00
|
|
|
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::InputHexadecimal("hex.builtin.view.information.block_size"_lang, &analysis.inputChunkSize);
|
2023-03-10 16:06:18 +01:00
|
|
|
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
ImGui::NewLine();
|
2023-03-10 16:06:18 +01:00
|
|
|
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::SetCursorPosX(50_scaled);
|
|
|
|
if (ImGuiExt::DimmedButton("hex.builtin.view.information.analyze"_lang, ImVec2(ImGui::GetContentRegionAvail().x - 50_scaled, 0)))
|
2023-11-21 13:47:50 +01:00
|
|
|
this->analyze();
|
|
|
|
}
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGuiExt::EndSubWindow();
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::EndDisabled();
|
2020-11-22 19:43:35 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.analyzerTask.isRunning()) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGuiExt::TextSpinner("hex.builtin.view.information.analyzing"_lang);
|
|
|
|
} else {
|
|
|
|
ImGui::NewLine();
|
|
|
|
}
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!analysis.analyzerTask.isRunning() && analysis.dataValid && analysis.analyzedProvider != nullptr) {
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
// Provider information
|
|
|
|
ImGuiExt::Header("hex.builtin.view.information.provider_information"_lang, true);
|
2020-11-15 16:06:10 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoKeepColumnsVisible)) {
|
|
|
|
ImGui::TableSetupColumn("type");
|
|
|
|
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
2020-11-15 16:06:10 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextRow();
|
2021-02-22 13:08:06 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
for (auto &[name, value] : analysis.analyzedProvider->getDataDescription()) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", name);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormattedWrapped("{}", value);
|
|
|
|
}
|
|
|
|
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.region"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("0x{:X} - 0x{:X}", analysis.analyzedRegion.getStartAddress(), analysis.analyzedRegion.getEndAddress());
|
2023-11-21 13:47:50 +01:00
|
|
|
|
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Magic information
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!(analysis.dataDescription.empty() && analysis.dataMimeType.empty())) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGuiExt::Header("hex.builtin.view.information.magic"_lang);
|
|
|
|
|
|
|
|
if (ImGui::BeginTable("magic", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
|
2022-07-31 16:57:35 +02:00
|
|
|
ImGui::TableSetupColumn("type");
|
|
|
|
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
2020-11-15 16:06:10 +01:00
|
|
|
|
2022-07-31 16:57:35 +02:00
|
|
|
ImGui::TableNextRow();
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!analysis.dataDescription.empty()) {
|
2022-07-31 16:57:35 +02:00
|
|
|
ImGui::TableNextColumn();
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.description"_lang);
|
2022-07-31 16:57:35 +02:00
|
|
|
ImGui::TableNextColumn();
|
2023-11-21 13:47:50 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.dataDescription == "data") {
|
|
|
|
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{} ({})", "hex.builtin.view.information.octet_stream_text"_lang, analysis.dataDescription);
|
2023-11-21 13:47:50 +01:00
|
|
|
} else {
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormattedWrapped("{}", analysis.dataDescription);
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
2022-07-31 16:57:35 +02:00
|
|
|
}
|
2020-11-12 09:38:52 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!analysis.dataMimeType.empty()) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.mime"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.dataMimeType.contains("application/octet-stream")) {
|
|
|
|
ImGuiExt::TextFormatted("{}", analysis.dataMimeType);
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
|
|
|
ImGuiExt::HelpHover("hex.builtin.view.information.octet_stream_warning"_lang);
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
} else {
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("{}", analysis.dataMimeType);
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
}
|
2021-03-02 13:49:45 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!analysis.dataAppleCreatorType.empty()) {
|
2024-01-25 20:53:08 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.apple_type"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("{}", analysis.dataAppleCreatorType);
|
2024-01-25 20:53:08 +01:00
|
|
|
}
|
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (!analysis.dataExtensions.empty()) {
|
2024-01-25 20:53:08 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.extension"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("{}", analysis.dataExtensions);
|
2024-01-25 20:53:08 +01:00
|
|
|
}
|
|
|
|
|
2022-07-31 16:57:35 +02:00
|
|
|
ImGui::EndTable();
|
2021-08-28 14:22:02 +02:00
|
|
|
}
|
2021-03-02 13:49:45 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::NewLine();
|
|
|
|
}
|
2023-07-02 10:27:56 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Information analysis
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.analyzedRegion.getSize() > 0) {
|
2021-03-02 13:49:45 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGuiExt::Header("hex.builtin.view.information.info_analysis"_lang);
|
2021-03-02 13:49:45 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_WindowBg));
|
|
|
|
ImPlot::PushStyleColor(ImPlotCol_FrameBg, ImGui::GetColorU32(ImGuiCol_WindowBg));
|
2023-11-07 00:46:17 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Display byte distribution analysis
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.distribution"_lang);
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.byteDistribution->draw(
|
2023-11-21 13:47:50 +01:00
|
|
|
ImVec2(-1, 0),
|
|
|
|
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect
|
|
|
|
);
|
2021-03-02 13:49:45 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Display byte types distribution analysis
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.byte_types"_lang);
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.byteTypesDistribution->draw(
|
2023-11-21 13:47:50 +01:00
|
|
|
ImVec2(-1, 0),
|
|
|
|
ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
|
2023-03-10 16:06:18 +01:00
|
|
|
true
|
2023-11-21 13:47:50 +01:00
|
|
|
);
|
2022-07-31 16:57:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Display chunk-based entropy analysis
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.entropy"_lang);
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.chunkBasedEntropy->draw(
|
2023-11-21 13:47:50 +01:00
|
|
|
ImVec2(-1, 0),
|
|
|
|
ImPlotFlags_NoLegend | ImPlotFlags_NoMenus | ImPlotFlags_NoBoxSelect,
|
|
|
|
true
|
|
|
|
);
|
2021-08-28 14:22:02 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImPlot::PopStyleColor();
|
|
|
|
ImGui::PopStyleColor();
|
2020-11-22 19:43:35 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::NewLine();
|
|
|
|
}
|
2020-11-22 19:43:35 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// Entropy information
|
|
|
|
if (ImGui::BeginTable("entropy_info", 2, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
|
|
|
|
ImGui::TableSetupColumn("type");
|
|
|
|
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
2022-07-31 16:57:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextRow();
|
2022-07-31 16:57:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.block_size"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("hex.builtin.view.information.block_size.desc"_lang, analysis.chunkBasedEntropy->getSize(), analysis.chunkBasedEntropy->getChunkSize());
|
2023-03-17 17:07:39 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.file_entropy"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.averageEntropy < 0) {
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::TextUnformatted("???");
|
2023-12-27 16:33:49 +01:00
|
|
|
} else {
|
2024-01-25 22:49:56 +01:00
|
|
|
auto entropy = std::abs(analysis.averageEntropy);
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F - (0.3F * entropy), 0.6F, 0.8F, 1.0F).Value);
|
|
|
|
ImGui::ProgressBar(entropy, ImVec2(200_scaled, ImGui::GetTextLineHeight()), hex::format("{:.5f}", entropy).c_str());
|
|
|
|
ImGui::PopStyleColor(2);
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
}
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.highest_entropy"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("{:.5f} @", analysis.highestBlockEntropy);
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
2024-01-25 22:49:56 +01:00
|
|
|
if (ImGui::Button(hex::format("0x{:06X}", analysis.highestBlockEntropyAddress).c_str())) {
|
|
|
|
ImHexApi::HexEditor::setSelection(analysis.highestBlockEntropyAddress, analysis.inputChunkSize);
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::PopStyleVar();
|
2022-07-31 16:57:35 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.lowest_entropy"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGuiExt::TextFormatted("{:.5f} @", analysis.lowestBlockEntropy);
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::SameLine();
|
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0, 0, 0, 0));
|
2024-01-25 22:49:56 +01:00
|
|
|
if (ImGui::Button(hex::format("0x{:06X}", analysis.lowestBlockEntropyAddress).c_str())) {
|
|
|
|
ImHexApi::HexEditor::setSelection(analysis.lowestBlockEntropyAddress, analysis.inputChunkSize);
|
2022-07-31 16:57:35 +02:00
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::PopStyleColor();
|
|
|
|
ImGui::PopStyleVar();
|
2021-08-28 14:22:02 +02:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormatted("{}", "hex.builtin.view.information.plain_text_percentage"_lang);
|
|
|
|
ImGui::TableNextColumn();
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.plainTextCharacterPercentage < 0) {
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::TextUnformatted("???");
|
2023-12-27 16:33:49 +01:00
|
|
|
} else {
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::PushStyleVar(ImGuiStyleVar_FrameBorderSize, 0.1F);
|
|
|
|
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImGui::GetColorU32(ImGuiCol_TableRowBgAlt));
|
2024-01-25 22:49:56 +01:00
|
|
|
ImGui::PushStyleColor(ImGuiCol_PlotHistogram, ImColor::HSV(0.3F * (analysis.plainTextCharacterPercentage / 100.0F), 0.8F, 0.6F, 1.0F).Value);
|
|
|
|
ImGui::ProgressBar(analysis.plainTextCharacterPercentage / 100.0F, ImVec2(200_scaled, ImGui::GetTextLineHeight()));
|
2023-12-12 12:15:20 +01:00
|
|
|
ImGui::PopStyleColor(2);
|
|
|
|
ImGui::PopStyleVar();
|
|
|
|
}
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::NewLine();
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
// General information
|
|
|
|
if (ImGui::BeginTable("info", 1, ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
|
|
|
|
ImGui::TableSetupColumn("value", ImGuiTableColumnFlags_WidthStretch);
|
|
|
|
ImGui::TableNextRow();
|
2022-12-28 23:06:49 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.averageEntropy > 0.83 && analysis.highestBlockEntropy > 0.9) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.encrypted"_lang);
|
2021-08-28 14:22:02 +02:00
|
|
|
}
|
2022-12-27 22:50:37 +01:00
|
|
|
|
2024-01-25 22:49:56 +01:00
|
|
|
if (analysis.plainTextCharacterPercentage > 95) {
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::TableNextColumn();
|
|
|
|
ImGuiExt::TextFormattedColored(ImVec4(0.92F, 0.25F, 0.2F, 1.0F), "{}", "hex.builtin.view.information.plain_text"_lang);
|
2022-12-27 22:50:37 +01:00
|
|
|
}
|
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::EndTable();
|
|
|
|
}
|
2022-12-27 22:50:37 +01:00
|
|
|
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::BeginGroup();
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.digram"_lang);
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.digram->draw(scaled(ImVec2(300, 300)));
|
2023-11-21 13:47:50 +01:00
|
|
|
}
|
|
|
|
ImGui::EndGroup();
|
|
|
|
|
|
|
|
ImGui::SameLine();
|
|
|
|
|
|
|
|
ImGui::BeginGroup();
|
|
|
|
{
|
|
|
|
ImGui::TextUnformatted("hex.builtin.view.information.layered_distribution"_lang);
|
2024-01-25 22:49:56 +01:00
|
|
|
analysis.layeredDistribution->draw(scaled(ImVec2(300, 300)));
|
2022-12-28 23:06:49 +01:00
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::EndGroup();
|
2020-11-12 12:01:13 +01:00
|
|
|
}
|
2020-11-12 09:38:52 +01:00
|
|
|
}
|
|
|
|
}
|
2023-11-21 13:47:50 +01:00
|
|
|
ImGui::EndChild();
|
2020-11-12 09:38:52 +01:00
|
|
|
}
|
|
|
|
|
2023-03-10 16:06:18 +01:00
|
|
|
}
|