为什么在已经运行的程序中使用此接口::WriteProcessMemory,会导致程序崩溃?(在线求解)

寻觅smile 2014-06-30 09:09:25
生成的dll,注入到“页游”所在进程后,页面直接崩溃。
调试问题出现在自定义HookApi函数里的WriteProcessMemory里,但返回值是1,应该没错啊,求大师兄指定一二。下面是代码。


代码来自http://blog.csdn.net/wuleibilly3/article/details/4359770
工程是一个dll
*/
/************myhook.cpp******************/
#include "stdafx.h"
#include <stdio.h>
#define KEYHOOKLIB_EXPORTS
#include "myhook.h"
#include <mmsystem.h>
#include <process.h>
#pragma comment(lib,"winmm.lib")
HWND g_hWndCaller = NULL; // 保存主窗口句柄
SetParam_Ptr mySetParam[12];

/***************************HOOKAPI部分通过修改API头8字节******************/
BOOL WINAPI HookApi(LPCSTR modname,char funname[],PROC hook,SetParam_Ptr myParam){
//初始化内存
memset((myParam->m_newjmp),0,sizeof(BYTE)*8);
memset((myParam->m_oldjmp),0,sizeof(BYTE)*8);
//生成跳转语句
BYTE newjmp[8]={0xB8,0x00,0x00,0x40,0x00,0xFF,0xE0,0x00};
//拷贝内存
BYTE *temp=myParam->m_newjmp;
memcpy(temp,newjmp,sizeof(BYTE)*8);
//保存我们自己的api地址
*(DWORD*)(myParam->m_newjmp+1)=(DWORD)hook;
//加载指定模块
myParam->m_hmodule=::LoadLibrary((char*)modname);
if(myParam->m_hmodule==NULL){
myParam->m_apiaddress=NULL;
return false;
}
//获得API地址
myParam->m_apiaddress=::GetProcAddress(myParam->m_hmodule,funname);

//修改原API地址的前8字节,让它转向我们自己的代理API函数
if(myParam->m_apiaddress!=NULL){
DWORD oldprotect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(myParam->m_apiaddress,&mbi,sizeof(mbi));
::VirtualProtect(myParam->m_apiaddress,8,PAGE_READWRITE,&oldprotect);
//保存原来的8字节
BYTE *temp2=myParam->m_oldjmp;
memcpy(temp2,myParam->m_apiaddress,sizeof(BYTE)*8);
//写入原来的执行代码
::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_newjmp,sizeof(DWORD)*2,NULL);
::VirtualProtect(myParam->m_apiaddress,8,mbi.Protect,0);
}
return true;
}

//取消挂钩API
BOOL WINAPI UnHookApi(SetParam_Ptr myParam){
if(myParam->m_apiaddress!=NULL){
DWORD oldprotect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(myParam->m_apiaddress,&mbi,sizeof(mbi));
::VirtualProtect(myParam->m_apiaddress,8,PAGE_READWRITE,&oldprotect);
//写入真正的API地址
::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_oldjmp,sizeof(DWORD)*2,NULL);
::VirtualProtect(myParam->m_apiaddress,8,mbi.Protect,0);
return true;
}
return false;
}
//重新挂钩API
BOOL WINAPI ReHookApi(SetParam_Ptr myParam){
if(myParam->m_apiaddress!=NULL){
DWORD oldprotect;
MEMORY_BASIC_INFORMATION mbi;
::VirtualQuery(myParam->m_apiaddress,&mbi,sizeof(mbi));
::VirtualProtect(myParam->m_apiaddress,8,PAGE_READWRITE,&oldprotect);
//写入我们自己的代理API地址
::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_newjmp,sizeof(DWORD)*2,NULL);
::VirtualProtect(myParam->m_apiaddress,8,mbi.Protect,0);
return true;
}
return false;
}

/***********************我们自己的代理API函数*********************************/
//代理
/*
DWORD __flag__=0;
DWORD WINAPI MyGetTickCount(){
UnHookApi(mySetParam[0]);
if(__flag__>=120){
__flag__=23;
}
DWORD __count__=0;
__flag__+=69;
__count__=::GetTickCount()+__flag__;
ReHookApi(mySetParam[0]);
return __count__;
}
*/
DWORD __flag__=0;
DWORD __flag1__=0;

DWORD WINAPI MyGetTickCount(){
UnHookApi(mySetParam[0]);
// if(__flag__>=120){
// __flag__=23;
// }
__flag1__++;
DWORD __count__=::GetTickCount();
__count__+=128*__flag1__;
// ::MessageBoxA(NULL,buff,"tick",MB_OK);
ReHookApi(mySetParam[0]);
return __count__;
}
DWORD WINAPI MytimeGetTime(){
UnHookApi(mySetParam[1]);
DWORD i=::timeGetTime();
__flag__++;
i+=128*__flag__;
// ::MessageBoxA(NULL,buff,"time",MB_OK);
ReHookApi(mySetParam[1]);
return i;

}

//HOOK初始化
int HookInit(){
//申请内存空间
for(int i=0;i<2;i++)
mySetParam[i]=new SetParam;


HookApi("winmm.dll","timeGetTime",(PROC)MytimeGetTime,mySetParam[1]);
HookApi("Kernel32.dll","GetTickCount",(PROC)MyGetTickCount,mySetParam[0]);

return 0;
}
//释放空间
int ReAllHook(){
for(int i=0;i<2;i++)
UnHookApi(mySetParam[i]);
fclose(fr);

return 1;
}
/**************************************************************************/



/*********************myhook.h****************************/

// 定义函数修饰宏,方便引用本DLL工程的导出函数
#ifdef KEYHOOKLIB_EXPORTS
#define KEYHOOKLIB_API __declspec(dllexport)
#else
#define KEYHOOKLIB_API __declspec(dllimport)
#endif

typedef struct SetParams{
PROC m_apiaddress; //目标函数地址
BYTE m_newjmp[8];//用来保存跳转地址
BYTE m_oldjmp[8];//用来保存原始跳转地址
HMODULE m_hmodule;//模块
}SetParam,*SetParam_Ptr;



// 声明要导出的函数
//初始化挂钩api
int HookInit();
//取消挂钩API
int ReAllHook();
BOOL KEYHOOKLIB_API WINAPI HookApi(LPCWSTR modname,char funname[],PROC hook,SetParam_Ptr myParam);
//重新挂钩API
BOOL KEYHOOKLIB_API WINAPI ReHookApi(SetParam_Ptr myParam);
//取消挂钩API
BOOL KEYHOOKLIB_API WINAPI UnHookApi(SetParam_Ptr myParam);



/***************************dllmain.cpp**************************/

// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include "stdafx.h"
#include "myhook.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{


switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
HookInit();
// ::MessageBox(NULL,"Hello World!","",MB_OK);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
ReAllHook();
break;
}

return TRUE;
}

/****************************myhook.def***********************/

EXPORTS
HookApi
ReHookApi
UnHookApi
HookInit
...全文
162 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
我不懂电脑 2014-07-02
  • 打赏
  • 举报
回复
修改了程序内存数据,很可能造成对方内存访问错误,崩溃。你需要了解内存内容才能改。

1,221

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧