mirror of https://github.com/WerWolv/ImHex.git
impr: Get rid of cimgui shared library by hooking pinvoke handler
This commit is contained in:
parent
876f091244
commit
fdf01dfb50
|
@ -123,7 +123,6 @@ cp -a lib/third_party/xdgpp/LICENSE %{buildroot
|
|||
%{_datadir}/pixmaps/%{name}.png
|
||||
%{_datadir}/applications/%{name}.desktop
|
||||
%{_libdir}/libimhex.so*
|
||||
%{_libdir}/cimgui.so*
|
||||
%{_libdir}/%{name}/
|
||||
%{_metainfodir}/net.werwolv.%{name}.metainfo.xml
|
||||
|
||||
|
|
|
@ -664,6 +664,12 @@ namespace hex {
|
|||
*/
|
||||
std::optional<InitialWindowProperties> getInitialWindowProperties();
|
||||
|
||||
/**
|
||||
* @brief Gets the module handle of libimhex
|
||||
* @return Module handle
|
||||
*/
|
||||
void* getLibImHexModuleHandle();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -331,4 +331,14 @@ namespace hex {
|
|||
|
||||
[[nodiscard]] std::string formatSystemError(i32 error);
|
||||
|
||||
/**
|
||||
* Gets the shared library handle for a given pointer
|
||||
* @param symbol Pointer to any function or variable in the shared library
|
||||
* @return The module handle
|
||||
* @warning Important! Calling this function on functions defined in other modules will return the handle of the current module!
|
||||
* This is because you're not actually passing a pointer to the function in the other module but rather a pointer to a thunk
|
||||
* that is defined in the current module.
|
||||
*/
|
||||
[[nodiscard]] void* getContainingModule(void* symbol);
|
||||
|
||||
}
|
||||
|
|
|
@ -599,6 +599,11 @@ namespace hex {
|
|||
return impl::s_initialWindowProperties;
|
||||
}
|
||||
|
||||
void* getLibImHexModuleHandle() {
|
||||
return hex::getContainingModule((void*)&getLibImHexModuleHandle);
|
||||
}
|
||||
|
||||
|
||||
const std::map<std::string, std::string>& getInitArguments() {
|
||||
return *impl::s_initArguments;
|
||||
}
|
||||
|
|
|
@ -344,5 +344,4 @@ namespace hex {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
#include <wolv/utils/guards.hpp>
|
||||
#elif defined(OS_LINUX)
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <hex/helpers/utils_linux.hpp>
|
||||
#elif defined(OS_MACOS)
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <hex/helpers/utils_macos.hpp>
|
||||
#elif defined(OS_WEB)
|
||||
#include "emscripten.h"
|
||||
|
@ -784,4 +786,23 @@ namespace hex {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
void* getContainingModule(void* symbol) {
|
||||
#if defined(OS_WINDOWS)
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (VirtualQuery(symbol, &mbi, sizeof(mbi)))
|
||||
return mbi.AllocationBase;
|
||||
|
||||
return nullptr;
|
||||
#elif !defined(OS_WEB)
|
||||
Dl_info info;
|
||||
if (dladdr(symbol, nullptr) == 0)
|
||||
return nullptr;
|
||||
|
||||
return dlopen(info.dli_fname, RTLD_LAZY);
|
||||
#else
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
|
@ -4,6 +4,7 @@
|
|||
#include <imgui_internal.h>
|
||||
#include <implot.h>
|
||||
#include <implot_internal.h>
|
||||
#include <cimgui.h>
|
||||
#include <opengl_support.h>
|
||||
|
||||
#undef IMGUI_DEFINE_MATH_OPERATORS
|
||||
|
|
|
@ -12,4 +12,4 @@ add_subdirectory(imnodes)
|
|||
add_subdirectory(custom)
|
||||
add_subdirectory(ColorTextEditor)
|
||||
|
||||
set(IMGUI_LIBRARIES imgui_imgui imgui_implot imgui_imnodes imgui_custom imgui_color_text_editor PARENT_SCOPE)
|
||||
set(IMGUI_LIBRARIES imgui_imgui imgui_cimgui imgui_implot imgui_imnodes imgui_custom imgui_color_text_editor PARENT_SCOPE)
|
|
@ -9,7 +9,7 @@ if (IMHEX_STATIC_LINK_PLUGINS)
|
|||
endif()
|
||||
|
||||
if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
||||
add_library(imgui_cimgui SHARED
|
||||
add_library(imgui_cimgui OBJECT
|
||||
source/cimgui.cpp
|
||||
)
|
||||
|
||||
|
@ -17,13 +17,7 @@ if (NOT IMHEX_EXTERNAL_PLUGIN_BUILD)
|
|||
include
|
||||
)
|
||||
|
||||
target_link_libraries(imgui_cimgui PRIVATE imgui_includes libimhex)
|
||||
set_target_properties(imgui_cimgui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
set_target_properties(imgui_cimgui PROPERTIES OUTPUT_NAME "cimgui")
|
||||
set_target_properties(imgui_cimgui PROPERTIES PREFIX "")
|
||||
target_link_libraries(imgui_cimgui PRIVATE imgui_includes)
|
||||
add_dependencies(imhex_all imgui_cimgui)
|
||||
|
||||
install(FILES "$<TARGET_FILE:imgui_cimgui>" DESTINATION "${CMAKE_INSTALL_LIBDIR}" PERMISSIONS ${LIBRARY_PERMISSIONS})
|
||||
set_target_properties(imgui_cimgui PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <nethost.h>
|
||||
#include <coreclr_delegates.h>
|
||||
#include <hostfxr.h>
|
||||
#include <imgui.h>
|
||||
#include <hex/api/plugin_manager.hpp>
|
||||
|
||||
#include <hex/helpers/fs.hpp>
|
||||
#include <wolv/io/fs.hpp>
|
||||
|
@ -22,6 +24,9 @@
|
|||
#include <wolv/utils/string.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
|
||||
extern "C" void igSetCurrentContext(ImGuiContext* ctx);
|
||||
|
||||
namespace hex::script::loader {
|
||||
|
||||
|
@ -64,6 +69,20 @@ namespace hex::script::loader {
|
|||
hostfxr_initialize_for_runtime_config_fn hostfxr_initialize_for_runtime_config = nullptr;
|
||||
hostfxr_get_runtime_delegate_fn hostfxr_get_runtime_delegate = nullptr;
|
||||
hostfxr_close_fn hostfxr_close = nullptr;
|
||||
hostfxr_set_runtime_property_value_fn hostfxr_set_runtime_property_value = nullptr;
|
||||
hostfxr_set_error_writer_fn hostfxr_set_error_writer = nullptr;
|
||||
|
||||
void* pInvokeOverride(const char *libraryName, const char *symbolName) {
|
||||
auto library = std::string_view(libraryName);
|
||||
if (library == "cimgui") {
|
||||
return getExport<void*>(ImHexApi::System::getLibImHexModuleHandle(), symbolName);
|
||||
} else if (library == "ImHex") {
|
||||
auto address = getExport<void*>(hex::getContainingModule((void*)&pInvokeOverride), symbolName);
|
||||
return address;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool loadHostfxr() {
|
||||
#if defined(OS_WINDOWS)
|
||||
|
@ -108,13 +127,26 @@ namespace hex::script::loader {
|
|||
= getExport<hostfxr_get_runtime_delegate_fn>(hostfxrLibrary, "hostfxr_get_runtime_delegate");
|
||||
hostfxr_close
|
||||
= getExport<hostfxr_close_fn>(hostfxrLibrary, "hostfxr_close");
|
||||
|
||||
hostfxr_set_runtime_property_value
|
||||
= getExport<hostfxr_set_runtime_property_value_fn>(hostfxrLibrary, "hostfxr_set_runtime_property_value");
|
||||
hostfxr_set_error_writer
|
||||
= getExport<hostfxr_set_error_writer_fn>(hostfxrLibrary, "hostfxr_set_error_writer");
|
||||
}
|
||||
|
||||
hostfxr_set_error_writer([] HOSTFXR_CALLTYPE (const char_t *message) {
|
||||
if constexpr (std::same_as<char_t, wchar_t>) {
|
||||
log::error("{}", utf16ToUtf8(message));
|
||||
} else {
|
||||
log::error("{}", message);
|
||||
}
|
||||
});
|
||||
|
||||
return
|
||||
hostfxr_initialize_for_runtime_config != nullptr &&
|
||||
hostfxr_get_runtime_delegate != nullptr &&
|
||||
hostfxr_close != nullptr;
|
||||
hostfxr_close != nullptr &&
|
||||
hostfxr_set_runtime_property_value != nullptr &&
|
||||
hostfxr_set_error_writer != nullptr;
|
||||
}
|
||||
|
||||
load_assembly_and_get_function_pointer_fn getLoadAssemblyFunction(const std::fs::path &path) {
|
||||
|
@ -131,6 +163,8 @@ namespace hex::script::loader {
|
|||
throw std::runtime_error(hex::format("Failed to initialize command line {:X}", result));
|
||||
}
|
||||
|
||||
hostfxr_set_runtime_property_value(ctx, STRING("PINVOKE_OVERRIDE"), utf8ToUtf16(hex::format("{}", (void*)pInvokeOverride)).c_str());
|
||||
|
||||
result = hostfxr_get_runtime_delegate(
|
||||
ctx,
|
||||
hostfxr_delegate_type::hdt_load_assembly_and_get_function_pointer,
|
||||
|
@ -237,4 +271,4 @@ namespace hex::script::loader {
|
|||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ using System.Text;
|
|||
|
||||
namespace ImHex
|
||||
{
|
||||
public class Bookmarks
|
||||
public partial class Bookmarks
|
||||
{
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void createBookmarkV1(UInt64 address, UInt64 size, UInt32 color, byte[] name, byte[] description);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void createBookmarkV1(UInt64 address, UInt64 size, UInt32 color, byte[] name, byte[] description);
|
||||
|
||||
public static void CreateBookmark(long address, long size, Color color, string name = "", string description = "")
|
||||
{
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
namespace ImHex
|
||||
{
|
||||
public static class Library
|
||||
{
|
||||
public const string Name = "script_loader.hexplug";
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
#pragma warning disable SYSLIB1054
|
||||
|
||||
using System.Drawing;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
|
@ -34,7 +33,7 @@ namespace ImHex
|
|||
string getTypeName();
|
||||
string getName();
|
||||
}
|
||||
public class Memory
|
||||
public partial class Memory
|
||||
{
|
||||
private static List<IProvider> _registeredProviders = new();
|
||||
private static List<Delegate> _registeredDelegates = new();
|
||||
|
@ -42,17 +41,17 @@ namespace ImHex
|
|||
private delegate void DataAccessDelegate(UInt64 address, IntPtr buffer, UInt64 size);
|
||||
private delegate UInt64 GetSizeDelegate();
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void readMemoryV1(UInt64 address, UInt64 size, IntPtr buffer);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void readMemoryV1(UInt64 address, UInt64 size, IntPtr buffer);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void writeMemoryV1(UInt64 address, UInt64 size, IntPtr buffer);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void writeMemoryV1(UInt64 address, UInt64 size, IntPtr buffer);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern bool getSelectionV1(IntPtr start, IntPtr end);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial int getSelectionV1(IntPtr start, IntPtr end);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void registerProviderV1(byte[] typeName, byte[] name, IntPtr readFunction, IntPtr writeFunction, IntPtr getSizeFunction);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void registerProviderV1(byte[] typeName, byte[] name, IntPtr readFunction, IntPtr writeFunction, IntPtr getSizeFunction);
|
||||
|
||||
|
||||
public static byte[] Read(ulong address, ulong size)
|
||||
|
@ -87,7 +86,7 @@ namespace ImHex
|
|||
unsafe
|
||||
{
|
||||
UInt64 start = 0, end = 0;
|
||||
if (!getSelectionV1((nint)(&start), (nint)(&end)))
|
||||
if (getSelectionV1((nint)(&start), (nint)(&end)) == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1,33 +1,31 @@
|
|||
#pragma warning disable SYSLIB1054
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace ImHex
|
||||
{
|
||||
public class UI
|
||||
public partial class UI
|
||||
{
|
||||
private delegate void DrawContentDelegate();
|
||||
|
||||
private static List<Delegate> _registeredDelegates = new();
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void showMessageBoxV1(byte[] message);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void showMessageBoxV1(byte[] message);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void showInputTextBoxV1(byte[] title, byte[] message, StringBuilder buffer, int bufferSize);
|
||||
[LibraryImport("ImHex")]
|
||||
private static unsafe partial void showInputTextBoxV1(byte[] title, byte[] message, IntPtr buffer, int bufferSize);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern unsafe void showYesNoQuestionBoxV1(byte[] title, byte[] message, bool* result);
|
||||
[LibraryImport("ImHex")]
|
||||
private static unsafe partial void showYesNoQuestionBoxV1(byte[] title, byte[] message, bool* result);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void showToastV1(byte[] message, UInt32 type);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void showToastV1(byte[] message, UInt32 type);
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern IntPtr getImGuiContextV1();
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial IntPtr getImGuiContextV1();
|
||||
|
||||
[DllImport(Library.Name)]
|
||||
private static extern void registerViewV1(byte[] icon, byte[] name, IntPtr drawFunction);
|
||||
[LibraryImport("ImHex")]
|
||||
private static partial void registerViewV1(byte[] icon, byte[] name, IntPtr drawFunction);
|
||||
|
||||
public static void ShowMessageBox(string message)
|
||||
{
|
||||
|
@ -46,13 +44,22 @@ namespace ImHex
|
|||
|
||||
public static string? ShowInputTextBox(string title, string message, int maxSize)
|
||||
{
|
||||
StringBuilder buffer = new(maxSize);
|
||||
showInputTextBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), buffer, buffer.Capacity);
|
||||
unsafe
|
||||
{
|
||||
var buffer = new byte[maxSize];
|
||||
GCHandle pinnedArray = GCHandle.Alloc(buffer, GCHandleType.Pinned);
|
||||
showInputTextBoxV1(Encoding.UTF8.GetBytes(title), Encoding.UTF8.GetBytes(message), pinnedArray.AddrOfPinnedObject(), maxSize);
|
||||
pinnedArray.Free();
|
||||
|
||||
if (buffer.Length == 0 || buffer[0] == '\x00')
|
||||
return null;
|
||||
else
|
||||
return buffer.ToString();
|
||||
if (buffer.Length == 0 || buffer[0] == '\x00')
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return Encoding.UTF8.GetString(buffer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum ToastType
|
||||
|
|
|
@ -1,8 +1,18 @@
|
|||
using ImHex;
|
||||
using ImGuiNET;
|
||||
class Script {
|
||||
|
||||
public static void OnLoad() {
|
||||
// This function is executed the first time the Plugin is loaded
|
||||
UI.RegisterView(new byte[]{ 0xEE, 0xAC, 0x89 }, "Test View", () =>
|
||||
{
|
||||
ImGui.SetCurrentContext(UI.GetImGuiContext());
|
||||
ImGui.TextUnformatted("Test Text");
|
||||
if (ImGui.Button("Hello World"))
|
||||
{
|
||||
UI.ShowToast("Hello World");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static void Main()
|
||||
|
|
Loading…
Reference in New Issue