Introduction
This article discusses a way to convert a Windows application that does not export any program interface to an automation server. Many very good publications have presented and discussed in depth various aspects of this problem. Most of these works dealt with techniques for injection of code into process to be automated (target process) and API hooking. This article demonstrates the injection to target process using remote thread and focuses on communication between injected code and outside world. Usage of Windows Communication Foundation (WCF) services for such communication is presented in this article.
Background
Actually this article is a continuation of my article Automating Windows Application describing injection of a COM object into target process. A well-known Notepad text editor was taken as an example target application for automation. The following approach was suggested. NotepadPlugin.dll was injected into Notepad.exe target process with the remote thread technique. The plug-in code subclasses both outer (frame) and inner (view) windows of Notepad application, installing custom handlers for several Windows messages (e. g., WM_CHAR). Prior to quit, the remote thread procedure posts a user-registered message WM_CREATE_OBJECT to, say, outer window. This message is handled by a subclass window procedure. The handler creates COM object which registers itself with Running Object Table (ROT) effectively exposing its direct interfaces outside target process, machine-wide. Clients bind to the object, use its direct interfaces to manipulate target application and implement its outgoing (sink) interfaces to subscribe to target applications events firing via connection point mechanism.
This technique works fine, but has a limitation: clients and target application should run on the same machine since ROT is available only locally. One possible way to overcome this limitation is suggested in this article.
To achieve this, the above technique is undergone a remarkable modification: instead of embedding of unmanaged true COM object into target process, this time a managed .NET object capable to communicate with outside world via WCF services is embedded into target process. This managed object is enveloped in COM Callable Wrapper (CCW) referred below to also as simply COM wrapper. The suggested technique is explained based on a code sample.
Injection Steps
The injection itself is remained almost unchanged with regard to the previous article. For the sake of simplicity we assume a single-threaded target application having an outer (frame) and an inner (view) windows. The following steps are taken to automate target application.
- NotepadPlugin.dll in injected into the target process with remote thread technique by Injector COM object. This is a worker thread, and its function is DllMain() of NotepadPlugin.dll. Remote thread ends after DllMain() returns. Injector COM object is instantiated by AutomationClientNET application running as a local client. Its purpose is to find a running target Notepad process (or to start a new one if there is no already running Notepads) and to inject plug-in into the target process. After NotepadPlugin.dll injection, the Injector is no longer used and may be released. Injector is used by only one local client, below referred to as Client-Injector.
- NotepadPlugin.dll subclasses outer and inner windows of target application with FrameWndProc() and ViewWndProc() window procedures respectively. These window procedures contain message handlers with new functionality for the target application. Function PluginProc() (called by DllMain()) of the NotepadPlugin.dll actually performs the subclassing. Both NotepadPlugin.dll and Injector use helper WindowFinder COM object to find Notepad windows.
- Function PluginProc() of NotepadPlugin.dll running in remote thread, posts a user-registered WM_CREATE_OBJECT Windows message to the Notepad frame window. FrameWndProc() window procedure handles WM_CREATE_OBJECT message. The handler creates a managed NotepadHandlerNET object using its COM wrapper.
Read more:
Codeproject Posted via email from .NET Info
0 comments:
Post a Comment