【发布时间】:2009-07-23 18:48:02
【问题描述】:
我有一个 Qt Dll,我使用 windows detours 库将其注入第三方应用程序:
if(!DetourCreateProcessWithDll( Path, NULL, NULL, NULL, TRUE,
CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED, NULL, NULL,
&si, &pi, "C:\\Program Files\\Microsoft Research\\Detours Express 2.1\\bin\\detoured.dll",
"C:\\Users\\Dave\\Documents\\Visual Studio 2008\\Projects\\XOR\\Debug\\XOR.dll", NULL))
然后我设置了一个系统范围的钩子来拦截窗口的创建:
HHOOK h_hook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProc, Status::getInstance()->getXORInstance(), 0);
XOR 是我的程序名称,Status::getInstance() 是一个 Singleton,我在其中保存全局变量。
在我的 CBTProc 回调中,我想拦截所有属于 QWidgets 的窗口:
HWND hwnd= FindWindow(L"QWidget", NULL);
效果很好,因为我得到了相应的 HWND(我用 Spy++ 检查过) 然后,我想得到一个指向 QWidget 的指针,这样我就可以使用它的功能了:
QWidget* q = QWidget::find(hwnd);
但是问题来了,返回的指针始终为 0。我没有正确地将代码注入进程吗?还是我没有使用 QWidget::find()?
谢谢,
戴夫
编辑:如果我将 QWidget::find() 函数更改为我的 DLL 的导出函数,在设置挂钩后(以便我可以设置和捕获断点),QWidgetPrivate::mapper 为 NULL。
【问题讨论】:
-
你能用调试器进入
QWidget::find(),看看QWidgetPrivate::mapper是不是NULL吗? -
QWidget::find() 在 CBT_Proc 回调中,似乎无法在此处设置断点...还有其他方法可以验证这一点吗?如果是NULL,那我该怎么办?
-
如果您想知道“他怎么知道代码会被执行?”,我正在控制台中打印。
-
我将 QWidget::find() 移到了导出函数中,QWidgetPrivate::mapper 为 NULL。
-
> QWidgetPrivate::mapper 为 NULL 这就是
QWidget::find()返回NULL的原因。接下来的问题是: 1. 您要注入的应用程序是加载 QtGui4.dll 还是静态链接到 Qt? 2. 你是静态链接你的 DLL 到 Qt 还是在 DLL 中使用 Qt? 3. 尝试使用调试器或进程资源管理器检查您正在挂接的进程加载了多少个 QtGui4.dll 副本。我的假设是进程中有 2 个 Qt 副本,并且您对QWidget::find()的调用引用了未由目标进程的 QApplication 初始化的那个。虽然我可能错了。
标签: qt dll hook code-injection qwidget