INJLIB_old.CPP
上传用户:nbcables
上传日期:2007-01-11
资源大小:1243k
文件大小:11k
源码类别:

钩子与API截获

开发平台:

Visual C++

  1. /*
  2.   此文件必须使用release方式编译才能正确运行
  3. */
  4. #include <windows.h>
  5. #include <stdio.h>
  6. #include "injlib.h"
  7. #include "util.h"
  8. typedef HINSTANCE (WINAPI *PROCLOADLIBRARY)(LPSTR);
  9. typedef BOOL (WINAPI *PROCFREELIBRARY)(HINSTANCE);
  10. typedef HMODULE (WINAPI *PROCGETMODULEHANDLE)(LPSTR);
  11. void WriteLog(char *fmt,...);
  12. #define LOAD_DLL 1
  13. #define FREE_DLL 0
  14. typedef struct {
  15.    PROCLOADLIBRARY fnLoadLibrary;
  16.    PROCFREELIBRARY fnFreeLibrary;
  17.    PROCGETMODULEHANDLE fnGetModuleHandle;
  18.    BOOL ActionFlag;
  19.    CHAR pbLibFile[MAX_PATH];
  20. } INJLIBINFO, *PINJLIBINFO;
  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 =NULL;
  27.    if(pInjLibInfo ==NULL || pInjLibInfo->fnGetModuleHandle ==NULL
  28. || pInjLibInfo->fnLoadLibrary ==NULL) return (DWORD)NULL;
  29.    hinstDll = pInjLibInfo->fnGetModuleHandle(pInjLibInfo->pbLibFile);
  30.    if (pInjLibInfo->ActionFlag == LOAD_DLL)
  31.    {
  32.      if (hinstDll == NULL)
  33.        hinstDll = pInjLibInfo->fnLoadLibrary(pInjLibInfo->pbLibFile);
  34.    }
  35.    else if (pInjLibInfo->ActionFlag == FREE_DLL)
  36.      pInjLibInfo->fnFreeLibrary(hinstDll);
  37.    // The thread's exit code is the handle of the DLL.
  38.    return((DWORD) hinstDll);
  39. }
  40. //////////////////////////////////////////////////////////////
  41. // This function marks the memory address after ThreadFunc.
  42. // ThreadFuncCodeSizeInBytes =
  43. //    (PBYTE) AfterThreadFunc - (PBYTE) ThreadFunc.
  44. static void AfterThreadFunc (void) {
  45. }
  46. #pragma check_stack 
  47. //////////////////////////////////////////////////////////////
  48. int WINAPI InjectLib (DWORD process_id, char *pbLibFile)
  49. {
  50.    // Kernel32.DLL's HINSTANCE is used to get the
  51.    // address of LoadLibraryA or LoadLibraryW and
  52.    // FreeLibrary.
  53.    HINSTANCE hinstKrnl = GetModuleHandle("Kernel32");
  54.    INJLIBINFO InjLibInfo;
  55.    // The address to which code will be copied in the
  56.    // remote process
  57.    PDWORD pdwCodeRemote = NULL;
  58.    // Calculate the number of bytes in the ThreadFunc
  59.    // function.
  60. #ifndef _PPC_
  61.    const int cbCodeSize = ((LPBYTE) (DWORD)
  62.       AfterThreadFunc - (LPBYTE) (DWORD) ThreadFunc);
  63. #else
  64.    // Note: The PowerPC does not support 32-bit immediate
  65.    // values. So, the VC++ PowerPC compiler implements 32-bit
  66.    // immediates using an offset into a table and grabbing
  67.    // the 32-bit value from the table. The references to
  68.    // the functions below, are actually offsets into this
  69.    // table. So, we have to subtract the contents of these
  70.    // offsets to get the actual code size.
  71.    const int cbCodeSize = ((LPBYTE) *(PDWORD)
  72.       AfterThreadFunc - (LPBYTE) *(PDWORD) ThreadFunc);
  73. #endif
  74.    // The address to which INJLIBINFO will be copied in
  75.    // the remote process
  76.    PINJLIBINFO pInjLibInfoRemote = NULL;
  77.    // The number of bytes written to the remote process
  78.    DWORD dwNumBytesXferred = 0;
  79.    // The handle and ID of the thread executing the
  80.    // remote copy of ThreadFunc
  81.    DWORD dwThreadId = 0;
  82.    HANDLE hThread = NULL;
  83.    HINSTANCE hinstDllRemote = NULL;
  84.    BOOL fOk = FALSE;
  85.    // Initialize the INJLIBINFO structure here, and
  86.    // then copy it to memory in the remote process.
  87.    InjLibInfo.fnLoadLibrary = (PROCLOADLIBRARY)GetProcAddress(hinstKrnl, "LoadLibraryA");
  88.    InjLibInfo.fnFreeLibrary = (PROCFREELIBRARY)GetProcAddress(hinstKrnl, "FreeLibrary");
  89.    InjLibInfo.fnGetModuleHandle = (PROCGETMODULEHANDLE)GetProcAddress(hinstKrnl, "GetModuleHandleA");
  90.    InjLibInfo.ActionFlag = LOAD_DLL;
  91.    InjLibInfo.pbLibFile[0] = 0;   // Initialized later
  92.       strcpy(InjLibInfo.pbLibFile, pbLibFile);
  93.     HANDLE hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
  94. if(hProcess ==NULL)
  95. {
  96. WriteLog("InjectLib:OpenProcess %d failed!", process_id);
  97. return -1;
  98. }
  99. if((pdwCodeRemote = (PDWORD)VirtualAllocEx(hProcess, NULL, cbCodeSize+20, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) ==NULL)
  100.   {
  101.   CloseHandle(hProcess);
  102.           return FALSE;
  103.   }
  104.       // Change the page protection of the allocated memory
  105.       // to executable, read, and write.
  106.   int ret;
  107.       ret =WriteProcessMemory(hProcess, pdwCodeRemote,
  108.          (LPVOID)(DWORD) ThreadFunc, cbCodeSize,
  109.          &dwNumBytesXferred);
  110.   //WriteLog("WriteProcessMemory pdwCodeRemote size:%d, ret=%d, %d", cbCodeSize, ret, STATUS_ACCESS_VIOLATION);
  111.   if(ret ==STATUS_ACCESS_VIOLATION || ret ==false)
  112.   {
  113.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  114.   CloseHandle(hProcess);
  115.   return false;
  116.   }
  117.       // Put InjLibInfo in the remote thread's memory block.
  118.       if((pInjLibInfoRemote = (INJLIBINFO *)VirtualAllocEx(hProcess, NULL, sizeof(InjLibInfo)+20, MEM_COMMIT, PAGE_READWRITE)) ==NULL)
  119.   {
  120.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  121.   CloseHandle(hProcess);
  122.          return FALSE;
  123.   }
  124.       ret =WriteProcessMemory(hProcess, pInjLibInfoRemote,
  125.          &InjLibInfo, sizeof(InjLibInfo), &dwNumBytesXferred);
  126.   //WriteLog("WriteProcessMemory InjLibInfo ret=%d", ret);
  127.   if(ret ==STATUS_ACCESS_VIOLATION || ret ==false)
  128.   {
  129.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  130.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  131.   CloseHandle(hProcess);
  132.   return false;
  133.   }
  134.   //WriteLog("CreateRemoteProcess...");
  135.       hThread = CreateRemoteThread(hProcess, NULL, 0, 
  136.          (LPTHREAD_START_ROUTINE)(DWORD) pdwCodeRemote,
  137.          pInjLibInfoRemote, 0, &dwThreadId);
  138.       if (hThread == NULL)
  139.   {
  140.   //WriteLog("CreateRemoteProcess failed");
  141.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  142.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  143.   CloseHandle(hProcess);
  144.   return false;
  145.   }
  146.   //WriteLog("CreateRemoteThread success, WaitForSingleObject...");
  147.       WaitForSingleObject(hThread, INFINITE);
  148.       if (hThread != NULL)
  149.   {
  150.          GetExitCodeThread(hThread, (PDWORD) &hinstDllRemote);
  151.          CloseHandle(hThread);
  152.       }
  153.       // Let the remote thread start executing the remote 
  154.       // ThreadFunc function using our modified stack, which
  155.       // now contains an initialized INJLIBINFO structure.
  156.       if(pdwCodeRemote)
  157.   {
  158.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  159.   }
  160.       if(pInjLibInfoRemote)
  161.   {
  162.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  163.   }
  164. //WriteLog("OK++++");
  165.   CloseHandle(hProcess);
  166. return(hinstDllRemote != NULL);
  167. }
  168. int WINAPI EjectLib (DWORD process_id, char *pbLibFile)
  169. {
  170.    // Kernel32.DLL's HINSTANCE is used to get the
  171.    // address of LoadLibraryA or LoadLibraryW and
  172.    // FreeLibrary.
  173.    HINSTANCE hinstKrnl = GetModuleHandle("Kernel32");
  174.    INJLIBINFO InjLibInfo;
  175.    // The address to which code will be copied in the
  176.    // remote process
  177.    PDWORD pdwCodeRemote = NULL;
  178.    // Calculate the number of bytes in the ThreadFunc
  179.    // function.
  180. #ifndef _PPC_
  181.    const int cbCodeSize = ((LPBYTE) (DWORD)
  182.       AfterThreadFunc - (LPBYTE) (DWORD) ThreadFunc);
  183. #else
  184.    // Note: The PowerPC does not support 32-bit immediate
  185.    // values. So, the VC++ PowerPC compiler implements 32-bit
  186.    // immediates using an offset into a table and grabbing
  187.    // the 32-bit value from the table. The references to
  188.    // the functions below, are actually offsets into this
  189.    // table. So, we have to subtract the contents of these
  190.    // offsets to get the actual code size.
  191.    const int cbCodeSize = ((LPBYTE) *(PDWORD)
  192.       AfterThreadFunc - (LPBYTE) *(PDWORD) ThreadFunc);
  193. #endif
  194.    // The address to which INJLIBINFO will be copied in
  195.    // the remote process
  196.    PINJLIBINFO pInjLibInfoRemote = NULL;
  197.    // The number of bytes written to the remote process
  198.    DWORD dwNumBytesXferred = 0;
  199.    // The handle and ID of the thread executing the
  200.    // remote copy of ThreadFunc
  201.    DWORD dwThreadId = 0;
  202.    HANDLE hThread = NULL;
  203.    HINSTANCE hinstDllRemote = NULL;
  204.    BOOL fOk = FALSE;
  205.    // Initialize the INJLIBINFO structure here, and
  206.    // then copy it to memory in the remote process.
  207.    InjLibInfo.fnLoadLibrary = (PROCLOADLIBRARY)GetProcAddress(hinstKrnl, "LoadLibraryA");
  208.    InjLibInfo.fnFreeLibrary = (PROCFREELIBRARY)GetProcAddress(hinstKrnl, "FreeLibrary");
  209.    InjLibInfo.fnGetModuleHandle = (PROCGETMODULEHANDLE)GetProcAddress(hinstKrnl, "GetModuleHandleA");
  210.    InjLibInfo.ActionFlag = FREE_DLL;
  211.    InjLibInfo.pbLibFile[0] = 0;   // Initialized later
  212.       strcpy(InjLibInfo.pbLibFile, pbLibFile);
  213.   HANDLE hProcess =OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
  214. if(hProcess ==NULL)
  215. {
  216. WriteLog("InjectLib:OpenProcess %d failed!", process_id);
  217. return -1;
  218. }
  219. if((pdwCodeRemote = (PDWORD)VirtualAllocEx(hProcess, NULL, cbCodeSize+20, MEM_COMMIT, PAGE_EXECUTE_READWRITE)) ==NULL)
  220.   {
  221.   CloseHandle(hProcess);
  222.          return FALSE;
  223.   }
  224.       // Change the page protection of the allocated memory
  225.       // to executable, read, and write.
  226.   int ret;
  227.       ret =WriteProcessMemory(hProcess, pdwCodeRemote,
  228.          (LPVOID)(DWORD) ThreadFunc, cbCodeSize,
  229.          &dwNumBytesXferred);
  230.   //WriteLog("WriteProcessMemory pdwCodeRemote size:%d, ret=%d, %d", cbCodeSize, ret, STATUS_ACCESS_VIOLATION);
  231.   if(ret ==STATUS_ACCESS_VIOLATION || ret ==false)
  232.   {
  233.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  234. CloseHandle(hProcess);
  235.   return false;
  236.   }
  237.       // Put InjLibInfo in the remote thread's memory block.
  238.       if((pInjLibInfoRemote = (INJLIBINFO *)VirtualAllocEx(hProcess, NULL, sizeof(InjLibInfo)+20, MEM_COMMIT, PAGE_READWRITE)) ==NULL)
  239.   {
  240.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  241. CloseHandle(hProcess);
  242.          return FALSE;
  243.   }
  244.       ret =WriteProcessMemory(hProcess, pInjLibInfoRemote,
  245.          &InjLibInfo, sizeof(InjLibInfo), &dwNumBytesXferred);
  246.   //WriteLog("WriteProcessMemory InjLibInfo ret=%d", ret);
  247.   if(ret ==STATUS_ACCESS_VIOLATION || ret ==false)
  248.   {
  249.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  250.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  251. CloseHandle(hProcess);
  252.   return false;
  253.   }
  254.   //WriteLog("CreateRemoteProcess...");
  255.       hThread = CreateRemoteThread(hProcess, NULL, 0, 
  256.          (LPTHREAD_START_ROUTINE)(DWORD) pdwCodeRemote,
  257.          pInjLibInfoRemote, 0, &dwThreadId);
  258.       if (hThread == NULL)
  259.   {
  260.   //WriteLog("CreateRemoteProcess failed");
  261.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  262.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  263. CloseHandle(hProcess);
  264.   return false;
  265.   }
  266.   //WriteLog("CreateRemoteThread success, WaitForSingleObject...");
  267.       WaitForSingleObject(hThread, INFINITE);
  268.       if (hThread != NULL)
  269.   {
  270.          GetExitCodeThread(hThread, (PDWORD) &hinstDllRemote);
  271.          CloseHandle(hThread);
  272.       }
  273.       // Let the remote thread start executing the remote 
  274.       // ThreadFunc function using our modified stack, which
  275.       // now contains an initialized INJLIBINFO structure.
  276.       if(pdwCodeRemote)
  277.   {
  278.   VirtualFreeEx(hProcess, pdwCodeRemote, 0, MEM_RELEASE);
  279.   }
  280.       if(pInjLibInfoRemote)
  281.   {
  282.   VirtualFreeEx(hProcess, pInjLibInfoRemote, 0, MEM_RELEASE);
  283.   }
  284. //WriteLog("OK++++");
  285. CloseHandle(hProcess);
  286. return(hinstDllRemote != NULL);
  287. }