Injlib.cpp
上传用户:tzh4061
上传日期:2007-01-08
资源大小:309k
文件大小:7k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. /*************************************************************
  2. Module name: InjLib.C
  3. Notices: Copyright (c) 1995-1997 Jeffrey Richter
  4. *************************************************************/
  5. #include "CmnHdr.H"                  /* See Appendix C. */
  6. #include <windows.h>
  7. #include "ProcMem.H"
  8. #include "InjLib.H"
  9. //////////////////////////////////////////////////////////////
  10. typedef HINSTANCE (WINAPI *PROCLOADLIBRARY)(LPBYTE);
  11. typedef BOOL (WINAPI *PROCFREELIBRARY)(HINSTANCE);
  12. typedef HMODULE (WINAPI *PROCGETMODULEHANDLE)(LPBYTE);
  13. typedef struct {
  14.    PROCLOADLIBRARY fnLoadLibrary;
  15.    PROCFREELIBRARY fnFreeLibrary;
  16.    PROCGETMODULEHANDLE fnGetModuleHandle;
  17.    BOOL ActionFlag;
  18.    BYTE pbLibFile[MAX_PATH * sizeof(WCHAR)];
  19. } INJLIBINFO, *PINJLIBINFO;
  20. //////////////////////////////////////////////////////////////
  21. // Calls to the stack checking routine must be disabled.
  22. #pragma check_stack (off)
  23. static DWORD WINAPI ThreadFunc (PINJLIBINFO pInjLibInfo) {
  24.    // There must be less than a page worth of local
  25.    // variables used in this function.
  26.    HINSTANCE hinstDll;
  27.    hinstDll = pInjLibInfo->fnGetModuleHandle(pInjLibInfo->pbLibFile);
  28.    if (pInjLibInfo->ActionFlag == LOAD_DLL)
  29.    {
  30.      if (hinstDll == NULL)
  31.        hinstDll = pInjLibInfo->fnLoadLibrary(pInjLibInfo->pbLibFile);
  32.    }
  33.    else if (pInjLibInfo->ActionFlag == FREE_DLL)
  34.      pInjLibInfo->fnFreeLibrary(hinstDll);
  35.    // The thread's exit code is the handle of the DLL.
  36.    return((DWORD) hinstDll);
  37. }
  38. //////////////////////////////////////////////////////////////
  39. // This function marks the memory address after ThreadFunc.
  40. // ThreadFuncCodeSizeInBytes =
  41. //    (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc.
  42. static void AfterThreadFunc (void) {
  43. }
  44. #pragma check_stack 
  45. //////////////////////////////////////////////////////////////
  46. static BOOL InjectLibWorA (HANDLE hProcess,
  47.    const BYTE * const pbLibFile, BOOL fUnicode, BOOL ActionFlag)
  48. {
  49.    // Kernel32.DLL's HINSTANCE is used to get the
  50.    // address of LoadLibraryA or LoadLibraryW and
  51.    // FreeLibrary.
  52.    HINSTANCE hinstKrnl = GetModuleHandle(__TEXT("Kernel32"));
  53.    INJLIBINFO InjLibInfo;
  54.    // The address to which code will be copied in the
  55.    // remote process
  56.    PDWORD pdwCodeRemote = NULL;
  57.    // Calculate the number of bytes in the ThreadFunc
  58.    // function.
  59. #ifndef _PPC_
  60.    const int cbCodeSize = ((LPBYTE) (DWORD)
  61.       AfterThreadFunc - (LPBYTE) (DWORD) ThreadFunc);
  62. #else
  63.    // Note: The PowerPC does not support 32-bit immediate
  64.    // values. So, the VC++ PowerPC compiler implements 32-bit
  65.    // immediates using an offset into a table and grabbing
  66.    // the 32-bit value from the table. The references to
  67.    // the functions below, are actually offsets into this
  68.    // table. So, we have to subtract the contents of these
  69.    // offsets to get the actual code size.
  70.    const int cbCodeSize = ((LPBYTE) *(PDWORD)
  71.       AfterThreadFunc - (LPBYTE) *(PDWORD) ThreadFunc);
  72. #endif
  73.    // The address to which INJLIBINFO will be copied in
  74.    // the remote process
  75.    PINJLIBINFO pInjLibInfoRemote = NULL;
  76.    // The number of bytes written to the remote process
  77.    DWORD dwNumBytesXferred = 0;
  78.    // The handle and ID of the thread executing the
  79.    // remote copy of ThreadFunc
  80.    DWORD dwThreadId = 0;
  81.    const DWORD cbMemSize =
  82.       cbCodeSize + sizeof(InjLibInfo) + 3;
  83.    HANDLE hThread = NULL;
  84.    HINSTANCE hinstDllRemote = NULL;
  85.    BOOL fOk = FALSE;
  86.    DWORD dwOldProtect;
  87.    // Initialize the INJLIBINFO structure here, and
  88.    // then copy it to memory in the remote process.
  89.    InjLibInfo.fnLoadLibrary = (PROCLOADLIBRARY)
  90.       GetProcAddress(hinstKrnl,
  91.          (fUnicode ? "LoadLibraryW" : "LoadLibraryA"));
  92.    InjLibInfo.fnFreeLibrary = (PROCFREELIBRARY)
  93.       GetProcAddress(hinstKrnl, "FreeLibrary");
  94.    InjLibInfo.fnGetModuleHandle = (PROCGETMODULEHANDLE)
  95.       GetProcAddress(hinstKrnl,
  96.        (fUnicode ? "GetModuleHandleW" : "GetModuleHandleA"));
  97.    InjLibInfo.ActionFlag = ActionFlag;
  98.    InjLibInfo.pbLibFile[0] = 0;   // Initialized later
  99.    __try {
  100.       // Finish initializing the INJLIBINFO structure
  101.       // by copying the desired DLL's pathname.
  102.       if (fUnicode)
  103.          wcscpy((LPWSTR) InjLibInfo.pbLibFile,
  104.             (LPCWSTR) pbLibFile);
  105.       else
  106.          strcpy((LPSTR) InjLibInfo.pbLibFile,
  107.             (LPCSTR) pbLibFile);
  108.       // Allocate enough memory in the remote process's
  109.       // address space to hold our ThreadFunc function
  110.       // and an INJLIBINFO structure.
  111.       pdwCodeRemote = (PDWORD)
  112.          AllocProcessMemory(hProcess, cbMemSize);
  113.       if (pdwCodeRemote == NULL)
  114.          __leave;
  115.       // Change the page protection of the allocated memory
  116.       // to executable, read, and write.
  117.       fOk = VirtualProtectEx(hProcess, pdwCodeRemote,
  118.          cbMemSize, PAGE_EXECUTE_READWRITE, &dwOldProtect);
  119.       if (!fOk)
  120.          __leave;
  121.       // Write a copy of ThreadFunc to the remote process.
  122.       fOk = WriteProcessMemory(hProcess, pdwCodeRemote,
  123.          (LPVOID)(DWORD) ThreadFunc, cbCodeSize,
  124.          &dwNumBytesXferred);
  125.       if (!fOk)
  126.          __leave;
  127.       // Write a copy of INJLIBINFO to the remote process.
  128.       // (The structure MUST start on an even 32-bit boundary.)
  129.       pInjLibInfoRemote = (PINJLIBINFO) 
  130.          ((PBYTE) pdwCodeRemote + ((cbCodeSize + 4) & ~3));
  131.       // Put InjLibInfo in the remote thread's memory block.
  132.       fOk = WriteProcessMemory(hProcess, pInjLibInfoRemote,
  133.          &InjLibInfo, sizeof(InjLibInfo), &dwNumBytesXferred);
  134.       if (!fOk)
  135.          __leave;
  136.       hThread = CreateRemoteThread(hProcess, NULL, 0, 
  137.          (LPTHREAD_START_ROUTINE)(DWORD) pdwCodeRemote,
  138.          pInjLibInfoRemote, 0, &dwThreadId);
  139.       if (hThread == NULL)
  140.          __leave;
  141.       WaitForSingleObject(hThread, INFINITE);
  142.    }  // __try
  143.    __finally {
  144.       if (hThread != NULL) {
  145.          GetExitCodeThread(hThread, (PDWORD) &hinstDllRemote);
  146.          CloseHandle(hThread);
  147.       }
  148.       // Let the remote thread start executing the remote 
  149.       // ThreadFunc function using our modified stack, which
  150.       // now contains an initialized INJLIBINFO structure.
  151.       FreeProcessMemory(hProcess, pdwCodeRemote);
  152.    }  //__finally
  153.    // Return TRUE if the DLL loaded successfully.
  154.    return(hinstDllRemote != NULL);
  155. }
  156. //////////////////////////////////////////////////////////////
  157. BOOL InjectLibA (HANDLE hProcess, LPCSTR lpszLibFile, BOOL ActionFlag)
  158. {
  159.   return(InjectLibWorA(hProcess, (LPBYTE) lpszLibFile, FALSE, ActionFlag));
  160. }
  161. //////////////////////////////////////////////////////////////
  162. BOOL InjectLibW (HANDLE hProcess, LPCWSTR lpszLibFile, BOOL ActionFlag)
  163. {
  164.   return(InjectLibWorA(hProcess, (LPBYTE) lpszLibFile, TRUE, ActionFlag));
  165. }
  166. //////////////////////// End Of File /////////////////////////