过游戏保护驱动

整理自CrazyWolf的博客

学习下过游戏驱动保护的方法。

篇一:

//
//define
#define SsdtTbaleSize 0x11C //
//全局

ULONG ZwHookOpenProcess = 0;
ULONG ZwHookWriteVirtualMemory = 0;
ULONG ZwHookQuerySystemInformation = 0;


DWORD oldssdt[SsdtTbaleSize] = {0};


VOID SaveOldSSdt()
{
//保存没有被HOOK前的SSDT表
PVOID pssdttableaddr = (PVOID)KeServiceDescriptorTable->ServiceTableBase;
RtlCopyMemory( oldssdt , pssdttableaddr , SsdtTbaleSize*sizeof(DWORD) );

KdPrint( ("SaveOldSSdt OK") );
}


ULONG GetFunctionId( char* FunctionName )
{
NTSTATUS ntstatus;
HANDLE hFile = NULL; 
HANDLE hSection = NULL ;
OBJECT_ATTRIBUTES object_attributes;
IO_STATUS_BLOCK io_status = {0};
PVOID baseaddress = NULL;
SIZE_T size = 0;
//模块基址
PVOID ModuleAddress = NULL;
//偏移量
ULONG dwOffset = 0;

PIMAGE_DOS_HEADER dos = NULL;
PIMAGE_NT_HEADERS nt = NULL; 
PIMAGE_DATA_DIRECTORY expdir = NULL;
PIMAGE_EXPORT_DIRECTORY exports = NULL;

ULONG addr;
ULONG Size;

PULONG functions;
PSHORT ordinals;
PULONG names;

ULONG max_name;
ULONG max_func;
ULONG i;

ULONG pFunctionAddress;

ULONG ServiceId;

UNICODE_STRING DllName;
RtlInitUnicodeString( &DllName, L"\\SystemRoot\\system32\\ntdll.dll");
//初始化OBJECT_ATTRIBUTES结构
InitializeObjectAttributes( 
   &object_attributes,
   &DllName,
    OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
   NULL,
   NULL);
//打开文件
ntstatus = ZwCreateFile(
   &hFile,
    FILE_EXECUTE | SYNCHRONIZE,
   &object_attributes,
   &io_status,
   NULL,
    FILE_ATTRIBUTE_NORMAL,
    FILE_SHARE_READ,
    FILE_OPEN,
    FILE_NON_DIRECTORY_FILE |
    FILE_RANDOM_ACCESS |
    FILE_SYNCHRONOUS_IO_NONALERT,
   NULL,
   0);
if( !NT_SUCCESS( ntstatus ))
{
    KdPrint(("[GetFunctionAddress] error0\n"));
    KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
   return 0;
}
//创建区段
InitializeObjectAttributes(
   &object_attributes,
   NULL,
    OBJ_CASE_INSENSITIVE|OBJ_KERNEL_HANDLE,
   NULL,
   NULL);

ntstatus = ZwCreateSection(
   &hSection,
    SECTION_ALL_ACCESS,
   &object_attributes,
   0,
    PAGE_EXECUTE,
    SEC_IMAGE,
    hFile);
if( !NT_SUCCESS( ntstatus ))
{
    KdPrint(("[GetFunctionAddress] error1\n"));
    KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
   return 0;
}
//映射区段到进程虚拟空间
ntstatus = ZwMapViewOfSection(
    hSection,
    NtCurrentProcess(), //ntddk.h定义的宏用来获取当前进程句柄
   &baseaddress,
   0,
   1000,
   0,
   &size,
   (SECTION_INHERIT)1,
    MEM_TOP_DOWN,
    PAGE_READWRITE);
if( !NT_SUCCESS( ntstatus ))
{
    KdPrint(("[GetFunctionAddress] error2\n"));
    KdPrint(("[GetFunctionAddress] ntstatus = 0x%x\n", ntstatus));
   return 0;
}
//得到模块基址
dwOffset = ( ULONG )baseaddress;
//验证基址
//KdPrint(("[GetFunctionAddress] BaseAddress:0x%x\n", dwOffset));
dos =(PIMAGE_DOS_HEADER) baseaddress; 
nt =(PIMAGE_NT_HEADERS)((ULONG) baseaddress + dos->e_lfanew);
expdir = (PIMAGE_DATA_DIRECTORY)(nt->OptionalHeader.DataDirectory + IMAGE_DIRECTORY_ENTRY_EXPORT);

addr = expdir->VirtualAddress;//数据块起始RVA
Size = expdir->Size;    //数据块长度

exports =(PIMAGE_EXPORT_DIRECTORY)((ULONG) baseaddress + addr);

functions =(PULONG)((ULONG) baseaddress + exports->AddressOfFunctions);
ordinals =(PSHORT)((ULONG) baseaddress + exports->AddressOfNameOrdinals);
names =(PULONG)((ULONG) baseaddress + exports->AddressOfNames);

max_name =exports->NumberOfNames;
max_func =exports->NumberOfFunctions;


for (i = 0; i < max_name; i++)
{
   ULONG ord = ordinals[i];
   if(i >= max_name || ord >= max_func) 
   {
    return 0;
   }
   if (functions[ord] < addr || functions[ord] >= addr + Size)
   {
    if (strcmp((PCHAR) baseaddress + names[i], FunctionName) == 0)
    {
      pFunctionAddress =(ULONG)((ULONG) baseaddress + functions[ord]);
     break;
    }
   }
}


//KdPrint(("[GetFunctionAddress] %s:0x%x\n",FunctionName, pFunctionAddress));
ServiceId = *(PSHORT)(pFunctionAddress + 1);
//打印导出函数服务号
//KdPrint(("[GetServiceId] ServiceId:0x%x\n",ServiceId));
//卸载区段,释放内存,关闭句柄
ZwUnmapViewOfSection( NtCurrentProcess(), baseaddress);
ZwClose( hSection);
ZwClose( hFile );
return ServiceId;
}

VOID InitSystemCallIndex()
{
ZwOpenProcessIndex      = GetFunctionId( "ZwOpenProcess" );
ZwHookOpenProcess = (KeServiceDescriptorTable->ServiceTableBase)[ZwOpenProcessIndex];
KdPrint(("[InitSystemCallIndex]ZwHookOpenProcess:0x%x,Orgin addrs:0x%x,Hook:0x%x\n",ZwOpenProcessIndex,oldssdt[ZwOpenProcessIndex], ZwHookOpenProcess ));

ZwWriteVirtualMemoryIndex           = GetFunctionId( "ZwWriteVirtualMemory" );
ZwHookWriteVirtualMemory = (KeServiceDescriptorTable->ServiceTableBase)[ZwWriteVirtualMemoryIndex];
KdPrint(("[InitSystemCallIndex]ZwWriteVirtualMemoryIndex:0x%x,Orgin addrs:0x%x,Hook:0x%x\n",ZwWriteVirtualMemoryIndex , oldssdt[ZwWriteVirtualMemoryIndex],ZwHookWriteVirtualMemory ));

ZwQuerySystemInformationIndex = GetFunctionId( "ZwQuerySystemInformation" );
ZwHookQuerySystemInformation = (KeServiceDescriptorTable->ServiceTableBase)[ZwQuerySystemInformationIndex];
KdPrint(("[InitSystemCallIndex]ZwQuerySystemInformationIndex:0x%x,Orgin addrs:0x%x,Hook:0x%x\n",ZwQuerySystemInformationIndex , oldssdt[ZwQuerySystemInformationIndex] , ZwHookQuerySystemInformation));

}

ULONG CalcJmpCode(ULONG des , ULONG org )
{
return ( des - org - 5 );
}

VOID ModifyJmpCode2( ULONG myZwFuction , ULONG zwHookFuction)
{
   BYTE JmpCode[5] = { 0xE9 , 0 , 0 , 0 , 0 };

   DWORD addr = (DWORD)myZwFuction;

if( !MmIsAddressValid((PVOID)addr) )
{
    KdPrint( ("MmIsAddressValid 0x%x Error\n" , addr ) );
   return ;
}

    KdPrint( ("inline hook addr:0x%x\n" ,addr ) );

   //计算跳转地址
    addr = CalcJmpCode( addr , zwHookFuction );
   *(DWORD*)&JmpCode[1]=(DWORD)addr;

if( !MmIsAddressValid((PVOID)zwHookFuction) )
{
    KdPrint( ("MmIsAddressValid 0x%x Error\n" , zwHookFuction ) );
   return ;
}
    RtlCopyMemory( (PVOID)zwHookFuction , JmpCode , 5 );
}


VOID inlineHook()
{

//这个是转到系统函数
WPOFF();

if( ZwHookQuerySystemInformation != oldssdt[ZwQuerySystemInformationIndex] )
{
    ModifyJmpCode2( (ULONG)oldssdt[ZwQuerySystemInformationIndex] , (ULONG)ZwHookQuerySystemInformation );
}

if( ZwHookOpenProcess != oldssdt[ZwOpenProcessIndex] )
{
    ModifyJmpCode2( (ULONG)oldssdt[ZwOpenProcessIndex] , (ULONG)ZwHookOpenProcess );

}

if( ZwHookWriteVirtualMemory != oldssdt[ZwWriteVirtualMemoryIndex] )
{
    ModifyJmpCode2( (ULONG)oldssdt[ZwWriteVirtualMemoryIndex] , (ULONG)ZwHookWriteVirtualMemory );
}

WPON();

}


VOID Kill()
{
InitSystemCallIndex();
inlineHook();
}

篇二:

#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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值