win原理Day006.zip

TestDll

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. #include <windows.h>
  4. BOOL APIENTRY DllMain( HMODULE hModule,
  5. DWORD ul_reason_for_call,
  6. LPVOID lpReserved
  7. )
  8. {
  9. switch (ul_reason_for_call)
  10. {
  11. case DLL_PROCESS_ATTACH:
  12. MessageBox(0, L"注入成功", L"good", 0);
  13. case DLL_THREAD_ATTACH:
  14. case DLL_THREAD_DETACH:
  15. case DLL_PROCESS_DETACH:
  16. break;
  17. }
  18. return TRUE;
  19. }

消息钩子

消息钩子DLL

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. #include <windows.h>
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. HHOOK g_hook;
  7. HMODULE g_mod;
  8. LRESULT CALLBACK KeyboardProc(
  9. _In_ int code,
  10. _In_ WPARAM wParam,
  11. _In_ LPARAM lParam
  12. )
  13. {
  14. // 判断是否wParam与lParam都有键盘消息,是的话则执行打印操作
  15. if (code == HC_ACTION){
  16. // 将256个虚拟键的状态拷贝到指定的缓冲区中,如果成功则继续
  17. BYTE KeyState[256] = { 0 };
  18. if (GetKeyboardState(KeyState)) {
  19. // 得到第16–23位,键盘虚拟码
  20. LONG KeyInfo = lParam;
  21. UINT keyCode = (KeyInfo >> 16) & 0x00ff;
  22. WCHAR wKeyCode = 0;
  23. ToAscii((UINT)wParam, keyCode, KeyState, (LPWORD)&wKeyCode, 0);
  24. // 将其打印出来
  25. CHAR szInfo[10] = { 0 };
  26. sprintf_s(szInfo, _countof(szInfo), "Hook_%c", wKeyCode);
  27. OutputDebugStringA(szInfo);
  28. return 0;
  29. }
  30. }
  31. // char str[10] = {};
  32. // str[0] = wParam;
  33. // OutputDebugStringA(str);
  34. return CallNextHookEx(g_hook, code, wParam, lParam);
  35. }
  36. void OnHook()
  37. {
  38. g_hook = SetWindowsHookEx(WH_KEYBOARD,
  39. KeyboardProc, g_mod, 0);
  40. // if ()
  41. // {
  42. // }
  43. }
  44. void UnHook()
  45. {
  46. if (!g_hook)
  47. {
  48. UnhookWindowsHookEx(g_hook);
  49. }
  50. }
  51. BOOL APIENTRY DllMain( HMODULE hModule,
  52. DWORD ul_reason_for_call,
  53. LPVOID lpReserved
  54. )
  55. {
  56. switch (ul_reason_for_call)
  57. {
  58. case DLL_PROCESS_ATTACH:
  59. MessageBoxW(0, 0, 0, 0);
  60. g_mod = hModule;//模块句柄
  61. OnHook();
  62. //case DLL_THREAD_ATTACH:
  63. //case DLL_THREAD_DETACH:
  64. //case DLL_PROCESS_DETACH:
  65. //UnHook();
  66. break;
  67. }
  68. return TRUE;
  69. }

内联HOOK

  1. // 内联HOOK.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. void UnHook();
  6. void OnHook();
  7. char g_OldCode[5];
  8. char g_NewCode[5] = { 0xE9 };
  9. int WINAPI MyMessageBoxW(
  10. _In_opt_ HWND hWnd,
  11. _In_opt_ LPCWSTR lpText,
  12. _In_opt_ LPCWSTR lpCaption,
  13. _In_ UINT uType)
  14. {
  15. lpText = L"你被HOOK\n";
  16. lpCaption = L"嘿嘿";
  17. //先卸载
  18. UnHook();
  19. //调用MessageBoxW
  20. int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType);
  21. //再次挂上钩子
  22. OnHook();
  23. return nRet;
  24. }
  25. void OnHook()
  26. {
  27. //1.保存原函数被修改的代码
  28. memcpy(g_OldCode, MessageBoxW, 5);
  29. //2.计算偏移量
  30. DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5;
  31. //3.写入指令
  32. memcpy(g_NewCode + 1, &dwOffset, 4);
  33. //修改内存属性(代码段没有可写属性)
  34. DWORD dwOld;
  35. VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);
  36. memcpy(MessageBoxW, g_NewCode, 5);
  37. VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);
  38. }
  39. void UnHook()
  40. {
  41. DWORD dwOld;
  42. VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);
  43. memcpy(MessageBoxW, g_OldCode, 5);
  44. VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);
  45. }
  46. int _tmain(int argc, _TCHAR* argv[])
  47. {
  48. MessageBoxW(0, 0, 0, 0);
  49. OnHook();
  50. MessageBoxW(0, 0, 0, 0);
  51. return 0;
  52. }

内联HOOK_DLL

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. #include <windows.h>
  4. void UnHook();
  5. void OnHook();
  6. char g_OldCode[5];
  7. char g_NewCode[5] = { 0xE9 };
  8. int WINAPI MyMessageBoxW(
  9. _In_opt_ HWND hWnd,
  10. _In_opt_ LPCWSTR lpText,
  11. _In_opt_ LPCWSTR lpCaption,
  12. _In_ UINT uType)
  13. {
  14. lpText = L"你被HOOK\n";
  15. lpCaption = L"嘿嘿";
  16. //先卸载
  17. UnHook();
  18. //调用MessageBoxW
  19. int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType);
  20. //再次挂上钩子
  21. OnHook();
  22. return nRet;
  23. }
  24. void OnHook()
  25. {
  26. //1.保存原函数被修改的代码
  27. memcpy(g_OldCode, MessageBoxW, 5);
  28. //2.计算偏移量
  29. DWORD dwOffset = (DWORD)MyMessageBoxW - (DWORD)MessageBoxW - 5;
  30. //3.写入指令
  31. memcpy(g_NewCode + 1, &dwOffset, 4);
  32. //修改内存属性(代码段没有可写属性)
  33. DWORD dwOld;
  34. VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);
  35. memcpy(MessageBoxW, g_NewCode, 5);
  36. VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);
  37. }
  38. void UnHook()
  39. {
  40. DWORD dwOld;
  41. VirtualProtect(MessageBoxW, 5, PAGE_EXECUTE_READWRITE, &dwOld);
  42. memcpy(MessageBoxW, g_OldCode, 5);
  43. VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);
  44. }
  45. BOOL APIENTRY DllMain( HMODULE hModule,
  46. DWORD ul_reason_for_call,
  47. LPVOID lpReserved
  48. )
  49. {
  50. switch (ul_reason_for_call)
  51. {
  52. case DLL_PROCESS_ATTACH:
  53. OnHook();
  54. //case DLL_THREAD_ATTACH:
  55. //case DLL_THREAD_DETACH:
  56. //case DLL_PROCESS_DETACH:
  57. // UnHook();
  58. break;
  59. }
  60. return TRUE;
  61. }

IAT_HOOK

  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。
  2. #include "stdafx.h"
  3. #include <windows.h>
  4. DWORD g_IatAddr;
  5. DWORD g_FunOldAddr;
  6. typedef int (WINAPI* FP_MessageBoxW)(
  7. _In_opt_ HWND hWnd,
  8. _In_opt_ LPCWSTR lpText,
  9. _In_opt_ LPCWSTR lpCaption,
  10. _In_ UINT uType);
  11. int WINAPI MyMessageBoxW(
  12. _In_opt_ HWND hWnd,
  13. _In_opt_ LPCWSTR lpText,
  14. _In_opt_ LPCWSTR lpCaption,
  15. _In_ UINT uType)
  16. {
  17. lpText = L"你被HOOK\n";
  18. lpCaption = L"嘿嘿";
  19. FP_MessageBoxW FpMsg = (FP_MessageBoxW)g_FunOldAddr;
  20. return FpMsg(hWnd, lpText, lpCaption, uType);
  21. }
  22. void OnHook(char* pFunName, char* pDllName)
  23. {
  24. //遍历导入表(INT)
  25. HMODULE hMod = GetModuleHandle(NULL);
  26. PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER)hMod;
  27. PIMAGE_NT_HEADERS pNt = (PIMAGE_NT_HEADERS)(pDos->e_lfanew + (DWORD)hMod);
  28. DWORD dwImportRVA = pNt->OptionalHeader.DataDirectory[1].VirtualAddress;
  29. PIMAGE_IMPORT_DESCRIPTOR pImport =
  30. (PIMAGE_IMPORT_DESCRIPTOR)
  31. (dwImportRVA + (DWORD)hMod);
  32. while (pImport->Name)
  33. {
  34. char* pDll = (char*)(pImport->Name + (DWORD)hMod);
  35. if (!_stricmp(pDll,pDllName))
  36. {
  37. //遍历INT
  38. IMAGE_THUNK_DATA* pInt =
  39. (IMAGE_THUNK_DATA*)
  40. (pImport->OriginalFirstThunk + (DWORD)hMod);
  41. IMAGE_THUNK_DATA* pIat =
  42. (IMAGE_THUNK_DATA*)
  43. (pImport->FirstThunk + (DWORD)hMod);
  44. while (pInt->u1.AddressOfData)
  45. {
  46. if (!IMAGE_SNAP_BY_ORDINAL(pInt->u1.AddressOfData))
  47. {
  48. PIMAGE_IMPORT_BY_NAME pName = (PIMAGE_IMPORT_BY_NAME)(pInt->u1.AddressOfData + (DWORD)hMod);
  49. if (!_stricmp(pName->Name,pFunName))
  50. {
  51. //函数地址
  52. g_FunOldAddr = pIat->u1.Function;
  53. g_IatAddr = (DWORD)pIat;
  54. //修改地址
  55. //修改内存属性
  56. DWORD dwOld;
  57. VirtualProtect(pIat, 4, PAGE_READWRITE, &dwOld);
  58. *(DWORD*)pIat = (DWORD)MyMessageBoxW;
  59. VirtualProtect(pIat, 4, dwOld, &dwOld);
  60. return;
  61. }
  62. }
  63. //下一个函数
  64. pInt++;
  65. pIat++;
  66. }
  67. }
  68. //下一个模块
  69. pImport++;
  70. }
  71. }
  72. void UnHook()
  73. {
  74. DWORD dwOld;
  75. VirtualProtect((LPVOID)g_IatAddr, 4, PAGE_READWRITE, &dwOld);
  76. *(DWORD*)g_IatAddr = g_FunOldAddr;
  77. VirtualProtect((LPVOID)g_IatAddr, 4, dwOld, &dwOld);
  78. }
  79. BOOL APIENTRY DllMain( HMODULE hModule,
  80. DWORD ul_reason_for_call,
  81. LPVOID lpReserved
  82. )
  83. {
  84. switch (ul_reason_for_call)
  85. {
  86. case DLL_PROCESS_ATTACH:
  87. OnHook("MessageBoxW", "user32.dll");
  88. case DLL_THREAD_ATTACH:
  89. case DLL_THREAD_DETACH:
  90. case DLL_PROCESS_DETACH:
  91. break;
  92. }
  93. return TRUE;
  94. }

注入工具代码

  1. // win原理Day006.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include <windows.h>
  5. #define DLL_MESSAGE "D:\\ProgramVS\\win原理Day006\\Debug\\消息钩子DLL.dll"
  6. #define DLL_PATH "D:\\ProgramVS\\win原理Day006\\Debug\\TestDll.dll"
  7. #define DLL_INLINE "D:\\ProgramVS\\win原理Day006\\Debug\\内联HOOK_DLL.dll"
  8. #define DLL_IAT "D:\\ProgramVS\\win原理Day006\\Debug\\IAT_HOOK.dll"
  9. //远程线程注入
  10. void Inject(char* pDllPath, DWORD dwPid)
  11. {
  12. //1.打开进程获取句柄
  13. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
  14. if (!hProcess)
  15. {
  16. printf("句柄打开失败\n");
  17. return;
  18. }
  19. //2. 再目标进程中申请足够大的内存,存储DLL的全路径
  20. LPVOID lpBuf = VirtualAllocEx(hProcess, NULL,
  21. strlen(pDllPath), MEM_COMMIT, PAGE_READWRITE);
  22. if (!lpBuf)
  23. {
  24. printf("内存申请失败\n");
  25. CloseHandle(hProcess);
  26. return;
  27. }
  28. //3.把DLL全路径写入进去
  29. DWORD dwWrite;
  30. WriteProcessMemory(hProcess, lpBuf,
  31. pDllPath, strlen(pDllPath), &dwWrite);
  32. //4.创建远程线程
  33. HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL,
  34. (LPTHREAD_START_ROUTINE)LoadLibraryA, lpBuf, NULL, NULL);
  35. //5.等待线程结束
  36. WaitForSingleObject(hThread, -1);
  37. //6.释放内存
  38. VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE);
  39. CloseHandle(hProcess);
  40. }
  41. //注入代码
  42. void InjectCode(char* pCode, DWORD dwSize,DWORD dwPid)
  43. {
  44. //1.打开进程获取句柄
  45. HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
  46. if (!hProcess)
  47. {
  48. printf("句柄打开失败\n");
  49. return;
  50. }
  51. //2. 再目标进程中申请足够大的内存,存储DLL的全路径
  52. LPVOID lpBuf = VirtualAllocEx(hProcess, NULL,
  53. strlen(pCode), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
  54. if (!lpBuf)
  55. {
  56. printf("内存申请失败\n");
  57. CloseHandle(hProcess);
  58. return;
  59. }
  60. //3.把DLL全路径写入进去
  61. DWORD dwWrite;
  62. WriteProcessMemory(hProcess, lpBuf,
  63. pCode, dwSize, &dwWrite);
  64. //4.创建远程线程
  65. HANDLE hThread = CreateRemoteThread(hProcess, NULL, NULL,
  66. (LPTHREAD_START_ROUTINE)lpBuf, NULL, NULL, NULL);
  67. //5.等待线程结束
  68. WaitForSingleObject(hThread, -1);
  69. //6.释放内存
  70. VirtualFreeEx(hProcess, lpBuf, 0, MEM_RELEASE);
  71. CloseHandle(hProcess);
  72. }
  73. int _tmain(int argc, _TCHAR* argv[])
  74. {
  75. //HMODULE hMod = LoadLibraryA(DLL_MESSAGE);
  76. int nPid;
  77. printf("输入PID:");
  78. scanf_s("%d", &nPid);
  79. Inject(DLL_IAT, nPid);
  80. //DWORD dwAddr;
  81. // __asm
  82. // {
  83. // push 0;
  84. // push 0;
  85. // push 0;
  86. // push 0;
  87. // mov eax, 0x99999999;
  88. // call eax;
  89. // }
  90. //
  91. // char pCode[] = "\x6A\x00\x6A\x00\x6A\x00\x6A\x00\xB8\x99\x99\x99\x99\xFF\xD0";
  92. // DWORD dwAddr;
  93. // scanf_s("%x", &dwAddr);
  94. // *(int*)(pCode + 9) = dwAddr;
  95. // DWORD dwPid;
  96. // scanf_s("%d", &dwPid);
  97. // InjectCode(pCode, sizeof(pCode),dwPid);
  98. //测试
  99. // printf("MessageBoxW:0x%08X\n", (DWORD)MessageBoxW);
  100. system("pause");
  101. return 0;
  102. }