mirror of
https://github.com/x64dbg/DataExplorer.git
synced 2026-11-10 05:21:27 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
904b75dc41 | ||
|
|
a15241cf80 |
No files matched your search
@@ -4,6 +4,7 @@
|
||||
#include <QDir>
|
||||
#include <QTextBlock>
|
||||
#include <QSettings>
|
||||
#include <QAction>
|
||||
#include <shlwapi.h>
|
||||
#include "QtPlugin.h"
|
||||
#include "pluginmain.h"
|
||||
@@ -112,7 +113,11 @@ DataExplorerDialog::DataExplorerDialog(QWidget* parent) : QDialog(parent), ui(ne
|
||||
|
||||
// Restore settings
|
||||
{
|
||||
#ifdef _WIN64
|
||||
QSettings settings("DataExplorer");
|
||||
#else
|
||||
QSettings settings("DataExplorer32");
|
||||
#endif // _WIN64
|
||||
|
||||
auto cursor = ui->codeEdit->textCursor();
|
||||
auto savedPosition = settings.value("cursor", cursor.position()).toInt();
|
||||
@@ -136,7 +141,11 @@ DataExplorerDialog::~DataExplorerDialog()
|
||||
|
||||
void DataExplorerDialog::closeEvent(QCloseEvent* event)
|
||||
{
|
||||
#ifdef _WIN64
|
||||
QSettings settings("DataExplorer");
|
||||
#else
|
||||
QSettings settings("DataExplorer32");
|
||||
#endif // _WIN64
|
||||
settings.setValue("code", ui->codeEdit->toPlainText());
|
||||
settings.setValue("cursor", ui->codeEdit->textCursor().position());
|
||||
settings.setValue("geometry", saveGeometry());
|
||||
|
||||
Generated
+13
-2
@@ -7,6 +7,9 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
message(FATAL_ERROR "In-tree builds are not supported. Run CMake from a separate directory: cmake -B build")
|
||||
endif()
|
||||
|
||||
# Enable support for MSVC_RUNTIME_LIBRARY
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
|
||||
set(CMKR_ROOT_PROJECT OFF)
|
||||
if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
set(CMKR_ROOT_PROJECT ON)
|
||||
@@ -22,6 +25,10 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
|
||||
|
||||
# Create a configure-time dependency on cmake.toml to improve IDE support
|
||||
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS cmake.toml)
|
||||
if(NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# Options
|
||||
@@ -29,18 +36,22 @@ option(LIBPL_ENABLE_CLI "" OFF)
|
||||
|
||||
project(PatternLanguage)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
add_compile_definitions(FMT_USE_CONSTEVAL=0)
|
||||
endif()
|
||||
|
||||
include(FetchContent)
|
||||
|
||||
# Fix warnings about DOWNLOAD_EXTRACT_TIMESTAMP
|
||||
if(POLICY CMP0135)
|
||||
cmake_policy(SET CMP0135 NEW)
|
||||
endif()
|
||||
message(STATUS "Fetching PatternLanguage (4e74b705f68a24377144d11c9e5143e4935cf1e0)...")
|
||||
message(STATUS "Fetching PatternLanguage (a9a93ab56b7808cb5d551ff94d7bad8a3c963618)...")
|
||||
FetchContent_Declare(PatternLanguage
|
||||
GIT_REPOSITORY
|
||||
"https://github.com/WerWolv/PatternLanguage"
|
||||
GIT_TAG
|
||||
4e74b705f68a24377144d11c9e5143e4935cf1e0
|
||||
a9a93ab56b7808cb5d551ff94d7bad8a3c963618
|
||||
)
|
||||
FetchContent_MakeAvailable(PatternLanguage)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# PatternLanguage
|
||||
|
||||
Requirements:
|
||||
- Zig 0.13 (installed in `PATH`)
|
||||
- Zig 0.15 (installed in `PATH`)
|
||||
- CMake
|
||||
- Ninja
|
||||
|
||||
@@ -9,6 +9,17 @@ Compilation:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/mrexodia/zig-cross
|
||||
cmake -B build -G Ninja --toolchain zig-cross/x86_64-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build
|
||||
cmake -B build64 -G Ninja --toolchain zig-cross/x86_64-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build64
|
||||
cmake -B build32 -G Ninja --toolchain zig-cross/x86-windows-gnu.cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
cmake --build build32
|
||||
```
|
||||
|
||||
With Visual Studio:
|
||||
|
||||
```
|
||||
cmake -B build-vs64 -A x64
|
||||
cmake --build build-vs64 --config Release
|
||||
cmake -B build-vs32 -A Win32
|
||||
cmake --build build-vs32 --config Release
|
||||
```
|
||||
@@ -1,9 +1,15 @@
|
||||
[project]
|
||||
name = "PatternLanguage"
|
||||
msvc-runtime = "static"
|
||||
cmake-after = """
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES \"Clang\" AND CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||
add_compile_definitions(FMT_USE_CONSTEVAL=0)
|
||||
endif()
|
||||
"""
|
||||
|
||||
[fetch-content.PatternLanguage]
|
||||
git = "https://github.com/WerWolv/PatternLanguage"
|
||||
tag = "4e74b705f68a24377144d11c9e5143e4935cf1e0"
|
||||
tag = "a9a93ab56b7808cb5d551ff94d7bad8a3c963618"
|
||||
|
||||
[options]
|
||||
LIBPL_ENABLE_CLI = false
|
||||
|
||||
@@ -160,30 +160,28 @@ public:
|
||||
private:
|
||||
static std::string debugPattern(const char *title, const ptrn::Pattern *pattern)
|
||||
{
|
||||
using ::fmt::format;
|
||||
|
||||
std::string p;
|
||||
p += format("{}(\n", title);
|
||||
p += format(" offset = {:#x}\n", pattern->getOffset());
|
||||
p += format(" size = {:#x}\n", pattern->getSize());
|
||||
p += format(" variableName = {}\n", pattern->getVariableName()); // name of the variable (or var[array_idx])
|
||||
p += format(" displayName = {}\n",
|
||||
p += fmt::format("{}(\n", title);
|
||||
p += fmt::format(" offset = {:#x}\n", pattern->getOffset());
|
||||
p += fmt::format(" size = {:#x}\n", pattern->getSize());
|
||||
p += fmt::format(" variableName = {}\n", pattern->getVariableName()); // name of the variable (or var[array_idx])
|
||||
p += fmt::format(" displayName = {}\n",
|
||||
pattern->getDisplayName()); // [[name("Whatever")]] (falls back to variable name)
|
||||
p += format(" formattedName = {}\n",
|
||||
p += fmt::format(" formattedName = {}\n",
|
||||
pattern->getFormattedName()); // formatted type name (falls back to type name)
|
||||
p += format(" typeName = {}\n", pattern->getTypeName()); // name of the type (without struct or array size)
|
||||
p += format(" line = {}\n", pattern->getLine()); // source line
|
||||
p += format(" visibility = {}\n", (int) pattern->getVisibility());
|
||||
p += fmt::format(" typeName = {}\n", pattern->getTypeName()); // name of the type (without struct or array size)
|
||||
p += fmt::format(" line = {}\n", pattern->getLine()); // source line
|
||||
p += fmt::format(" visibility = {}\n", (int) pattern->getVisibility());
|
||||
//p += format(" endian = {}\n", (int) pattern->getEndian());
|
||||
//p += format(" section = {}\n", pattern->getSection());
|
||||
p += format(" comment = {}\n", pattern->getComment());
|
||||
p += format(" color = {:#x}\n", pattern->getColor());
|
||||
p += format(" sealed = {}\n", pattern->isSealed());
|
||||
p += format(")");
|
||||
p += fmt::format(" comment = {}\n", pattern->getComment());
|
||||
p += fmt::format(" color = {:#x}\n", pattern->getColor());
|
||||
p += fmt::format(" sealed = {}\n", pattern->isSealed());
|
||||
p += fmt::format(")");
|
||||
return p;
|
||||
}
|
||||
|
||||
TreeNode apiVisit(const char *reason, const ptrn::Pattern *pattern, const std::string &value)
|
||||
TreeNode apiVisit(const char *reason, ptrn::Pattern *pattern, const std::string &value)
|
||||
{
|
||||
// TODO: array elements,
|
||||
auto formattedTypeName = pattern->getFormattedName();
|
||||
@@ -204,7 +202,7 @@ private:
|
||||
return m_args->visit(m_args->userdata, treeTop(), &info);
|
||||
}
|
||||
|
||||
static std::string readFormatter(const ptrn::Pattern *pattern)
|
||||
static std::string readFormatter(ptrn::Pattern *pattern)
|
||||
{
|
||||
if (const auto &functionName = pattern->getReadFormatterFunction(); !functionName.empty())
|
||||
{
|
||||
@@ -216,7 +214,7 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
void formatValue(const ptrn::Pattern *pattern)
|
||||
void formatValue(ptrn::Pattern *pattern)
|
||||
{
|
||||
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
|
||||
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
|
||||
@@ -228,25 +226,25 @@ private:
|
||||
|
||||
value = std::visit(wolv::util::overloaded{
|
||||
// TODO: print full-width
|
||||
[&](std::integral auto value) -> std::string
|
||||
{ return ::fmt::format("0x{:0{}X}\t{}", value, pattern->getSize() * 2, value); },
|
||||
[&](pl::integral auto value) -> std::string
|
||||
{ return fmt::format("0x{:0{}X}\t{}", value, pattern->getSize() * 2, value); },
|
||||
[&](std::floating_point auto value) -> std::string
|
||||
{ return ::fmt::format("{}", value); },
|
||||
{ return fmt::format("{}", value); },
|
||||
[&](const std::string &value) -> std::string
|
||||
{ return ::fmt::format("\"{}\"", value); },
|
||||
{ return fmt::format("\"{}\"", value); },
|
||||
[&](bool value) -> std::string
|
||||
{ return value ? "true" : "false"; },
|
||||
[&](char value) -> std::string
|
||||
{ return ::fmt::format("'{}'", value); },
|
||||
{ return fmt::format("'{}'", value); },
|
||||
[&](const std::shared_ptr<ptrn::Pattern> &value) -> std::string
|
||||
{ return ::fmt::format("\"{}\"", value->toString()); },
|
||||
{ return fmt::format("\"{}\"", value->toString()); },
|
||||
}, pattern->getValue());
|
||||
}
|
||||
|
||||
apiVisit("formatValue", pattern, value);
|
||||
}
|
||||
|
||||
void formatString(const ptrn::Pattern *pattern)
|
||||
void formatString(ptrn::Pattern *pattern)
|
||||
{
|
||||
if (pattern->getVisibility() == ptrn::Visibility::Hidden) return;
|
||||
if (pattern->getVisibility() == ptrn::Visibility::TreeHidden) return;
|
||||
@@ -333,16 +331,16 @@ PatternStatus PatternRun(const PatternRunArgs *args)
|
||||
enum core::LogConsole::Level;
|
||||
|
||||
case Debug:
|
||||
::fmt::print("[DEBUG] {}\n", stripped);
|
||||
fmt::print("[DEBUG] {}\n", stripped);
|
||||
break;
|
||||
case Info:
|
||||
::fmt::print("[INFO] {}\n", stripped);
|
||||
fmt::print("[INFO] {}\n", stripped);
|
||||
break;
|
||||
case Warning:
|
||||
::fmt::print("[WARN] {}\n", stripped);
|
||||
fmt::print("[WARN] {}\n", stripped);
|
||||
break;
|
||||
case Error:
|
||||
::fmt::print("[ERROR] {}\n", stripped);
|
||||
fmt::print("[ERROR] {}\n", stripped);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -353,7 +351,26 @@ PatternStatus PatternRun(const PatternRunArgs *args)
|
||||
for (size_t i = 0; i < includePaths.size(); i++)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
includePaths[i] = wolv::util::utf8ToWstring(args->includes_data[i], {});
|
||||
const auto setIncludePath = [&](const auto &includePath)
|
||||
{
|
||||
using IncludePathType = std::remove_cvref_t<decltype(includePath)>;
|
||||
if constexpr (requires(const IncludePathType &path) { path.has_value(); })
|
||||
{
|
||||
if (includePath.has_value())
|
||||
{
|
||||
includePaths[i] = *includePath;
|
||||
}
|
||||
else
|
||||
{
|
||||
includePaths[i] = args->includes_data[i];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
includePaths[i] = includePath;
|
||||
}
|
||||
};
|
||||
setIncludePath(wolv::util::utf8ToWstring(args->includes_data[i]));
|
||||
#else
|
||||
includePaths[i] = args->includes_data[i];
|
||||
#endif
|
||||
@@ -385,7 +402,7 @@ PatternStatus PatternRun(const PatternRunArgs *args)
|
||||
{
|
||||
filename = api::Source::DefaultSource;
|
||||
}
|
||||
if (!runtime.executeString(args->source, filename))
|
||||
if (const auto exitCode = runtime.executeString(args->source, filename); exitCode != 0)
|
||||
{
|
||||
auto compileErrors = runtime.getCompileErrors();
|
||||
if (!compileErrors.empty())
|
||||
@@ -423,22 +440,35 @@ PatternStatus PatternRun(const PatternRunArgs *args)
|
||||
}
|
||||
else
|
||||
{
|
||||
auto error = runtime.getEvalError().value();
|
||||
if (args->eval_error == nullptr)
|
||||
std::string pretty;
|
||||
EvalError cerror = {
|
||||
.location = {
|
||||
.file = filename,
|
||||
.line = 0,
|
||||
.column = 0,
|
||||
.length = 0,
|
||||
},
|
||||
.pretty = nullptr,
|
||||
};
|
||||
|
||||
if (const auto &error = runtime.getEvalError(); error.has_value())
|
||||
{
|
||||
fmt::print("Pattern Error: {}:{} -> {}\n", error.line, error.column, error.message);
|
||||
cerror.location.line = error->line;
|
||||
cerror.location.column = error->column;
|
||||
pretty = error->message;
|
||||
}
|
||||
else
|
||||
{
|
||||
pretty = fmt::format("Pattern execution failed with exit code {} without an evaluation error.", exitCode);
|
||||
}
|
||||
|
||||
cerror.pretty = pretty.c_str();
|
||||
if (args->eval_error == nullptr)
|
||||
{
|
||||
fmt::print("Pattern Error: {}:{} -> {}\n", cerror.location.line, cerror.location.column, pretty);
|
||||
}
|
||||
else
|
||||
{
|
||||
EvalError cerror = {
|
||||
.location = {
|
||||
.file = filename,
|
||||
.line = error.line,
|
||||
.column = error.column,
|
||||
.length = 0,
|
||||
},
|
||||
.pretty = error.message.c_str(),
|
||||
};
|
||||
args->eval_error(args->userdata, &cerror);
|
||||
}
|
||||
|
||||
@@ -457,7 +487,14 @@ PatternStatus PatternRun(const PatternRunArgs *args)
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
args->log_handler(args->userdata, LogLevelError, e.what());
|
||||
if (args->log_handler != nullptr)
|
||||
{
|
||||
args->log_handler(args->userdata, LogLevelError, e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt::print("[ERROR] {}\n", e.what());
|
||||
}
|
||||
return PatternEvalError;
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,6 @@ The DataExplorer plugin integrates the [pattern language](https://docs.werwolv.n
|
||||
- Install the plugin so you have:
|
||||
```
|
||||
<x64dbg-dir>/x64/plugins/DataExplorer/DataExplorer.dp64
|
||||
<x64dbg-dir>/x32/plugins/DataExplorer/DataExplorer.dp32
|
||||
```
|
||||
- Launch x64dbg and open the plugin via `Plugins -> DataExplorer -> Open` (Ctrl+Shift+D)
|
||||
|
||||
**Note**: There is no 32-bit support and it is not planned.
|
||||
Reference in new issue
Block a user