Code Monkey home page Code Monkey logo

hxd-plugin-framework's Introduction

Plugin framework for HxD's data inspector

This plugin framework allows to create extensions for HxD's data inspector, as plugin DLLs, which can be written in Delphi, C, C++, or PureBasic (external).

Any other language that can create DLLs and export C like functions should work equally well (but you would need to translate the C headers).

Currently, you can write data type converters, such that byte sequences can be translated to strings and strings to byte sequences.

Features

  • Variable width encodings (such as UTF-8 code points, or x86 assembly) as well as fixed width encodings (such as 32-bit integers, or single precision floats) are supported.

  • You can override the handling of byte reordering (little endian vs. big endian) to customize it for your type specific requirements, such as mixed endianness.

  • Finally, navigating to the next/previous or first/last "array" element is supported by default, with the additional ability to customize to type specific needs (especially necessary for variable width encodings).

Coding conventions

Identifiers are named in a Delphi-typical manner, also in the C and C++ versions, to make it easier to keep the interfaces in all languages in synch (the original being in Delphi, just like HxD itself). That means types begin with a T and pointer types begin with a P. Fields (member variables in C++) begin with an F.

This concerns contributions to the plugin framework itself. You are free to use your own coding conventions for your plugins, obviously.

Quick start

There are example projects that make it simple to quickly get you started writing your data type converter. See DataInspectorPluginExample.dproj for Delphi, and DataInspectorPluginExample.sln for C/C++ (Visual Studio).

Make sure to place the created DLL in the Plugins folder, which is at the same level as HxD.exe. Then simply start HxD, and your newly defined types will appear in the data inspector.

If they are missing or have the wrong name, right-click on the data inspector, select "Options..." and click "Reset". A 32 bit and 64 bit version of the plugin is needed to support HxD fully; put the right one in the Plugins folder for the bitness of HxD you have installed.

Folder structure:

HxD.exe
Plugins\<AnyName>.dll

(Both files, HxD.exe and the plugin DLL, must be either 32 or 64 bit.)

Use HxD 2.5 or higher to test / develop your plugins (using the portable is simpler, since creating a Plugins directory does not require admin rights):

https://mh-nexus.de/en/downloads.php?product=HxD20

Non-OO interface: plain Delphi / plain C

There is a basic procedural API, that works in plain Delphi and C, and can be found in DataInspectorPluginInterface.inc and DataInspectorPluginInterface.h, respectively. DataInspectorPluginInterface.inc/.h declares all the functions that need to be exported. Additional types are declared in DataInspectorShared.pas/.h.

Memory management is simple: the plugin DLL manages its own memory and HxD does so with its own, as well. Therefore, there is no need to use a shared/central memory manager. HxD guarantees that every string or byte array, that is returned by the plugin, will be copied immediately, after the function call. So it is sufficient to return references to strings or byte arrays, and free them on the next call of the same function.

For example, BytesToStr() returns a string. Store the result in a global variable or a member variable, and return a reference to it. Keep the variable unchanged until BytesToStr() is called again.

See the OO interface for an implementation of this strategy, if you need more details, or refer to the plain C example. If possible, use the simple OO solution directly (see below).

OO interface (more comfortable): Delphi / C++

A more comfortable OO solution is provided in DataInspectorPluginServer.pas and DataInspectorPluginServer.h/.cpp.

The simple base class TExternalDataTypeConverter presents a nicely abstracted interface, from which you can derive a class for your type converter, and only need to override a couple methods to implement it.

Calling RegisterDataTypeConverter() in DllMain() is the only remaining task.

See the example projects for details!

The DataInspectorPluginServer unit/module handles everything else for you: from providing implementations for the necessary functions, that define the raw plugin interface, to handling memory. It also automatically creates class instances of the right TExternalDataTypeConverter descendants, and translates between the plain data types / function pointers and class instances / methods, seamlessly.

Implementation guidelines

For details on what the data type conversion functions have to do exactly, and what the interface contracts are, check out the implementation guidelines.

Debugging

Debugging works like debugging any DLL project.

  • Delphi

    • Specify HxD.exe with its full path as the host application in the IDE (Start|Parameter...). Also set the working directory to the dir of HxD.exe.
  • VC++

    • Specify HxD.exe with its full path as command (Project options|Debugging|Command). Also set the working directory to the dir of HxD.exe.

Note: Make sure that the generated DLL is really created in the Plugins folder of HxD. You have to adapt the project options accordingly!

Publishing your plugin

If you wrote a plugin that you would like to share (link from here or my website), please contact me by mail, so we can discuss the details.

Even if you don't intend to publish it, letting me know what you did, would still be interesting to know, as that's part of the motivation to make HxD.

Open source plugins

License

Copyright (C) 2019-2021 Maël Hörz

The plugin framework is licensed under the MPL. But you are welcome to contact me if another open source license would be more suitable.

Contact

HxD hex and disk editor is available at: http://mh-nexus.de/hxd

See the website for ways to contact me, Maël Hörz, by mail.

For bugs and feature requests related to plugins, please use the issue tracker on GitHub.

For other topics related to HxD, please use the forum: https://forum.mh-nexus.de

hxd-plugin-framework's People

Contributors

maelh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

hxd-plugin-framework's Issues

[Suggestion] Add a `Version()` function to the framework

The changes introduced by commits 1fd3ef0/05ccf3e and c3abba5/86afeb6 include breaking changes of existing APIs. This means that, when a new version of HxD is released that incorporates these new additions in the plugin framework, old plugins will have undefined behaviour. Unless there's a way to check the format of arguments that a DLL's function expects,

I suggest adding a Version() function to the framework which would report to HxD what version of the framework a plugin targets. From there, if a loaded plugin reports an unexpected target version, HxD can either adapt to the plugin (if it targets an older version) or reject it, to prevent a plugin from misconfiguring itself, crashing, or producing some other undefined behaviour.

Though I will note, in the event that you won't have HxD adapt to plugins targeting older versions of the API, I'd highly encourage you to instead incorporate changes to existing APIs in new functions, so old plugins will always keep working without any surprises or requiring additional work.

HxD 'Plugins' folder not being looked for specifically relative to the HxD Application folder?

Hi Maël,

A user of my Disassembler Plugin (exodustx0), has noted an issue when running HxD via the Windows "Open with" context menu.
i.e. When opening HxD via right clicking on the target file.

When this is done, the Plugin does not appear to be activated by HxD.

Thinking the issue was just a problem with my Plugin itself not correctly locating it's own CPU Definitions (which default to being in the same 'Plugins' relative directory), I started implementing changes to ensure relative directory references also look relative to the actual Application path.

However, in testing I determined that in the case of "Open with" context menu use, my Plugin wasn't even being called/initialised by HxD.

i.e. It appeared HxD was not finding the HxD Applications directory's 'Plugins' subfolder, and therefore not intialising the Plugins contained therein.

I am now wondering if HxD is ensuring it looks for it's 'Plugins' folder relative to the Applcation path, to cater for cases where HxD is not being run directly (e.g. when run via the File Manager's "Open with" context menu)?

For interest, in first attempting to resolve this in my Plugin, I locate the actual Application's path via the either of the following:

  ApplicationPath := ExtractFilePath(Application.ExeName);
  // or
  ApplicationPath := ExtractFilePath(Paramstr(0));

...which I have verified returns the expected HxD installation folder.

In my Plugin's case, I also determine if the user provided CPU defintions path (DefinitionFilePath), is a Relative path or a Fully Defined path via:

System.IOUtils.TPath.IsPathRooted(IniSettings[CurrentDasmType].DefinitionFilePath)

But, as I say, my testing of the changes I need to make within my Plugin (essentially to not assume a relative folder reference is relative to the Windows Current Path), came to a halt when I discovered that HxD itself appears to not be calling/initialising my Plugin at all, when called via the Windows "Open with" contect menu.

Hope you can assist with zeroing in on the problem, so that I can find a solution to ensure the 'Plugins' relative folder (or any HxD application folder relative reference), is always being correctly located.

Compare tool

First of all, sorry if this doesnt fit here. I havent found any other place to ask/request for HxD plugins/features.

Would be nice if, when using the compare tool, you highlight all the differences between the files.

BytesToStr should report selection details

It would be nice if the BytesToStr function had a selection length parameter. This way the plug-in could choose to display only exact matches in the inspector.

... BytesToStr(
    void* ThisPtr,
    uint8_t* Bytes,
    int ByteCount,
    TFormattingOptions FormattingOptions,
    int* ConvertedByteCount,
    const wchar_t** ConvertedStr,
    int ByteSelectionCount
);

ByteSelectionCount would be 0 if there is no selection, just a cursor position change. This is the way the API works today. To only display exact matches a plug-in could choose to do something like:

if (ByteCount >= 4 && (ByteSelectionCount == 0 || ByteSelectionCount == 4))
{
  const wchar_t* match = LookupUINT32Constants(Bytes);
  if (match) ...
} 
if (ByteCount >= 2 && (ByteSelectionCount == 0 || ByteSelectionCount == 2))
{
  ...
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.