ApiHooks 3.1: dwFlags.txt

  dwFlags member of API_HOOK structure can be:

  0               ignore this API_HOOK structure (and go on with the next),

  otherwise it can be any combination of the following flags (attributes):

  HOOK_EXPORT     changes export of ModuleExport, so 
                  GetProcAddress(ModuleExport, ApiNameOrOrd)
                  will return HookAddress (useful for packed files).
                  This is absolutely true in NT (hence GetProcAddress
                  doesn't need to be hooked) but only partially true
                  for 9X, when HOOK_HARD wasn't specified (GetProcAddress
                  must return HookAddress if original API was exported
                  by DLL lying above 2GB - KERNEL32, USER32,...).
                  Any newly loaded module will have modified import
                  according to ModuleExport's export (which was changed
                  by HOOK_EXPORT).
                  ApiNameOrOrd is always found by name/ordinal number match.
                  By using HOOK_EXPORT you're intercepting APIs from all
                  modules  potentially, so use this flag only when
                  ModuleImport == ALL_MODULES.

  HOOK_BY_NAME    (formerly called HOOK_IMPORT) changes address of ApiNameOrOrd
                  in ModuleImport's import.
                  ApiNameOrOrd is found according to API name/ordinal number match
                  (API names table must be correct, which is not true for e.g.
                  Delphi and packed modules).

  HOOK_BY_ADDRESS changes address of ApiNameOrOrd in ModuleImport's import.
                  ApiNameOrOrd is found according address match (GetProcAddress
                  is used). 

                  HOOK_BY_ADDRESS can be used together with HOOK_BY_NAME.

  HOOK_HARD       attribute ignored in NT. When you want to hook modules lying
                  above 2GB (system DLLs) in Windows 9x you must use this option
                  (see 9xGlobal.txt). When you have specified HOOK_EXPORT+HOOK_HARD
                  and ModuleExport was shared DLL, you're intercepting API calls
                  from all newly created processes (see EXAMPLES\ASM\SafeHard,
                  VxDCall, VxDCall2, VirtualAllocFreeEx9X).
                  When you don't specify HOOK_HARD, ApiHooks will not hook modules
                  above 2GB even if their import/export tables lie in writeable
                  sections.

  HOOK_LOAD_IMPORT use when you want to load ModuleImport immediatelly before
                  hooks application. ModuleImport is loaded only if there is also
                  HOOK_BY_NAME or HOOK_BY_ADDRESS among dwFlags. ModuleImport can
                  be specified with PathTo. Note that ModuleImport specified with
                  PathTo needn't be in Target's search path. You can specify this
                  dwFlag only once in one (1st) API_HOOK structure containing wanted
                  ModuleImport. If you want to load ModuleImport only and don't want
                  to apply hooks on it, specify nonexisting ApiNameOrOrd or
                  ModuleExport.
                  See Examples\C\Beep\SelectedModules.

  HOOK_SPECIAL    ignored in NT. In 9X zeroes HOOK_BY_ADDRESS flag.
                  Useful when hooking APIs which share address but not parameter
                  types with other APIs (observed in 9X only).

  HOOK_NOT_NT     ignore this API_HOOK structure in NT and go on with the next.
                  Suitable for not hooking GetProcAddress in NT (there it is not
                  required when HOOK_EXPORT was used).

  HOOK_NOT_9X     ignore this API_HOOK structure in 9X and go on with the next.


 Suggested combinations (because they contain HOOK_EXPORT, they should be used
                  with ModuleImport == ALL_MODULES only):

  HOOK_EXACT  =   HOOK_EXPORT + HOOK_BY_NAME
                  HOOK_BY_NAME presence means that ApiNameOrOrd is found
                  according to name/ordinal match. When ModuleImport hasn't
                  correct API names table (Delphi or packed) it is not hooked.
                  Use HDK\BIN\SuggestFlags.exe to determine if using
                  HOOK_BY_NAME (HOOK_EXACT) will affect specified module.

                 Examples:
                  1) You want to hook lstrcmpi. Then this and only this API will
                  be hooked in ModuleImport. Doesn't matter if other APIs have
                  the same original address (case of lstrcmpiA).  

                  2) You want to hook ZwClose. Then this and only this API will
                  be hooked in ModuleImport. Doesn't matter if other APIs have
                  the same original address (case of NtClose).

  HOOK_ALL    =   HOOK_EXPORT + HOOK_BY_NAME + HOOK_BY_ADDRESS
                  HOOK_BY_NAME presence means that ApiNameOrOrd is found
                  according to name/ordinal match. When ModuleImport hasn't
                  correct API names table (Delphi or packed) it is not hooked.
                  Then comes HOOK_BY_ADDRESS and hooks ModuleImports which
                  weren't affected by HOOK_BY_NAME.
                  HOOK_ALL is recommended for packed modules.

                 Examples:
                  1) You want to hook lstrcmpi. Then this API and then all other APIs
                  with the same address (lstrcmpiA) will be hooked in ModuleImport.

                  2) You want to hook ZwClose. Then this API and then all other APIs
                  with the same address (NtClose) will be hooked in ModuleImport.

  HOOK_SMART  =   HOOK_ALL + HOOK_SPECIAL
                  It means : In NT == HOOK_ALL
                             In 9X == HOOK_EXACT


Correct API_HOOK structures:
 {"USER32.dll",   "FindWindowW",    HOOK_ALL,        ALL_MODULES,   NULL,       NewFindowW}
 {"KERNEL32.dll", "CreateProcessA", HOOK_BY_ADRESS,  MAIN_MODULE,   NULL,       NewCreateProcess}
 {"GDI32.dll",    "Pie",            HOOK_BY_NAME,    "Display.drv", &UnhookPie, NewPie}

Incorrect API_HOOK structure:
 {"GDI32.dll",    "Pie",            HOOK_EXACT,      "Display.drv", &UnhookPie, NewPie}

 Where is the bug? User wants to intercept GDI32.Pie called from Display.drv only,
but HOOK_EXACT (as combined constant) contains HOOK_EXPORT which may cause intercepting
calls to GDI32.Pie from _arbitrary_ module in the process.




  9X abnormalities:

               A) Nonwriteable sections of modules lying above 2GB in 9X can't be
                  modified normally. These modules are visible to every process and
                  their change would affect any (new) process. Specify HOOK_HARD
                  attribute in dwFlags to force modification of such modules. Then
                  your Hooks_DLL should be also loaded above 2GB (see 9xGlobal.txt).

                 Examples:
                  1) You want to hook (HOOK_ALL) KERNEL32.CloseHandle used by 9X
                  USER32.dll. KERNEL32.dll lies above 2GB - HOOK_HARD must be specified
                  in order changes were successful. This change is then visible to
                  every process. USER32.dll lies above 2GB - HOOK_HARD must be
                  specified. 

               B) Some APIs (typically APIs which set LastError to
                  ERROR_CALL_NOT_IMPLEMENTED; it means 98% of *W functions and also 
                  some NT only functions like Get*Times, VirtualAllocEx,...) share the
                  same address and parameters number but not parameter types. This is
                  serious problem when you want to work with parameters (and for example
                  emulate the API). Specify HOOK_SPECIAL (part of HOOK_SMART) in dwFlags
                  to be sure the parameter types are what you expect.

                 Examples:
                  1) You want to hook WriteConsoleW. It is supported by NT so it should
                  be hooked as HOOK_BY_ADDRESS. However, in 9X would HOOK_BY_ADDRESS
                  hook also VirtualAllocEx, GetProcTimes, GetThreadTimes,...
                  You can't distinguish which function was called (parameter types
                  are undefined) in 9X -> you can't work with parameters. HOOK_SPECIAL
                  ensures that only WriteConsoleW was hooked and parameters types are
                  correct.