7

I have a Qt Dll wich I inject into a third-party Application using windows detours library:

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))

and then I set a system-wide hook to intercept window creation:

HHOOK h_hook = ::SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProc, Status::getInstance()->getXORInstance(), 0);

Where XOR is my programs name, and Status::getInstance() is a Singleton where I keep globals.

In my CBTProc callback, I want to intercept all windows that are QWidgets:

HWND hwnd= FindWindow(L"QWidget", NULL);

which works well, since I get a corresponding HWND (I checked with Spy++) Then, I want to get a pointer to the QWidget, so I can use its functions:

QWidget* q = QWidget::find(hwnd);

but here's the problem, the returned pointer is always 0. Am I not injecting my code into the process properly? Or am I not using QWidget::find() as I should?

Thanks,

Dave

EDIT:If i change the QWidget::find() function to an exported function of my DLL, after setting the hooks (so I can set and catch a breakpoint), QWidgetPrivate::mapper is NULL.

David Menard
  • 2,261
  • 3
  • 43
  • 67
  • Can you step into `QWidget::find()` with debugger and see whether `QWidgetPrivate::mapper` is `NULL` or not? – Paul Jul 25 '09 at 13:16
  • QWidget::find() is in the CBT_Proc callback and a breakpoint can't seem to be hit there... is there any other way of verifying this? and if it is NULL, what do I do then? – David Menard Jul 27 '09 at 15:27
  • In case your wondering "How does he know the code gets executed then?", I am printing in the console. – David Menard Jul 27 '09 at 15:33
  • I moved the QWidget::find() to a exported function, and QWidgetPrivate::mapper is NULL. – David Menard Jul 27 '09 at 15:37
  • > QWidgetPrivate::mapper is NULL That's why `QWidget::find()` returns `NULL`. The next questions are: 1. Does application that you are injecting to loads QtGui4.dll or it is linked to Qt statically? 2. Do you link your DLL to Qt statically or use Qt in DLLs? 3. Try to check with debugger or with Process Explorer how many copies of QtGui4.dll is loaded by process that you are hooking. My assumption is that there are 2 copies of Qt in the process and your call to `QWidget::find()` references the one that is not initialized by QApplication of target process. Though I may be wrong. – Paul Jul 27 '09 at 19:13
  • According to Process Explorer I am only loading a single copy of QtGui4.dll and QtCore4.dll. I am loading Qt dynamicaly. Thanks for the help and replies, greatly appreciated! – David Menard Jul 27 '09 at 19:56
  • The application that I am injecting is also loading Qt dynamicaly – David Menard Jul 27 '09 at 19:56

2 Answers2

2

Answered:

Stupid mistake, I was compiling in Debug, so it was QtGui4d.dll and QtCore4d.dll that where loading, not QtCore4.dll and QtGui.dll

David Menard
  • 2,261
  • 3
  • 43
  • 67
  • David, could you email me, ron@silentmusic.net I have some questions regarding this as I am trying to do something similar and am getting stuck. Thanks. – flavour404 Jan 04 '11 at 03:12
0

Compare the addresses of `QWidgetPrivate::mapper in the DLL and in your code. Esp. if one is linked statically, there might be two instance of it, each with it's own, disjoint, set of widgets.

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90