鱼C论坛

 找回密码
 立即注册
查看: 3303|回复: 7

[技术交流] APIHOOK拦截MessageBox

[复制链接]
发表于 2015-2-25 11:54:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 迷雾少年 于 2015-2-25 11:57 编辑
不久开学了!!!做个小例子送给大家~~~~
小小例子 ,高手勿喷!!!

  1. #include<windows.h>

  2. LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
  3. /*
  4. Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数)。
  5. 回调函数需要到函数最后面几行找
  6. */

  7. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,PSTR szCmdLine,int iCmdShow)

  8. {
  9. static TCHAR szAppName[] = TEXT("Windows");
  10. HWND hwnd;
  11. MSG msg;
  12. WNDCLASS wndclass;
  13. wndclass.style = CS_HREDRAW;
  14. wndclass.lpfnWndProc = WndProc;
  15. wndclass.cbClsExtra = 0;
  16. wndclass.cbWndExtra = 0;
  17. wndclass.hInstance = hInstance;
  18. wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
  19. wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
  20. wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_CAPTIONTEXT); //背景色
  21. wndclass.lpszMenuName = NULL;
  22. wndclass.lpszClassName = szAppName;


  23. if(!RegisterClass(&wndclass))
  24. {

  25. MessageBox(NULL,TEXT("这个程序无法执行"),szAppName,MB_OK);
  26. return 0;
  27. }


  28. hwnd =CreateWindow(szAppName,
  29. TEXT("AAAAAAAAAA"),
  30. WS_OVERLAPPEDWINDOW,
  31. CW_USEDEFAULT,
  32. CW_USEDEFAULT,
  33. CW_USEDEFAULT,
  34. CW_USEDEFAULT,
  35. NULL,
  36. NULL,
  37. hInstance,
  38. NULL);

  39. ShowWindow(hwnd,iCmdShow); //显示窗口
  40. UpdateWindow(hwnd); //更新窗口

  41. while(GetMessage(&msg,NULL,0,0))


  42. {
  43. TranslateMessage(&msg);


  44. DispatchMessage(&msg);

  45. }
  46. return msg.wParam;


  47. }

  48. /*
  49. WINUSERAPI int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
  50. */

  51. /* 根据原型我们 自己定义一个函数*/
  52. /* PS 不要修改返回值和参数类型或参数个数 否则栈不平衡 */
  53. int  _MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
  54. {
  55. /* 在这里我们可以做很多事 */
  56. /* 比如直接返回 等于啥也没调用 */
  57. /* 还可以在之前保存入口的5字节现在在这里修改回去 然后调用就可以 实现数据监控 */
  58. return 0;
  59. }



  60. <FONT color=red>//内存对齐
  61. #pragma pack(1)
  62. struct _
  63. {
  64. BYTE type; //直接填233 也就是JMP
  65. int *p; //地址 需要计算
  66. };</FONT>


  67. void _Created(HWND hWnd)
  68. {
  69. _ __={0};
  70. __.type = 233; //233 = JMP

  71. // USER32.DLL 为什么是这个DL 因为我们要拦截的函数在里面
  72. char szUsee32[] = "User32.DLL";
  73. //为什么是char 因为 GetProcAddress 函数第二个参数是char*
  74. char szFunName[] = "MessageBoxA"; //拦截 ansi版的
  75. //加载这个DLL返回事例句柄 也可以用 GetModuleHandle
  76. HMODULE hModule = LoadLibraryA(szUsee32);
  77. //得到 MessageBoxA 函数在内存的地址
  78. <FONT color=red>void *p = GetProcAddress(hModule,szFunName); //</FONT>
  79. // 关键 计算 最终地址 = 我们函数地址 - 目标地址 - 5
  80. int* address =(int*)((int)_MessageBoxA - (int)p - 5);
  81. // 把计算后的地址放上去
  82. __.p = address;

  83. //得到最终地址后还要做一件事

  84. //我们要做的就是把 MessageBoxA 函数入口的 5 个字节改为 jmp address 这个address就是我们经过计算后的地址
  85. //但是默认DLL加载到的那段地址空间不能写数据
  86. //所以我们要修改他的内存属性
  87. //需要用 VirtualProtectEx VirtualProtect VirtualProtectEx 是 VirtualProtect 扩展版 推荐用VirtualProtectEx
  88. //http://baike.baidu.com/link?url=nH6bZ9peV5SPveHjtRNzG-bIsm7pNQJJTlomZjerGvYqr1aCY4FhGBtmWo_GRkHBwzThbB-kWAUov6BfvUSFz_
  89. HANDLE hProcess = (HANDLE)-1; //-1代表我们自身进程句柄
  90. DWORD lNewPro = PAGE_EXECUTE_READWRITE,lOldPro=0 ;//属性为可读可写
  91. //如果成功,返回非零。失败返回零。

  92. <FONT color=red>int ret = VirtualProtectEx(hProcess,(LPVOID)p,5,lNewPro,&lOldPro</FONT>);
  93. if(!ret) MessageBoxA(NULL,"擦,属性修改失败",NULL,NULL);


  94. /* 实际写入了多少字节 */
  95. DWORD _Byte = 0;

  96. //第一个参数是进程句柄
  97. //第二个参数是写的地址
  98. //第三个参数是要写的数据缓冲区
  99. //第四个参数是要写多少字节
  100. //第五个参数是函数实际写入多少字节了

  101. // 一次性写入去
  102. <FONT color=red>ret = WriteProcessMemory(hProcess,(LPVOID)p,(LPCVOID)&__,5,&_Byte);</FONT>


  103. //然后调用 实际是到我们的函数了
  104. MessageBoxA(NULL,NULL,NULL,NULL);




  105. }



  106. LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
  107. {


  108. switch (message)
  109. {
  110. case WM_DESTROY:
  111. PostQuitMessage(0);
  112. break;
  113. case WM_CREATE: //当接到窗口创建完的消息
  114. _Created(hwnd);
  115. break;
  116. }

  117. return DefWindowProc(hwnd, message, wParam, lParam);
  118. }
复制代码




图片
6.png
只能执行和READ 所以我们要修改属性
7.png
可以看到 函数入口变成JMP  XXXX了

然后按F5

8.png
如果你按F5继续走

结果是这样
9.png
为什么??

MessageBoxA 这个函数是 _stacall 协定的
但是我们定义的       函数是 _cdecl协定的

这样就导致了栈不平衡

所以呢
10.png
在前面加个 __stdcall

然后运行
正常

没有消息框也没有错误 -> ->



打得很辛苦的 ~~~顶下吧














评分

参与人数 4荣誉 +16 鱼币 +16 贡献 +9 收起 理由
拈花小仙 + 5 + 5 + 3 感谢楼主无私奉献!
freeparty + 5 + 5 + 5 支持楼主!
1048870116 + 5 + 5 + 1 感谢楼主无私奉献!
川本姨夫 + 1 + 1 支持原创

查看全部评分

本帖被以下淘专辑推荐:

  • · 迷雾|主题: 5, 订阅: 1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2015-2-25 13:16:22 | 显示全部楼层
2楼自坐
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-25 16:27:31 | 显示全部楼层
学习一下
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-25 23:10:45 | 显示全部楼层
屌屌的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-2-27 18:45:34 | 显示全部楼层
这是什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2015-2-27 19:37:43 | 显示全部楼层

拦截 MessageBoxA
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-2 11:53:02 | 显示全部楼层
{:1_1:}好贴必回  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-3-3 09:01:45 | 显示全部楼层
求鱼币,看不懂
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 08:11

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表