Types of Dependencies Handled By Dependency Walker


There are several ways a module can be a dependent of another module:

  1. Implicit Dependency (also known as a load-time dependency or sometimes incorrectly referred to as static dependency): Module A is implicitly linked with a LIB file for Module B at compile/link time, and Module A's source code actually calls one or more functions in Module B. Module B is a load time dependency of Module A and will be loaded into memory regardless if Module A actually makes a call to Module B at run-time. Module B will be listed in Module A's import table.

  2. Delay-load Dependency: Module A is delay-load linked with a LIB file for Module B at compile/link time, and Module A's source code actually calls one or more functions in Module B. Module B is a dynamic dependency and will only be loaded if Module A actually makes a call to Module B at run-time. Module B will be listed in Module A's delay-load import table.

  3. Forward Dependency: Module A is linked with a LIB file for Module B at compile/link time, and Module A's source code actually calls one or more functions in Module B. One of the functions called in Module B is actually a forwarded function call to Module C. Module B and Module C are both dependencies of Module A, but only Module B will be listed in Module A's import table.

  4. Explicit Dependency (also known as a dynamic or run-time dependency): Module A is not linked with Module B at compile/link time. At runtime, Module A dynamically loads Module B via a LoadLibrary type function. Module B becomes a run time dependency of Module A, but will not be listed in any of Module A's tables. This type of dependency is common with OCXs, COM objects, and Visual Basic applications.

  5. System Hook Dependency (also known as an injected dependency): This type of dependency occurs when another application hooks a specific event (like a mouse event) in a process. When that process produces that event, the OS can inject a module into the process to handle the event. The module that is injected into the process is not really a dependent of any other module, but does resides in that process' address space.

Dependency Walker fully supports modules loaded by all of the above techniques. Case 1, 2, and 3 can easily be detected by just opening a module in Dependency Walker. Case 4 and 5 require runtime profiling, a new feature in Dependency Walker 2.0. For more information on profiling, see the Using Application Profiling to Detect Dynamic Dependencies section.