如何使用 .dll 注入覆盖 Qt 成员函数

Posted

技术标签:

【中文标题】如何使用 .dll 注入覆盖 Qt 成员函数【英文标题】:How to override Qt member function with .dll injection 【发布时间】:2015-11-06 14:57:43 【问题描述】:

我正在尝试提供一些代码here 的Windows 版本,用于记录Qt (4.7) 事件。目标应用程序是基于 Qt 的,执行注入的代码 fwiw 也是如此。 linux 版本使用库预加载来覆盖 QWidget::x11event 作为录制代码的起点。

我也尝试过这样做,将 winEvent 用作 x11event 的适当等效项。我正在使用 dll 注入,据我所知是成功的。 dll在调试器的加载模块中列出并且加载例程都成功。

但是我从来没有看到我的 winEvent 被调用。我尝试用相同的结果覆盖其他函数。

我是 dll 创建的新手,更不用说注入了,所以可能在某处遗漏了一个重要步骤,但是当我构建包含我的 winEvent 实现的 .dll 时,编译器警告引起了我的怀疑;我收到“警告 C4273:'QWidget::winEvent':dll 链接不一致”。 dll虽然编译成功。目前我只是有

bool QWidget::winEvent ( MSG *message, long *result)

 // my code

在我的 .dll 中的其中一个 cpp 文件中。这够了吗?

【问题讨论】:

如果你想在一个开源应用程序中重写一个函数,为什么不自己改变源代码呢?处理 DLL 注入的麻烦有什么意义? 开源代码通过使用库预加载在 linux 中记录任何 Qt 目标应用程序中的用户操作。我在 Windows 中最接近的方法是 dll 注入。 【参考方案1】:

Qt 如何使其类 DLL 导出?

class Q_WIDGETS_EXPORT QWidget : public QObject, public QPaintDevice

或者更早的 Qt 暴露了相同的类:

class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice

什么是 Q_WIDGETS_EXPORT?毕竟动态Qt的#ifdef/#define重定向你应该得到它的值:

__declspec(dllexport)

这是在您的普通 Qt 应用程序项目中设置的。对于包含 Qt 标头之前的那个 DLL 注入项目(我猜),您可以尝试这样做:

#define Q_WIDGETS_EXPORT __declspec(dllexport)

#define Q_GUI_EXPORT __declspec(dllexport)

弄清楚如何将 Q_GUI_EXPORT 的值设为 __declspec(dllexport)

您应该仔细检查宏 Q_WIDGETS_EXPORT 以及您尝试使用 DLL 注入的特定 Qt 版本。我偷看了 Qt 5.3.2 的源代码。

记住 DLL 导出和导入范例,对于您的应用项目,它是导入,对于 DLL 公开函数,它是导出。就像国际贸易一样。

【讨论】:

感谢您的建议,不幸的是,它似乎没有帮助。在我重新定义 QWidget::winEvent 的 .cpp 文件中,我还有其他 Qt 代码应该引入那些#defines,所以我不会太惊讶。 那么不清楚那个DLL项目到底是怎么实现的?带有 QWidget::winEvent 的文件包括什么? 在Qt 4.7中,QWidget被定义为:class Q_GUI_EXPORT QWidget : public QObject, public QPaintDevice,而Q_GUI_EXPORT被定义为#define Q_GUI_EXPORT Q_DECL_IMPORT,又是#define Q_DECL_IMPORT __declspec(dllimport)(对不起我不清楚如何在不导致发布的情况下格式化此评论!)。这似乎与您的 dllexport 不一致。有什么想法吗?我覆盖 QWidget::winEvent 的代码包括 和一些增强的东西。 在您的 DLL 项目中,您应该有 DLL 导出。在您的应用项目中有 DLL 导入。 恐怕到目前为止运气不好。似乎我应该能够使用 QT_MAKEDLL 来使其工作,而不必专门覆盖我的文件中的任何内容,但到目前为止,各种预处理器定义都没有帮助。哼哼。

以上是关于如何使用 .dll 注入覆盖 Qt 成员函数的主要内容,如果未能解决你的问题,请参考以下文章

Qt DLL总结-VS2008+Qt 使用QPluginLoader访问DLL

MFC 应用程序中的 Qt DLL - 如何使 QDialog *真正* 模态?

在 Qt 中访问 DLL 的 C++ 类成员函数

如何使用基于 Qt 的依赖项来组织 Qt DLL

如何使用 QNetworkAccessManager 作为 QT DLL 函数下载文件?

如何在dll注入中调用特定函数?