Add support for custom providers via plugins
This commit is contained in:
parent
8ba96904a6
commit
f74eff8934
1
.idea/.name
generated
Normal file
1
.idea/.name
generated
Normal file
@ -0,0 +1 @@
|
||||
imhex
|
@ -1,6 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include <hex.hpp>
|
||||
|
||||
#include "views/view.hpp"
|
||||
#include "providers/provider.hpp"
|
||||
|
||||
#include <string_view>
|
||||
|
||||
@ -11,18 +14,18 @@ namespace hex {
|
||||
Plugin(std::string_view path);
|
||||
~Plugin();
|
||||
|
||||
void setImGuiContext(ImGuiContext *ctx) const;
|
||||
void initializePlugin(ImGuiContext *ctx, prv::Provider **provider) const;
|
||||
View* createView() const;
|
||||
void drawToolsEntry() const;
|
||||
|
||||
private:
|
||||
using SetImGuiContextFunc = void(*)(ImGuiContext*);
|
||||
using InitializePluginFunc = void(*)(ImGuiContext*, hex::prv::Provider**);
|
||||
using CreateViewFunc = View*(*)();
|
||||
using DrawToolsEntryFunc = void(*)();
|
||||
|
||||
void *m_handle = nullptr;
|
||||
|
||||
SetImGuiContextFunc m_setImGuiContextFunction = nullptr;
|
||||
InitializePluginFunc m_initializePluginFunction = nullptr;
|
||||
CreateViewFunc m_createViewFunction = nullptr;
|
||||
DrawToolsEntryFunc m_drawToolsEntryFunction = nullptr;
|
||||
|
||||
|
@ -13,15 +13,13 @@ namespace hex {
|
||||
|
||||
class ViewBookmarks : public View {
|
||||
public:
|
||||
explicit ViewBookmarks(prv::Provider* &dataProvider);
|
||||
explicit ViewBookmarks();
|
||||
~ViewBookmarks() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
|
||||
std::list<Bookmark> m_bookmarks;
|
||||
};
|
||||
|
||||
|
@ -51,14 +51,13 @@ namespace hex {
|
||||
|
||||
class ViewDataInspector : public View {
|
||||
public:
|
||||
explicit ViewDataInspector(prv::Provider* &dataProvider);
|
||||
explicit ViewDataInspector();
|
||||
~ViewDataInspector() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_shouldInvalidate = true;
|
||||
|
||||
std::endian m_endianess = std::endian::native;
|
||||
|
@ -24,14 +24,13 @@ namespace hex {
|
||||
|
||||
class ViewDisassembler : public View {
|
||||
public:
|
||||
explicit ViewDisassembler(prv::Provider* &dataProvider);
|
||||
explicit ViewDisassembler();
|
||||
~ViewDisassembler() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_shouldInvalidate = false;
|
||||
|
||||
u64 m_baseAddress = 0;
|
||||
|
@ -10,15 +10,13 @@ namespace hex {
|
||||
|
||||
class ViewHashes : public View {
|
||||
public:
|
||||
explicit ViewHashes(prv::Provider* &dataProvider);
|
||||
explicit ViewHashes();
|
||||
~ViewHashes() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
|
||||
bool m_shouldInvalidate = true;
|
||||
int m_currHashFunction = 0;
|
||||
u64 m_hashRegion[2] = { 0 };
|
||||
|
@ -20,7 +20,7 @@ namespace hex {
|
||||
|
||||
class ViewHexEditor : public View {
|
||||
public:
|
||||
ViewHexEditor(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData);
|
||||
ViewHexEditor(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewHexEditor() override;
|
||||
|
||||
void drawContent() override;
|
||||
@ -31,7 +31,6 @@ namespace hex {
|
||||
MemoryEditor m_memoryEditor;
|
||||
imgui_addons::ImGuiFileBrowser m_fileBrowser;
|
||||
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
|
||||
char m_searchStringBuffer[0xFFFF] = { 0 };
|
||||
|
@ -13,15 +13,13 @@ namespace hex {
|
||||
|
||||
class ViewInformation : public View {
|
||||
public:
|
||||
explicit ViewInformation(prv::Provider* &dataProvider);
|
||||
explicit ViewInformation();
|
||||
~ViewInformation() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
|
||||
bool m_dataValid = false;
|
||||
u32 m_blockSize = 0;
|
||||
float m_averageEntropy = 0;
|
||||
|
@ -13,16 +13,13 @@ namespace hex {
|
||||
|
||||
class ViewPatches : public View {
|
||||
public:
|
||||
explicit ViewPatches(prv::Provider* &dataProvider);
|
||||
explicit ViewPatches();
|
||||
~ViewPatches() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
|
||||
|
||||
u64 m_selectedPatch;
|
||||
};
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace hex {
|
||||
|
||||
class ViewPattern : public View {
|
||||
public:
|
||||
explicit ViewPattern(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData);
|
||||
explicit ViewPattern(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewPattern() override;
|
||||
|
||||
void drawMenu() override;
|
||||
@ -25,7 +25,6 @@ namespace hex {
|
||||
|
||||
private:
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::filesystem::path m_possiblePatternFile;
|
||||
|
||||
TextEditor m_textEditor;
|
||||
|
@ -16,7 +16,7 @@ namespace hex {
|
||||
|
||||
class ViewPatternData : public View {
|
||||
public:
|
||||
ViewPatternData(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData);
|
||||
ViewPatternData(std::vector<lang::PatternData*> &patternData);
|
||||
~ViewPatternData() override;
|
||||
|
||||
void drawContent() override;
|
||||
@ -24,7 +24,6 @@ namespace hex {
|
||||
|
||||
private:
|
||||
|
||||
prv::Provider* &m_dataProvider;
|
||||
std::vector<lang::PatternData*> &m_patternData;
|
||||
std::vector<lang::PatternData*> m_sortedPatternData;
|
||||
};
|
||||
|
@ -17,14 +17,13 @@ namespace hex {
|
||||
|
||||
class ViewStrings : public View {
|
||||
public:
|
||||
explicit ViewStrings(prv::Provider* &dataProvider);
|
||||
explicit ViewStrings();
|
||||
~ViewStrings() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
prv::Provider* &m_dataProvider;
|
||||
bool m_shouldInvalidate = false;
|
||||
|
||||
std::vector<FoundString> m_foundStrings;
|
||||
|
@ -15,15 +15,13 @@ namespace hex {
|
||||
|
||||
class ViewTools : public View {
|
||||
public:
|
||||
ViewTools(hex::prv::Provider* &provider);
|
||||
ViewTools();
|
||||
~ViewTools() override;
|
||||
|
||||
void drawContent() override;
|
||||
void drawMenu() override;
|
||||
|
||||
private:
|
||||
hex::prv::Provider* &m_dataProvider;
|
||||
|
||||
char *m_mangledBuffer = nullptr;
|
||||
std::string m_demangledName;
|
||||
|
||||
|
@ -3,10 +3,7 @@ project(example)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
|
||||
if (TARGET ${CMAKE_PROJECT_NAME})
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/ImGui ${CMAKE_CURRENT_BINARY_DIR}/external/ImGui)
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex)
|
||||
endif()
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex)
|
||||
|
||||
set(CMAKE_SHARED_LIBRARY_PREFIX "plugin")
|
||||
|
||||
@ -14,5 +11,5 @@ add_library(example SHARED
|
||||
source/plugin_example.cpp
|
||||
)
|
||||
|
||||
target_include_directories(example PUBLIC include)
|
||||
target_link_libraries(example PRIVATE imgui libimhex)
|
||||
target_include_directories(example PRIVATE include)
|
||||
target_link_libraries(example PRIVATE libimhex)
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include <hex.hpp>
|
||||
#include <plugin.hpp>
|
||||
|
||||
#include <views/view.hpp>
|
||||
#include <imgui.h>
|
||||
|
||||
class ViewExample : public hex::View {
|
||||
public:
|
||||
|
@ -17,4 +17,4 @@ add_library(libimhex STATIC
|
||||
)
|
||||
|
||||
target_include_directories(libimhex PUBLIC include)
|
||||
target_link_libraries(libimhex PRIVATE imgui)
|
||||
target_link_libraries(libimhex PUBLIC imgui)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
#include <type_traits>
|
||||
|
||||
using u8 = std::uint8_t;
|
||||
using u16 = std::uint16_t;
|
||||
@ -18,16 +19,56 @@ using s128 = __int128_t;
|
||||
extern int mainArgc;
|
||||
extern char **mainArgv;
|
||||
|
||||
#define IMHEX_PLUGIN namespace hex::plugin::internal { \
|
||||
void setImGuiContext(ImGuiContext *ctx) { \
|
||||
gladLoadGL(); \
|
||||
ImGui::SetCurrentContext(ctx); \
|
||||
} \
|
||||
} \
|
||||
namespace hex::plugin
|
||||
|
||||
#ifdef OS_WINDOWS
|
||||
#define MAGIC_PATH_SEPARATOR ";"
|
||||
#else
|
||||
#define MAGIC_PATH_SEPARATOR ":"
|
||||
#endif
|
||||
|
||||
template<>
|
||||
struct std::is_integral<u128> : public std::true_type { };
|
||||
template<>
|
||||
struct std::is_integral<s128> : public std::true_type { };
|
||||
template<>
|
||||
struct std::is_signed<s128> : public std::true_type { };
|
||||
|
||||
#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000
|
||||
#if __has_include(<concepts>)
|
||||
// Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above
|
||||
#include <concepts>
|
||||
#endif
|
||||
// libcxx 12 still doesn't have many default concepts implemented, as a result we need to define it ourself using clang built-ins.
|
||||
// [concept.derived] (patch from https://reviews.llvm.org/D74292)
|
||||
namespace hex {
|
||||
template<class _Dp, class _Bp>
|
||||
concept derived_from =
|
||||
__is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp*, const volatile _Bp*);
|
||||
}
|
||||
|
||||
// [concepts.arithmetic] (patch from https://reviews.llvm.org/D88131)
|
||||
namespace hex {
|
||||
template<class _Tp>
|
||||
concept integral = __is_integral(_Tp);
|
||||
|
||||
template<class _Tp>
|
||||
concept signed_integral = integral<_Tp> && __is_signed(_Tp);
|
||||
|
||||
template<class _Tp>
|
||||
concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>;
|
||||
|
||||
template<class _Tp>
|
||||
concept floating_point = __is_floating_point(_Tp);
|
||||
}
|
||||
#else
|
||||
// Assume supported
|
||||
#include <concepts>
|
||||
|
||||
namespace hex {
|
||||
using std::derived_from;
|
||||
|
||||
using std::integral;
|
||||
using std::signed_integral;
|
||||
using std::unsigned_integral;
|
||||
using std::floating_point;
|
||||
}
|
||||
#endif
|
18
plugins/libimhex/include/plugin.hpp
Normal file
18
plugins/libimhex/include/plugin.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include <glad/glad.h>
|
||||
#include <imgui.h>
|
||||
|
||||
#include <hex.hpp>
|
||||
#include <views/view.hpp>
|
||||
#include <providers/provider.hpp>
|
||||
|
||||
#define IMHEX_PLUGIN namespace hex::plugin::internal { \
|
||||
void initializePlugin(ImGuiContext *ctx, hex::prv::Provider **provider) { \
|
||||
if (glGetString == NULL) \
|
||||
gladLoadGL(); \
|
||||
ImGui::SetCurrentContext(ctx); \
|
||||
hex::prv::Provider::setProviderStorage(*provider); \
|
||||
} \
|
||||
} \
|
||||
namespace hex::plugin
|
@ -40,10 +40,20 @@ namespace hex::prv {
|
||||
|
||||
virtual std::vector<std::pair<std::string, std::string>> getDataInformation() = 0;
|
||||
|
||||
static void setProviderStorage(Provider* &provider) {
|
||||
Provider::s_currProvider = &provider;
|
||||
}
|
||||
|
||||
static Provider*& getCurrentProvider() {
|
||||
return *Provider::s_currProvider;
|
||||
}
|
||||
|
||||
protected:
|
||||
u32 m_currPage = 0;
|
||||
|
||||
std::vector<std::map<u64, u8>> m_patches;
|
||||
|
||||
static inline Provider **s_currProvider = nullptr;
|
||||
};
|
||||
|
||||
}
|
@ -9,8 +9,8 @@ namespace hex {
|
||||
constexpr auto CreateViewSymbol = "_ZN3hex6plugin10createViewEv";
|
||||
// hex::plugin::drawToolsEntry(void)
|
||||
constexpr auto DrawToolsEntrySymbol = "_ZN3hex6plugin14drawToolsEntryEv";
|
||||
// hex::plugin::internal::setImGuiContext(ImGuiContext*)
|
||||
constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin8internal15setImGuiContextEP12ImGuiContext";
|
||||
// hex::plugin::internal::initializePlugin(ImGuiContext*, hex::prv::Provider**)
|
||||
constexpr auto InitializePluginSymbol = "_ZN3hex6plugin8internal16initializePluginEP12ImGuiContextPPNS_3prv8ProviderE";
|
||||
|
||||
Plugin::Plugin(std::string_view path) {
|
||||
this->m_handle = dlopen(path.data(), RTLD_LAZY);
|
||||
@ -20,7 +20,7 @@ namespace hex {
|
||||
|
||||
this->m_createViewFunction = reinterpret_cast<CreateViewFunc>(dlsym(this->m_handle, CreateViewSymbol));
|
||||
this->m_drawToolsEntryFunction = reinterpret_cast<DrawToolsEntryFunc>(dlsym(this->m_handle, DrawToolsEntrySymbol));
|
||||
this->m_setImGuiContextFunction = reinterpret_cast<SetImGuiContextFunc>(dlsym(this->m_handle, SetImGuiContextSymbol));
|
||||
this->m_initializePluginFunction = reinterpret_cast<InitializePluginFunc>(dlsym(this->m_handle, InitializePluginSymbol));
|
||||
}
|
||||
|
||||
Plugin::~Plugin() {
|
||||
@ -28,9 +28,9 @@ namespace hex {
|
||||
dlclose(this->m_handle);
|
||||
}
|
||||
|
||||
void Plugin::setImGuiContext(ImGuiContext *ctx) const {
|
||||
if (this->m_setImGuiContextFunction != nullptr)
|
||||
this->m_setImGuiContextFunction(ctx);
|
||||
void Plugin::initializePlugin(ImGuiContext *ctx, prv::Provider **provider) const {
|
||||
if (this->m_initializePluginFunction != nullptr)
|
||||
this->m_initializePluginFunction(ctx, provider);
|
||||
}
|
||||
|
||||
View* Plugin::createView() const {
|
||||
|
@ -31,19 +31,20 @@ int main(int argc, char **argv) {
|
||||
// Shared Data
|
||||
std::vector<hex::lang::PatternData*> patternData;
|
||||
hex::prv::Provider *dataProvider = nullptr;
|
||||
hex::prv::Provider::setProviderStorage(dataProvider);
|
||||
|
||||
// Create views
|
||||
window.addView<hex::ViewHexEditor>(dataProvider, patternData);
|
||||
window.addView<hex::ViewPattern>(dataProvider, patternData);
|
||||
window.addView<hex::ViewPatternData>(dataProvider, patternData);
|
||||
window.addView<hex::ViewDataInspector>(dataProvider);
|
||||
window.addView<hex::ViewHashes>(dataProvider);
|
||||
window.addView<hex::ViewInformation>(dataProvider);
|
||||
window.addView<hex::ViewStrings>(dataProvider);
|
||||
window.addView<hex::ViewDisassembler>(dataProvider);
|
||||
window.addView<hex::ViewBookmarks>(dataProvider);
|
||||
window.addView<hex::ViewPatches>(dataProvider);
|
||||
window.addView<hex::ViewTools>(dataProvider);
|
||||
window.addView<hex::ViewHexEditor>(patternData);
|
||||
window.addView<hex::ViewPattern>(patternData);
|
||||
window.addView<hex::ViewPatternData>(patternData);
|
||||
window.addView<hex::ViewDataInspector>();
|
||||
window.addView<hex::ViewHashes>();
|
||||
window.addView<hex::ViewInformation>();
|
||||
window.addView<hex::ViewStrings>();
|
||||
window.addView<hex::ViewDisassembler>();
|
||||
window.addView<hex::ViewBookmarks>();
|
||||
window.addView<hex::ViewPatches>();
|
||||
window.addView<hex::ViewTools>();
|
||||
window.addView<hex::ViewCommandPalette>();
|
||||
window.addView<hex::ViewHelp>();
|
||||
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewBookmarks::ViewBookmarks(prv::Provider* &dataProvider) : View("Bookmarks"), m_dataProvider(dataProvider) {
|
||||
ViewBookmarks::ViewBookmarks() : View("Bookmarks") {
|
||||
View::subscribeEvent(Events::AddBookmark, [this](const void *userData) {
|
||||
Bookmark bookmark = *reinterpret_cast<const Bookmark*>(userData);
|
||||
bookmark.name.resize(64);
|
||||
@ -55,7 +55,7 @@ namespace hex {
|
||||
|
||||
{
|
||||
u8 bytes[10] = { 0 };
|
||||
this->m_dataProvider->read(region.address, bytes, std::min(region.size, size_t(10)));
|
||||
prv::Provider::getCurrentProvider()->read(region.address, bytes, std::min(region.size, size_t(10)));
|
||||
|
||||
std::string bytesString;
|
||||
for (u8 i = 0; i < std::min(region.size, size_t(10)); i++) {
|
||||
|
@ -9,11 +9,13 @@ extern int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewDataInspector::ViewDataInspector(prv::Provider* &dataProvider) : View("Data Inspector"), m_dataProvider(dataProvider) {
|
||||
ViewDataInspector::ViewDataInspector() : View("Data Inspector") {
|
||||
View::subscribeEvent(Events::RegionSelected, [this](const void* userData){
|
||||
Region region = *static_cast<const Region*>(userData);
|
||||
|
||||
if (this->m_dataProvider == nullptr) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (provider == nullptr) {
|
||||
this->m_validBytes = 0;
|
||||
return;
|
||||
}
|
||||
@ -23,9 +25,9 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
this->m_validBytes = std::min(u64(this->m_dataProvider->getSize() - region.address), u64(sizeof(PreviewData)));
|
||||
this->m_validBytes = std::min(u64(provider->getSize() - region.address), u64(sizeof(PreviewData)));
|
||||
std::memset(&this->m_previewData, 0x00, sizeof(PreviewData));
|
||||
this->m_dataProvider->read(region.address, &this->m_previewData, this->m_validBytes);
|
||||
provider->read(region.address, &this->m_previewData, this->m_validBytes);
|
||||
|
||||
this->m_shouldInvalidate = true;
|
||||
});
|
||||
@ -118,7 +120,9 @@ namespace hex {
|
||||
|
||||
|
||||
if (ImGui::Begin("Data Inspector", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
if (ImGui::BeginChild("##scrolling", ImVec2(0, ImGui::GetWindowHeight() - 60))) {
|
||||
if (ImGui::BeginTable("##datainspector", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody)) {
|
||||
ImGui::TableSetupColumn("Name");
|
||||
|
@ -9,7 +9,7 @@ using namespace std::literals::string_literals;
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewDisassembler::ViewDisassembler(prv::Provider* &dataProvider) : View("Disassembler"), m_dataProvider(dataProvider) {
|
||||
ViewDisassembler::ViewDisassembler() : View("Disassembler") {
|
||||
View::subscribeEvent(Events::DataChanged, [this](const void*){
|
||||
this->m_shouldInvalidate = true;
|
||||
});
|
||||
@ -51,10 +51,11 @@ namespace hex {
|
||||
|
||||
if (cs_open(Disassembler::toCapstoneArchictecture(this->m_architecture), mode, &capstoneHandle) == CS_ERR_OK) {
|
||||
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
std::vector<u8> buffer(2048, 0x00);
|
||||
for (u64 address = 0; address < (this->m_codeRegion[1] - this->m_codeRegion[0] + 1); address += 2048) {
|
||||
size_t bufferSize = std::min(u64(2048), (this->m_codeRegion[1] - this->m_codeRegion[0] + 1) - address);
|
||||
this->m_dataProvider->read(this->m_codeRegion[0] + address, buffer.data(), bufferSize);
|
||||
provider->read(this->m_codeRegion[0] + address, buffer.data(), bufferSize);
|
||||
|
||||
size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, this->m_baseAddress + address, 0, &instructions);
|
||||
|
||||
@ -94,7 +95,8 @@ namespace hex {
|
||||
|
||||
if (ImGui::Begin("Disassembler", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
ImGui::TextUnformatted("Position");
|
||||
ImGui::Separator();
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewHashes::ViewHashes(prv::Provider* &dataProvider) : View("Hashes"), m_dataProvider(dataProvider) {
|
||||
ViewHashes::ViewHashes() : View("Hashes") {
|
||||
View::subscribeEvent(Events::DataChanged, [this](const void*){
|
||||
this->m_shouldInvalidate = true;
|
||||
});
|
||||
@ -41,7 +41,8 @@ namespace hex {
|
||||
if (ImGui::Begin("Hashing", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
|
||||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isAvailable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider != nullptr && provider->isAvailable()) {
|
||||
|
||||
ImGui::TextUnformatted("Region");
|
||||
ImGui::Separator();
|
||||
@ -59,7 +60,7 @@ namespace hex {
|
||||
if (ImGui::Combo("Hash Function", &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *)))
|
||||
this->m_shouldInvalidate = true;
|
||||
|
||||
size_t dataSize = this->m_dataProvider->getSize();
|
||||
size_t dataSize = provider->getSize();
|
||||
if (this->m_hashRegion[1] >= dataSize)
|
||||
this->m_hashRegion[1] = dataSize - 1;
|
||||
|
||||
@ -82,7 +83,7 @@ namespace hex {
|
||||
static u16 result = 0;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = crc16(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
|
||||
result = crc16(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
snprintf(buffer, sizeof(buffer), "%04X", result);
|
||||
@ -107,7 +108,7 @@ namespace hex {
|
||||
static u32 result = 0;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = crc32(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
|
||||
result = crc32(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
snprintf(buffer, sizeof(buffer), "%08X", result);
|
||||
@ -122,7 +123,7 @@ namespace hex {
|
||||
static std::array<u32, 4> result;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = md4(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = md4(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -138,7 +139,7 @@ namespace hex {
|
||||
static std::array<u32, 4> result = { 0 };
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = md5(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = md5(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -154,7 +155,7 @@ namespace hex {
|
||||
static std::array<u32, 5> result = { 0 };
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = sha1(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = sha1(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -170,7 +171,7 @@ namespace hex {
|
||||
static std::array<u32, 7> result = { 0 };
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = sha224(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = sha224(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -186,7 +187,7 @@ namespace hex {
|
||||
static std::array<u32, 8> result;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = sha256(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = sha256(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -202,7 +203,7 @@ namespace hex {
|
||||
static std::array<u32, 12> result;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = sha384(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = sha384(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
@ -218,7 +219,7 @@ namespace hex {
|
||||
static std::array<u32, 16> result;
|
||||
|
||||
if (this->m_shouldInvalidate)
|
||||
result = sha512(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
result = sha512(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1);
|
||||
|
||||
char buffer[sizeof(result) * 2 + 1];
|
||||
formatBigHexInt(result, buffer, sizeof(buffer));
|
||||
|
@ -15,29 +15,27 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View("Hex Editor"), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
ViewHexEditor::ViewHexEditor(std::vector<lang::PatternData*> &patternData)
|
||||
: View("Hex Editor"), m_patternData(patternData) {
|
||||
|
||||
this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 {
|
||||
ViewHexEditor *_this = (ViewHexEditor *) data;
|
||||
|
||||
if (!_this->m_dataProvider->isAvailable() || !_this->m_dataProvider->isReadable())
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (!provider->isAvailable() || !provider->isReadable())
|
||||
return 0x00;
|
||||
|
||||
ImU8 byte;
|
||||
_this->m_dataProvider->read(off, &byte, sizeof(ImU8));
|
||||
provider->read(off, &byte, sizeof(ImU8));
|
||||
|
||||
return byte;
|
||||
};
|
||||
|
||||
this->m_memoryEditor.WriteFn = [](ImU8 *data, size_t off, ImU8 d) -> void {
|
||||
ViewHexEditor *_this = (ViewHexEditor *) data;
|
||||
|
||||
if (!_this->m_dataProvider->isAvailable() || !_this->m_dataProvider->isWritable())
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (!provider->isAvailable() || !provider->isWritable())
|
||||
return;
|
||||
|
||||
_this->m_dataProvider->write(off, &d, sizeof(ImU8));
|
||||
_this->postEvent(Events::DataChanged);
|
||||
provider->write(off, &d, sizeof(ImU8));
|
||||
View::postEvent(Events::DataChanged);
|
||||
ProjectFile::markDirty();
|
||||
};
|
||||
|
||||
@ -69,11 +67,12 @@ namespace hex {
|
||||
View::subscribeEvent(Events::SelectionChangeRequest, [this](const void *userData) {
|
||||
const Region ®ion = *reinterpret_cast<const Region*>(userData);
|
||||
|
||||
auto page = this->m_dataProvider->getPageOfAddress(region.address);
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
auto page = provider->getPageOfAddress(region.address);
|
||||
if (!page.has_value())
|
||||
return;
|
||||
|
||||
this->m_dataProvider->setCurrentPage(page.value());
|
||||
provider->setCurrentPage(page.value());
|
||||
this->m_memoryEditor.GotoAddr = region.address;
|
||||
this->m_memoryEditor.DataPreviewAddr = region.address;
|
||||
this->m_memoryEditor.DataPreviewAddrEnd = region.address + region.size - 1;
|
||||
@ -96,26 +95,26 @@ namespace hex {
|
||||
}
|
||||
|
||||
ViewHexEditor::~ViewHexEditor() {
|
||||
if (this->m_dataProvider != nullptr)
|
||||
delete this->m_dataProvider;
|
||||
this->m_dataProvider = nullptr;
|
||||
|
||||
}
|
||||
|
||||
void ViewHexEditor::drawContent() {
|
||||
size_t dataSize = (this->m_dataProvider == nullptr || !this->m_dataProvider->isReadable()) ? 0x00 : this->m_dataProvider->getSize();
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
this->m_memoryEditor.DrawWindow("Hex Editor", &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : this->m_dataProvider->getBaseAddress());
|
||||
size_t dataSize = (provider == nullptr || !provider->isReadable()) ? 0x00 : provider->getSize();
|
||||
|
||||
this->m_memoryEditor.DrawWindow("Hex Editor", &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : provider->getBaseAddress());
|
||||
|
||||
if (dataSize != 0x00) {
|
||||
ImGui::Begin("Hex Editor");
|
||||
ImGui::SameLine();
|
||||
ImGui::Spacing();
|
||||
ImGui::SameLine();
|
||||
ImGui::Text("Page %d / %d", this->m_dataProvider->getCurrentPage() + 1, this->m_dataProvider->getPageCount());
|
||||
ImGui::Text("Page %d / %d", provider->getCurrentPage() + 1, provider->getPageCount());
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) {
|
||||
this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() - 1);
|
||||
provider->setCurrentPage(provider->getCurrentPage() - 1);
|
||||
|
||||
Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 };
|
||||
View::postEvent(Events::RegionSelected, &dataPreview);
|
||||
@ -124,7 +123,7 @@ namespace hex {
|
||||
ImGui::SameLine();
|
||||
|
||||
if (ImGui::ArrowButton("nextPage", ImGuiDir_Right)) {
|
||||
this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() + 1);
|
||||
provider->setCurrentPage(provider->getCurrentPage() + 1);
|
||||
|
||||
Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 };
|
||||
View::postEvent(Events::RegionSelected, &dataPreview);
|
||||
@ -173,11 +172,11 @@ namespace hex {
|
||||
ImGui::NewLine();
|
||||
|
||||
confirmButtons("Load", "Cancel",
|
||||
[this] {
|
||||
[this, &provider] {
|
||||
if (!this->m_loaderScriptScriptPath.empty() && !this->m_loaderScriptFilePath.empty()) {
|
||||
this->openFile(this->m_loaderScriptFilePath);
|
||||
LoaderScript::setFilePath(this->m_loaderScriptFilePath);
|
||||
LoaderScript::setDataProvider(this->m_dataProvider);
|
||||
LoaderScript::setDataProvider(provider);
|
||||
LoaderScript::processFile(this->m_loaderScriptScriptPath);
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
@ -231,7 +230,7 @@ namespace hex {
|
||||
auto patch = hex::loadIPSPatch(patchData);
|
||||
|
||||
for (auto &[address, value] : patch) {
|
||||
this->m_dataProvider->write(address, &value, 1);
|
||||
provider->write(address, &value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,7 +239,7 @@ namespace hex {
|
||||
auto patch = hex::loadIPS32Patch(patchData);
|
||||
|
||||
for (auto &[address, value] : patch) {
|
||||
this->m_dataProvider->write(address, &value, 1);
|
||||
provider->write(address, &value, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,11 +252,11 @@ namespace hex {
|
||||
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
for (u64 offset = 0; offset < this->m_dataProvider->getActualSize(); offset += bufferSize) {
|
||||
if (bufferSize > this->m_dataProvider->getActualSize() - offset)
|
||||
bufferSize = this->m_dataProvider->getActualSize() - offset;
|
||||
for (u64 offset = 0; offset < provider->getActualSize(); offset += bufferSize) {
|
||||
if (bufferSize > provider->getActualSize() - offset)
|
||||
bufferSize = provider->getActualSize() - offset;
|
||||
|
||||
this->m_dataProvider->read(offset, buffer.data(), bufferSize);
|
||||
provider->read(offset, buffer.data(), bufferSize);
|
||||
fwrite(buffer.data(), 1, bufferSize, file);
|
||||
}
|
||||
|
||||
@ -267,6 +266,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewHexEditor::drawMenu() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (ImGui::BeginMenu("File")) {
|
||||
if (ImGui::MenuItem("Open File...", "CTRL + O")) {
|
||||
@ -274,12 +274,12 @@ namespace hex {
|
||||
View::doLater([]{ ImGui::OpenPopup("Open File"); });
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Save", "CTRL + S", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) {
|
||||
for (const auto &[address, value] : this->m_dataProvider->getPatches())
|
||||
this->m_dataProvider->writeRaw(address, &value, sizeof(u8));
|
||||
if (ImGui::MenuItem("Save", "CTRL + S", false, provider != nullptr && provider->isWritable())) {
|
||||
for (const auto &[address, value] : provider->getPatches())
|
||||
provider->writeRaw(address, &value, sizeof(u8));
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) {
|
||||
if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, provider != nullptr && provider->isWritable())) {
|
||||
View::doLater([]{ ImGui::OpenPopup("Save As"); });
|
||||
}
|
||||
|
||||
@ -290,7 +290,7 @@ namespace hex {
|
||||
View::doLater([]{ ImGui::OpenPopup("Open Project"); });
|
||||
}
|
||||
|
||||
if (ImGui::MenuItem("Save Project", "", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) {
|
||||
if (ImGui::MenuItem("Save Project", "", false, provider != nullptr && provider->isWritable())) {
|
||||
View::postEvent(Events::ProjectFileStore);
|
||||
|
||||
if (ProjectFile::getProjectFilePath() == "")
|
||||
@ -329,12 +329,12 @@ namespace hex {
|
||||
ImGui::EndMenu();
|
||||
}
|
||||
|
||||
if (ImGui::BeginMenu("Export...", this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) {
|
||||
if (ImGui::BeginMenu("Export...", provider != nullptr && provider->isWritable())) {
|
||||
if (ImGui::MenuItem("IPS Patch")) {
|
||||
Patches patches = this->m_dataProvider->getPatches();
|
||||
Patches patches = provider->getPatches();
|
||||
if (!patches.contains(0x00454F45) && patches.contains(0x00454F46)) {
|
||||
u8 value = 0;
|
||||
this->m_dataProvider->read(0x00454F45, &value, sizeof(u8));
|
||||
provider->read(0x00454F45, &value, sizeof(u8));
|
||||
patches[0x00454F45] = value;
|
||||
}
|
||||
|
||||
@ -342,10 +342,10 @@ namespace hex {
|
||||
View::doLater([]{ ImGui::OpenPopup("Export File"); });
|
||||
}
|
||||
if (ImGui::MenuItem("IPS32 Patch")) {
|
||||
Patches patches = this->m_dataProvider->getPatches();
|
||||
Patches patches = provider->getPatches();
|
||||
if (!patches.contains(0x00454F45) && patches.contains(0x45454F46)) {
|
||||
u8 value = 0;
|
||||
this->m_dataProvider->read(0x45454F45, &value, sizeof(u8));
|
||||
provider->read(0x45454F45, &value, sizeof(u8));
|
||||
patches[0x45454F45] = value;
|
||||
}
|
||||
|
||||
@ -421,8 +421,9 @@ namespace hex {
|
||||
|
||||
bool ViewHexEditor::handleShortcut(int key, int mods) {
|
||||
if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_S) {
|
||||
for (const auto &[address, value] : this->m_dataProvider->getPatches())
|
||||
this->m_dataProvider->writeRaw(address, &value, sizeof(u8));
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
for (const auto &[address, value] : provider->getPatches())
|
||||
provider->writeRaw(address, &value, sizeof(u8));
|
||||
return true;
|
||||
} else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT) && key == GLFW_KEY_S) {
|
||||
ImGui::OpenPopup("Save As");
|
||||
@ -449,13 +450,15 @@ namespace hex {
|
||||
|
||||
|
||||
void ViewHexEditor::openFile(std::string path) {
|
||||
if (this->m_dataProvider != nullptr)
|
||||
delete this->m_dataProvider;
|
||||
auto& provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
this->m_dataProvider = new prv::FileProvider(path);
|
||||
this->m_memoryEditor.ReadOnly = !this->m_dataProvider->isWritable();
|
||||
if (provider != nullptr)
|
||||
delete provider;
|
||||
|
||||
if (this->m_dataProvider->isAvailable())
|
||||
provider = new prv::FileProvider(path);
|
||||
this->m_memoryEditor.ReadOnly = !provider->isWritable();
|
||||
|
||||
if (provider->isAvailable())
|
||||
ProjectFile::setFilePath(path);
|
||||
|
||||
this->getWindowOpenState() = true;
|
||||
@ -495,13 +498,15 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewHexEditor::copyBytes() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
size_t copySize = (end - start) + 1;
|
||||
|
||||
std::vector<u8> buffer(copySize, 0x00);
|
||||
this->m_dataProvider->read(start, buffer.data(), buffer.size());
|
||||
provider->read(start, buffer.data(), buffer.size());
|
||||
|
||||
std::string str;
|
||||
for (const auto &byte : buffer)
|
||||
@ -512,6 +517,8 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewHexEditor::copyString() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
@ -519,19 +526,21 @@ namespace hex {
|
||||
|
||||
std::string buffer(copySize, 0x00);
|
||||
buffer.reserve(copySize + 1);
|
||||
this->m_dataProvider->read(start, buffer.data(), copySize);
|
||||
provider->read(start, buffer.data(), copySize);
|
||||
|
||||
ImGui::SetClipboardText(buffer.c_str());
|
||||
}
|
||||
|
||||
void ViewHexEditor::copyLanguageArray(Language language) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
size_t copySize = (end - start) + 1;
|
||||
|
||||
std::vector<u8> buffer(copySize, 0x00);
|
||||
this->m_dataProvider->read(start, buffer.data(), buffer.size());
|
||||
provider->read(start, buffer.data(), buffer.size());
|
||||
|
||||
std::string str;
|
||||
switch (language) {
|
||||
@ -625,13 +634,15 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewHexEditor::copyHexView() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
size_t copySize = (end - start) + 1;
|
||||
|
||||
std::vector<u8> buffer(copySize, 0x00);
|
||||
this->m_dataProvider->read(start, buffer.data(), buffer.size());
|
||||
provider->read(start, buffer.data(), buffer.size());
|
||||
|
||||
std::string str = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n";
|
||||
|
||||
@ -670,13 +681,15 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewHexEditor::copyHexViewHTML() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
size_t copySize = (end - start) + 1;
|
||||
|
||||
std::vector<u8> buffer(copySize, 0x00);
|
||||
this->m_dataProvider->read(start, buffer.data(), buffer.size());
|
||||
provider->read(start, buffer.data(), buffer.size());
|
||||
|
||||
std::string str =
|
||||
R"(
|
||||
@ -801,8 +814,9 @@ R"(
|
||||
void ViewHexEditor::drawSearchPopup() {
|
||||
static auto InputCallback = [](ImGuiInputTextCallbackData* data) -> int {
|
||||
auto _this = static_cast<ViewHexEditor*>(data->UserData);
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
*_this->m_lastSearchBuffer = _this->m_searchFunction(_this->m_dataProvider, data->Buf);
|
||||
*_this->m_lastSearchBuffer = _this->m_searchFunction(provider, data->Buf);
|
||||
_this->m_lastSearchIndex = 0;
|
||||
|
||||
if (_this->m_lastSearchBuffer->size() > 0)
|
||||
@ -812,7 +826,9 @@ R"(
|
||||
};
|
||||
|
||||
static auto Find = [this](char *buffer) {
|
||||
*this->m_lastSearchBuffer = this->m_searchFunction(this->m_dataProvider, buffer);
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
*this->m_lastSearchBuffer = this->m_searchFunction(provider, buffer);
|
||||
this->m_lastSearchIndex = 0;
|
||||
|
||||
if (this->m_lastSearchBuffer->size() > 0)
|
||||
@ -888,6 +904,8 @@ R"(
|
||||
}
|
||||
|
||||
void ViewHexEditor::drawGotoPopup() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (ImGui::BeginPopup("Goto")) {
|
||||
ImGui::TextUnformatted("Goto");
|
||||
if (ImGui::BeginTabBar("gotoTabs")) {
|
||||
@ -895,8 +913,8 @@ R"(
|
||||
if (ImGui::BeginTabItem("Begin")) {
|
||||
ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
if (this->m_gotoAddress >= this->m_dataProvider->getActualSize())
|
||||
this->m_gotoAddress = this->m_dataProvider->getActualSize() - 1;
|
||||
if (this->m_gotoAddress >= provider->getActualSize())
|
||||
this->m_gotoAddress = provider->getActualSize() - 1;
|
||||
|
||||
newOffset = this->m_gotoAddress;
|
||||
|
||||
@ -913,9 +931,9 @@ R"(
|
||||
s64 currHighlightStart = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd);
|
||||
|
||||
newOffset = this->m_gotoAddress + currHighlightStart;
|
||||
if (newOffset >= this->m_dataProvider->getActualSize()) {
|
||||
newOffset = this->m_dataProvider->getActualSize() - 1;
|
||||
this->m_gotoAddress = (this->m_dataProvider->getActualSize() - 1) - currHighlightStart;
|
||||
if (newOffset >= provider->getActualSize()) {
|
||||
newOffset = provider->getActualSize() - 1;
|
||||
this->m_gotoAddress = (provider->getActualSize() - 1) - currHighlightStart;
|
||||
} else if (newOffset < 0) {
|
||||
newOffset = 0;
|
||||
this->m_gotoAddress = -currHighlightStart;
|
||||
@ -926,16 +944,16 @@ R"(
|
||||
if (ImGui::BeginTabItem("End")) {
|
||||
ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal);
|
||||
|
||||
if (this->m_gotoAddress >= this->m_dataProvider->getActualSize())
|
||||
this->m_gotoAddress = this->m_dataProvider->getActualSize() - 1;
|
||||
if (this->m_gotoAddress >= provider->getActualSize())
|
||||
this->m_gotoAddress = provider->getActualSize() - 1;
|
||||
|
||||
newOffset = (this->m_dataProvider->getActualSize() - 1) - this->m_gotoAddress;
|
||||
newOffset = (provider->getActualSize() - 1) - this->m_gotoAddress;
|
||||
|
||||
ImGui::EndTabItem();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Goto")) {
|
||||
this->m_dataProvider->setCurrentPage(std::floor(newOffset / double(prv::Provider::PageSize)));
|
||||
provider->setCurrentPage(std::floor(newOffset / double(prv::Provider::PageSize)));
|
||||
this->m_memoryEditor.GotoAddr = newOffset;
|
||||
this->m_memoryEditor.DataPreviewAddr = newOffset;
|
||||
this->m_memoryEditor.DataPreviewAddrEnd = newOffset;
|
||||
|
@ -14,8 +14,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewInformation::ViewInformation(prv::Provider* &dataProvider)
|
||||
: View("Information"), m_dataProvider(dataProvider) {
|
||||
ViewInformation::ViewInformation() : View("Information") {
|
||||
View::subscribeEvent(Events::DataChanged, [this](const void*) {
|
||||
this->m_dataValid = false;
|
||||
this->m_highestBlockEntropy = 0;
|
||||
@ -50,20 +49,22 @@ namespace hex {
|
||||
if (ImGui::Begin("Data Information", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav);
|
||||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
if (this->m_shouldInvalidate) {
|
||||
|
||||
this->m_analyzedRegion = { this->m_dataProvider->getBaseAddress(), this->m_dataProvider->getBaseAddress() + this->m_dataProvider->getSize() };
|
||||
this->m_analyzedRegion = { provider->getBaseAddress(), provider->getBaseAddress() + provider->getSize() };
|
||||
|
||||
{
|
||||
this->m_blockSize = std::ceil(this->m_dataProvider->getSize() / 2048.0F);
|
||||
this->m_blockSize = std::ceil(provider->getSize() / 2048.0F);
|
||||
std::vector<u8> buffer(this->m_blockSize, 0x00);
|
||||
std::memset(this->m_valueCounts.data(), 0x00, this->m_valueCounts.size() * sizeof(u32));
|
||||
this->m_blockEntropy.clear();
|
||||
|
||||
for (u64 i = 0; i < this->m_dataProvider->getSize(); i += this->m_blockSize) {
|
||||
for (u64 i = 0; i < provider->getSize(); i += this->m_blockSize) {
|
||||
std::array<float, 256> blockValueCounts = { 0 };
|
||||
this->m_dataProvider->read(i, buffer.data(), std::min(u64(this->m_blockSize), this->m_dataProvider->getSize() - i));
|
||||
provider->read(i, buffer.data(), std::min(u64(this->m_blockSize), provider->getSize() - i));
|
||||
|
||||
for (size_t j = 0; j < this->m_blockSize; j++) {
|
||||
blockValueCounts[buffer[j]]++;
|
||||
@ -72,13 +73,13 @@ namespace hex {
|
||||
this->m_blockEntropy.push_back(calculateEntropy(blockValueCounts, this->m_blockSize));
|
||||
}
|
||||
|
||||
this->m_averageEntropy = calculateEntropy(this->m_valueCounts, this->m_dataProvider->getSize());
|
||||
this->m_averageEntropy = calculateEntropy(this->m_valueCounts, provider->getSize());
|
||||
this->m_highestBlockEntropy = *std::max_element(this->m_blockEntropy.begin(), this->m_blockEntropy.end());
|
||||
}
|
||||
|
||||
{
|
||||
std::vector<u8> buffer(this->m_dataProvider->getSize(), 0x00);
|
||||
this->m_dataProvider->read(0x00, buffer.data(), buffer.size());
|
||||
std::vector<u8> buffer(provider->getSize(), 0x00);
|
||||
provider->read(0x00, buffer.data(), buffer.size());
|
||||
|
||||
this->m_fileDescription.clear();
|
||||
this->m_mimeType.clear();
|
||||
@ -134,7 +135,7 @@ namespace hex {
|
||||
|
||||
if (this->m_dataValid) {
|
||||
|
||||
for (auto &[name, value] : this->m_dataProvider->getDataInformation()) {
|
||||
for (auto &[name, value] : prv::Provider::getCurrentProvider()->getDataInformation()) {
|
||||
ImGui::LabelText(name.c_str(), "%s", value.c_str());
|
||||
}
|
||||
|
||||
|
@ -11,15 +11,17 @@ using namespace std::literals::string_literals;
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewPatches::ViewPatches(prv::Provider* &dataProvider) : View("Patches"), m_dataProvider(dataProvider) {
|
||||
ViewPatches::ViewPatches() : View("Patches") {
|
||||
View::subscribeEvent(Events::ProjectFileStore, [this](const void*) {
|
||||
if (this->m_dataProvider != nullptr)
|
||||
ProjectFile::setPatches(this->m_dataProvider->getPatches());
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider != nullptr)
|
||||
ProjectFile::setPatches(provider->getPatches());
|
||||
});
|
||||
|
||||
View::subscribeEvent(Events::ProjectFileLoad, [this](const void*) {
|
||||
if (this->m_dataProvider != nullptr)
|
||||
this->m_dataProvider->getPatches() = ProjectFile::getPatches();
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider != nullptr)
|
||||
provider->getPatches() = ProjectFile::getPatches();
|
||||
});
|
||||
}
|
||||
|
||||
@ -30,8 +32,9 @@ namespace hex {
|
||||
|
||||
void ViewPatches::drawContent() {
|
||||
if (ImGui::Begin("Patches", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
|
||||
if (ImGui::BeginTable("##patchesTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable |
|
||||
ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
|
||||
@ -42,7 +45,7 @@ namespace hex {
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
auto& patches = this->m_dataProvider->getPatches();
|
||||
auto& patches = provider->getPatches();
|
||||
u32 index = 0;
|
||||
for (const auto &[address, patch] : patches) {
|
||||
|
||||
@ -61,7 +64,7 @@ namespace hex {
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
u8 previousValue = 0x00;
|
||||
this->m_dataProvider->readRaw(address, &previousValue, sizeof(u8));
|
||||
provider->readRaw(address, &previousValue, sizeof(u8));
|
||||
ImGui::Text("0x%02X", previousValue);
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -72,8 +72,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View("Pattern"), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
ViewPattern::ViewPattern(std::vector<lang::PatternData*> &patternData) : View("Pattern"), m_patternData(patternData) {
|
||||
|
||||
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
|
||||
this->m_textEditor.SetShowWhitespaces(false);
|
||||
@ -110,8 +109,13 @@ namespace hex {
|
||||
if (error)
|
||||
return;
|
||||
|
||||
std::vector<u8> buffer(std::min(this->m_dataProvider->getSize(), size_t(0xFFFF)), 0x00);
|
||||
this->m_dataProvider->read(0, buffer.data(), buffer.size());
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (provider == nullptr)
|
||||
return;
|
||||
|
||||
std::vector<u8> buffer(std::min(provider->getSize(), size_t(0xFFFF)), 0x00);
|
||||
provider->read(0, buffer.data(), buffer.size());
|
||||
|
||||
std::string mimeType;
|
||||
|
||||
@ -178,7 +182,9 @@ namespace hex {
|
||||
|
||||
void ViewPattern::drawContent() {
|
||||
if (ImGui::Begin("Pattern", &this->getWindowOpenState(), ImGuiWindowFlags_None | ImGuiWindowFlags_NoCollapse)) {
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isAvailable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (provider != nullptr && provider->isAvailable()) {
|
||||
this->m_textEditor.Render("Pattern");
|
||||
|
||||
if (this->m_textEditor.IsTextChanged()) {
|
||||
@ -309,7 +315,8 @@ namespace hex {
|
||||
return;
|
||||
}
|
||||
|
||||
hex::lang::Evaluator evaluator(this->m_dataProvider, defaultDataEndianess);
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
hex::lang::Evaluator evaluator(provider, defaultDataEndianess);
|
||||
auto patternData = evaluator.evaluate(ast.value());
|
||||
if (!patternData.has_value()) {
|
||||
this->m_textEditor.SetErrorMarkers({ evaluator.getError() });
|
||||
|
@ -5,8 +5,8 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View("Pattern Data"), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
ViewPatternData::ViewPatternData(std::vector<lang::PatternData*> &patternData)
|
||||
: View("Pattern Data"), m_patternData(patternData) {
|
||||
|
||||
this->subscribeEvent(Events::PatternChanged, [this](auto data) {
|
||||
this->m_sortedPatternData.clear();
|
||||
@ -50,14 +50,15 @@ namespace hex {
|
||||
|
||||
void ViewPatternData::drawContent() {
|
||||
if (ImGui::Begin("Pattern Data", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
|
||||
if (beginPatternDataTable(this->m_dataProvider, this->m_patternData, this->m_sortedPatternData)) {
|
||||
if (beginPatternDataTable(provider, this->m_patternData, this->m_sortedPatternData)) {
|
||||
if (this->m_sortedPatternData.size() > 0) {
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto &patternData : this->m_sortedPatternData)
|
||||
patternData->createEntry(this->m_dataProvider);
|
||||
patternData->createEntry(provider);
|
||||
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@ using namespace std::literals::string_literals;
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewStrings::ViewStrings(prv::Provider* &dataProvider) : View("Strings"), m_dataProvider(dataProvider) {
|
||||
ViewStrings::ViewStrings() : View("Strings") {
|
||||
View::subscribeEvent(Events::DataChanged, [this](const void*){
|
||||
this->m_foundStrings.clear();
|
||||
});
|
||||
@ -47,6 +47,8 @@ namespace hex {
|
||||
|
||||
|
||||
void ViewStrings::drawContent() {
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
|
||||
if (this->m_shouldInvalidate) {
|
||||
this->m_shouldInvalidate = false;
|
||||
|
||||
@ -54,9 +56,10 @@ namespace hex {
|
||||
|
||||
std::vector<u8> buffer(1024, 0x00);
|
||||
u32 foundCharacters = 0;
|
||||
for (u64 offset = 0; offset < this->m_dataProvider->getSize(); offset += buffer.size()) {
|
||||
size_t readSize = std::min(u64(buffer.size()), this->m_dataProvider->getSize() - offset);
|
||||
this->m_dataProvider->read(offset, buffer.data(), readSize);
|
||||
|
||||
for (u64 offset = 0; offset < provider->getSize(); offset += buffer.size()) {
|
||||
size_t readSize = std::min(u64(buffer.size()), provider->getSize() - offset);
|
||||
provider->read(offset, buffer.data(), readSize);
|
||||
|
||||
for (u32 i = 0; i < readSize; i++) {
|
||||
if (buffer[i] >= 0x20 && buffer[i] <= 0x7E)
|
||||
@ -69,7 +72,7 @@ namespace hex {
|
||||
foundString.size = foundCharacters;
|
||||
foundString.string.reserve(foundCharacters);
|
||||
foundString.string.resize(foundCharacters);
|
||||
this->m_dataProvider->read(foundString.offset, foundString.string.data(), foundCharacters);
|
||||
provider->read(foundString.offset, foundString.string.data(), foundCharacters);
|
||||
|
||||
this->m_foundStrings.push_back(foundString);
|
||||
}
|
||||
@ -82,7 +85,7 @@ namespace hex {
|
||||
|
||||
|
||||
if (ImGui::Begin("Strings", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
if (provider != nullptr && provider->isReadable()) {
|
||||
if (ImGui::InputInt("Minimum length", &this->m_minimumLength, 1, 0))
|
||||
this->m_shouldInvalidate = true;
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewTools::ViewTools(hex::prv::Provider* &provider) : View("Tools"), m_dataProvider(provider) {
|
||||
ViewTools::ViewTools() : View("Tools") {
|
||||
this->m_mangledBuffer = new char[0xF'FFFF];
|
||||
std::memset(this->m_mangledBuffer, 0x00, 0xF'FFFF);
|
||||
|
||||
@ -42,23 +42,25 @@ namespace hex {
|
||||
this->m_mathEvaluator.setFunction("read", [this](auto args) -> std::optional<long double> {
|
||||
u8 value = 0;
|
||||
|
||||
if (this->m_dataProvider == nullptr || !this->m_dataProvider->isReadable() || args[0] >= this->m_dataProvider->getActualSize())
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider == nullptr || !provider->isReadable() || args[0] >= provider->getActualSize())
|
||||
return { };
|
||||
|
||||
this->m_dataProvider->read(args[0], &value, sizeof(u8));
|
||||
provider->read(args[0], &value, sizeof(u8));
|
||||
|
||||
return value;
|
||||
}, 1, 1);
|
||||
|
||||
this->m_mathEvaluator.setFunction("write", [this](auto args) -> std::optional<long double> {
|
||||
if (this->m_dataProvider == nullptr || !this->m_dataProvider->isWritable() || args[0] >= this->m_dataProvider->getActualSize())
|
||||
auto provider = prv::Provider::getCurrentProvider();
|
||||
if (provider == nullptr || !provider->isWritable() || args[0] >= provider->getActualSize())
|
||||
return { };
|
||||
|
||||
if (args[1] > 0xFF)
|
||||
return { };
|
||||
|
||||
u8 value = args[1];
|
||||
this->m_dataProvider->write(args[0], &value, sizeof(u8));
|
||||
provider->write(args[0], &value, sizeof(u8));
|
||||
|
||||
return { };
|
||||
}, 2, 2);
|
||||
|
@ -66,9 +66,6 @@ namespace hex {
|
||||
while (!glfwWindowShouldClose(this->m_window)) {
|
||||
this->frameBegin();
|
||||
|
||||
for (const auto &plugin : PluginHandler::getPlugins())
|
||||
plugin.setImGuiContext(ImGui::GetCurrentContext());
|
||||
|
||||
for (const auto &call : View::getDeferedCalls())
|
||||
call();
|
||||
View::getDeferedCalls().clear();
|
||||
@ -380,6 +377,7 @@ namespace hex {
|
||||
PluginHandler::load((std::filesystem::path(mainArgv[0]).parent_path() / "plugins").string());
|
||||
|
||||
for (const auto &plugin : PluginHandler::getPlugins()) {
|
||||
plugin.initializePlugin(ImGui::GetCurrentContext(), &prv::Provider::getCurrentProvider());
|
||||
if (auto view = plugin.createView(); view != nullptr)
|
||||
this->m_pluginViews.push_back(view);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user