| 
 | 
 
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册  
 
x
 
 本帖最后由 迷雾少年 于 2015-2-25 11:57 编辑  
不久开学了!!!做个小例子送给大家~~~~ 
小小例子 ,高手勿喷!!! 
 
- #include<windows.h>
 
  
- LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
 
 - /*
 
 - Windows 的窗口总是基于窗口类来创建的,窗口类同时确定了处理窗口消息的窗口过程(回调函数)。
 
 - 回调函数需要到函数最后面几行找
 
 - */
 
  
- int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hprevInstance,PSTR szCmdLine,int iCmdShow)
 
  
- {
 
 - static TCHAR szAppName[] = TEXT("Windows");
 
 - HWND hwnd;
 
 - MSG msg;
 
 - WNDCLASS wndclass;
 
 - wndclass.style = CS_HREDRAW;
 
 - wndclass.lpfnWndProc = WndProc;
 
 - wndclass.cbClsExtra = 0;
 
 - wndclass.cbWndExtra = 0;
 
 - wndclass.hInstance = hInstance;
 
 - wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
 
 - wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
 
 - wndclass.hbrBackground = (HBRUSH)GetStockObject(COLOR_CAPTIONTEXT); //背景色
 
 - wndclass.lpszMenuName = NULL;
 
 - wndclass.lpszClassName = szAppName;
 
  
 
- if(!RegisterClass(&wndclass))
 
 - {
 
  
- MessageBox(NULL,TEXT("这个程序无法执行"),szAppName,MB_OK);
 
 - return 0;
 
 - }
 
  
 
- hwnd =CreateWindow(szAppName,
 
 - TEXT("AAAAAAAAAA"),
 
 - WS_OVERLAPPEDWINDOW,
 
 - CW_USEDEFAULT,
 
 - CW_USEDEFAULT,
 
 - CW_USEDEFAULT,
 
 - CW_USEDEFAULT,
 
 - NULL,
 
 - NULL,
 
 - hInstance,
 
 - NULL);
 
  
- ShowWindow(hwnd,iCmdShow); //显示窗口 
 
 - UpdateWindow(hwnd); //更新窗口
 
  
- while(GetMessage(&msg,NULL,0,0))
 
  
 
- {
 
 - TranslateMessage(&msg);
 
  
 
- DispatchMessage(&msg);
 
  
- } 
 
 - return msg.wParam;
 
  
 
- }
 
  
- /*
 
 - WINUSERAPI int WINAPI MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); 
 
 - */
 
  
- /* 根据原型我们 自己定义一个函数*/
 
 - /* PS 不要修改返回值和参数类型或参数个数 否则栈不平衡 */
 
 - int  _MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
 
 - {
 
 - /* 在这里我们可以做很多事 */
 
 - /* 比如直接返回 等于啥也没调用 */
 
 - /* 还可以在之前保存入口的5字节现在在这里修改回去 然后调用就可以 实现数据监控 */
 
 - return 0;
 
 - }
 
  
 
 
- <FONT color=red>//内存对齐
 
 - #pragma pack(1)
 
 - struct _
 
 - {
 
 - BYTE type; //直接填233 也就是JMP
 
 - int *p; //地址 需要计算
 
 - };</FONT>
 
  
 
- void _Created(HWND hWnd)
 
 - {
 
 - _ __={0};
 
 - __.type = 233; //233 = JMP
 
  
- // USER32.DLL 为什么是这个DL 因为我们要拦截的函数在里面
 
 - char szUsee32[] = "User32.DLL";
 
 - //为什么是char 因为 GetProcAddress 函数第二个参数是char*
 
 - char szFunName[] = "MessageBoxA"; //拦截 ansi版的
 
 - //加载这个DLL返回事例句柄 也可以用 GetModuleHandle
 
 - HMODULE hModule = LoadLibraryA(szUsee32);
 
 - //得到 MessageBoxA 函数在内存的地址
 
 - <FONT color=red>void *p = GetProcAddress(hModule,szFunName); //</FONT>
 
 - // 关键 计算 最终地址 = 我们函数地址 - 目标地址 - 5
 
 - int* address =(int*)((int)_MessageBoxA - (int)p - 5);
 
 - // 把计算后的地址放上去 
 
 - __.p = address;
 
  
- //得到最终地址后还要做一件事
 
  
- //我们要做的就是把 MessageBoxA 函数入口的 5 个字节改为 jmp address 这个address就是我们经过计算后的地址
 
 - //但是默认DLL加载到的那段地址空间不能写数据 
 
 - //所以我们要修改他的内存属性
 
 - //需要用 VirtualProtectEx VirtualProtect VirtualProtectEx 是 VirtualProtect 扩展版 推荐用VirtualProtectEx 
 
 - //http://baike.baidu.com/link?url=nH6bZ9peV5SPveHjtRNzG-bIsm7pNQJJTlomZjerGvYqr1aCY4FhGBtmWo_GRkHBwzThbB-kWAUov6BfvUSFz_
 
 - HANDLE hProcess = (HANDLE)-1; //-1代表我们自身进程句柄
 
 - DWORD lNewPro = PAGE_EXECUTE_READWRITE,lOldPro=0 ;//属性为可读可写
 
 - //如果成功,返回非零。失败返回零。
 
  
- <FONT color=red>int ret = VirtualProtectEx(hProcess,(LPVOID)p,5,lNewPro,&lOldPro</FONT>);
 
 - if(!ret) MessageBoxA(NULL,"擦,属性修改失败",NULL,NULL);
 
  
 
- /* 实际写入了多少字节 */
 
 - DWORD _Byte = 0;
 
  
- //第一个参数是进程句柄
 
 - //第二个参数是写的地址
 
 - //第三个参数是要写的数据缓冲区
 
 - //第四个参数是要写多少字节
 
 - //第五个参数是函数实际写入多少字节了
 
  
- // 一次性写入去
 
 - <FONT color=red>ret = WriteProcessMemory(hProcess,(LPVOID)p,(LPCVOID)&__,5,&_Byte);</FONT>
 
  
 
- //然后调用 实际是到我们的函数了
 
 - MessageBoxA(NULL,NULL,NULL,NULL);
 
  
 
 
 
- }
 
  
 
 
- LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
 
 - {
 
  
 
- switch (message)
 
 - {
 
 - case WM_DESTROY: 
 
 - PostQuitMessage(0);
 
 - break;
 
 - case WM_CREATE: //当接到窗口创建完的消息
 
 - _Created(hwnd);
 
 - break;
 
 - }
 
  
- return DefWindowProc(hwnd, message, wParam, lParam);
 
 - }
 
  复制代码 
 
 
 
图片 
 
 
只能执行和READ 所以我们要修改属性 
 
 
可以看到 函数入口变成JMP  XXXX了 
 
然后按F5 
 
 
 
如果你按F5继续走 
 
结果是这样 
 
 
为什么?? 
 
MessageBoxA 这个函数是 _stacall 协定的 
但是我们定义的       函数是 _cdecl协定的 
 
这样就导致了栈不平衡 
 
所以呢 
 
 
在前面加个 __stdcall 
 
然后运行 
正常 
 
没有消息框也没有错误 -> -> 
 
 
 
打得很辛苦的 ~~~顶下吧 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 |   
 
评分
- 
查看全部评分
 
 
 
 
 
 |