Problems using wxWidgets (wxMSW) within multiple DLL instances - user-interface

Preface
I'm developing VST-plugins which are DLL-based software modules and loaded by VST-supporting host applications. To open a VST-plugin the host applications loads the VST-DLL and calls an appropriate function of the plugin while providing a native window handle, which the plugin can use to draw it's GUI. I managed to port my original VSTGUI
code to the wxWidgets-Framework and now all my plugins run under wxMSW and wxMac but I still have problems under wxMSW to find a correct way to open and close the plugins and I am not sure if this is a wxMSW-only issue.
Problem
If I use any VST-host application I can open and close multiple instances of one of my VST-plugins without any problems. As soon as I open another of my VST-plugins besides my first VST-plugin and then close all instances of my first VST-plugin the application crashes after a short amount of time within the wxEventHandlerr::ProcessEvent function telling me that the wxTheApp object isn't valid any longer during execution of wxTheApp->FilterEvent (see below). So it seems to be that the wxTheApp objects was deleted after closing all instances of the first plugin and is no longer available for the second plugin.
bool wxEvtHandler::ProcessEvent(wxEvent& event)
{
// allow the application to hook into event processing
if ( wxTheApp )
{
int rc = wxTheApp->FilterEvent(event);
if ( rc != -1 )
{
wxASSERT_MSG( rc == 1 || rc == 0,
_T("unexpected wxApp::FilterEvent return value") );
return rc != 0;
}
//else: proceed normally
}
....
}
Preconditions
1.) All my VST-plugins a dynamically linked against the C-Runtime and wxWidgets libraries. With regard to the wxWidgets
forum this seemed to be the best way to run multiple instances of the software side by side.
2.) The DllMain of each VST-Plugin is defined as follows:
// WXW
#include "wx/app.h"
#include "wx/defs.h"
#include "wx/gdicmn.h"
#include "wx/image.h"
#ifdef __WXMSW__
#include <windows.h>
#include "wx/msw/winundef.h"
BOOL APIENTRY DllMain
( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
wxInitialize();
::wxInitAllImageHandlers();
break;
}
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
wxUninitialize();
break;
}
return TRUE;
}
#endif // __WXMSW__
class Application : public wxApp {};
IMPLEMENT_APP_NO_MAIN(Application)
Question
How can I prevent this behavior respectively how can I properly handle the wxTheApp object if I have multiple instances
of different VST-plugins (DLL-modules), which are dynamically linked against the C-Runtime and wxWidgets libraries?
Best reagards, Steffen

We had similar issues using a LSP created with wxWidgets when an wxWidgets application loaded our DLL. Check for NULL == wxTheApp before calling ::wxInitialize().
Pseudo code:
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch(dwReason) {
case DLL_PROCESS_ATTACH :
if(NULL == wxTheApp) {
::wxInitialize();
}
break;
}
}
Also, I suggest doing as little possible in your DllMain() as possible, e.g. move wxInitAllImageHandlers() elsewhere if possible. Additionally, you may wish to track if you called ::wxInitialize() to pair up with ::wxUninitialize()

I encountered a similar issue but with Acrobat plugins.
While adjusting our Acrobat plugins to Acrobat X (10) we had to remove code related to ADM (Acrobat Dialog Manager - Used to be a cross-platform GUI framework on Acrobat 7, 8 & 9. Removed with Acrobat X) and use a different GUI framework.
Acrobat SDK comes with samples of using wxWidgets as a cross-platform framework so we headed that way (we support MAC & Windows).
The plugin architecture of Acrobat is very similar to the one you described above: dlls (for Acrobat plugins the binary file extension is *.api) which are dynamically loaded by a main process (exe) and their functions are being called in a documented, pre-defined order.
Because the Acrobat wxWidgets example was written with 2.8.12 and due to the fact that this is the stable version we decided to NOT use the 2.9.x ongoing version.
So we statically linked our plugins (total of 3 different plugins) to the wx2.8.12 libs and found out that if 3 of them are installed, the two that were loaded last were not functioning. By that I mean - Our custom wxFrames, wxWindows & wxDialogs belonging to these two plugins were all messed up (like someone tried to erase them, with rubber :-)).
Digging deeply we narrowed it down to the fact that the first plugin being loaded, initializes wxWidgets and the latter do not, even though the explicit call to wxInitialize(). Something there went wrong....
Here I forgot to mention - In an Acrobat plugin you cannot change the DllMain() function, so the initialization of wx is done in a "Plugin Init() function".
Just to be clear - The wx libs are statically linked to the *.api files, so each should have a "copy" of its own and not influence on each other.
Using Google for 2-3 FULL days I managed to find this post
,which suggested to apply this patch (for 2.8x ONLY!!!). I believe (or hope) that the 2.9.x version does not suffer from this issue (didn't have the chance to check it).
BTW - The patch is only one file which is very clear, so reading the code to understand it and to be calm that it does no harm is pretty easy.
I hope others using wx 2.8.x and suffering from the same issue will find this.
Omri

Related

Windbg find missing dlls

Background:
I am writing a app using an open source library. This open source libarary comes with many plugin dlls. Some of which we are using in our project (NOT all of them).
While in developement, we just consumed the library as a whole and everything worked fine.
Now when we are trying to build a shippable binary package, seems like we need to sort things out and find only those plugin binaries (dlls) from the open source lib which are in use.
These library comes with 100 of plugin dlls. During runtime, we just using a primary lib plugin dlls, which in turn loads up other dlls (Curently when we run the App, it loads both essential or non-essential dlls). We need to find out a way how to only pack those dlls which we are using in the code. And since these are plugins only, if the primary dll don't finds the non-essential dlls, then it is completely fine (App won't crash). We just have to help it locate the essential ones (without that pur either won't work or will crash).
Approach:
In order to find only the essential dlls, what I have done is removed all the dlls from the path and started placing one dlls each time to check, until our App start working. The problem is that with this approach it is going to take a long time. Rather than randomly picking each dlls I trying to use WinDbg to find out which missing dlls has caused the failure.
Question:
Is there a way in Windbg to identify from a dump, to see which missing dll has caused failure?
Your Question As it Appears is Ambiguous.
Most of commenters have provided you hints For a live Debugging Session Like.
Ldr Snaps
ProcMon
Etw Traces
you seem to have asked For looking at it in a dump
Question: Is there a way in Windbg to identify from a dump, to see which missing dll has caused failure?
a plugin by its nature will be allowed to fail gracefully By its Parent Binary and as such it will Create an Unload Event
This Will Be reflected in the dump by lm Command
the Unloaded Modules will be listed at the end of Module List
:\>cdb -c "lm;q" -z c:\odbgdmp.dmp |awk "/Unloaded/,/quit/"
Unloaded modules:
66940000 66957000 OllyDumpEx_Imm17.dll
quit:
ntdll maintains an array 0x40 last unloaded dlls windbg Retrieves this from the same place as the below code does.
#include <stdio.h>
#include <windows.h>
typedef struct _RTL_UNLOAD_EVENT_TRACE {
PVOID BaseAddress;SIZE_T SizeOfImage;ULONG Sequence;ULONG TimeDateStamp;
ULONG CheckSum;WCHAR ImageName[32];
} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE;
typedef VOID (WINAPI* RtlGetUnloadEventTraceEx) (
_Out_ PULONG *ElementSize,_Out_ PULONG *ElementCount,_Out_ PVOID *EventTrace
);
RtlGetUnloadEventTraceEx evt;
int main(void) {
//ollydbg plugin wont load in curproc will create an unloaded mod event
LoadLibraryA("OllyDumpEx_Od20.dll");
HMODULE nt=LoadLibraryA("ntdll.dll");
if(nt != NULL){
evt=(RtlGetUnloadEventTraceEx)GetProcAddress(nt,
"RtlGetUnloadEventTraceEx");
PULONG elsiz = NULL, elcnt = NULL;PVOID evarr = NULL;
evt(&elsiz,&elcnt,&evarr);
printf("%p %p %p\n" , elsiz,elcnt,evarr);
printf("%x %x %x\n" , *elsiz,*elcnt,*(int*)evarr);
PRTL_UNLOAD_EVENT_TRACE u1=((PRTL_UNLOAD_EVENT_TRACE)(*(int*)evarr));
printf("bas\t%p\nsiz\t%x\nSeq\t%x\nstamp\t%x\nCsum\t%x\nname\t%S\n",
u1->BaseAddress,u1->SizeOfImage,u1->Sequence,u1->TimeDateStamp,
u1->CheckSum,u1->ImageName);
}
return 0;
}
on executing
:\>UnloadModList.exe
7706CDA0 7706CD9C 77067144
5c 40 1fafd8
base 676F0000
size 19000
Seq 0
stamp 55953f77
Chksum 12b14
imgname OllyDumpEx_Od20.dll
corroboration of dll details which failed to load
:\>dumpbin /headers OllyDumpEx_Od20.dll | grep -iE "CheckSum|Stamp|size of image|image base"
55953F77 time date stamp Thu Jul 2 19:11:11 2015
6A680000 image base (6A680000 to 6A698FFF)
19000 size of image
12B14 checksum

Identify and intercept function call

I'm developing a launcher for a game.
Want to intercept game's call for a function that prints text.
I don't know whether the code that contains this function is dynamically linked or statically. So I dont even know the function name.
I did intercepted some windows-api calls of this game through microsoft Detours, Ninject and some others.
But this one is not in import table either.
What should I do to catch this function call? What profiler should be used? IDA? How this could be done?
EDIT:
Finally found function address. Thanks, Skino!
Tried to hook it with Detours, injected dll. Injected DllMain:
typedef int (WINAPI *PrintTextType)(char *, int, float , int);
static PrintTextType PrintText_Origin = NULL;
int WINAPI PrintText_Hooked(char * a, int b, float c, int d)
{
return PrintText_Origin(a, b, c , d);
}
HMODULE game_dll_base;
/* game_dll_base initialization goes here */
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
if(fdwReason==DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(hinstDLL);
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
PrintText_Origin = (PrintTextType)((DWORD)game_dll_base + 0x6049B0);
DetourAttach((PVOID *)&PrintText_Origin , PrintText_Hooked);
DetourTransactionCommit();
}
}
It hooks as expected. Parameter a has text that should be displayed. But when calling original function return PrintText_Origin (a, b, c , d); application crashes(http://i46.tinypic.com/ohabm.png, http://i46.tinypic.com/dfeh4.png)
Original function disassembly:
http://pastebin.com/1Ydg7NED
After Detours:
http://pastebin.com/eM3L8EJh
EDIT2:
After Detours:
http://pastebin.com/GuJXtyad
PrintText_Hooked disassembly http://pastebin.com/FPRMK5qt w3_loader.dll is the injected dll
Im bad at ASM, please tell what can be wrong ?
Want to intercept game's call for a function that prints text.
You can use a debugger for the investigative phase. Either IDA, or even Visual Studio (in combination with e.g. HxD), should do. It should be relatively easy to identify the function using the steps below:
Identify a particular fragment of text whose printing you want to trace (e.g. Hello World!)
Break the game execution at any point before the game normally prints the fragment you identified above
Search for that fragment of text† (look for either Unicode or ANSI) in the game's memory. IDA will allow you to do that IIRC, as will the free HxD (Extras > Open RAM...)
Once the address of the fragment has been identified, set a break-on-access/read data breakpoint so the debugger will give you control the moment the game attempts to read said fragment (while or immediately prior to displaying it)
Resume execution, wait for the data breakpoint to trigger
Inspect the stack trace and look for a suitable candidate for hooking
Step through from the moment the fragment is read from memory until it is printed if you want to explore additional potential hook points
†provided text is not kept compressed (or, for whatever reason, encrypted) until the very last moment
Once you are done with the investigative phase and you have identified where you'd like to inject your hook, you have two options when writing your launcher:
If, based on the above exercise, you were able to identify an export/import after all, then use any API hooking techniques
EDIT Use Microsoft Detours, making sure that you first correctly identify the calling convention (cdecl, fastcall, stdcall) of the function you are trying to detour, and use that calling convention for both the prototype of the original as well as for the implementation of the dummy. See examples.
If not, you will have to
use the Debugging API to programatically load the game
compute the hook address based on your investigative phase (either as a hard-coded offset from the module base, or by looking for the instruction bytes around the hook site‡)
set a breakpoint
resume the process
wait for the breakpoint to trigger, do whatever you have to do
resume execution, wait for the next trigger etc. again, all done programatically by your launcher via the Debugging API.
‡to be able to continue to work with eventual patch releases of the game
At this stage it sounds like you don't have a notion of what library function you're trying to hook, and you've stated it's not (obviously at least) an imported external function in the import table which probably means that the function responsible for generating the text is likely located inside the .text of the application you are disassembling directly or loaded dynamically, the text generation (especially in a game) is likely a part of the application.
In my experience, this simplest way to find code that is difficult to trace such as this is by stopping the application shortly during or before/after text is displayed and using IDA's fabulous call-graph functionality to establish what is responsible for writing it out (use watches and breakpoints liberally!)
Look carefully to calls to CreateRemoteThread or any other commonly used dynamic loading mechanism if you have reason to believe this functionality might be provided by an exported function that isn't showing up in the import table.
I strongly advice against it but for the sake of completeness, you could also hook NtSetInformationThread in the system service dispatch table. here's a good dump of the table for different Windows versions here. If you want to get the index in the table yourself you can just disassemble the NtSetInformationThread export from ntdll.dll.

How to conditionally execute function if operating system supports it?

I'd like to build an application that invokes CancelIoEx on Windows Vista and newer (where it is supported) and does something else on Windows XP (where it is not).
What happens if I compile the application under Windows 7 but run it under Windows XP? What will happen at runtime? Will I get some sort of load error?
How do I get my application to pick one code path or another (avoiding load errors) depending on what operating system is being used at runtime? Please provide sample code.
UPDATE: Please note that the DLL exists on Windows XP but the function does not.
Yes, an application that references a non-existent DLL export will fail to load.
Adding code to take different paths based on the OS version won't help much, because you'll still have the reference to the non-existent function.
Instead, you need to resolve the reference at run-time.
One option is Delay Load Import (with the /DELAYLOAD linker flag), but I don't think this is supported for the core system DLLs (like kernel32).
The other is to use LoadLibrary and GetProcAddress. The code is something like this, though in reality you'd do the lookup once when your app starts, not each time you call the function.
// Declare type of pointer to CancelIoEx function
typedef BOOL (WINAPI *CancelIoExType)(HANDLE hFile, LPOVERLAPPED lpOverlapped);
// Load module; won't fail because it's already imported
HMODULE hKernel32 = LoadLibrary(L"kernel32.dll");
// Look up function address
CancelIoExType pCancelIoEx = (CancelIoExType)GetProcAddress(hKernel32, "CancelIoEx");
// Do something with it
if (pCancelIoEx)
{
// Function exists so call it
pCancelIoEx(hMyFile, pMyOverlapped);
}
else
{
// Function doesn't exist
}
In order to resolve a symbol at runtime, you need to use LoadLibrary and GetProcAddress:
HMODULE kernel32 = LoadLibrary("kernel32.dll");
BOOL (WINAPI *pCancelIoEx)(HANDLE, LPOVERLAPPED) = GetProcAddress(kernel32, "CancelIoEx");
In the case that CancelIoEx is not available, you will get NULL back from GetProcAddress. Once you have the pointer (you only need to do the above once), you can call it normally with:
pCancelIoEx(h, &lp);

SetWindowsHook Global not very Global

I'm playing around with SetWindowsHookEx, specifically I would like be able to find out about any window (on my desktop) thats been activated, via mouse or keyboard.
Reading through MSDN docs for SetWindowsHookEx it would appear that a WH_CBT type would do the job. I've created a dll and put all the code in there, which I control from a gui app (which also handles the unhook).
BUT I only appear to be getting the activation code when I activate my gui app though, any other app I activate is ignored.
In my dll I have the setup code and the CBTProc like so:
LRESULT WINAPI CBTProc(int Code, WPARAM W, LPARAM L) {
if(Code<0) CallN....
if (Code == HCBT_ACTIVATE) { // never get unless I activate my app
HWND a = reinterpret_cast<HWND>(W);
TRACE("this window was activated %d\n", a);
}
CallNext....
}
EXPORTED HHOOK WINAPI Setup(HWND MyWind) {
...
// gDllUInstance set in dllmain
return SetWindowsHookEx(WH_CBT, CBTProc, gDllUInstance, 0);
}
All pretty simple stuff, i've tried moving the setup out of the dll but I still get the same effect.
It would appear that the dll is getting loaded into other processes, I'm counting the number of DLL_PROCESS_ATTACHs I'm getting and can see its going up (not very scientific i know.
NOTE that this is 32 bit code running on 32bit OS - win2k3.
Are my expectations of the hooking mechanism wrong? should I only be getting the activation of my app or do I need a different type of hook?
EDIT: the trace function writes to a file telling me whats sending me activations
TIA.
Turns out its working ok, as Hans points out, i'm just not seeing the output from the debugger from the other processes, if I put in some extra tracing code - one trace file per attached process - I can see can see that things are working after all.
Many thanks for the replies.

Attach window to running application

I have customer that uses older, custom built ERP application for which they don't have source code and company that developed it does not exist any more. Application is developed in 2000 and it's built with Delphi. Since last executable is from 2003, it could be D6 or D7.
On one important form there are some fields where customer would like to display additional data from other databases and asked me if it's possible to "duct tape" data over existing form.
First idea I got is to build application that will:
browse list of windows target application creates and find controls on form
attach "some" event when to get notified when target form is displayed
attach "some" event when to get notified when field on target form is changed
display additional information in small window overlaying target form
Are there any examples on how to do something like this. I searched google with variations of this question title, but without success.
Note - rewriting of ERP application is not planned.
About language - I can do it with C# or Delphi.
I'm going to answer this from a purely C & Win32 point of view, because I don't know Delphi or its libraries. Converting this to C# can be accomplished via p/invoke, but some parts may/will need to be unmanaged.
First off, no guarantees. If the target application is doing windows-less controls (if there isn't an HWND under every on-screen control) you're pretty much out of luck. This isn't all that uncommon, so yeah...
Step 1, register a window hook listening for new windows created by the target process*:
//dllHMod is an HMODULE that refers to the DLL containing ShellHookProc
HHOOK hook = SetWindowsHookEx(WH_SHELL, ShellHookProc, dllHMod, 0);
// error handling, stashing hook away for unregistering later, etc...
LRESULT CALLBACK ShellHookProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if(nCode < 0) return CallNextHookEx(NULL, nCode, wParam, lParam);
if(nCode == HSHELL_WINDOWCREATED)
{
WindowCreate((HWND)wParam);
}
return 0;
}
WindowCreated(HWND) should stash the HWND away if the correct process (determined via GetWindowThreadProcessId) owns it. At this point, you'll be able to get every top-level window owned by the target process. Note that registering a global hook carries a notable performance penalty, not that it really matters in your case but you should expect it.
Now for the fun part. There's no reliable way to tell when a window is fully constructed, or when its done rendering (there are ways to tell when it STARTS rendering, but that doesn't really help). My advice, guess. Just throw some arbitrary wait in there and then try and enumerate all the child windows.
To enumerate child windows (if you know enough about the target window, there are better ways to do this; but I'm assuming a search is easiest):
//targetHWND is an HWND of one of the top-level windows you've found
EnumChildWindows(targetHWND, ChildWindowCallback, NULL);
//more code...
BOOL ChildWindowCallback(HWND window, LPARAM ignored)
{
if(IsTargetWindow(window)) { /* Do something */ }
return TRUE;
}
Implementing IsTargetWindow is another tricky part. Hopefully you'll find some reliable test for doing so (like checking the class name, window name, style, something; look at GetWindowInfo).
Once you have the window you want to monitor, you can use SetWindowLongPtr and GWLP_WNDPROC to watch all messages it receives. This will require code injection (and thus unmanaged code) and is awfully low level. I'd advise against it if you could possibly avoid it, but lacking the source...
I think this answers is a decent starting point, but once again this is going to be incredibly painful if its even possible at all. Good luck.
*Alternatively, if you know that the target app doesn't create windows except at startup (or at detectable/predictable points in time) you can use EnumWindows.

Resources