ApiHooks 2.1c, Feb-22-2000, test version
========================================


Apihooks.DLL
============
1) Exports EstablishApiHooksA/W,          (EAH)
           EstablishApiHooksTimeA/W,      (EAHT)
           EstablishApiHooksTimeW2KA/W,   (EAHTW2K)
           RemoteExecuteTime,             (RET)
           RemoteExecuteTimeW2K.          (RETW2K)

   EstablishApiHooks(lpszDll, PID) == EstablishApiHooksTime(lpszDll, PID, INFINITE)

   EstablishApiHooksTime have the "first" 2 parameters as EstablishApiHooks,
   the 3rd (integer or INFINITE) parameter is the time interval in milliseconds which
   you give this functions to apply hooks. If the time interval elapses, functions
   return with return value == ErrorTimeOut. These functions have sense in Windows 9X
   (and Windows 2000 when EAHTW2K weren't used) when hooking "the process of no return".
   "The process of no return" is running process where hooks application
   via EstablishApiHooks never ends.

   EAH and EAHT functions use W9X technique in Windows 2000.

   EstablishApiHooksTimeW2K have the same parameters as EstablishApiHooksTime
   and have this meaning:
   In W9X,NT4 == EstablishApiHooksTime.
   In W2K == EstablishApiHooksTime but try to use NT4 technique in Windows 2000.
   EAHTW2K is useful when applying hooks to "the process of no return" in Windows 2000.
   EAHTW2K is the best and safe function suitable for applying hooks to an unknown
   process.

   RemoteExecute functions have this format:
        RemoteExecuteTime(PID, dwMilliseconds, lpBlock, BlockSize, lpCodeEnd)
     RemoteExecuteTimeW2K(PID, dwMilliseconds, lpBlock, BlockSize, lpCodeEnd)
    lpBlock    is a pointer to a block of code and data; this block will be copied to
               the process represented by PID and executed there.
    BlockSize  is the size of the block.
    lpCodeEnd  marks the code end zone of the block. There must be 4 bytes reserved.
   Code must begin on block's begin. Block can be in read-only memory and is not changed.
   ApiHooks itself is such a block.
   See ReFilter example for Block design and details.
 
2) Reentrancy is supported.
3) Hooks can be applied to process with any priority.
4) New elegant VirtualAllocEx9x.
5) All threads in the process are stopped if W9X technique is used.
6) Code rewritten, size optimized.
7) If ModuleExport is missing it is not uploaded automatically now.


ApiHooks.EXE
============
1) It calls EstablishApiHooksTimeW2KA with 10 second interval.
   => in NT4/W2K can be hooked everything what contains kernel32.dll if you are
   admin.
2) W2K: When -o? was specified and Target contains PathTo, AH tries to find it by use
   of NT4 technique.
3) Command line parameters [PathTo\]Hooks and [PathTo\]Target can contain environment
   variables. It means something like:
   apihooks -n %HOMEDRIVE%%HOMEPATH%Hooks.dll %SystemRoot%\explorer.exe "fwerf"%OS%f
    will be "translated" to:
               C:\Hooks.dll C:\WINNT\explorer.exe "fwerf"%OS%f


TMext01x.dll
============
1) It calls EstablishApiHooksTimeW2KA (with 10 sec interval) so it always returns.


Misc
====
1) In NT4/W2K can be ApiHooks.exe's return code used to determine which processes
   are currently running (see Runs.bat). It was possible already with the 1st version
   of ApiHooks.
2) In W9X can be hooks applied to process where no module imports from kernel32.dll.
   It was possible already with the 1st version of ApiHooks.
3) Infilter example shows how to make pseudoglobal hooks.
   In W9X can be hooks applied to mixed 16/32bit processes like KERNEL32.DLL.
   Even if NT4 technique wasn't used in W2K (=> EAH or EAHTime were used), hooks can
   be applied to mixed 16/32bit processes like NTVDM.exe.
4) You can load the same DLL or DLL with name which matches the name of DLL already
   present in process to process as many times as you want. But the path to this DLL
   must be changed. So the following commands succeed:
   apihooks -o c:\hooks.dll explorer.exe
   apihooks -o e:\hooks.dll explorer.exe
   apihooks -o c:\1\hooks.dll explorer.exe
5) If RemoteExecute/Hooks have to be applied to process which was created in debug mode
   and is in status "DebugBreak" (for example if Ctrl+C was pressed) the things will go
   as follows:
   In NT4 and W2K_with_TimeW2K_function will be hooks applied after debugged process
   resumes execution. If Time function was called it can return with ErrorTimeOut.
   Otherwise (W9X, W2K_with(out)_Time) hooks will not be applied and Time function
   returns with ErrorTimeOut; this is critical.
6) It is very important to give AH fuctions "enough" time (>20 seconds or infinite).
7) In W9X when you want to hook module importing procedure from kernel32.dll through
   ordinal number, use HOOK_IMPORT. HOOK_BY_ADDRESS will not work (caused by Microsoft).
   Any other dll is ok.
8) If you want to hook newly uploaded module in LoadLibrary* hooks through dynamic hooks
   and the new module has bound import (you can delete it with UnbindPE) it is better to
   use HOOK_IMPORT+GetProcAddressHook instead of HOOK_BY_ADDRESS, especially if you've
   used HOOK_EXPORT before.
9) New examples added.


Bugreports
==========
to EliCZ@xoommail.com. I'd like to know if ApiHooks runs on Windows Millennium (W98te).