1
0
mirror of synced 2024-11-28 01:20:51 +01:00

store: Added support for downloading tar'd folders

This commit is contained in:
WerWolv 2021-09-23 22:56:49 +02:00
parent ee26839292
commit d9134f7fe1
15 changed files with 700 additions and 73 deletions

View File

@ -22,31 +22,11 @@ findLibraries()
detectOS()
detectArch()
if (NOT USE_SYSTEM_LLVM)
add_subdirectory(external/llvm)
else()
find_package(LLVM REQUIRED Demangle)
endif()
if (NOT USE_SYSTEM_YARA)
add_subdirectory(external/yara)
set(YARA_LIBRARIES libyara)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
endif()
# Add bundled dependencies
add_subdirectory(plugins/libimhex)
# Add include directories
include_directories(include ${MBEDTLS_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${Python_INCLUDE_DIRS})
if (USE_SYSTEM_LLVM)
include_directories(${LLVM_INCLUDE_DIRS})
endif()
if (USE_SYSTEM_YARA)
include_directories(${YARA_INCLUDE_DIRS})
endif()
include_directories(include)
enable_testing()
add_subdirectory(tests)
@ -97,14 +77,11 @@ add_executable(imhex ${application_type}
)
set_target_properties(imhex PROPERTIES CXX_VISIBILITY_PRESET hidden)
target_link_directories(imhex PRIVATE ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
if (WIN32)
target_link_libraries(imhex ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} wsock32 ws2_32
${YARA_LIBRARIES} Dwmapi.lib dl)
target_link_libraries(imhex dl libimhex wsock32 ws2_32 Dwmapi.lib)
else ()
target_link_libraries(imhex ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread
${YARA_LIBRARIES})
target_link_libraries(imhex dl libimhex pthread)
endif ()
createPackage()

10
external/microtar/CMakeLists.txt vendored Normal file
View File

@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.16)
project(microtar)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC")
add_library(microtar STATIC
source/microtar.c
)
target_include_directories(microtar PUBLIC include)

19
external/microtar/LICENSE vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2017 rxi
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

99
external/microtar/README.md vendored Normal file
View File

@ -0,0 +1,99 @@
# microtar
A lightweight tar library written in ANSI C
## Basic Usage
The library consists of `microtar.c` and `microtar.h`. These two files can be
dropped into an existing project and compiled along with it.
#### Reading
```c
mtar_t tar;
mtar_header_t h;
char *p;
/* Open archive for reading */
mtar_open(&tar, "test.tar", "r");
/* Print all file names and sizes */
while ( (mtar_read_header(&tar, &h)) != MTAR_ENULLRECORD ) {
printf("%s (%d bytes)\n", h.name, h.size);
mtar_next(&tar);
}
/* Load and print contents of file "test.txt" */
mtar_find(&tar, "test.txt", &h);
p = calloc(1, h.size + 1);
mtar_read_data(&tar, p, h.size);
printf("%s", p);
free(p);
/* Close archive */
mtar_close(&tar);
```
#### Writing
```c
mtar_t tar;
const char *str1 = "Hello world";
const char *str2 = "Goodbye world";
/* Open archive for writing */
mtar_open(&tar, "test.tar", "w");
/* Write strings to files `test1.txt` and `test2.txt` */
mtar_write_file_header(&tar, "test1.txt", strlen(str1));
mtar_write_data(&tar, str1, strlen(str1));
mtar_write_file_header(&tar, "test2.txt", strlen(str2));
mtar_write_data(&tar, str2, strlen(str2));
/* Finalize -- this needs to be the last thing done before closing */
mtar_finalize(&tar);
/* Close archive */
mtar_close(&tar);
```
## Error handling
All functions which return an `int` will return `MTAR_ESUCCESS` if the operation
is successful. If an error occurs an error value less-than-zero will be
returned; this value can be passed to the function `mtar_strerror()` to get its
corresponding error string.
## Wrapping a stream
If you want to read or write from something other than a file, the `mtar_t`
struct can be manually initialized with your own callback functions and a
`stream` pointer.
All callback functions are passed a pointer to the `mtar_t` struct as their
first argument. They should return `MTAR_ESUCCESS` if the operation succeeds
without an error, or an integer below zero if an error occurs.
After the `stream` field has been set, all required callbacks have been set and
all unused fields have been zeroset the `mtar_t` struct can be safely used with
the microtar functions. `mtar_open` *should not* be called if the `mtar_t`
struct was initialized manually.
#### Reading
The following callbacks should be set for reading an archive from a stream:
Name | Arguments | Description
--------|------------------------------------------|---------------------------
`read` | `mtar_t *tar, void *data, unsigned size` | Read data from the stream
`seek` | `mtar_t *tar, unsigned pos` | Set the position indicator
`close` | `mtar_t *tar` | Close the stream
#### Writing
The following callbacks should be set for writing an archive to a stream:
Name | Arguments | Description
--------|------------------------------------------------|---------------------
`write` | `mtar_t *tar, const void *data, unsigned size` | Write data to the stream
## License
This library is free software; you can redistribute it and/or modify it under
the terms of the MIT license. See [LICENSE](LICENSE) for details.

93
external/microtar/include/microtar.h vendored Normal file
View File

@ -0,0 +1,93 @@
/**
* Copyright (c) 2017 rxi
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the MIT license. See `microtar.c` for details.
*/
#ifndef MICROTAR_H
#define MICROTAR_H
#include <stdio.h>
#include <stdlib.h>
#if defined(__cplusplus)
extern "C" {
#endif
#define MTAR_VERSION "0.1.0"
enum {
MTAR_ESUCCESS = 0,
MTAR_EFAILURE = -1,
MTAR_EOPENFAIL = -2,
MTAR_EREADFAIL = -3,
MTAR_EWRITEFAIL = -4,
MTAR_ESEEKFAIL = -5,
MTAR_EBADCHKSUM = -6,
MTAR_ENULLRECORD = -7,
MTAR_ENOTFOUND = -8
};
enum {
MTAR_TREG = '0',
MTAR_TLNK = '1',
MTAR_TSYM = '2',
MTAR_TCHR = '3',
MTAR_TBLK = '4',
MTAR_TDIR = '5',
MTAR_TFIFO = '6'
};
typedef struct {
unsigned mode;
unsigned owner;
unsigned size;
unsigned mtime;
unsigned type;
char name[100];
char linkname[100];
} mtar_header_t;
typedef struct mtar_t mtar_t;
struct mtar_t {
int (*read)(mtar_t *tar, void *data, unsigned size);
int (*write)(mtar_t *tar, const void *data, unsigned size);
int (*seek)(mtar_t *tar, unsigned pos);
int (*close)(mtar_t *tar);
void *stream;
unsigned pos;
unsigned remaining_data;
unsigned last_header;
};
const char *mtar_strerror(int err);
int mtar_open(mtar_t *tar, const char *filename, const char *mode);
int mtar_close(mtar_t *tar);
int mtar_seek(mtar_t *tar, unsigned pos);
int mtar_rewind(mtar_t *tar);
int mtar_next(mtar_t *tar);
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h);
int mtar_read_header(mtar_t *tar, mtar_header_t *h);
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size);
int mtar_write_header(mtar_t *tar, const mtar_header_t *h);
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size);
int mtar_write_dir_header(mtar_t *tar, const char *name);
int mtar_write_data(mtar_t *tar, const void *data, unsigned size);
int mtar_finalize(mtar_t *tar);
#if defined(__cplusplus)
}
#endif
#endif

376
external/microtar/source/microtar.c vendored Normal file
View File

@ -0,0 +1,376 @@
/*
* Copyright (c) 2017 rxi
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <microtar.h>
typedef struct {
char name[100];
char mode[8];
char owner[8];
char group[8];
char size[12];
char mtime[12];
char checksum[8];
char type;
char linkname[100];
char _padding[255];
} mtar_raw_header_t;
static unsigned round_up(unsigned n, unsigned incr) {
return n + (incr - n % incr) % incr;
}
static unsigned checksum(const mtar_raw_header_t* rh) {
unsigned i;
unsigned char *p = (unsigned char*) rh;
unsigned res = 256;
for (i = 0; i < offsetof(mtar_raw_header_t, checksum); i++) {
res += p[i];
}
for (i = offsetof(mtar_raw_header_t, type); i < sizeof(*rh); i++) {
res += p[i];
}
return res;
}
static int tread(mtar_t *tar, void *data, unsigned size) {
int err = tar->read(tar, data, size);
tar->pos += size;
return err;
}
static int twrite(mtar_t *tar, const void *data, unsigned size) {
int err = tar->write(tar, data, size);
tar->pos += size;
return err;
}
static int write_null_bytes(mtar_t *tar, int n) {
int i, err;
char nul = '\0';
for (i = 0; i < n; i++) {
err = twrite(tar, &nul, 1);
if (err) {
return err;
}
}
return MTAR_ESUCCESS;
}
static int raw_to_header(mtar_header_t *h, const mtar_raw_header_t *rh) {
unsigned chksum1, chksum2;
/* If the checksum starts with a null byte we assume the record is NULL */
if (*rh->checksum == '\0') {
return MTAR_ENULLRECORD;
}
/* Build and compare checksum */
chksum1 = checksum(rh);
sscanf(rh->checksum, "%o", &chksum2);
if (chksum1 != chksum2) {
return MTAR_EBADCHKSUM;
}
/* Load raw header into header */
sscanf(rh->mode, "%o", &h->mode);
sscanf(rh->owner, "%o", &h->owner);
sscanf(rh->size, "%o", &h->size);
sscanf(rh->mtime, "%o", &h->mtime);
h->type = rh->type;
strcpy(h->name, rh->name);
strcpy(h->linkname, rh->linkname);
return MTAR_ESUCCESS;
}
static int header_to_raw(mtar_raw_header_t *rh, const mtar_header_t *h) {
unsigned chksum;
/* Load header into raw header */
memset(rh, 0, sizeof(*rh));
sprintf(rh->mode, "%o", h->mode);
sprintf(rh->owner, "%o", h->owner);
sprintf(rh->size, "%o", h->size);
sprintf(rh->mtime, "%o", h->mtime);
rh->type = h->type ? h->type : MTAR_TREG;
strcpy(rh->name, h->name);
strcpy(rh->linkname, h->linkname);
/* Calculate and write checksum */
chksum = checksum(rh);
sprintf(rh->checksum, "%06o", chksum);
rh->checksum[7] = ' ';
return MTAR_ESUCCESS;
}
const char* mtar_strerror(int err) {
switch (err) {
case MTAR_ESUCCESS : return "success";
case MTAR_EFAILURE : return "failure";
case MTAR_EOPENFAIL : return "could not open";
case MTAR_EREADFAIL : return "could not read";
case MTAR_EWRITEFAIL : return "could not write";
case MTAR_ESEEKFAIL : return "could not seek";
case MTAR_EBADCHKSUM : return "bad checksum";
case MTAR_ENULLRECORD : return "null record";
case MTAR_ENOTFOUND : return "file not found";
}
return "unknown error";
}
static int file_write(mtar_t *tar, const void *data, unsigned size) {
unsigned res = fwrite(data, 1, size, tar->stream);
return (res == size) ? MTAR_ESUCCESS : MTAR_EWRITEFAIL;
}
static int file_read(mtar_t *tar, void *data, unsigned size) {
unsigned res = fread(data, 1, size, tar->stream);
return (res == size) ? MTAR_ESUCCESS : MTAR_EREADFAIL;
}
static int file_seek(mtar_t *tar, unsigned offset) {
int res = fseek(tar->stream, offset, SEEK_SET);
return (res == 0) ? MTAR_ESUCCESS : MTAR_ESEEKFAIL;
}
static int file_close(mtar_t *tar) {
fclose(tar->stream);
return MTAR_ESUCCESS;
}
int mtar_open(mtar_t *tar, const char *filename, const char *mode) {
int err;
mtar_header_t h;
/* Init tar struct and functions */
memset(tar, 0, sizeof(*tar));
tar->write = file_write;
tar->read = file_read;
tar->seek = file_seek;
tar->close = file_close;
/* Assure mode is always binary */
if ( strchr(mode, 'r') ) mode = "rb";
if ( strchr(mode, 'w') ) mode = "wb";
if ( strchr(mode, 'a') ) mode = "ab";
/* Open file */
tar->stream = fopen(filename, mode);
if (!tar->stream) {
return MTAR_EOPENFAIL;
}
/* Read first header to check it is valid if mode is `r` */
if (*mode == 'r') {
err = mtar_read_header(tar, &h);
if (err != MTAR_ESUCCESS) {
mtar_close(tar);
return err;
}
}
/* Return ok */
return MTAR_ESUCCESS;
}
int mtar_close(mtar_t *tar) {
return tar->close(tar);
}
int mtar_seek(mtar_t *tar, unsigned pos) {
int err = tar->seek(tar, pos);
tar->pos = pos;
return err;
}
int mtar_rewind(mtar_t *tar) {
tar->remaining_data = 0;
tar->last_header = 0;
return mtar_seek(tar, 0);
}
int mtar_next(mtar_t *tar) {
int err, n;
mtar_header_t h;
/* Load header */
err = mtar_read_header(tar, &h);
if (err) {
return err;
}
/* Seek to next record */
n = round_up(h.size, 512) + sizeof(mtar_raw_header_t);
return mtar_seek(tar, tar->pos + n);
}
int mtar_find(mtar_t *tar, const char *name, mtar_header_t *h) {
int err;
mtar_header_t header;
/* Start at beginning */
err = mtar_rewind(tar);
if (err) {
return err;
}
/* Iterate all files until we hit an error or find the file */
while ( (err = mtar_read_header(tar, &header)) == MTAR_ESUCCESS ) {
if ( !strcmp(header.name, name) ) {
if (h) {
*h = header;
}
return MTAR_ESUCCESS;
}
mtar_next(tar);
}
/* Return error */
if (err == MTAR_ENULLRECORD) {
err = MTAR_ENOTFOUND;
}
return err;
}
int mtar_read_header(mtar_t *tar, mtar_header_t *h) {
int err;
mtar_raw_header_t rh;
/* Save header position */
tar->last_header = tar->pos;
/* Read raw header */
err = tread(tar, &rh, sizeof(rh));
if (err) {
return err;
}
/* Seek back to start of header */
err = mtar_seek(tar, tar->last_header);
if (err) {
return err;
}
/* Load raw header into header struct and return */
return raw_to_header(h, &rh);
}
int mtar_read_data(mtar_t *tar, void *ptr, unsigned size) {
int err;
/* If we have no remaining data then this is the first read, we get the size,
* set the remaining data and seek to the beginning of the data */
if (tar->remaining_data == 0) {
mtar_header_t h;
/* Read header */
err = mtar_read_header(tar, &h);
if (err) {
return err;
}
/* Seek past header and init remaining data */
err = mtar_seek(tar, tar->pos + sizeof(mtar_raw_header_t));
if (err) {
return err;
}
tar->remaining_data = h.size;
}
/* Read data */
err = tread(tar, ptr, size);
if (err) {
return err;
}
tar->remaining_data -= size;
/* If there is no remaining data we've finished reading and seek back to the
* header */
if (tar->remaining_data == 0) {
return mtar_seek(tar, tar->last_header);
}
return MTAR_ESUCCESS;
}
int mtar_write_header(mtar_t *tar, const mtar_header_t *h) {
mtar_raw_header_t rh;
/* Build raw header and write */
header_to_raw(&rh, h);
tar->remaining_data = h->size;
return twrite(tar, &rh, sizeof(rh));
}
int mtar_write_file_header(mtar_t *tar, const char *name, unsigned size) {
mtar_header_t h;
/* Build header */
memset(&h, 0, sizeof(h));
strcpy(h.name, name);
h.size = size;
h.type = MTAR_TREG;
h.mode = 0664;
/* Write header */
return mtar_write_header(tar, &h);
}
int mtar_write_dir_header(mtar_t *tar, const char *name) {
mtar_header_t h;
/* Build header */
memset(&h, 0, sizeof(h));
strcpy(h.name, name);
h.type = MTAR_TDIR;
h.mode = 0775;
/* Write header */
return mtar_write_header(tar, &h);
}
int mtar_write_data(mtar_t *tar, const void *data, unsigned size) {
int err;
/* Write data */
err = twrite(tar, data, size);
if (err) {
return err;
}
tar->remaining_data -= size;
/* Write padding if we've written all the data for this file */
if (tar->remaining_data == 0) {
return write_null_bytes(tar, round_up(tar->pos, 512) - tar->pos);
}
return MTAR_ESUCCESS;
}
int mtar_finalize(mtar_t *tar) {
/* Write two NULL records */
return write_null_bytes(tar, sizeof(mtar_raw_header_t) * 2);
}

View File

@ -9,6 +9,7 @@
#include <array>
#include <future>
#include <string>
#include <filesystem>
namespace hex {
@ -19,6 +20,8 @@ namespace hex {
std::string link;
std::string hash;
bool isFolder;
bool downloading;
bool installed;
bool hasUpdate;
@ -39,8 +42,9 @@ namespace hex {
Net m_net;
std::future<Response<std::string>> m_apiRequest;
std::future<Response<void>> m_download;
std::filesystem::path m_downloadPath;
std::vector<StoreEntry> m_patterns, m_includes, m_magics, m_constants;
std::vector<StoreEntry> m_patterns, m_includes, m_magics, m_constants, m_yara;
void drawStore();

View File

@ -316,6 +316,7 @@ namespace hex::plugin::builtin {
{ "hex.view.store.tab.libraries", "Libraries" },
{ "hex.view.store.tab.magics", "Magic Files" },
{ "hex.view.store.tab.constants", "Konstanten" },
{ "hex.view.store.tab.yara", "Yara Rules" },
{ "hex.view.store.loading", "Store inhalt wird geladen..." },
{ "hex.view.diff.name", "Diffing" },

View File

@ -316,6 +316,7 @@ namespace hex::plugin::builtin {
{ "hex.view.store.tab.libraries", "Libraries" },
{ "hex.view.store.tab.magics", "Magic Files" },
{ "hex.view.store.tab.constants", "Constants" },
{ "hex.view.store.tab.yara", "Yara Rules" },
{ "hex.view.store.loading", "Loading store content..." },
{ "hex.view.diff.name", "Diffing" },

View File

@ -315,6 +315,7 @@ namespace hex::plugin::builtin {
{ "hex.view.store.tab.libraries", "Librerie" },
{ "hex.view.store.tab.magics", "File Magici" },
{ "hex.view.store.tab.constants", "Costanti" },
{ "hex.view.store.tab.yara", "Regole di Yara" },
{ "hex.view.store.loading", "Caricamento del content store..." },
//{ "hex.view.diff.name", "Diffing" },

View File

@ -316,7 +316,8 @@ namespace hex::plugin::builtin {
{ "hex.view.store.tab.libraries", "" },
{ "hex.view.store.tab.magics", "魔术数据库" },
{ "hex.view.store.tab.constants", "常量" },
{ "hex.view.store.loading", "正在加载仓库内容..." },
{ "hex.view.store.tab.yara", "Yara规则" },
{ "hex.view.store.loading", "正在加载仓库内容..." },
//{ "hex.view.diff.name", "Diffing" },
/* Builtin plugin features */

View File

@ -5,6 +5,13 @@ set(CMAKE_CXX_STANDARD 20)
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/ImGui ${CMAKE_CURRENT_BINARY_DIR}/external/ImGui)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/nativefiledialog ${CMAKE_CURRENT_BINARY_DIR}/external/nativefiledialog EXCLUDE_FROM_ALL)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/microtar ${CMAKE_CURRENT_BINARY_DIR}/external/microtar EXCLUDE_FROM_ALL)
set(XDGPP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../external/xdgpp")
set(CMAKE_USE_MBEDTLS ON)
set(BUILD_CURL_EXE OFF)
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
if(NOT USE_SYSTEM_NLOHMANN_JSON)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/nlohmann_json ${CMAKE_CURRENT_BINARY_DIR}/external/nlohmann_json)
@ -14,7 +21,6 @@ else()
set(NLOHMANN_JSON_LIBRARIES nlohmann_json::nlohmann_json)
endif()
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/nativefiledialog ${CMAKE_CURRENT_BINARY_DIR}/external/nativefiledialog EXCLUDE_FROM_ALL)
if(NOT USE_SYSTEM_FMT)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/fmt ${CMAKE_CURRENT_BINARY_DIR}/external/fmt)
set(FMT_LIBRARIES fmt-header-only)
@ -23,11 +29,6 @@ else()
set(FMT_LIBRARIES fmt::fmt)
endif()
set(XDGPP_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/../../external/xdgpp")
set(CMAKE_USE_MBEDTLS ON)
set(BUILD_CURL_EXE OFF)
set(FPHSA_NAME_MISMATCHED ON CACHE BOOL "")
if(NOT USE_SYSTEM_CURL)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/curl ${CMAKE_CURRENT_BINARY_DIR}/external/curl EXCLUDE_FROM_ALL)
set_target_properties(libcurl PROPERTIES POSITION_INDEPENDENT_CODE ON)
@ -37,6 +38,20 @@ else()
pkg_check_modules(LIBCURL REQUIRED IMPORTED_TARGET libcurl>=7.78.0)
endif()
if (NOT USE_SYSTEM_LLVM)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/llvm ${CMAKE_CURRENT_BINARY_DIR}/external/llvm EXCLUDE_FROM_ALL)
else()
find_package(LLVM REQUIRED Demangle)
endif()
if (NOT USE_SYSTEM_YARA)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/yara ${CMAKE_CURRENT_BINARY_DIR}/external/yara EXCLUDE_FROM_ALL)
set(YARA_LIBRARIES libyara)
else()
find_package(PkgConfig REQUIRED)
pkg_check_modules(YARA REQUIRED IMPORTED_TARGET yara)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
set(CMAKE_SHARED_LIBRARY_PREFIX "")
@ -83,27 +98,17 @@ if (APPLE)
endif ()
endif ()
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/paths_mac.mm include/hex/helpers/file.hpp)
set(LIBIMHEX_SOURCES ${LIBIMHEX_SOURCES} source/helpers/paths_mac.mm)
endif ()
add_library(libimhex SHARED ${LIBIMHEX_SOURCES})
target_include_directories(libimhex PUBLIC include ${MBEDTLS_INCLUDE_DIR} ${XDGPP_INCLUDE_DIRS})
if (USE_SYSTEM_FMT)
target_include_directories(libimhex PUBLIC include ${FMT_INCLUDE_DIRS})
endif()
if (USE_SYSTEM_CURL)
target_include_directories(libimhex PUBLIC include ${CURL_INCLUDE_DIRS})
endif()
target_link_directories(libimhex PUBLIC ${MBEDTLS_LIBRARY_DIR})
target_include_directories(libimhex PUBLIC include ${MBEDTLS_INCLUDE_DIR} ${XDGPP_INCLUDE_DIRS} ${MBEDTLS_INCLUDE_DIRS} ${CAPSTONE_INCLUDE_DIRS} ${MAGIC_INCLUDE_DIRS} ${Python_INCLUDE_DIRS} ${LLVM_INCLUDE_DIRS} ${FMT_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS} ${YARA_INCLUDE_DIRS})
target_link_directories(libimhex PUBLIC ${MBEDTLS_LIBRARY_DIR} ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS})
if (APPLE)
find_library(FOUNDATION NAMES Foundation)
target_link_libraries(libimhex PUBLIC imgui ${NLOHMANN_JSON_LIBRARIES} ${MBEDTLS_LIBRARIES} ${FOUNDATION} nfd
${FMT_LIBRARIES} ${LIBCURL_LIBRARIES} magic)
else ()
target_link_libraries(libimhex PUBLIC imgui ${NLOHMANN_JSON_LIBRARIES} ${MBEDTLS_LIBRARIES} nfd magic
${FMT_LIBRARIES} ${LIBCURL_LIBRARIES})
target_link_libraries(libimhex PUBLIC ${FOUNDATION})
endif ()
target_link_libraries(libimhex PUBLIC imgui nfd magic capstone LLVMDemangle microtar ${NLOHMANN_JSON_LIBRARIES} ${YARA_LIBRARIES} ${LIBCURL_LIBRARIES} ${MBEDTLS_LIBRARIES} ${FMT_LIBRARIES} ${Python_LIBRARIES})

View File

@ -24,8 +24,8 @@ namespace hex {
}
void View::drawCommonInterfaces() {
ImGui::SetNextWindowSize(ImVec2(200, 100) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.info"_lang)) {
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.info"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
ImGui::NewLine();
ImGui::Separator();
@ -35,8 +35,8 @@ namespace hex {
ImGui::EndPopup();
}
ImGui::SetNextWindowSize(ImVec2(200, 100) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.error"_lang)) {
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.error"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
ImGui::NewLine();
ImGui::Separator();
@ -46,8 +46,8 @@ namespace hex {
ImGui::EndPopup();
}
ImGui::SetNextWindowSize(ImVec2(200, 100) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.fatal"_lang, nullptr)) {
ImGui::SetNextWindowSizeConstraints(ImVec2(400, 100) * SharedData::globalScale, ImVec2(600, 300) * SharedData::globalScale);
if (ImGui::BeginPopupModal("hex.common.fatal"_lang, nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::TextWrapped("%s", SharedData::popupMessage.c_str());
ImGui::NewLine();
ImGui::Separator();

View File

@ -25,7 +25,7 @@ using namespace std::literals::chrono_literals;
namespace hex::init {
WindowSplash::WindowSplash(int &argc, char **&argv) {
WindowSplash::WindowSplash(int &argc, char **&argv) : m_window(nullptr) {
SharedData::mainArgc = argc;
SharedData::mainArgv = argv;
@ -57,7 +57,7 @@ namespace hex::init {
{
std::lock_guard guard(this->m_progressMutex);
this->m_progress += 1.0F / m_tasks.size();
this->m_progress += 1.0F / this->m_tasks.size();
}
}
@ -69,9 +69,7 @@ namespace hex::init {
}
bool WindowSplash::loop() {
ImGui::Texture splashTexture;
splashTexture = ImGui::LoadImageFromMemory(splash, splash_size);
ImGui::Texture splashTexture = ImGui::LoadImageFromMemory(splash, splash_size);
if (splashTexture == nullptr) {
log::fatal("Could not load splash screen image!");
@ -168,10 +166,14 @@ namespace hex::init {
glfwWindowHint(GLFW_FLOATING, GLFW_TRUE);
if (GLFWmonitor *monitor = glfwGetPrimaryMonitor(); monitor != nullptr) {
float xscale, yscale;
glfwGetMonitorContentScale(monitor, &xscale, &yscale);
float xScale = 0, yScale = 0;
glfwGetMonitorContentScale(monitor, &xScale, &yScale);
SharedData::globalScale = SharedData::fontScale = std::midpoint(xscale, yscale);
SharedData::globalScale = SharedData::fontScale = std::midpoint(xScale, yScale);
if (SharedData::globalScale <= 0) {
SharedData::globalScale = 1.0;
}
}
this->m_window = glfwCreateWindow(640 * SharedData::globalScale, 400 * SharedData::globalScale, "ImHex", nullptr, nullptr);

View File

@ -13,6 +13,8 @@
#include <filesystem>
#include <functional>
#include <nlohmann/json.hpp>
#include <microtar.h>
#include <hex/helpers/file.hpp>
namespace hex {
@ -34,7 +36,7 @@ namespace hex {
this->refresh();
}
auto drawTab = [this](auto title, ImHexPath pathType, auto &content, std::function<void()> downloadDoneCallback) {
auto drawTab = [this](auto title, ImHexPath pathType, auto &content, std::function<void(const StoreEntry&)> downloadDoneCallback) {
if (ImGui::BeginTabItem(title)) {
if (ImGui::BeginTable("##pattern_language", 3, ImGuiTableFlags_ScrollY | ImGuiTableFlags_Borders | ImGuiTableFlags_SizingStretchSame | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupScrollFreeze(0, 1);
@ -66,7 +68,34 @@ namespace hex {
if (response.code == 200) {
entry.installed = true;
entry.hasUpdate = false;
downloadDoneCallback();
if (entry.isFolder) {
mtar_t ctx;
mtar_open(&ctx, this->m_downloadPath.string().c_str(), "r");
mtar_header_t header;
auto extractBasePath = this->m_downloadPath.parent_path() / this->m_downloadPath.stem();
while (mtar_read_header(&ctx, &header) != MTAR_ENULLRECORD) {
auto filePath = extractBasePath / fs::path(header.name);
fs::create_directories(filePath.parent_path());
File outputFile(filePath.string(), File::Mode::Create);
std::vector<u8> buffer(0x10000);
for (u64 offset = 0; offset < header.size; offset += buffer.size()) {
auto readSize = std::min(buffer.size(), header.size - offset);
mtar_read_data(&ctx, buffer.data(), readSize);
buffer.resize(readSize);
outputFile.write(buffer);
}
mtar_next(&ctx);
}
mtar_finalize(&ctx);
mtar_close(&ctx);
}
downloadDoneCallback(entry);
} else
log::error("Download failed!");
@ -103,12 +132,17 @@ namespace hex {
};
if (ImGui::BeginTabBar("storeTabs")) {
drawTab("hex.view.store.tab.patterns"_lang, ImHexPath::Patterns, this->m_patterns, []{});
drawTab("hex.view.store.tab.libraries"_lang, ImHexPath::PatternsInclude, this->m_includes, []{});
drawTab("hex.view.store.tab.magics"_lang, ImHexPath::Magic, this->m_magics, []{
auto extractTar = []{
};
drawTab("hex.view.store.tab.patterns"_lang, ImHexPath::Patterns, this->m_patterns, [](auto){});
drawTab("hex.view.store.tab.libraries"_lang, ImHexPath::PatternsInclude, this->m_includes, [](auto){});
drawTab("hex.view.store.tab.magics"_lang, ImHexPath::Magic, this->m_magics, [](auto){
magic::compile();
});
drawTab("hex.view.store.tab.constants"_lang, ImHexPath::Constants, this->m_constants, []{});
drawTab("hex.view.store.tab.constants"_lang, ImHexPath::Constants, this->m_constants, [](auto){});
drawTab("hex.view.store.tab.yara"_lang, ImHexPath::Yara, this->m_yara, [](auto){});
ImGui::EndTabBar();
}
@ -119,6 +153,7 @@ namespace hex {
this->m_includes.clear();
this->m_magics.clear();
this->m_constants.clear();
this->m_yara.clear();
this->m_apiRequest = this->m_net.getString(ImHexApiURL + "/store"s);
}
@ -135,10 +170,10 @@ namespace hex {
for (auto &entry : storeJson[name]) {
// Check if entry is valid
if (entry.contains("name") && entry.contains("desc") && entry.contains("file") && entry.contains("url") && entry.contains("hash")) {
if (entry.contains("name") && entry.contains("desc") && entry.contains("file") && entry.contains("url") && entry.contains("hash") && entry.contains("folder")) {
// Parse entry
StoreEntry storeEntry = { entry["name"], entry["desc"], entry["file"], entry["url"], entry["hash"], false, false, false };
StoreEntry storeEntry = { entry["name"], entry["desc"], entry["file"], entry["url"], entry["hash"], entry["folder"],false, false, false };
// Check if file is installed already or has an update available
for (const auto &folder : hex::getPath(pathType)) {
@ -170,6 +205,7 @@ namespace hex {
parseStoreEntries(json, "includes", ImHexPath::PatternsInclude, this->m_includes);
parseStoreEntries(json, "magic", ImHexPath::Magic, this->m_magics);
parseStoreEntries(json, "constants", ImHexPath::Constants, this->m_constants);
parseStoreEntries(json, "yara", ImHexPath::Yara, this->m_yara);
}
this->m_apiRequest = { };
@ -208,11 +244,13 @@ namespace hex {
void ViewStore::download(ImHexPath pathType, const std::string &fileName, const std::string &url, bool update) {
if (!update) {
this->m_download = this->m_net.downloadFile(url, hex::getPath(pathType).front() / fs::path(fileName));
this->m_downloadPath = hex::getPath(pathType).front() / fs::path(fileName);
this->m_download = this->m_net.downloadFile(url, this->m_downloadPath);
} else {
for (const auto &path : hex::getPath(pathType)) {
auto fullPath = path / fs::path(fileName);
if (fs::exists(fullPath)) {
this->m_downloadPath = fullPath;
this->m_download = this->m_net.downloadFile(url, fullPath);
}
}