mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-04-01 21:17:44 -05:00
feat: Added LEB128 in data inspector (#615)
* feat: Added LEB128 in data inspector * feat: Added support for editing LEB128 values * Moved LEB functions from utils.cpp to crypto.cpp * Added placeholders for translations * Made DataInspector::impl::Entry.maxSize mandatory * Fixed undefined leftshifting behaviour
This commit is contained in:
@@ -206,6 +206,7 @@ namespace hex {
|
||||
struct Entry {
|
||||
std::string unlocalizedName;
|
||||
size_t requiredSize;
|
||||
size_t maxSize;
|
||||
impl::GeneratorFunction generatorFunction;
|
||||
std::optional<impl::EditingFunction> editingFunction;
|
||||
};
|
||||
@@ -213,6 +214,7 @@ namespace hex {
|
||||
}
|
||||
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, size_t maxSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction = std::nullopt);
|
||||
|
||||
std::vector<impl::Entry> &getEntries();
|
||||
}
|
||||
|
||||
@@ -39,6 +39,11 @@ namespace hex::crypt {
|
||||
std::vector<u8> decode16(const std::string &input);
|
||||
std::string encode16(const std::vector<u8> &input);
|
||||
|
||||
i128 decodeSleb128(const std::vector<u8> &bytes);
|
||||
u128 decodeUleb128(const std::vector<u8> &bytes);
|
||||
std::vector<u8> encodeSleb128(i128 value);
|
||||
std::vector<u8> encodeUleb128(u128 value);
|
||||
|
||||
enum class AESMode : u8 {
|
||||
ECB = 0,
|
||||
CBC = 1,
|
||||
|
||||
@@ -348,7 +348,13 @@ namespace hex {
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction) {
|
||||
log::debug("Registered new data inspector format: {}", unlocalizedName);
|
||||
|
||||
getEntries().push_back({ unlocalizedName, requiredSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
getEntries().push_back({ unlocalizedName, requiredSize, requiredSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
}
|
||||
|
||||
void add(const std::string &unlocalizedName, size_t requiredSize, size_t maxSize, impl::GeneratorFunction displayGeneratorFunction, std::optional<impl::EditingFunction> editingFunction) {
|
||||
log::info("Registered new data inspector format: {}", unlocalizedName);
|
||||
|
||||
getEntries().push_back({ unlocalizedName, requiredSize, maxSize, std::move(displayGeneratorFunction), std::move(editingFunction) });
|
||||
}
|
||||
|
||||
std::vector<impl::Entry> &getEntries() {
|
||||
|
||||
@@ -422,6 +422,77 @@ namespace hex::crypt {
|
||||
return output;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T safeLeftShift(T t, u32 shift) {
|
||||
if (shift >= sizeof(t) * 8) {
|
||||
return 0;
|
||||
} else {
|
||||
return t << shift;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T decodeLeb128(const std::vector<u8> &bytes) {
|
||||
T value = 0;
|
||||
u32 shift = 0;
|
||||
u8 b = 0;
|
||||
for (u8 byte : bytes) {
|
||||
b = byte;
|
||||
value |= safeLeftShift(static_cast<T>(byte & 0x7F), shift);
|
||||
shift += 7;
|
||||
if ((byte & 0x80) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if constexpr(std::is_signed<T>::value) {
|
||||
if ((b & 0x40) != 0) {
|
||||
value |= safeLeftShift(~static_cast<T>(0), shift);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
u128 decodeUleb128(const std::vector<u8> &bytes) {
|
||||
return decodeLeb128<u128>(bytes);
|
||||
}
|
||||
|
||||
i128 decodeSleb128(const std::vector<u8> &bytes) {
|
||||
return decodeLeb128<i128>(bytes);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static std::vector<u8> encodeLeb128(T value) {
|
||||
std::vector<u8> bytes;
|
||||
u8 byte;
|
||||
while (true) {
|
||||
byte = value & 0x7F;
|
||||
value >>= 7;
|
||||
if constexpr(std::is_signed<T>::value) {
|
||||
if (value == 0 && (byte & 0x40) == 0) {
|
||||
break;
|
||||
}
|
||||
if (value == -1 && (byte & 0x40) != 0) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (value == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
bytes.push_back(byte | 0x80);
|
||||
}
|
||||
bytes.push_back(byte);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
std::vector<u8> encodeUleb128(u128 value) {
|
||||
return encodeLeb128<u128>(value);
|
||||
}
|
||||
|
||||
std::vector<u8> encodeSleb128(i128 value) {
|
||||
return encodeLeb128<i128>(value);
|
||||
}
|
||||
|
||||
static std::vector<u8> aes(mbedtls_cipher_type_t type, mbedtls_operation_t operation, const std::vector<u8> &key, std::array<u8, 8> nonce, std::array<u8, 8> iv, const std::vector<u8> &input) {
|
||||
std::vector<u8> output;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user