突破游戲驅動級反外掛保護2009-01-25 14:01現在大多數網絡游戲都使用驅動級的反外掛保護,使其他程序無法獲得其游戲窗口句柄,下面驅動代碼可以恢復被TesSafe.sys Hook掉的API。
#include <ntddk.h>
#include <windef.h>
#include <ntimage.h>
#include "Common.h"
typedef struct _KAPC_STATE
{
LIST_ENTRY ApcListHead[2];
PVOID Process;
BOOLEAN KernelApcInProgress;
BOOLEAN KernelApcPending;
BOOLEAN UserApcPending;
} KAPC_STATE, *PKAPC_STATE;
ULONG g_nOpenIndex?????? = 0;
ULONG g_nThreadIndex????? = 0;
ULONG g_nReadIndex?????? = 0;
ULONG g_nWriteIndex?????? = 0;
ULONG g_NtOpenProcess????? = 0;
ULONG g_NtOpenThread????? = 0;
ULONG g_NtReadVirtualMemory???? = 0;
ULONG g_NtWriteVirtualMemory??? = 0;
ULONG g_KiAttachProcess????? = 0;
ULONG g_PsCreateSystemThread??? = 0;
ULONG g_PsCreateSystemThreadAddr?? = 0;
BYTE g_NtOpenProcessSave[0x300];
BYTE g_NtOpenThreadSave[0x300];
BYTE g_NtReadVirtualMemorySave[0x10];
BYTE g_NtWriteVirtualMemorySave[0x10];
BYTE g_KiAttachProcessSave[0x10];
INLINEHOOK g_hPsCreateSystemThread;
VOID NTAPI MyThread(PVOID pContext)
{
__asm
{
?? push eax
?? cli
?? mov?? eax, cr0
?? and?? eax, not 0x10000
?? mov?? cr0, eax
?? pop?? eax
}
if (g_NtOpenProcess)
{
?? memcpy((PVOID)g_NtOpenProcess, (PVOID)g_NtOpenProcessSave, sizeof(g_NtOpenProcessSave));
// DbgPrint("恢復NtOpenProcess成功");
}
if (g_NtOpenThread)
{
?? memcpy((PVOID)g_NtOpenThread, (PVOID)g_NtOpenThreadSave, sizeof(g_NtOpenThreadSave));
// DbgPrint("恢復NtOpenThread成功");
}
if (g_NtReadVirtualMemory)
{
?? memcpy((PVOID)g_NtReadVirtualMemory, (PVOID)g_NtReadVirtualMemorySave, sizeof(g_NtReadVirtualMemorySave));
// DbgPrint("恢復NtReadVirtualMemory成功");
}
if (g_NtWriteVirtualMemory)
{
?? memcpy((PVOID)g_NtWriteVirtualMemory, (PVOID)g_NtWriteVirtualMemorySave, sizeof(g_NtWriteVirtualMemorySave));
// DbgPrint("恢復NtWriteVirtualMemory成功");
}
if (g_KiAttachProcess)
{
?? memcpy((PVOID)g_KiAttachProcess, (PVOID)g_KiAttachProcessSave, sizeof(g_KiAttachProcessSave));
// DbgPrint("恢復KiAttachProcess成功");
}
__asm
{
?? push eax
?? mov?? eax, cr0
?? or?? eax, 0x10000
?? mov?? cr0, eax
?? sti
?? pop?? eax
}
DbgPrint("恢復成功");
PsTerminateSystemThread(STATUS_SUCCESS);
}
__declspec(naked) NTSTATUS MyPsCreateSystemThread_(PHANDLE ThreadHandle,ULONG DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,HANDLE ProcessHandle,PCLIENT_ID ClientId,PKSTART_ROUTINE StartRoutine,PVOID StartContext)
{
__asm
{
?? jmp?? dword ptr [g_PsCreateSystemThreadAddr]
}
}
NTSTATUS MyPsCreateSystemThread(PHANDLE ThreadHandle,ULONG DesiredAccess,POBJECT_ATTRIBUTES ObjectAttributes,HANDLE ProcessHandle,PCLIENT_ID ClientId,PKSTART_ROUTINE StartRoutine,PVOID StartContext)
{
PDWORD Addr = (PDWORD)StartRoutine;
HANDLE hThread = NULL;
if ( (*Addr == 0x81EC8B55 && *(Addr + 1) == 0x94EC) || (*Addr == 0x0149F6E9 && *(Addr + 1) == 0xB2120100) || (*Addr == 0x01F1DFE9 && *(Addr + 1) == 0x13A5F300) || (*Addr == 0x02120FE9 && *(Addr + 1) == 0x6E800) )
{
?? DbgPrint("創建內核線程:%X\n",StartRoutine);
// MyPsCreateSystemThread_(&hThread, (ACCESS_MASK)0, NULL,(HANDLE)0, NULL, MyThread, NULL);
// ZwClose(hThread);
?? StartRoutine = MyThread;
}
return MyPsCreateSystemThread_(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, ClientId, StartRoutine, StartContext);
}
ULONG GetKiAttachProcessAddr()
{
ULONG DisassemblerLen = 0, Size = 0;
PBYTE FunctionAddr = (PBYTE)GetFunctionAddr(L"KeStackAttachProcess");
do
{
?? DisassemblerLen = GetOpCodeSize(FunctionAddr);
?? FunctionAddr = FunctionAddr + DisassemblerLen;
?? Size = Size + DisassemblerLen;
?? if (Size > 0x100 || *(PWORD)FunctionAddr == 0x8C2)
?? {
??? return 0;
?? }
} while ( *FunctionAddr != 0xE8 );
return (LONG)FunctionAddr + *(PLONG)(FunctionAddr + 1) + 5;
}
VOID Hook()
{
g_nOpenIndex????? = GetFunctionIndex("NtOpenProcess");
g_nThreadIndex????? = GetFunctionIndex("NtOpenThread");
g_nReadIndex????? = GetFunctionIndex("NtReadVirtualMemory");
g_nWriteIndex????? = GetFunctionIndex("NtWriteVirtualMemory");
g_NtOpenProcess????? = KeServiceDescriptorTable->ServiceTableBase[g_nOpenIndex];
g_NtOpenThread????? = KeServiceDescriptorTable->ServiceTableBase[g_nThreadIndex];
g_NtReadVirtualMemory??? = KeServiceDescriptorTable->ServiceTableBase[g_nReadIndex];
g_NtWriteVirtualMemory??? = KeServiceDescriptorTable->ServiceTableBase[g_nWriteIndex];
g_KiAttachProcess???? = GetKiAttachProcessAddr();
g_PsCreateSystemThread??? = GetFunctionAddr(L"PsCreateSystemThread");
if (g_NtOpenProcess)
{
?? memcpy((PVOID)g_NtOpenProcessSave, (PVOID)g_NtOpenProcess, sizeof(g_NtOpenProcessSave));
?? DbgPrint("NtOpenProcess 地址:%08X", g_NtOpenProcess);
}
else
{
?? DbgPrint("獲取NtOpenProcess地址失敗");
}
if (g_NtOpenThread)
{
?? memcpy((PVOID)g_NtOpenThreadSave, (PVOID)g_NtOpenThread, sizeof(g_NtOpenThreadSave));
?? DbgPrint("NtOpenThread 地址:%08X", g_NtOpenThread);
}
else
{
?? DbgPrint("獲取NtOpenThread地址失敗");
}
if (g_NtReadVirtualMemory)
{
?? memcpy((PVOID)g_NtReadVirtualMemorySave, (PVOID)g_NtReadVirtualMemory, sizeof(g_NtReadVirtualMemorySave));
?? DbgPrint("NtReadVirtualMemory 地址:%08X", g_NtReadVirtualMemory);
}
else
{
?? DbgPrint("獲取NtReadVirtualMemory地址失敗");
}
if (g_NtWriteVirtualMemory)
{
?? memcpy((PVOID)g_NtWriteVirtualMemorySave, (PVOID)g_NtWriteVirtualMemory, sizeof(g_NtWriteVirtualMemorySave));
?? DbgPrint("NtWriteVirtualMemory 地址:%08X", g_NtWriteVirtualMemory);
}
else
{
?? DbgPrint("獲取NtWriteVirtualMemory地址失敗");
}
if (g_KiAttachProcess)
{
?? memcpy((PVOID)g_KiAttachProcessSave, (PVOID)g_KiAttachProcess, sizeof(g_KiAttachProcessSave));
?? DbgPrint("KiAttachProcess 地址:%08X", g_KiAttachProcess);
}
else
{
?? DbgPrint("獲取KiAttachProcess地址失敗");
}
HookFunction(g_PsCreateSystemThread, (ULONG)MyPsCreateSystemThread, &g_hPsCreateSystemThread, &g_PsCreateSystemThreadAddr);
}
VOID UnHook()
{
UnHookFunction(&g_hPsCreateSystemThread);
}
void OnUnload(PDRIVER_OBJECT pDriverObj)
{
UnHook();
DbgPrint("卸載成功");
}
// 驅動程序加載時調用DriverEntry例程
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
pDriverObj->DriverUnload = OnUnload;
DbgPrint("加載成功");
Hook();
return STATUS_SUCCESS;
}
?