APISpy32

Introduction

APISpy32 is a system-wide API spying utility capable of intercepting API calls made by ALL active Windows processes and their attached DLLs. While other API spying utilities can only monitor one application at a time, APISpy32 uses several sophisticated low-level techniques in order to intercept API calls made by EVERY process running on the system, making it the most powerful utility of its kind.

New features offered by this version include:

  • Interception of console applications and system processes under Windows NT !
  • Numerous enhancements to the low-level interception routines.
  • Logging of return values and origin of each API call.
  • Support for Unicode strings passed as parameters (PWSTR).
  • Full compatiblity with Visual C++ 6.
  • New and improved GUI written in C.
  • Several bug fixes.

Using APISpy32

Using APISpy32 is a simple matter of editing a text file (apispy32.api) which contains a list of intercepted API functions. This file must be located in the Windows directory (e.g. C:\WINNT) and should be saved in ASCII format. Each entry in the file represents a single API function along with the various parameters which comprise it.

Here is an example:

USER32.DLL:MessageBoxW(HWND, PWSTR, PWSTR, DWORD)

The parameter types which are recognized by APISpy32 are listed below:

Type | Size | C Type
BYTE | 8 bits | unsigned char
WORD | 16 bits | unsigned short
DWORD | 32 bits | unsigned int
INT | 32 bits | int
HWND | 32 bits | unsigned int
HANDLE | 32 bits | unsigned int
BOOL | 32 bits | unsigned int
PBYTE | 32 bits | unsigned char *
PWORD | 32 bits | unsigned short *
PDWORD | 32 bits | unsigned int *
PSTR | 32 bits | char *
PWSTR | 32 bits | wchar_t *

I've provided a sample API declaration file (located in the root of the zip file) that can be used for testing APISpy32 functionality. Simply copy this file to your Windows directory and you're ready to go...

Known issues

  1. APISpy32 can only intercept functions that use the _stdcall calling convention (e.g. Windows APIs). Do not use it with functions that use the _cdecl or the _fastcall calling conventions.

  2. If you attempt to intercept a function that is shorter than 5 bytes, APISpy32 will overwrite the memory region following the intercepted function. This may cause problems (such as crashing Windows ;) if there is valuable information stored at that address.

  3. When APISpy32 is executed under Windows NT, it periodically attempts to inject APISpyNT.dll into the address space of all running processes. Currently, this happens every 500 milliseconds. In case an application issues a call to an intercepted function before APISpyNT.dll is injected into its address space, APISpy32 will miss that call. You can set the DLL_INJECTION_TIMEOUT constant (defined in APISpy32.h) to a smaller value if you need a better accuracy.

  4. The Windows 9x version of APISpy32 cannot intercept API functions located in DLLs which are not shared among all running processes (i.e. have a different base address in each address space. e.g. WSOCK32.DLL). The Windows NT version of APISpy32 is capable of intercepting such functions.

  5. When declaring a function in the apispy32.api file, you must specify the exact number of parameters that this function expects. Failing to do so will cause any process that issues a call to this function to terminate unexpectedly.

  6. There is a problem with the interception of the ExitProcess API under Windows 95/98. As soon as this API resumes execution, Windows passes control to the task scheduler inside kernel32 rather than returning to the caller of this function. This makes it impossible for APISpy32 to reestablish the API hook after issuing a call to the original function.

If you need to intercept API calls made by a specific Windows application, rather than by all active processes, you might want to try a different approach such as the one offered by Matt Pietrek in his excellent book: "Windows 95 System Programming Secrets". There are several advantages (and disadvantages) to this technique which relies on patching the import table of the target application. Check out Matt's web site for additional information on this subject: http://www.tiac.net/users/mpietrek.

Bugs and other anomalies

Creating an API spying utility is far from being a trivial programming task. Various low-level techniques must be utilized in order to intercept the API calls without sacrificing performance and usability. If you encounter bugs or other anomalies in APISpy32, please send an email to yariv@internals.com with a description of the problem and a list of the actions which caused the software to malfunction. I will do my best to correct all bugs and place fixed versions on my web site as soon as they become available.

Legal Issues

The following terms apply to all files associated with the software unless explicitly disclaimed in individual files.

You may not distribute APISpy32 in any form, without the express written permission of Yariv Kaplan.

You may not use APISpy32 source code in a commercial or non-commercial product, without the express written permission of Yariv Kaplan.

In no event shall the author be liable to any party for direct, indirect, special, incidental, or consequential damages arising out of the use of this software, its documentation, or any derivatives thereof, even if the author has been advised of the possibility of such damage. The author specifically disclaim any warranties, including but not limited to, the implied warranties of merchantability, fitness for a particular purpose, and non-infringment. This software is provided on an "AS IS" basis, and the author has no obligation to provide maintenance, support, updates, enhancements, or modifications.

The code of InjectLib is Copyright 1995-1997 by Jeffrey Richter.

I can be reached at yariv@internals.com.

Yariv Kaplan