Remote Library Loading

Environment: Microsoft Windows NT/2000/XP

Description

This article describes the customization of existing applications through the use of custom Dynamic-Link Libraries (DLLs) and the process of, what I have titled, Remote Library Loading. It also presents a small utility I developed to make this process easier; I titled it the Remote Library Loader.

For the ideas here I give credit originally to Jeffrey Ricther in Programming Applications for Microsoft Windows with his "DLL Injection." The primary difference between our applications is that his works with running target processes, where mine also acts as a target process loader. In any case, much credit to him!

The Problem

There is one major problem that arises when it comes to customizing existing applications: virtual address spaces. In 32-bit Windows environments, each application has its own virtual address space that only its components can see. This means that one application cannot freely modify another without some additional work. This is the problem that is overcome with the Remote Library Loader and the use of custom DLLs. With the architecture described below, developers can work around this problem fairly easily, and accomplish their intended tasks.

The Achitecture

The architecture developed to solve the problem above can be broken down into three discrete components. These components are as follows:

  • An existing target application that is to be customized
  • A created "plugin" DLL for customizing the target application
  • A loader application that is responsible for starting the target application and mapping the plugin DLL into its address space

We will now examine the second two components in detail. The target application will not be discussed here because its functionality is only pertinent to the plugin DLL developer, and could be one of many different things.

The Loader

The loader component is provided to you as the Remote Library Loader. This executable acts as a controller and error-reporter for the entire architecture, and covers the basic tasks. Its tasks are as follows:

  • Start the target executable (using CreateProcess())
  • Allocate memory in target process address space (using VirtualAllocEx())
  • Copy the plugin DLL filename into remotely allocated memory (using WriteProcessMemory())
  • Create a thread in the target process which will call LoadLibrary() passing the plugin DLL filename stored earlier (using CreateRemoteThread())
  • Wait for this thread to finish (using WaitForSingleObject())
  • Free allocated memory in target process (using VirtualFreeEx())

If an error occurs during any one of the preceding steps, a message box is presented to the user, informing them of the error. This includes if the remote LoadLibrary() call fails to load the plugin DLL.

Please read the Readme.txt in the download package for specific information about loader installation/usage.

The Plugin

When the plugin DLL is loaded into the target process address space during the LoadLibrary() call, its entry-point function will be called. At this point, the DLL can perform initialization tasks and do whatever it wants to customize the application. The following model is recommended, for reasons I will explain:

  • Catch the DLL_PROCESS_ATTACH notification in the entry-point function.
  • On this notification, create a new thread (using CreateThread()).
  • Perform any and all customizations in this newly created thread.

It is important to follow this model for one main reason: Access to the entry-point function is serialized, meaning that it can be called only once at a time. Performing a lengthy operation in the DLL_PROCESS_ATTACH notification may force other threads attempting to call the entry-point function to wait, including threads within the target process (see Footnote #1). For this reason, use the model above for best performance.

Once in the newly created thread, customizations can be performed, such as subclassing one of the applications windows, and so forth, and other things that you can do in the context of the target process.

Download

Remote Library Loader Package zip file - 18Kb

This download includes an installation/usage Readme.txt, the Remote Library Loader source code and executable, and a sample plugin DLL source code and executable. The loader was written directly in Assembly for small size and fast speed. The sample plugin DLL was written in C for more clarity.

Conclusion

I hope this article will help people interested in this topic! Thank you for taking the time to read it.

John Peloquin
http://www.peloweb.com


Footnotes

1. Here it is good to remember that newly created threads thread will attempt to call the entry-point function with a DLL_THREAD_ATTACH notification. But it is also important to note that even the target process primary thread may be affected when not using this model. The reason has to do with the functionality of CreateProcess() and LoadLibrary(). Because CreateProcess() can return before the target process primary thread has loaded all its required DLLs, it could still be calling LoadLibrary() even after the plugin DLL receives the DLL_PROCESS_ATTACH notification. If a lengthy operation prevents a return from this notification before another LoadLibrary() call occurs, that call will attempt to send a DLL_PROCESS_ATTACH notification. This then makes the primary thread waitg, which is certainly not desirable. So, for these two reasons it is important to use the recommended model for best results.



Comments

  • Can you make it applicable if target exe is IE6.0

    Posted by Legacy on 08/26/2003 12:00am

    Originally posted by: SaiSrinivas

    If target exe is IE how can we inject our DLL at runtime without closing the application?

    • use OpenProcess

      Posted by Krishnaa on 04/10/2006 08:15am

      Use openProcess API instead of CreateProcess and rest of the process is same

      Reply
    Reply
  • Remote Control

    Posted by Legacy on 07/25/2003 12:00am

    Originally posted by: Nataraj

    Is it possible to control tv actions from the PC through IR. If you have idea about this do let me know.

    Thanks,
    Nataraj

    Reply
  • Library loading

    Posted by Legacy on 05/13/2003 12:00am

    Originally posted by: Charles Coleman

    Is it possible to load a library, without using a DLL, to a specific place in memory(user defined)? My intent is to place it on a separate memory card for multiple CPU access.
    Thanks

    Reply
  • Can this be used to...

    Posted by Legacy on 04/04/2003 12:00am

    Originally posted by: Scott-e

    Firstly I'd like to say thanks a million, I think you have just solved a huge problem. Can the injected DLL wrap or override the message handling system between the application and the GUI and pass the messages across a network. I am trying to develope a simple thinclient.

    Reply
  • Codes for Loader Components?

    Posted by Legacy on 08/29/2002 12:00am

    Originally posted by: Galahad

    Hi. I find your article very useful. But can I request for you to attach the codes for the loader components though?

    Reply
  • creating a thread with MFC will fail in DllMain

    Posted by Legacy on 05/27/2002 12:00am

    Originally posted by: Carsten Wiessmeier

    MFC disallows the starting of threads during dll startup phase (during DLL_PROCESS_ATTACH, see MSDN Q142243).

    The result in doing so will be a deadlock situation.

    Be careful not to use MFC functions to create the initialization thread.

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds