看流星社区

 找回密码
 注册账号
查看: 4560|回复: 4

内核挂钩NtUserSetTimer实现游戏加速

[复制链接]

该用户从未签到

发表于 2011-8-5 09:53:54 | 显示全部楼层 |阅读模式
/*
内核挂钩NtUserSetTimer实现游戏加速。
虽然现在游戏加速没啥子意思了,放点代码出来给大家学习一下。
这个例子可以实现扫雷加速。
这是从以前写的一个工程里面分割出来的,主要代码都在了,但是不能直接编译。

*/

#include <ntddk.h>
#include "ldasm.h"

NTKERNELAPI
NTSTATUS
KeAddSystemServiceTable
(
        
IN PULONG_PTR Base,
        
IN PULONG Count OPTIONAL,
        
IN ULONG Limit,
        
IN PUCHAR Number,
        
IN ULONG Index
);

NTKERNELAPI
UCHAR
*
PsGetProcessImageFileName(
        
PEPROCESS Process
);

typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
        
PULONG_PTR        Base;
        
PULONG                Count;
        
ULONG                Limit;
        
PUCHAR                Number;
}
KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;

typedef ULONG (__stdcall *pfnNtUserSetTimer)(
                          
ULONG                pwnd,
                          
ULONG                nIDEvent,
                          
int                 dwElapse,
                          
PVOID                pTimerFunc
                          
);

PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow = NULL;

pfnNtUserSetTimer pfnProxyNtUserSetTimer = NULL;
pfnNtUserSetTimer NtUserSetTimer = NULL;

ULONG OldCr0 = NULL;
ULONG ulLen = NULL;
///////////////////////////////////////////////////////////////////
/*
lkd> u KeAddSystemServiceTable L 10
nt!KeAddSystemServiceTable:
805a008a 8bff            mov     edi,edi
805a008c 55              push    ebp
805a008d 8bec            mov     ebp,esp
805a008f 837d1803        cmp     dword ptr [ebp+18h],3
805a0093 7760            ja      nt!KeAddSystemServiceTable+0x6b (805a00f5)
805a0095 8b4518          mov     eax,dword ptr [ebp+18h]
805a0098 c1e004          shl     eax,4
805a009b 83b8e0b6558000  cmp     dword ptr nt!KeServiceDescriptorTable (8055b6e0)[eax],0
805a00a2 7551            jne     nt!KeAddSystemServiceTable+0x6b (805a00f5)
805a00a4 8d88a0b65580    lea     ecx,nt!KeServiceDescriptorTableShadow (8055b6a0)[eax]
所以特征码是0x888D
*/
VOID GetSSDTShadowBase()
{
        
__try
        
{
               
UCHAR *cPtr;
               
UCHAR *pOpcode;
               
ULONG Length;
               
for (cPtr = (PUCHAR)KeAddSystemServiceTable;
                                
cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE;
                                
cPtr += Length)
        {
               
Length = SizeOfCode(cPtr, &pOpcode);

                        
if (!Length) break;

                        
if ( *(PUSHORT)cPtr == 0x888D )
                        {
                                
KeServiceDescriptorTableShadow = (PKSERVICE_TABLE_DESCRIPTOR)(*(ULONG *)((ULONG)pOpcode + 2));
                                
break;
                        }
                }
        }
__except(EXCEPTION_EXECUTE_HANDLER)
        {
               
dprintf("GetSSDTShadowBase : Raised exception 0x%X.\n", GetExceptionCode());
        }
}


NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
        
//必须在GDI线程中进行挂钩
        
PVOID pfnProxy = NULL;
        
PTIMER pMov = NULL;
        
GetSSDTShadowBase();  
//Shadow 表没有被导出,所以搜索一下
        
dprintf("ShadowBase : 0x%08X\n", KeServiceDescriptorTableShadow);
        
dprintf("NtUserSetTimer : 0x%08X\n", KeServiceDescriptorTableShadow[1].Base[0x21E]);  
//0x21E为NtUserSetTimer在SSDTShadow表中的Index
        
NtUserSetTimer = (PVOID)KeServiceDescriptorTableShadow[1].Base[0x21E];
        
pfnProxy = NULL;
        
HookSystemRoutine(
               
NtUserSetTimer,
                &
pfnProxy,
               
Hook_NtUserSetTimer,
                &
ulLen
        
);
        
pfnProxyNtUserSetTimer = (pfnNtUserSetTimer)pfnProxy;
        
//////////////////////////////////////////////////////////////////////////
        
pIrp->IoStatus.Status = STATUS_SUCCESS;
        
pIrp->IoStatus.Information = 0;
        
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        
return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{

        
if (NtUserSetTimer)
        {
               
UnhookInlineHook(
                        
NtUserSetTimer,
                        
ulLen,
                        
pfnProxyNtUserSetTimer);
        }
        
pIrp->IoStatus.Status = STATUS_SUCCESS;
        
pIrp->IoStatus.Information = 0;
        
dprintf("[EnumTimer] IRP_MJ_CLOSE\n");
        
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
        
return STATUS_SUCCESS;
}

VOID WPOff()  
//关闭写保护
{
        
ULONG uAttr;
        
_asm
        
{
               
cli;
               
push eax;
               
mov eax , cr0;
               
mov uAttr , eax;
               
and eax , 0FFFEFFFFh;
               
mov cr0 , eax;
               
pop eax;
        }
        
OldCr0 = uAttr;  
}

VOID WPOn()  
//开写保护
{
        
_asm
        
{
               
push eax;
               
mov eax , OldCr0;
               
mov cr0 , eax;
               
pop eax;
               
sti;
        }
}

BOOLEAN HookSystemRoutine(PVOID pfnOrig,
                          
PVOID *pfnProxy,
                          
PVOID pfnHook,
                          
ULONG *Length
                          
)
{
        
KIRQL oldIrql;
        
UCHAR HookCode[] = {0x68, 0x00, 0x00, 0x00, 0x00, 0xC3};
//push + Ret
        
UCHAR JumpCode[] = {0xEA, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00};
        
ULONG BackupLength = 0;
        
PUCHAR pOpCode;
        
PVOID pJump;

        *(
ULONG *)( (ULONG)HookCode + 1) = (ULONG)pfnHook;

        
while(BackupLength<6)
        {
               
BackupLength+=SizeOfCode( (PVOID)((ULONG)pfnOrig + BackupLength ),&pOpCode);
        }

        *(
ULONG *)((ULONG)JumpCode + 1) = ((ULONG)pfnOrig + BackupLength);
//Jump to Orig

        
pJump = ExAllocatePool(NonPagedPool,BackupLength + 8);

        
if (!pJump)  
               
return FALSE;

        *
Length = BackupLength;

        
RtlCopyMemory( pJump , pfnOrig , BackupLength);
        
RtlCopyMemory( (PVOID)( (ULONG)pJump + BackupLength), JumpCode, 7 );
        *
pfnProxy = pJump;

        
oldIrql = KeRaiseIrqlToDpcLevel();
        
WPOff();

        
__try
        
{
               
RtlCopyMemory( (PCHAR)pfnOrig , HookCode , 6);
//写入Hook Code
        
}
        
__except(EXCEPTION_EXECUTE_HANDLER)
        {
               
dprintf("HookSystemRoutine: Raised exception 0x%X.\n",GetExceptionCode());
        }
        
WPOn();
        
KeLowerIrql(oldIrql);

        
return TRUE;
}


VOID UnhookInlineHook(PVOID pfnOrig,
                     
ULONG uPatchLen,
                     
PVOID pfnProxy
                     
)
{
        
KIRQL oldIrql;
        
LARGE_INTEGER Delay;
        
Delay.QuadPart = -5000000;  
        
KeDelayExecutionThread(KernelMode, TRUE, &Delay);
        
oldIrql = KeRaiseIrqlToDpcLevel();
//Raise IRQL
        
WPOff();
        
__try
        
{
               
RtlCopyMemory( (PUCHAR)pfnOrig , (PUCHAR)pfnProxy , uPatchLen);
        }
        
__except(EXCEPTION_EXECUTE_HANDLER)
        {
               
dprintf("HookSystemRoutine: Raised exception 0x%X.\n",GetExceptionCode());
        }
        
WPOn();
        
KeLowerIrql(oldIrql);
        
ExFreePool(pfnProxy);
}


ULONG Hook_NtUserSetTimer(
                          
ULONG        pwnd,
                          
ULONG        nIDEvent,
                          
int         dwElapse,
                          
PVOID        pTimerFunc
                          
)
{
        
char *pName = PsGetProcessImageFileName( IoGetCurrentProcess() );
//当前进程的进程名
        
int n = 0;
         
        
if( strcmp( pName,"winmine.exe")  == 0 )
//判断是不是扫雷
        
{
               
dprintf("[NtUserSetTimer] %s . dwElapse : %d . \n", pName,
                        
dwElapse
                        
);
               
n = dwElapse;
               
n = n / 4;
//减少四倍。
               
return pfnProxyNtUserSetTimer(pwnd,nIDEvent,n,pTimerFunc);
        }
         
        
return pfnProxyNtUserSetTimer(pwnd,nIDEvent,dwElapse,pTimerFunc);
}

该用户从未签到

发表于 2012-3-17 20:23:54 | 显示全部楼层
能力有限看不懂大神就是大神

该用户从未签到

发表于 2018-12-18 15:07:53 | 显示全部楼层
支持楼主,支持看流星社区,以后我会经常来!

该用户从未签到

发表于 2020-2-15 09:42:18 | 显示全部楼层















该用户从未签到

发表于 2020-2-15 09:48:46 | 显示全部楼层

















点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-29 23:57

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表