变速齿轮

/*

变速齿轮原理是,游戏在刷新画面时会用到时钟来控制刷新速度,有过游戏开发的人都知道,一般游戏锁定1秒30帧,这样会很流畅,人眼有视觉停顿,当速度达到1秒16帧的时候,就是在跑动画了,游戏用到的计时器有大部分是两个windows提供的api函数,一个是::GetTickCount,一个是::timeGetTime,这两个api的原型请查msdn,我们利用hook api 去修改它的值,从而改变游戏速度,下面是示例源代码。

工程是一个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;
}
/**************************************************************************/
BOOL WINAPI HookApi2(LPCSTR modname,char funname[],PROC hook,SetParam_Ptr myParam){
 //初始化内存
 memset((myParam->m_newjmp),0,sizeof(BYTE)*12);
 memset((myParam->m_oldjmp),0,sizeof(BYTE)*12);
 //生成跳转语句
 BYTE newjmp[12]={0x00,0x00,0x00,0x00,0xB8,0x00,0x00,0x40,0x00,0xFF,0xE0,0x00}; 
 //拷贝内存
 BYTE *temp=myParam->m_newjmp;
 memcpy(temp,newjmp,sizeof(BYTE)*12);
 //保存我们自己的api地址
 *(DWORD*)(myParam->m_newjmp+5)=(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,12,PAGE_READWRITE,&oldprotect);
  //保存原来的8字节
  BYTE *temp2=myParam->m_oldjmp;
  memcpy(temp2,myParam->m_apiaddress,sizeof(BYTE)*12);
  //写入原来的执行代码
  ::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_newjmp,sizeof(DWORD)*3,NULL);
  ::VirtualProtect(myParam->m_apiaddress,12,mbi.Protect,0);
 }
 return true;
}

//取消挂钩API
BOOL WINAPI UnHookApi2(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,12,PAGE_READWRITE,&oldprotect);
  //写入真正的API地址
  ::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_oldjmp,sizeof(BYTE)*12,NULL);
  ::VirtualProtect(myParam->m_apiaddress,12,mbi.Protect,0);
  return true;
 } 
 return false;
}
//重新挂钩API
BOOL WINAPI ReHookApi2(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,12,PAGE_READWRITE,&oldprotect);
  //写入我们自己的代理API地址
  ::WriteProcessMemory(::GetCurrentProcess(),(void*)myParam->m_apiaddress,myParam->m_newjmp,sizeof(BYTE)*12,NULL);
  ::VirtualProtect(myParam->m_apiaddress,12,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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值