⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-apiworks.txt

📁 Cracker终结者——提供最优秀的软件保护技术
💻 TXT
📖 第 1 页 / 共 2 页
字号:
  ApiWorks is very complex Scout that allows loading given module(s) and establishing
"hooks".

--------------------------------------------------------------------------------------------------------------------------------------------------------------------
  ApiWorks functions have ANSI(A)/UNICODE(W) form.  UNICODE strings are converted
to ANSI strings - some characters may have different meaning in calling process and
in Target.

  Every string passed to ApiWorks functions can have (including zero terminator)
max. MAX_PATH characters. If it has more, ApiWorks returns ErrorAHException.

  For successful ApiWorks execution, KERNEL32.dll mustn't have altered export entries
for GetModuleHandleA, LoadLibraryA, GetProcAddress, VirtualQuery, GetModuleFileNameA,
VirtualProtect, lstrcmpiA, LocalAlloc, LocalFreee, FlushInstructionCache, ordinal 1.
If they are altered, ApiWorks may fail with ErrorAHRemote.

  9x: When a (large) module(s) is/are about to be loaded into more/all processes,
there must be "enough" (~100 MB) free space available on the drive with paging file
(Win386.swp).

  NT: Don't forget to set appropriate access to module to Hooks_DLL. Typically set
Read & Execute for Everyone. It is important for intersession hooking. The same applies
onto imported modules (e.g. ApiHooks.dll, PrcWorks.dll, ..).

--------------------------------------------------------------------------------------------------------------------------------------------------------------------
  ApiWorks exports these functions for hooking:

  DWORD __stdcall  EstablishApiHooks(PRCINFO pRCI, LPCTSTR  lpszDll, DWORD ProcessId, LONG dwMilliseconds);
  DWORD __stdcall hEstablishApiHooks(PRCINFO pRCI, LPCTSTR  lpszDll, HANDLE hProcess, LONG dwMilliseconds);

    lpszDll is module that is loaded into Target and which exposes ApiHookChain.
    If lpszDll is already present in Target
  - and dwMilliseconds is even value, EAH returns with ErrorAWSuccess immediatelly
  (hooks are taken as applied already).
  - and dwMilliseconds is odd value lpszDll usage count is incremented (LoadLibrary)
  and hooks are reapplied.
    lpszDll is loaded, gets DLL_PROCESS_ATTACH followed by DLL_THREAD_DETACH notification
    for the same thread.
    lpszDll is also called Hooks_DLL in the following text.

  dwMilliseconds is ExpTime user gives EAH function to establish API hooks.
  if(dwMilliseconds & 1) { // dwMilliseconds is odd
    --dwMilliseconds;
    if(Hooks aren't dynamic)
      ReEstablishApiHooks := TRUE;
  }
  
  If there wasn't unexpected exception in ApiWorks, ErrorAWSuccess is returned.
  (this tells nothing about hooks application -> check UnhookAddresses.CurNoAddr)
  Otherwise AH error codes
  or AM error codes can be returned:
    ErrorAMModule = lpszDll can't be found/loaded,
    ErrorAMApi    = lpszDll doesn't export ApiHookChain (via GetApiHookChain or ApiHookChain).

  RemoteFunction for (h)EstablishApiHooks is implemented approx. as follows:
    HMODULE Modules[256];
    DWORD ModCnt = BuildModuleList(&Modules);
    LPHMODULE ExcludeModules= NULL;
    PAPI_HOOK AHChain;
    PAPI_HOOK (__stdcall *GetAHChain)(DWORD CallerPID);
    PAPI_HOOK (__stdcall *GetAHChain)(VOID);
    if(*(LPDWORD)lpszDll == HOOKS_DYNAMIC)
      AHChain = (PAPI_HOOK)lpszDll;
    else {  
      if(GetModuleHandle(lpszDll) && !ReEstablishApiHooks) 
        return(ErrorAWSuccess); // lpszDll already present && not reestablish -> hooks are thought as already applied
      else {
        if(hHooks = LoadLibrary(lpszDll)) {
          if(!(GetAHChain = GetProcAddress(hHooks, "GetApiHookChain"))) {
            if(!(AHChain = GetProcAddress(hHooks, "ApiHookChain"))) {
                return(ErrorAMApi);  // Can't find AHChain
              }
            }
          }
          else {
            AHChain = GetAHChain(CallerPID);
            if(AHChain == NULL)
              return(ErrorAMApi);  // No AHChain
          }
        } 
        else {
          return(ErrorAMModule);  // Can't load lpszDll
        }
      } 
    } 
    while(AHChain->ModuleExport != HOOKS_END) {
      if(AHChain->ModuleExport == HOOKS_DYNAMIC) {
        ExcludeModules = AHChain.UnhookAddresses;
      }  
      else {
        if(AHChain->dwFlags == HOOK_ALL_SAFE) {
          AHChain->dwFlags = HOOK_OVERWRITE;
          if(ApplyHook(AHChain, AHChain->ModuleImport)) {
            AHChain++;
            continue;
          }
          else { 
            AHChain->dwFlags = HOOK_BY_NAME | HOOK_BY_ADDRESS;
            AHChain->ModuleImport = ALL_MODULES;
          }
        } 
        if(AHChain->ModuleImport == ALL_MODULES) { 
          for(i=0; i<ModCnt; i++) {
            ApplyHook(AHChain, Modules[i]);
          }
        }
        else {
          if(AHChain->dwFlags & (HOOK_BY_ADDRESS | HOOK_BY_NAME | HOOK_OVERWRITE | HOOK_RAW)) {
            ApplyHook(AHChain, AHChain->ModuleImport);
          }
        }
      }  
      AHChain++;
    }
    return(ErrorAWSuccess);

    BOOL ApplyHooks (PAPI_HOOK ApiHook, LPSTR ModuleImport) {
      if((ApiHook->dwFlags & (HOOK_BY_NAME | HOOK_BY_ADDRESS))
         && IsExcluded(GetModuleHandle(ModuleImport)))
        return;
      if((ApiHook->dwFlags & (HOOK_BY_NAME | HOOK_LOAD_IMPORT)) == (HOOK_BY_NAME | HOOK_LOAD_IMPORT))
        LoadLibraryA(ModuleImport);
      HookPlace = EvaluateHook(ApiHooks->dwFlags, ModBase);
      ChangeBytes(ApiHook, HookPlace);
    }

    BOOL ChangeBytes(PAPI_HOOK ApiHook, PVOID HookPlace) {
      if(IsNT)
        goto StoreOld;
      if(ApiHook->dwFlags & HOOK_RAW) //can't estimate if it lies in shared section
        goto Check2GB;
      if(HookPlace is in shared section)
        if(!(ApiHook->dwFlags & HOOK_HARD))
          return(FALSE);
      Check2GB:
      if(HookPlace >= 2GB)
        if(!(ApiHook->dwFlags & HOOK_HARD))
          return(FALSE);
      StoreOld:
      if(ApiHook->UnhookAddresses)
        StoreOldBytes(ApiHook->UnhookAddresses, HookPlace);
      return(WriteBytes(HookPlace));
    }


  ApiWorks understands these structures (all must lie within writeable memory):

 a) For unhooking

  typedef struct  _ADDR_CONTENTS   {
   DWORD         *ReturnWhere;
   DWORD          ReturnWhat;
  } ADDR_CONTENTS, *PADDR_CONTENTS;

  ReturnWhere contains address of place where ReturnWhat should be written.


  typedef  struct _API_UNHOOK  {
   DWORD          MaxNoAddr;
   DWORD          CurNoAddr;
   PADDR_CONTENTS WhereWhat; 
  } API_UNHOOK, *PAPI_UNHOOK;

  MaxNoAddr is maximum number of ADDR_CONTENTS structures in WhereWhat field.
  CurNoAddr (filled by AH) is the current number of filled and valid ADDR_CONTENTS
  structures in WhereWhat field.
  All API_UNHOOK members must be initialized.

 b) For hooking

  typedef struct  _API_HOOK   {
   LPCSTR       ModuleExport;
   LPCSTR       ApiNameOrOrd;
   DWORD        dwFlags;
   LPCVOID      ModuleImport;
   PAPI_UNHOOK  UnhookAddresses;
   LPVOID       HookAddress;
  } API_HOOK, *PAPI_HOOK;

  ModuleExport -  pointer to ANSI name of module which exports wanted API.
                  Can be specified with PathTo. It doesn't have to be present
                  in Target.
                  Special values: MAIN_MODULE for main (.exe) module (mustn't
                                  be used with HOOK_BY_NAME flag; specify main
                                  module name instead).
                                  HOOKS_END marks end of ApiHookChain.
                                  HOOKS_DYNAMIC marks dynamic hooks.
                  
                  If HOOK_RAW is set, ModuleExport can contain everything,
                  for example, pointer to symbol name.

                  Note: ApiWorks does not load ModuleExport.

  ApiNameOrOrd -  ordinal number (1..65535) of wanted API or
                  pointer to the ANSI name of wanted API.
                  It can be nonexisting (not exported by ModuleExport) name
                  or ordinal. It can be NULL only if ModuleExport doesn't exist.

                  If HOOK_RAW is set, ApiNameOrOrd must contain 32bit virtual
                  address (valid in Target). 

  dwFlags      -  specifies how to hook, see "C-ApiWorks-dwFlags.txt".
 
  ModuleImport -  if dwFlags contains HOOK_OVERWRITE, HOOK_RAW or HOOK_ALL_SAFE
                  flag, ModuleImport is thought as pointer to pointer-to-routine
                  -to-jump-to-original-API. If this pointer is initially NULL,
                  space for routine is allocated from process' heap. Space for
                  routine must be at least 32 bytes long.
               -  otherwise is is: 
                  pointer to ANSI name of module which imports wanted API.
                  Can be specified with PathTo. If it isn't present in Target,
                  ModuleImport isn't hooked. However, you can preload
                  ModuleImport immediatelly before hooking via HOOK_LOAD_IMPORT
                  dwFlag. 
                  Special values: MAIN_MODULE for main (.exe) module.
                                  ALL_MODULES for all modules in Target.

  UnhookAddresses pointer to API_UNHOOK structure for storing addresses for
                  unhooking.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -