mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-30 21:05:56 -05:00
Add support for custom providers via plugins
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user