2022-07-29 13:59:57 +02:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <hex.hpp>
|
|
|
|
|
2023-05-14 21:50:58 +02:00
|
|
|
#include <hex/api/task.hpp>
|
2022-07-29 13:59:57 +02:00
|
|
|
#include <hex/ui/view.hpp>
|
2022-08-07 12:20:40 +02:00
|
|
|
#include <ui/widgets.hpp>
|
2022-07-29 13:59:57 +02:00
|
|
|
|
|
|
|
#include <atomic>
|
|
|
|
#include <vector>
|
|
|
|
|
2023-05-11 09:27:23 +02:00
|
|
|
#include <wolv/container/interval_tree.hpp>
|
2023-05-14 21:50:58 +02:00
|
|
|
#include <imgui.h>
|
2022-08-06 12:57:47 +02:00
|
|
|
|
2022-07-29 13:59:57 +02:00
|
|
|
namespace hex::plugin::builtin {
|
|
|
|
|
|
|
|
class ViewFind : public View {
|
|
|
|
public:
|
|
|
|
ViewFind();
|
|
|
|
~ViewFind() override = default;
|
|
|
|
|
|
|
|
void drawContent() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
2022-08-03 11:38:36 +02:00
|
|
|
struct Occurrence {
|
|
|
|
Region region;
|
2022-09-19 10:34:57 +02:00
|
|
|
enum class DecodeType { ASCII, Binary, UTF16, Unsigned, Signed, Float, Double } decodeType;
|
|
|
|
std::endian endian = std::endian::native;
|
2022-08-03 11:38:36 +02:00
|
|
|
};
|
|
|
|
|
2022-08-03 10:19:34 +02:00
|
|
|
struct BinaryPattern {
|
|
|
|
u8 mask, value;
|
|
|
|
};
|
|
|
|
|
2022-07-29 13:59:57 +02:00
|
|
|
struct SearchSettings {
|
2023-04-10 14:08:21 +02:00
|
|
|
ui::RegionType range = ui::RegionType::EntireData;
|
|
|
|
Region region = { 0, 0 };
|
2022-07-29 13:59:57 +02:00
|
|
|
|
|
|
|
enum class Mode : int {
|
|
|
|
Strings,
|
|
|
|
Sequence,
|
2022-08-03 10:19:34 +02:00
|
|
|
Regex,
|
2022-09-19 10:34:57 +02:00
|
|
|
BinaryPattern,
|
|
|
|
Value
|
2022-07-29 13:59:57 +02:00
|
|
|
} mode = Mode::Strings;
|
|
|
|
|
2023-03-17 08:16:13 +01:00
|
|
|
enum class StringType : int { ASCII = 0, UTF16LE = 1, UTF16BE = 2, ASCII_UTF16LE = 3, ASCII_UTF16BE = 4 };
|
|
|
|
|
2022-07-29 13:59:57 +02:00
|
|
|
struct Strings {
|
|
|
|
int minLength = 5;
|
|
|
|
bool nullTermination = false;
|
2023-03-17 08:16:13 +01:00
|
|
|
StringType type = StringType::ASCII;
|
|
|
|
|
|
|
|
bool lowerCaseLetters = true;
|
|
|
|
bool upperCaseLetters = true;
|
|
|
|
bool numbers = true;
|
|
|
|
bool underscores = true;
|
|
|
|
bool symbols = true;
|
|
|
|
bool spaces = true;
|
|
|
|
bool lineFeeds = false;
|
2022-07-29 13:59:57 +02:00
|
|
|
} strings;
|
|
|
|
|
2022-09-19 10:34:57 +02:00
|
|
|
struct Sequence {
|
2022-07-29 13:59:57 +02:00
|
|
|
std::string sequence;
|
|
|
|
} bytes;
|
|
|
|
|
|
|
|
struct Regex {
|
2023-03-17 08:16:13 +01:00
|
|
|
int minLength = 5;
|
|
|
|
bool nullTermination = false;
|
|
|
|
StringType type = StringType::ASCII;
|
|
|
|
|
2022-07-29 13:59:57 +02:00
|
|
|
std::string pattern;
|
2022-09-13 14:06:08 +02:00
|
|
|
bool fullMatch = true;
|
2022-07-29 13:59:57 +02:00
|
|
|
} regex;
|
2022-08-03 10:19:34 +02:00
|
|
|
|
|
|
|
struct BinaryPattern {
|
|
|
|
std::string input;
|
|
|
|
std::vector<ViewFind::BinaryPattern> pattern;
|
2023-04-09 15:28:31 +02:00
|
|
|
u32 alignment = 1;
|
2022-08-03 10:19:34 +02:00
|
|
|
} binaryPattern;
|
2022-09-19 10:34:57 +02:00
|
|
|
|
|
|
|
struct Value {
|
|
|
|
std::string inputMin, inputMax;
|
|
|
|
std::endian endian = std::endian::native;
|
2023-04-08 20:59:33 +02:00
|
|
|
bool aligned = false;
|
|
|
|
bool range = false;
|
2022-09-19 10:34:57 +02:00
|
|
|
|
|
|
|
enum class Type {
|
|
|
|
U8 = 0, U16 = 1, U32 = 2, U64 = 3,
|
|
|
|
I8 = 4, I16 = 5, I32 = 6, I64 = 7,
|
|
|
|
F32 = 8, F64 = 9
|
|
|
|
} type = Type::U8;
|
|
|
|
} value;
|
|
|
|
|
2022-07-29 13:59:57 +02:00
|
|
|
} m_searchSettings, m_decodeSettings;
|
|
|
|
|
2023-05-11 09:27:23 +02:00
|
|
|
using OccurrenceTree = wolv::container::IntervalTree<Occurrence, u64, 0>;
|
2022-08-06 12:57:47 +02:00
|
|
|
|
2023-05-07 23:27:43 +02:00
|
|
|
PerProvider<std::vector<Occurrence>> m_foundOccurrences, m_sortedOccurrences;
|
|
|
|
PerProvider<OccurrenceTree> m_occurrenceTree;
|
|
|
|
PerProvider<std::string> m_currFilter;
|
2022-08-06 12:57:47 +02:00
|
|
|
|
2023-03-17 11:32:08 +01:00
|
|
|
TaskHolder m_searchTask, m_filterTask;
|
2022-07-29 13:59:57 +02:00
|
|
|
bool m_settingsValid = false;
|
|
|
|
|
|
|
|
private:
|
2022-09-19 10:34:57 +02:00
|
|
|
static std::vector<Occurrence> searchStrings(Task &task, prv::Provider *provider, Region searchRegion, const SearchSettings::Strings &settings);
|
|
|
|
static std::vector<Occurrence> searchSequence(Task &task, prv::Provider *provider, Region searchRegion, const SearchSettings::Sequence &settings);
|
|
|
|
static std::vector<Occurrence> searchRegex(Task &task, prv::Provider *provider, Region searchRegion, const SearchSettings::Regex &settings);
|
|
|
|
static std::vector<Occurrence> searchBinaryPattern(Task &task, prv::Provider *provider, Region searchRegion, const SearchSettings::BinaryPattern &settings);
|
|
|
|
static std::vector<Occurrence> searchValue(Task &task, prv::Provider *provider, Region searchRegion, const SearchSettings::Value &settings);
|
2022-08-03 10:19:34 +02:00
|
|
|
|
|
|
|
static std::vector<BinaryPattern> parseBinaryPatternString(std::string string);
|
2022-09-19 10:34:57 +02:00
|
|
|
static std::tuple<bool, std::variant<u64, i64, float, double>, size_t> parseNumericValueInput(const std::string &input, SearchSettings::Value::Type type);
|
2022-07-29 13:59:57 +02:00
|
|
|
|
|
|
|
void runSearch();
|
2023-04-01 11:04:07 +02:00
|
|
|
std::string decodeValue(prv::Provider *provider, Occurrence occurrence, size_t maxBytes = 0xFFFF'FFFF) const;
|
2022-07-29 13:59:57 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
}
|