1>变速齿轮原理:
变速齿轮利用HOOK API实现针对Windows主流应用程序的变速功能,
QueryPerformanceCounter,
GetTickCount,
timeGetTime
3个API实现的完美加速。
(有些程序如<扫雷>是通过timer计时的,Hook这三个函数还不能实现加速)
为了实现变速效果,按键精灵作者采用公式算法实现了加速减速效果,公式如下:
Result := 上次返回时间 + Round((当前返回时间 - 上次正常时间) * Power(2,倍数));
[注:Round 表示取整]
原文:http://baike.baidu.com/view/384648.htm
根据这个分析, 所以我们写变速齿轮的思路就出来了:
挂钩这三个函数, 修改器返回值. 完成~
2>逆向这三个Api:
- GetTickCount
mov edx,7FFE0000h
mov eax,dword ptr ds:[edx]
mul dword ptr ds:[edx+4]
shrd eax,edx,18h
retn
- timeGetTime
cmp dword ptr ds:[76B30014],0
jnz GetTickCount
call Func_1
sub eax,dword ptr ds:[76B30018]
push 0
sbb edx,dword ptr ds:[76B3001C]
push 2710
push edx
push eax
call Func_2
add eax,dword ptr ds:[76B30020]
retn
Func_1:
mov edi,edi
mov edx,dword ptr ds:[7FFE000C]
mov eax,dword ptr ds:[7FFE0008]
cmp edx,dword ptr ds:[7FFE0010]
jnz short winmm.76B12B0B
retn
Func_2:
;// 从第一个"jnz GetTickCount"的跳转来看,
;// 只要让timeGetTime的返回值跟GetTickCount一样即可~
- QueryPerformanceCounter
mov edi,edi
push ebp
mov ebp,esp
push ecx
push ecx
lea eax,dword ptr ss:[ebp-8]
push eax
push dword ptr ss:[ebp+8]
call ntdll.ZwQueryPerformanceCounter ;// 看这个~
test eax,eax
jl 0xxxxxxxxx
cmp dword ptr ss:[ebp-8],0
je 0xxxxxxxxx
xor eax,eax
inc eax
leave
retn 4
;// ntdll.ZwQueryPerformanceCounter:
;// 直接进入内核了....
mov eax,0A5
mov edx,7FFE0300
call dword ptr ds:[edx]
retn 8
;// 看win源码知道, 这孙子进内核后又会调用
;// "KeQueryPerformanceCounter"
;// 而这个内核函数做的也只是查询下_KUSER_SHARED_DATA中的东西
3>挂钩实现:
开始动手Hook:(部分源码)
//////////////////////////////////////////////////////////////////////////
// 1> GetTickCount 的Hook
// 7C80934A kernel32.GetTi> BA 0000FE7F mov edx,7FFE0000
// 7C80934F 8B02 mov eax,dword ptr ds:[edx]
// 7C809351 F762 04 mul dword ptr ds:[edx+4]
// 7C809354 0FACD0 18 shrd eax,edx,18
// 7C809358 C3 retn
// Hook地址
DWORD HookAddr_GetTickCount = 0x7C809358;
DWORD dwSpead = 0;
DWORD dwTmp = 0;
DWORD dwStartTime = 0;
_declspec(naked) void HookFunc_GetTickCount()
{
// 记录初始时间.(回忆前面的变速齿轮公式...)
if (0 == dwStartTime)
{
__asm mov dwStartTime, eax
__asm retn;
}
__asm
{
mov ecx, eax ;//now time
sub ecx, dwStartTime //sub time
//shl ecx, 1
mov dwTmp, ecx
push eax
}
dwTmp *= dwSpead;//加速多少倍?
__asm
{
pop eax
mov ecx, dwTmp
add eax, ecx
retn
}
}
//////////////////////////////////////////////////////////////////////////
// 2> timeGetTime
// 76B14E4F > 833D 1400B376 0>CMP DWORD PTR DS:[76B30014],0
// 76B14E56 0F85 97770000 JNZ <JMP.&KERNEL32.GetTickCount>
// 76B14E5C E8 A8DCFFFF CALL winmm.76B12B09
// 76B14E61 2B05 1800B376 SUB EAX,DWORD PTR DS:[76B30018]
// 76B14E67 6A 00 PUSH 0
// 76B14E69 1B15 1C00B376 SBB EDX,DWORD PTR DS:[76B3001C]
// 76B14E6F 68 10270000 PUSH 2710
// 76B14E74 52 PUSH EDX
// 76B14E75 50 PUSH EAX
// 76B14E76 E8 07000000 CALL winmm.76B14E82
// 76B14E7B 0305 2000B376 ADD EAX,DWORD PTR DS:[76B30020]
// 76B14E81 C3 RETN
// Hook地址:
DWORD HookAddr_timeGetTime = 0x76B14E4F;
_declspec(naked) void HookFunc_timeGetTime()
{
__asm
{
mov edx, 0x7ffe0000
mov eax, dword ptr ds:[edx]
mul dword ptr ds:[edx+4]
shrd eax, edx, 0x18
}
// 记录初始时间.(回忆前面的变速齿轮公式...)
if(0 == dwStartTime)
{
__asm mov dwStartTime, eax
__asm retn;
}
__asm
{
mov ecx, eax
sub ecx, dwStartTime
mov dwTmp, ecx
push eax
}
// dwSpead加速倍数
dwTmp *= dwSpead;
__asm
{
pop eax
mov ecx, dwTmp
add eax, ecx
retn
}
}
//////////////////////////////////////////////////////////////////////////
// 3> QueryPerformanceCounter
typedef DWORD (__stdcall * pZwQueryPerformanceCounter)(DWORD, DWORD);
pZwQueryPerformanceCounter ZwQueryPerformanceCounter = NULL;
// 这个函数需要在挂钩之前调用一次,
// 以完成初始化: 找到ZwQueryPerformanceCounter的地址...
void fuck_ZwQueryPerformanceCounter()
{
HMODULE hModule = LoadLibrary("ntdll.dll");
if (NULL == hModule)
{
//cout << ">load lib error!" << endl;
return;
}
void * p = GetProcAddress(hModule, "ZwQueryPerformanceCounter");
if (NULL == p)
{
//cout << ">get proc addr error!" << endl;
goto FUCK_END;
}
ZwQueryPerformanceCounter = (pZwQueryPerformanceCounter)p;
FUCK_END:
//FreeLibrary(hModule);
//hModule = NULL;
return;
}
// --- QueryPerformanceCounter ----
// 7C80A4C7 8BFF mov edi,edi
// 7C80A4C9 . 55 push ebp
// 7C80A4CA . 8BEC mov ebp,esp <--
// 7C80A4CC . 51 push ecx
// 7C80A4CD . 51 push ecx
// 7C80A4CE . 8D45 F8 lea eax,dword ptr ss:[ebp-8]
// 7C80A4D1 . 50 push eax ; 接收一个返回
// 7C80A4D2 . FF75 08 push dword ptr ss:[ebp+8] ; 入口参数地址
// 7C80A4D5 . FF15 DC13807C call dword ptr ds:[<&ntdll.NtQueryPerformanceCounter>] ; ntdll.ZwQueryPerformanceCounter
// 7C80A4DB . 85C0 test eax,eax
// 7C80A4DD . 0F8C AB750300 jl kernel32.7C841A8E ; 非零则跳
// 7C80A4E3 . 837D F8 00 cmp dword ptr ss:[ebp-8],0
// 7C80A4E7 . 0F84 AB750300 je kernel32.7C841A98
// 7C80A4ED > 33C0 xor eax,eax
// 7C80A4EF . 40 inc eax
// 7C80A4F0 > C9 leave
// 7C80A4F1 . C2 0400 retn 4
DWORD HookAddr_QueryPerformanceCounter = 0x7C80A4C7;
LARGE_INTEGER liStartTime = {0};
LARGE_INTEGER liTmp = {0};
LARGE_INTEGER *lpPerformanceCount = NULL;// QueryPerformanceCounter的形参...
__declspec(naked) BOOL __stdcall HookFunc_QueryPerformanceCounter()
{
__asm
{
mov edi, edi
push ebp
mov ebp, esp
push ecx
push ecx
lea eax, dword ptr [ebp-8]
push eax
push dword ptr [ebp+8] ;//形参
mov eax, ZwQueryPerformanceCounter
call eax
}
//初始化开始时间
if ((__int64)0 == *(__int64*)&liStartTime)
{
__asm
{
mov eax, dword ptr[ebp+8] //lpPerformanceCount
lea edx, liStartTime
mov ecx, dword ptr [eax]
mov dword ptr [edx], ecx
add eax, 4
add edx, 4
mov ecx, dword ptr [eax]
mov dword ptr [edx], ecx
// 返回程序
xor eax, eax
inc eax
leave
retn 4
}
}
///// 修改查询回来的时间///////
__asm mov eax, dword ptr [ebp+8]//lpPerformanceCount
__asm mov lpPerformanceCount, eax
*(__int64*)&liTmp = *(__int64*)lpPerformanceCount - *(__int64*)&liStartTime;
*(__int64*)&liTmp *= __int64(dwSpead); // 加速倍数
*(__int64*)lpPerformanceCount += *(__int64*)&liTmp;
////////////////////////////////
__asm
{
xor eax, eax
inc eax
leave
retn 4
}
}
版权属于: 顾锦歌——发现生活的美!
本文链接: https://main.huat.fun/index.php/archives/24/
本文最后更新于2022年05月09日 ,已超过1125天没有更新,若内容或图片失效,请留言反馈。
本文允许转载,但请在转载时请以超链接或其它形式标明文章出处
Your go-to source for leads. We can provide business to business and business to consumer leads, custom-tailored to your needs. CustomDatabases.org
Hi, It is with sad regret to inform you TopDataList.com is shutting down. We are ceasing operations on TopDataList.com and have made our leads available at a $149 once off fee. Visit us on TopDataList.com Regards, Otilia
Hello, from CustomData.click we are a provider of unique databases that could help your business. Please visit us at CustomData.click to see if we can help you. Regards, Ervin
Hello. It is with sad regret to inform you TopDataList.com is shutting down. We have made all our databases available for you for a once off fee. Visit us on TopDataList.com
ZippyLeads.org is running an easter special till the 18th of April. Get all the leads you need for your company with our easter special.
Hello. My name is Johan Fourie and I am looking to sell DataList.biz. We are a data company that has been in the industry for 12 years. We do around $170k/year in revenue. 1) I am looking to sell 50% of the business for $5k. 2) It would be helpful if you are knowledgeable about the Data Business. 3) I am looking for someone that is willing to take over administration, support, client relations. 4) I will continue to do the marketing for new products. 5) You will accept all future income and pay me from it. Please contact me on WhatsApp +27 72 280 1952 or my personal email: johanfourieinc@gmail.com if you are interested in this and we can have a call. Regards, Johan Fourie
Hi, I am interested in some of your products. Please give me a call on +1 304-873-4360
欢迎加入 Typecho 大家族