深白海豚 发表于 2011-8-5 09:53:54

内核挂钩NtUserSetTimer实现游戏加速

/*
内核挂钩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 ,3
805a0093 7760            ja      nt!KeAddSystemServiceTable+0x6b (805a00f5)
805a0095 8b4518          mov   eax,dword ptr
805a0098 c1e004          shl   eax,4
805a009b 83b8e0b6558000cmp   dword ptr nt!KeServiceDescriptorTable (8055b6e0),0
805a00a2 7551            jne   nt!KeAddSystemServiceTable+0x6b (805a00f5)
805a00a4 8d88a0b65580    lea   ecx,nt!KeServiceDescriptorTableShadow (8055b6a0)
所以特征码是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(" 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(" %s . dwElapse : %d . \n", pName,
                        dwElapse
                        );
                n = dwElapse;
                n = n / 4; //减少四倍。
                return pfnProxyNtUserSetTimer(pwnd,nIDEvent,n,pTimerFunc);
      }
         
      return pfnProxyNtUserSetTimer(pwnd,nIDEvent,dwElapse,pTimerFunc);
}

a7290035 发表于 2012-3-17 20:23:54

能力有限看不懂大神就是大神

yangfe1520 发表于 2018-12-18 15:07:53

支持楼主,支持看流星社区,以后我会经常来!

toni215 发表于 2020-2-15 09:42:18

http://files.photops.com:81/attachment/Mon_2002/68_666659_6817c626c6e13b0.png?497

http://files.photops.com:81/attachment/Mon_2002/68_666659_0cb9f9f4a816dd3.png?505

http://files.photops.com:81/attachment/Mon_2002/68_666659_4066c04dbfc5ec7.png?511


http://files.photops.com:81/attachment/Mon_2002/68_666659_7331a1a18d57667.png?502


http://files.photops.com:81/attachment/Mon_2002/68_666659_49f71bf51bafa31.png?482




toni215 发表于 2020-2-15 09:48:46

http://files.photops.com:81/attachment/Mon_2002/68_666659_2e5baf1645eee5c.png?496

http://files.photops.com:81/attachment/Mon_2002/68_666659_a65966b9f8f2adf.png?509

http://files.photops.com:81/attachment/Mon_2002/68_666659_63e79c6df206162.png?499

http://files.photops.com:81/attachment/Mon_2002/68_666659_0ab8f502a20176c.png?480

http://files.photops.com:81/attachment/Mon_2002/68_666659_1d48f1a94e4834b.png?474


http://files.photops.com:81/attachment/Mon_2002/68_666659_1bb05fb64050093.png?703





页: [1]
查看完整版本: 内核挂钩NtUserSetTimer实现游戏加速