feat: Added Base64 provider
This commit is contained in:
parent
96fe608d60
commit
83fa024fab
@ -60,6 +60,7 @@ add_imhex_plugin(
|
||||
source/content/providers/motorola_srec_provider.cpp
|
||||
source/content/providers/memory_file_provider.cpp
|
||||
source/content/providers/process_memory_provider.cpp
|
||||
source/content/providers/base64_provider.cpp
|
||||
|
||||
source/content/tools/ascii_table.cpp
|
||||
source/content/tools/base_converter.cpp
|
||||
|
@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <content/providers/file_provider.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
class Base64Provider : public FileProvider {
|
||||
public:
|
||||
explicit Base64Provider() = default;
|
||||
~Base64Provider() override = default;
|
||||
|
||||
void readRaw(u64 offset, void *buffer, size_t size) override;
|
||||
void writeRaw(u64 offset, const void *buffer, size_t size) override;
|
||||
[[nodiscard]] u64 getActualSize() const override { return (3 * m_file.getSize()) / 4; }
|
||||
|
||||
void resizeRaw(u64 newSize) override;
|
||||
void insertRaw(u64 offset, u64 size) override;
|
||||
void removeRaw(u64 offset, u64 size) override;
|
||||
|
||||
[[nodiscard]] std::string getTypeName() const override {
|
||||
return "hex.builtin.provider.base64";
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "Daten konnten nicht exportiert werden. Datei konnte nicht erstellt werden!",
|
||||
"hex.builtin.menu.file.export.title": "Datei exportieren",
|
||||
"hex.builtin.menu.file.import": "Importieren...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 Datei",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "Datei hat kein gültiges Base64 Format!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "Öffnen der Datei fehlgeschlagen!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS Patch",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 Patch",
|
||||
"hex.builtin.menu.file.import.modified_file": "Modifizierte Datei",
|
||||
|
@ -140,9 +140,6 @@
|
||||
"hex.builtin.menu.file.export.report.popup.export_error": "Failed to create new report file!",
|
||||
"hex.builtin.menu.file.export.title": "Export File",
|
||||
"hex.builtin.menu.file.import": "Import...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 File",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "File is not in a valid Base64 format!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "Failed to open file!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS Patch",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 Patch",
|
||||
"hex.builtin.menu.file.import.modified_file": "Modified File",
|
||||
@ -375,6 +372,7 @@
|
||||
"hex.builtin.popup.waiting_for_tasks.desc": "There are still tasks running in the background.\nImHex will close after they are finished.",
|
||||
"hex.builtin.provider.tooltip.show_more": "Hold SHIFT for more information",
|
||||
"hex.builtin.provider.error.open": "Failed to open provider: {}",
|
||||
"hex.builtin.provider.base64": "Base64 Provider",
|
||||
"hex.builtin.provider.disk": "Raw Disk Provider",
|
||||
"hex.builtin.provider.disk.disk_size": "Disk Size",
|
||||
"hex.builtin.provider.disk.elevation": "Accessing raw disks most likely requires elevated privileges",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "No se pudieron exportar los datos. ¡Fallo al crear archivo!",
|
||||
"hex.builtin.menu.file.export.title": "Exportar Archivo",
|
||||
"hex.builtin.menu.file.import": "Importar...",
|
||||
"hex.builtin.menu.file.import.base64": "Archivo Base64",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "¡El archivo no tiene un formato Base64 válido!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "¡Fallo al abrir archivo!",
|
||||
"hex.builtin.menu.file.import.ips": "Parche IPS",
|
||||
"hex.builtin.menu.file.import.ips32": "Parche IPS32",
|
||||
"hex.builtin.menu.file.import.modified_file": "Archivo Modificado",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "",
|
||||
"hex.builtin.menu.file.export.title": "Esporta File",
|
||||
"hex.builtin.menu.file.import": "Importa...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 File",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "",
|
||||
"hex.builtin.menu.file.import.ips": "IPS Patch",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 Patch",
|
||||
"hex.builtin.menu.file.import.modified_file": "",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "データをエクスポートできません。\nファイルの作成に失敗しました。",
|
||||
"hex.builtin.menu.file.export.title": "ファイルをエクスポート",
|
||||
"hex.builtin.menu.file.import": "インポート…",
|
||||
"hex.builtin.menu.file.import.base64": "Base64ファイル",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "有効なBase64形式ではありません。",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "ファイルを開けません。",
|
||||
"hex.builtin.menu.file.import.ips": "IPSパッチ",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32パッチ",
|
||||
"hex.builtin.menu.file.import.modified_file": "",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "데이터를 내보낼 수 없습니다. 파일을 만들지 못했습니다!",
|
||||
"hex.builtin.menu.file.export.title": "파일 내보내기",
|
||||
"hex.builtin.menu.file.import": "가져오기...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 파일",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "파일이 올바른 Base64 형식이 아닙니다!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "파일을 열지 못했습니다!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS 패치",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 패치",
|
||||
"hex.builtin.menu.file.import.modified_file": "수정된 파일",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "Não é possível exportar os dados. Falha ao criar arquivo!",
|
||||
"hex.builtin.menu.file.export.title": "Exportar Arquivo",
|
||||
"hex.builtin.menu.file.import": "Importar...",
|
||||
"hex.builtin.menu.file.import.base64": "Arquivo Base64",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "Esse arquivo não é baseado em um formato Base64 valido!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "Falha ao abrir o arquivo!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS Patch",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 Patch",
|
||||
"hex.builtin.menu.file.import.modified_file": "",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "无法导出文件。文件创建失败!",
|
||||
"hex.builtin.menu.file.export.title": "导出文件",
|
||||
"hex.builtin.menu.file.import": "导入...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 文件",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "文件不是有效的 Base64 格式!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "打开文件失败!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS 补丁",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 补丁",
|
||||
"hex.builtin.menu.file.import.modified_file": "已修改",
|
||||
|
@ -124,9 +124,6 @@
|
||||
"hex.builtin.menu.file.export.popup.create": "無法匯出資料。無法建立檔案!",
|
||||
"hex.builtin.menu.file.export.title": "匯出檔案",
|
||||
"hex.builtin.menu.file.import": "匯入...",
|
||||
"hex.builtin.menu.file.import.base64": "Base64 檔案",
|
||||
"hex.builtin.menu.file.import.base64.popup.import_error": "檔案並非有效的 Base64 格式!",
|
||||
"hex.builtin.menu.file.import.base64.popup.open_error": "無法開啟檔案!",
|
||||
"hex.builtin.menu.file.import.ips": "IPS 修補檔案",
|
||||
"hex.builtin.menu.file.import.ips32": "IPS32 修補檔案",
|
||||
"hex.builtin.menu.file.import.modified_file": "已修改檔案",
|
||||
|
@ -73,37 +73,6 @@ namespace hex::plugin::builtin {
|
||||
// Import
|
||||
namespace {
|
||||
|
||||
void importBase64() {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
wolv::io::File inputFile(path, wolv::io::File::Mode::Read);
|
||||
if (!inputFile.isValid()) {
|
||||
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.open_error"_lang);
|
||||
return;
|
||||
}
|
||||
|
||||
auto base64 = inputFile.readVector();
|
||||
|
||||
if (!base64.empty()) {
|
||||
auto data = crypt::decode64(base64);
|
||||
|
||||
if (data.empty())
|
||||
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
|
||||
else {
|
||||
fs::openFileBrowser(fs::DialogMode::Save, {}, [&data](const std::fs::path &path) {
|
||||
wolv::io::File outputFile(path, wolv::io::File::Mode::Create);
|
||||
|
||||
if (!outputFile.isValid())
|
||||
ui::ToastError::open("hex.builtin.menu.file.import.base64.popup.import_error"_lang);
|
||||
|
||||
outputFile.writeVector(data);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
ui::ToastError::open("hex.builtin.popup.file_open_error"_lang);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void importIPSPatch() {
|
||||
fs::openFileBrowser(fs::DialogMode::Open, {}, [](const auto &path) {
|
||||
TaskManager::createTask("hex.ui.common.processing", TaskManager::NoProgress, [path](auto &task) {
|
||||
@ -422,14 +391,6 @@ namespace hex::plugin::builtin {
|
||||
|
||||
/* Import */
|
||||
{
|
||||
/* Base 64 */
|
||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.base64" }, 2050,
|
||||
Shortcut::None,
|
||||
importBase64,
|
||||
noRunningTaskAndWritableProvider);
|
||||
|
||||
ContentRegistry::Interface::addMenuItemSeparator({ "hex.builtin.menu.file", "hex.builtin.menu.file.import" }, 2100);
|
||||
|
||||
/* IPS */
|
||||
ContentRegistry::Interface::addMenuItem({ "hex.builtin.menu.file", "hex.builtin.menu.file.import", "hex.builtin.menu.file.import.ips"}, 2150,
|
||||
Shortcut::None,
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "content/providers/memory_file_provider.hpp"
|
||||
#include "content/providers/view_provider.hpp"
|
||||
#include <content/providers/process_memory_provider.hpp>
|
||||
#include <content/providers/base64_provider.hpp>
|
||||
#include <popups/popup_notification.hpp>
|
||||
#include "content/helpers/notification.hpp"
|
||||
|
||||
@ -32,6 +33,7 @@ namespace hex::plugin::builtin {
|
||||
ContentRegistry::Provider::add<GDBProvider>();
|
||||
ContentRegistry::Provider::add<IntelHexProvider>();
|
||||
ContentRegistry::Provider::add<MotorolaSRECProvider>();
|
||||
ContentRegistry::Provider::add<Base64Provider>();
|
||||
ContentRegistry::Provider::add<MemoryFileProvider>(false);
|
||||
ContentRegistry::Provider::add<ViewProvider>(false);
|
||||
|
||||
|
65
plugins/builtin/source/content/providers/base64_provider.cpp
Normal file
65
plugins/builtin/source/content/providers/base64_provider.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
#include <content/providers/base64_provider.hpp>
|
||||
|
||||
#include <hex/helpers/crypto.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
void Base64Provider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
const u64 base64Offset = 4 * (offset / 3);
|
||||
const u64 base64Size = hex::alignTo<u64>(4 * (size / 3), 4) + 4;
|
||||
|
||||
std::vector<u8> bytes(base64Size);
|
||||
FileProvider::readRaw(base64Offset, bytes.data(), bytes.size());
|
||||
|
||||
auto decoded = crypt::decode64(bytes);
|
||||
if (decoded.empty())
|
||||
return;
|
||||
|
||||
u64 startOffset = offset % 3;
|
||||
std::memcpy(buffer, decoded.data() + startOffset, std::min<size_t>(decoded.size() - startOffset, size));
|
||||
}
|
||||
|
||||
void Base64Provider::writeRaw(u64 offset, const void *buffer, size_t size) {
|
||||
const u64 base64Offset = 4 * (offset / 3);
|
||||
const u64 base64Size = hex::alignTo<u64>(4 * (size / 3), 4) + 4;
|
||||
|
||||
std::vector<u8> bytes(base64Size);
|
||||
FileProvider::readRaw(base64Offset, bytes.data(), bytes.size());
|
||||
|
||||
auto decoded = crypt::decode64(bytes);
|
||||
if (decoded.empty())
|
||||
return;
|
||||
|
||||
u64 startOffset = offset % 3;
|
||||
std::memcpy(decoded.data() + startOffset, buffer, std::min<size_t>(decoded.size() - startOffset, size));
|
||||
|
||||
auto encoded = crypt::encode64(decoded);
|
||||
if (encoded.empty())
|
||||
return;
|
||||
|
||||
FileProvider::writeRaw(base64Offset, encoded.data(), encoded.size());
|
||||
}
|
||||
|
||||
void Base64Provider::resizeRaw(u64 newSize) {
|
||||
u64 newFileLength = 4 * (newSize / 3);
|
||||
FileProvider::resizeRaw(newFileLength);
|
||||
}
|
||||
|
||||
void Base64Provider::insertRaw(u64 offset, u64 size) {
|
||||
u64 newFileLength = 4 * ((getActualSize() + size) / 3);
|
||||
FileProvider::insertRaw(4 * (offset / 3), newFileLength);
|
||||
|
||||
constexpr static auto NullByte = 0x00;
|
||||
for (u64 i = 0; i < size; i++)
|
||||
writeRaw(offset + i, &NullByte, 1);
|
||||
}
|
||||
|
||||
void Base64Provider::removeRaw(u64 offset, u64 size) {
|
||||
u64 newFileLength = 4 * ((getActualSize() - size) / 3);
|
||||
FileProvider::removeRaw(4 * (offset / 3), newFileLength);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -43,8 +43,7 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
|
||||
void FileProvider::readRaw(u64 offset, void *buffer, size_t size) {
|
||||
auto actualSize = this->getActualSize();
|
||||
if (actualSize == 0 || (offset + size) > actualSize || buffer == nullptr || size == 0)
|
||||
if (m_fileSize == 0 || (offset + size) > m_fileSize || buffer == nullptr || size == 0)
|
||||
return;
|
||||
|
||||
std::memcpy(buffer, m_file.getMapping() + offset, size);
|
||||
|
Loading…
x
Reference in New Issue
Block a user