- 注册时间
- 2011-3-6
- 最后登录
- 1970-1-1
该用户从未签到
|
之前提到过新奇迹世界用的Hackshield,用雪村看了下它的驱动,发现做一些hook,
有ssdt hook和inline函数hook:
思路就是:在nt!KiFastCallEntry中,通过ssdt计算出内核函数后,调用内核函数前,先进入我的函数,根据索引号判断是否使用通过ssdt计算出的内核函数,还是原始的内核函数。
下面的代码我只做了NtWriteVirtualMemory、NtReadVirtualMemory、NtClose和NtOpenProcess的恢复,环境是win7 32bit,nt模块为ntkrnlpa.exe。此程序只为研究,所以代码中有些硬编码,请见谅。- #include "moniprocess.h"
- #include "HookKiFastCallEntry.h"
- ULONG g_uHookKiFastCallEntryCr0 = 0;
- ULONG g_ulHookKiFastCallEntry = 0; // 将要被hook的地址
- ULONG g_ulJmpBackAddr = 0; // 跳回的地址
- JmpCode g_struOldValue_KiFastCallEntry;
- ULONG g_uIndexOfNtWriteVirtualMemory = 0x18f; // NtWriteVirtualMemory在ssdt中的索引号
- ULONG g_uAddrOfNtWriteVirtualMemory = 0; // NtWriteVirtualMemory首地址 rva=0x26171C
- ULONG g_uIndexOfNtReadVirtualMemory = 0x115; // NtReadVirtualMemory在ssdt中的索引号
- ULONG g_uAddrOfNtReadVirtualMemory = 0; // NtReadVirtualMemory首地址 rva=0x26182C
- ULONG g_uIndexOfNtClose = 0x32; // NtClose在ssdt中的索引号
- ULONG g_uAddrOfNtClose = 0; // NtClose首地址 rva=0x24637A
- ULONG g_uIndexOfNtOpenProcess = 0x0be; // NtOpenProcess在ssdt中的索引号
- ULONG g_uAddrOfPsOpenProcess = 0; // PsOpenProcess首地址 rva=0x277E6C
- __declspec(naked) int MyNtOpenProcess() // 由于NtOpenProcess被做了inline函数hook,所以这里我自己实现了这个函数,这里是直接拷贝的反汇编代码
- {
- _asm
- {
- mov edi, edi
- push ebp
- mov ebp, esp
- push ecx
- push ecx
- mov eax, dword ptr fs:[0x124]
- mov al, byte ptr [eax+0x13A]
- mov ecx, dword ptr [ebp+0x14]
- mov edx, dword ptr [ebp+0x10]
- mov byte ptr [ebp-0x4], al
- push dword ptr [ebp-0x4]
- push dword ptr [ebp-0x4]
- push dword ptr [ebp+0x0C]
- push dword ptr [ebp+0x8]
- mov eax, g_uAddrOfPsOpenProcess
- call eax
-
-
-
- //leave ==
- mov esp, ebp
- pop ebp
- retn 0x10
- }
- }
- __declspec(naked) int Jmp_KiFastCallEntry()
- {
- // eax为ssdt的索引号
- // edi为ServiceTableBase地址
- // edx为得到的系统函数地址
- _asm
- {
- //pushfd
- //pushad
- // 判断是否需要恢复
- cmp eax, g_uIndexOfNtWriteVirtualMemory
- je Goto_Set_NtWriteVirtualMemory
-
- cmp eax, g_uIndexOfNtReadVirtualMemory
- je Goto_Set_NtReadVirtualMemory
- cmp eax, g_uIndexOfNtOpenProcess
- je Goto_Set_NtOpenProcess
- cmp eax, g_uIndexOfNtClose
- je Goto_Set_NtClose
- jmp Goto_End
- }
- Goto_Set_NtClose:
- _asm
- {
- mov edx, g_uAddrOfNtClose // 设置原始的内核函数地址
- jmp Goto_End
- }
- Goto_Set_NtOpenProcess:
- _asm
- {
- mov edx, MyNtOpenProcess // 设置原始的内核函数地址
- jmp Goto_End
- }
- Goto_Set_NtReadVirtualMemory:
- _asm
- {
- mov edx, g_uAddrOfNtReadVirtualMemory // 设置原始的内核函数地址
- jmp Goto_End
- }
- Goto_Set_NtWriteVirtualMemory:
- _asm
- {
- mov edx, g_uAddrOfNtWriteVirtualMemory
- }
- Goto_End:
- _asm
- {
- //popad
- //popfd
- sub esp, ecx
- shr ecx, 2
- jmp g_ulJmpBackAddr
- }
- }
- NTSTATUS RealHookKiFastCallEntry()
- {
- if( 0 != g_ulHookKiFastCallEntry )
- {
- ULONG ulMachineCode;
- ulMachineCode = GetMachineCode( g_ulHookKiFastCallEntry, Jmp_KiFastCallEntry );
- WPOFF( &g_uHookKiFastCallEntryCr0 );
- __asm
- {
- // save 5字节
- mov eax, g_ulHookKiFastCallEntry
- mov ebx, dword ptr [ eax ]
- mov g_struOldValue_KiFastCallEntry.dwJmpCode[0], ebx
- mov bl, byte ptr [ eax + 4 ]
- mov ecx, offset g_struOldValue_KiFastCallEntry
- mov byte ptr [ ecx + 4 ], bl
- // hook
- mov byte ptr [ eax ], 0x0e9
- add eax, 1
- mov ecx, ulMachineCode
- mov dword ptr [ eax ], ecx
- }
- WPON( &g_uHookKiFastCallEntryCr0 );
- return STATUS_SUCCESS;
- }
- g_ulHookKiFastCallEntry = 0;
- return STATUS_ACCESS_DENIED;
- }
- NTSTATUS HookKiFastCallEntry( IN ULONG ulFunAddr )
- {
- NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
- if( 0 == ulFunAddr )
- return ntStatus;
- g_ulHookKiFastCallEntry = ulFunAddr;
- if( 0x0e9c1e12b == *( (PDWORD)g_ulHookKiFastCallEntry ) )
- {
- ntStatus = RealHookKiFastCallEntry();
- if( !NT_SUCCESS( ntStatus ) )
- g_ulHookKiFastCallEntry = 0;
- }
- return ntStatus;
- }
- VOID UnHookKiFastCallEntry()
- {
- if( 0 != g_ulHookKiFastCallEntry )
- {
- WPOFF( &g_uHookKiFastCallEntryCr0 );
- __asm
- {
- // 恢复 5字节
- mov eax, g_ulHookKiFastCallEntry
- mov ebx, g_struOldValue_KiFastCallEntry.dwJmpCode[0]
- mov dword ptr [ eax ], ebx
- mov ecx, offset g_struOldValue_KiFastCallEntry
- mov bl, byte ptr [ ecx + 4 ]
- mov byte ptr [ eax + 4 ], bl
- }
- WPON( &g_uHookKiFastCallEntryCr0 );
- KeSleep( 1 );
- }
- g_ulHookKiFastCallEntry = 0;
- }
- BOOL GetKiFastCallEntryAddr_XP32_And_WIN732( OUT PULONG pFunAddr )
- {
- BOOL bRet = FALSE;
- ULONG nModuleBase, nModuleSize;
- ULONG nCopyModuleBase = 0, nCopyModuleSize = 0;
- ULONG ulBuildNumber, ulMinorVersion, ulMajorVersion;
- ULONG ulArrayFeatures[ 16 ];
- ULONG ulOffset, ulTemp;
- UNICODE_STRING uniNtKrnlFileName;
- do
- {
- if( NULL == pFunAddr )
- break;
- PsGetVersion( &ulMajorVersion, &ulMinorVersion, &ulBuildNumber, 0 );
- if( ulMajorVersion == 5 && ulMinorVersion == 1 ) // xp 32位
- {
- ulOffset = 0x8053e553 - 0x8053e540;
- }
- else if( ulMajorVersion == 6 && ulMinorVersion == 1 ) // win7 32位
- {
- ulOffset = 0x8053e554 - 0x8053e540;
- }
- else
- {
- break;
- }
- bRet = GetModuleBaseAndSize( NameOfNT1, &nModuleBase, &nModuleSize, &uniNtKrnlFileName );
- if( !bRet )
- {
- bRet = GetModuleBaseAndSize( NameOfNT2, &nModuleBase, &nModuleSize, &uniNtKrnlFileName );
- }
- if( !bRet )
- break;
- bRet = FALSE;
- if( CopyModule( &uniNtKrnlFileName, &nCopyModuleBase, &nCopyModuleSize ) )
- {
- ulArrayFeatures[0] = 0x6a04618b;
- ulArrayFeatures[1] = 0x6a9c5223;
- ulArrayFeatures[2] = 0x08c28302;
- ulArrayFeatures[3] = 0x244c809d;
- ulArrayFeatures[4] = 0x1b6a0201;
- ulArrayFeatures[5] = 0x030435ff;
- ulArrayFeatures[6] = 0x006affdf;
- ulArrayFeatures[7] = 0x57565355;
- ulTemp = GetUnDocApiAddr( nCopyModuleBase, nCopyModuleSize, ulArrayFeatures, 8 );
- if( 0 != ulTemp )
- {
- ulTemp = ulTemp + nModuleBase - ulOffset;
- if( 0 != ulTemp )
- {
- *pFunAddr = ulTemp;
- g_uAddrOfNtWriteVirtualMemory = 0x26171C;
- g_uAddrOfNtReadVirtualMemory = 0x26182C;
- g_uAddrOfPsOpenProcess = 0x277E6C;
- g_uAddrOfNtClose = 0x24637A;
- g_uAddrOfNtWriteVirtualMemory += nModuleBase;
- g_uAddrOfNtReadVirtualMemory += nModuleBase;
- g_uAddrOfPsOpenProcess += nModuleBase;
- g_uAddrOfNtClose += nModuleBase;
-
- bRet = TRUE;
- }
- }
- }
- RtlFreeUnicodeString( &uniNtKrnlFileName );
- } while (0);
- if( 0 != nCopyModuleBase )
- {
- ExFreePool( (PVOID)nCopyModuleBase );
- }
- return bRet;
- }
- BOOL InitKiFastCallEntry()
- {
- BOOL bRet = FALSE;
- ULONG nTemp, nHookAddr, ulBuildNumber, ulMinorVersion, ulMajorVersion;
- do
- {
- if( !GetKiFastCallEntryAddr_XP32_And_WIN732( &nTemp ) ) // 获得nt!KiFastCallEntry的地址
- break;
- PsGetVersion( &ulMajorVersion, &ulMinorVersion, &ulBuildNumber, 0 );
- if( ulMajorVersion == 5 && ulMinorVersion == 1 ) // xp 32位
- {
- nHookAddr = nTemp + 0x0e1;
- g_ulJmpBackAddr = nTemp + 0x0e6;
- }
- else if( ulMajorVersion == 6 && ulMinorVersion == 1 ) // win7 32位
- {
- nHookAddr = nTemp + 0x0e4;
- g_ulJmpBackAddr = nTemp + 0x0e9;
- }
- else
- break;
- if( NT_SUCCESS( HookKiFastCallEntry( nHookAddr ) ) )
- bRet = TRUE;
- } while (0);
- return bRet;
- }
复制代码 通过以上的恢复,可以打开、杀掉游戏进程。
目前用od附加还是要失败,估计是NtGetContextThread之类的hook还没有恢复。
明天再搞,今天就这样了。 |
|