
*) If you have (bad) impression that ApiHooks hasn't hooked wanted
   module(s) use ShowAH, ShowHooks and other debugging support.

*) Both exported code and data can be hooked.
   Code that's not exported can be hooked too.

*) Don't forget to save (after original API call) and restore (after post
   orginal API call action(s)) LastError value:

   ResultType CallType MyApi(Par0, Par1,...) {
     ResultType result;
        // pre-orig-call actions: modify parameters, bufers
        result = OrigApi(Par0, Par1,...);  // optional
        lasterr = GetLastError(); 
        // post-orig-call actions: modify parameters, buffers, result
        SetLastError(lasterr); 
        return(result);
   }

*) Source code compile with structure alignment <= 8.
   API_HOOK structure must have size 0x18.
   ADDR_CONTENTS structure must have size 8.

*) Hooks_DLL can be packed/encrypted (static ApiHookChain is restored
   during Hooks_DLL initialization. Static ApiHookChain can be always
   created/modified during Hooks_DLL initialization (= before hooks
   application), of course it should lie within writeable section. ShowAH
   will fail with such a packed/encrypted module.

*) Don't forget that you can hook (here better implement) APIs which have no
   useful implementation in Win9X (APIs are exported but GetLastError() returns
   ERROR_CALL_NOT_IMPLEMENTED).

*) If you want to be sure that ModuleExport is loaded before hooks application
   (EAH, hEAH, HookApi functions do NOT load ModuleExport!), you can do this:
   *) Import any API/data from ModuleExport (done during linking)
   or
   *) call LoadAndCall("ExportModule",....) before calling EAH, hEAH, HookApi.
   or
   *) use load import technique: before standard hooks place API_HOOK which looks
      like:
      {"", NULL, HOOK_BY_NAME | HOOK_LOAD_IMPORT, "ExportModule", NULL, NULL},
      //ExportModule is loaded (if it was in search path), standard hooks follow:
      {"ExportModule", ...},
   HOOK_LOAD_IMPORT loads Module after DllMain (allows selective loading, Hooks_DLL
   can be loaded even if Module doesn't exist)). If you want Module to be loaded
   before DllMain, you must import from it (and Module must exist otherwise
   Hooks_DLL isn't loaded at all; nonselective loading).

*) It is good to call AH functions with full Hooks_DLL/Module pathname, because
   there may exist many modules with the same base name in the Target!

*) When ApiHooks.exe with ALL is run, it displays AH error for the last found
   process. For example, if the last found process was 16bit, "Can't open process!"
   is displayed. Use HDK\BIN utils to see which processes were affected.

*) When hooking nonexported code (RAW) you should preserve integer registers and flags
   if you don't know details.

*) When is AH linked statically, it is good to call AH function as soon as possible
   to initialize AH (ideal is calling GetDefaultRCInfo() from DllMain).

*) Some applications (including AH) consider addresses of KERNEL32.dll functions to be
   constant in every process (because KERNEL32.dll is loaded at the same base address
   in every process). If such applications are hooked using PE hooking flags (BY_NAME,
   BY_ADDRESS) and/or GetProcAdress hook, the (returned) address of the function can be
   valid in the current process only, while jumping to this address in other process
   will raise an exception (AH handles this case, nothing crashes).
   Solution:
   *) Hook KERNEL32.dll APIs using HOOK_OVERWRITE or
   *) Exclude the modules that use constant adresses from hooking.

*) Exposing ApiHookChain via GetApiHookChain has one advantage: Hooks_DLL can contain
   more significantly different AHchains and Hooks_DLL can choose which of them will
   GetApiHookChain return.

*) Module containing AH mustn't be packed with packer creating stubs for imported APIs.

*) Module containing AH mustn't be packed with packer that fills module's IAT via
   GetProcAddress (it doesn't work on 9x KERNEL32.dll ordinals). The IAT should be filled
   by OS's PE loader.