Flash加速功能实现

news/2024/11/8 0:31:40/

实现Flash加速原理是Hook住与时间相关的几个API函数,将API返回的实际时间值进行改写,来实现加速。

模板依赖于mhook库(https://github.com/SirAnthony/mhook)

#pragma onceclass SpeedMgr
{
public:static SpeedMgr& Instance();BOOL StartService();BOOL StopService();BOOL SetSpeed(float fRate);BOOL Restore();// Inner callDWORD WINAPI GetTickCount(VOID);BOOL  WINAPI QueryPerformanceFrequency(__out LARGE_INTEGER *lpFrequency);BOOL  WINAPI QueryPerformanceCounter(__out LARGE_INTEGER *lpPerformanceCount);VOID  WINAPI Sleep(__in DWORD dwMilliseconds);DWORD WINAPI timeGetTime(VOID);private:SpeedMgr(void);~SpeedMgr(void);private:// EnableBOOL	bSpeed_;// GetTickCountDWORD	gtcLastReal_;DWORD	gtcLastFake_;base::TLock gtc_lock_;// timeGetTimeDWORD	tgtLastReal_;DWORD	tgtLastFake_;base::TLock tgt_lock_;// QueryPerformanceCounterLONGLONG	qpcLastReal_;LONGLONG	qpcLastFake_;base::TLock qpc_lock_;// QueryPerformanceFrequencyLONGLONG	qpfLastReal_;LONGLONG	qpfLastFake_;base::TLock qpf_lock_;// Speed Factorfloat	speedFactor_;
};

cpp实现

#include "StdAfx.h"
#include "SpeedMgr.h"
#include "mhook.h"
#include <tchar.h>
#include <math.h>// kernel32.dll
typedef DWORD (WINAPI *pfn_GetTickCount)(VOID);
typedef BOOL  (WINAPI *pfn_QueryPerformanceFrequency)(__out LARGE_INTEGER *lpFrequency);
typedef BOOL  (WINAPI *pfn_QueryPerformanceCounter)(__out LARGE_INTEGER *lpPerformanceCount);
typedef VOID  (WINAPI *pfn_Sleep)(__in DWORD dwMilliseconds);
// winmm.dll
typedef DWORD (WINAPI *pfn_timeGetTime)(VOID);// Real Functions
namespace SpeedAid
{// kernel32.dllpfn_GetTickCount				Real_GetTickCount				= NULL;pfn_QueryPerformanceFrequency	Real_QueryPerformanceFrequency	= NULL;pfn_QueryPerformanceCounter		Real_QueryPerformanceCounter	= NULL;pfn_Sleep						Real_Sleep						= NULL;// winmm.dllpfn_timeGetTime					Real_timeGetTime				= NULL;
}// Hook Functions
// kernel32.dll
DWORD WINAPI Hook_GetTickCount(VOID)
{return SpeedMgr::Instance().GetTickCount();
}BOOL WINAPI Hook_QueryPerformanceFrequency(__out LARGE_INTEGER *lpFrequency)
{return SpeedMgr::Instance().QueryPerformanceFrequency(lpFrequency);
}BOOL WINAPI Hook_QueryPerformanceCounter(__out LARGE_INTEGER *lpPerformanceCount)
{return SpeedMgr::Instance().QueryPerformanceCounter(lpPerformanceCount);
}VOID WINAPI Hook_Sleep(__in DWORD dwMilliseconds)
{return SpeedMgr::Instance().Sleep(dwMilliseconds);
}// winmm.dll
DWORD WINAPI Hook_timeGetTime(VOID)
{return SpeedMgr::Instance().timeGetTime();
}SpeedMgr::SpeedMgr(void): speedFactor_(1), bSpeed_(FALSE), gtcLastReal_(0), gtcLastFake_(0), tgtLastReal_(0), tgtLastFake_(0), qpcLastReal_(0), qpcLastFake_(0), qpfLastReal_(0), qpfLastFake_(0)
{HMODULE hMod							= ::GetModuleHandle(_T("kernel32.dll"));SpeedAid::Real_GetTickCount				= (pfn_GetTickCount)				::GetProcAddress(hMod,	"GetTickCount");SpeedAid::Real_QueryPerformanceFrequency= (pfn_QueryPerformanceFrequency)	::GetProcAddress(hMod,	"QueryPerformanceFrequency");SpeedAid::Real_QueryPerformanceCounter	= (pfn_QueryPerformanceCounter)		::GetProcAddress(hMod,	"QueryPerformanceCounter");SpeedAid::Real_Sleep					= (pfn_Sleep)						::GetProcAddress(hMod,	"Sleep");hMod									= LoadLibrary(_T("winmm.dll"));SpeedAid::Real_timeGetTime				= (pfn_timeGetTime)					::GetProcAddress(hMod,	"timeGetTime");
}SpeedMgr::~SpeedMgr(void)
{StopService();
}SpeedMgr& SpeedMgr::Instance()
{static SpeedMgr instance;return instance;
}BOOL SpeedMgr::StartService()
{BOOL ret = TRUE;ret = Mhook_SetHook((PVOID*)&SpeedAid::Real_GetTickCount,				Hook_GetTickCount);ret = Mhook_SetHook((PVOID*)&SpeedAid::Real_QueryPerformanceFrequency,	Hook_QueryPerformanceFrequency);ret = Mhook_SetHook((PVOID*)&SpeedAid::Real_QueryPerformanceCounter,	Hook_QueryPerformanceCounter);ret = Mhook_SetHook((PVOID*)&SpeedAid::Real_Sleep,						Hook_Sleep);ret = Mhook_SetHook((PVOID*)&SpeedAid::Real_timeGetTime,				Hook_timeGetTime);// 初始化值gtcLastReal_ = gtcLastFake_ = SpeedAid::Real_GetTickCount();tgtLastReal_ = tgtLastFake_ = SpeedAid::Real_timeGetTime();LARGE_INTEGER f;SpeedAid::Real_QueryPerformanceFrequency(&f);qpfLastReal_ = qpfLastFake_ = f.QuadPart;LARGE_INTEGER t;SpeedAid::Real_QueryPerformanceCounter(&t);qpcLastReal_ = qpcLastFake_ = t.QuadPart;return ret;
}BOOL SpeedMgr::StopService()
{BOOL ret = TRUE;ret = Mhook_Unhook ((PVOID*)&Hook_GetTickCount);ret = Mhook_Unhook ((PVOID*)&Hook_QueryPerformanceCounter);ret = Mhook_Unhook ((PVOID*)&Hook_QueryPerformanceFrequency);ret = Mhook_Unhook ((PVOID*)&Hook_Sleep);ret = Mhook_Unhook ((PVOID*)&Hook_timeGetTime);return ret;
}BOOL SpeedMgr::SetSpeed(float fRate)
{bSpeed_ = TRUE;speedFactor_ = fRate;return TRUE;
}BOOL SpeedMgr::Restore()
{bSpeed_ = FALSE;speedFactor_ = 1;return TRUE;
}// Inner call
DWORD WINAPI SpeedMgr::GetTickCount(VOID)
{DWORD ret = SpeedAid::Real_GetTickCount();DWORD nReal = ret;DWORD dReal = nReal - gtcLastReal_;DWORD dFake = speedFactor_ * dReal;gtcLastFake_ = gtcLastFake_ + dFake;gtcLastReal_ = nReal;return bSpeed_ ? gtcLastFake_ : gtcLastReal_;
}BOOL  WINAPI SpeedMgr::QueryPerformanceFrequency(__out LARGE_INTEGER *lpFrequency)
{BOOL ret = SpeedAid::Real_QueryPerformanceFrequency(lpFrequency);LONGLONG nReal = lpFrequency->QuadPart;LONGLONG dReal = nReal - qpfLastReal_;LONGLONG dFake = speedFactor_ * dReal;qpfLastFake_ = qpfLastFake_ + dFake;qpfLastReal_ = nReal;if (bSpeed_)lpFrequency->QuadPart = qpfLastFake_;return ret;
}BOOL  WINAPI SpeedMgr::QueryPerformanceCounter(__out LARGE_INTEGER *lpPerformanceCount)
{BOOL ret = SpeedAid::Real_QueryPerformanceCounter(lpPerformanceCount);LONGLONG nReal = lpPerformanceCount->QuadPart;LONGLONG dReal = nReal - qpcLastReal_;LONGLONG dFake = speedFactor_ * dReal;qpcLastFake_ = qpcLastFake_ + dFake;qpcLastReal_ = nReal;if (bSpeed_)lpPerformanceCount->QuadPart = qpcLastFake_;return ret;
}VOID  WINAPI SpeedMgr::Sleep(__in DWORD dwMilliseconds)
{if (bSpeed_){DWORD dwValue = dwMilliseconds;dwMilliseconds = static_cast<DWORD> (floor(dwValue / speedFactor_ + 0.5));DWORD dwMinValue = 1;if (dwMilliseconds < dwMinValue){if (dwValue < dwMinValue)dwMilliseconds = dwValue;elsedwMilliseconds = dwMinValue;}}return SpeedAid::Real_Sleep(dwMilliseconds);
}DWORD WINAPI SpeedMgr::timeGetTime(VOID)
{DWORD ret = SpeedAid::Real_timeGetTime();DWORD nReal = ret;DWORD dReal = nReal - tgtLastReal_;DWORD dFake = speedFactor_ * dReal;tgtLastFake_ = tgtLastFake_ + dFake;tgtLastReal_ = nReal;return bSpeed_ ? tgtLastFake_ : tgtLastReal_;
}



http://www.ppmy.cn/news/560030.html

相关文章

使用Abaqus, Fortran, MATLAB和Python实现基于纤维的超弹性模型: 深入了解局部坐标基础的应用

引言 欢迎各位读者&#xff0c;我非常荣幸有这个机会来和你们分享关于在Abaqus中使用局部坐标基础的基于纤维的超弹性模型的教程。在这篇文章中&#xff0c;我将会详细解析如何在Abaqus中使用Fortran, MATLAB和Python来实现一个基于纤维的超弹性模型。希望这篇文章能够帮助你们…

C#面试题

C#里面的五种访问权限修饰符 public&#xff0c;是公开的&#xff0c;对类和类成员有效&#xff0c;没有访问成员的级别限制private&#xff0c;是私有的&#xff0c;对类成员有效&#xff0c;只能在类的内部使用internal&#xff0c;是内部的&#xff0c;对类和类成员有效&am…

物理引擎--Open Dynamics Engine(ODE)

物理引擎--Open Dynamics Engine--ODE 1 介绍1.1 概述1.2 代码1.3 wiki1.4 特征1.5 许可 2 安装使用3 概念3.1 背景3.2 刚体3.2.1 岛屿和禁用实体 3.3 一体化3.4 积分器3.5 关节和约束3.6 关节组3.7 关节误差和误差减少参数 (ERP) Joint error and the Error Reduction Paramet…

flex:1;

CSS属性 flex 规定了弹性元素如何伸长或缩短以适应flex容器中的可用空间。这是一个简写属性&#xff0c;用来设置 flex-grow, flex-shrink 与 flex-basis。 所以&#xff0c;flex:1其实就是设置了三个属性&#xff1a; flex-grow: 1; flex-shrink: 1; flex-basis: 0%; 这其中起…

Flex3学习笔记2

Flex3学习笔记2 Flex脚本基础 一般来说&#xff0c;使用MXML进行应用程序布局和结构设计&#xff0c;使用ActionScript实现应用程序上的各种动作操作。 认识到ActionScript和MXML怎样一起工作使理解Flex框架的关键。 1 &#xff09;内联的ActionScript 内联ActionScript&…

[Flex 2] 02 Flex

#################### Flex与Web设计################### 大多数企业级的Web设计都需有3层结构&#xff1a; * 表现层(Presentation Tier)&#xff1a;这一层构建的是用户看到的内容。有时候&#xff0c;人们也把这一层叫做图形用户界面(graphical user interface,GUI)。 …

Flex3实战2

???¡⟘ML OR XMLList <mx:XML id"myXML"> <friends> <friend name"Jon h" /> <friend name"hi"/> </friends> <mx:XML source"my.xml" id"myXML" /> </mx:XML> <mx:X…

flex3 视频播放器

前段时间央视的视频播放网站发布时&#xff0c;我第一时间上去参观了一下。感觉还不错&#xff0c;作为一名开发人员&#xff0c;我对它的视频播放系统还挺兴趣&#xff0c;有了想模仿一个的念头。后来&#xff0c;上网易的视频频道时&#xff0c;发现网易也开始用类似的播放系…