HookPort.sys分析二 hookport.sys引起蓝屏

直接粘源代码:

里面实现了一个简易HookPort驱动,并在XPSP3下通过。并且实现了大多数关键功能。

由于HookPort里面有太多的重复性劳动,所以对于Hook函数我只写了一个hookntcreatekey函数的原型,其他都类似。

没有注释,大家凑合看吧。

#include <ntddk.h>
#include <stdio.h>
#include <string.h>
#include <ntimage.h>
#include "MyHookPort.h"


extern PULONG InitSafeBootMode;
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRINGpRegistryPath)
{
ULONG MajorVersion;
ULONG MinorVersion;
ULONG BuildNumber;
PDEVICE_OBJECT pDeviceObject;
UNICODE_STRING DeviceName;
UNICODE_STRING SymboLinkName;
NTSTATUS status;


PsGetVersion(&MajorVersion,&MinorVersion, &BuildNumber,0);
if ( MajorVersion != 5&& MajorVersion != 6)
returnSTATUS_NOT_IMPLEMENTED;
if ( MinorVersion != 0&& MinorVersion != 1)
returnSTATUS_UNSUCCESSFUL;
if ( *InitSafeBootMode > 0)
return STATUS_UNSUCCESSFUL;

RtlInitUnicodeString(&DeviceName,L"\Device\MyHookPort");
RtlInitUnicodeString(&SymboLinkName,L"\DosDevices\MyHookPort");

status = IoCreateDevice(pDriverObject,sizeof(MYHOOKPORT_DEVICE_EXTENSION),&DeviceName,FILE_DEVICE_UNKNOWN, 0x100, 0,&pDeviceObject);

if ( !NT_SUCCESS(status) )
{
//HookPortInitial();
returnSTATUS_UNSUCCESSFUL;
}

if ( !NT_SUCCESS(IoCreateSymbolicLink(&SymboLinkName,&DeviceName)))
{
IoDeleteDevice(pDeviceObject);
returnSTATUS_UNSUCCESSFUL;
}
pDriverObject->MajorFunction[IRP_MJ_CREATE]= PassThrough;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]= PassThrough;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= MyDeviceIoControl;


//else
//{
//SetDeviceExtension(pDeviceObject);
//MonitorKiFastCallHook();
//}

HookPortInitial();
HookKiFastCallEntry();

//IoDeleteSymbolicLink(&SymboLinkName);
//IoDeleteDevice(pDeviceObject);

return STATUS_SUCCESS;
}

NTSTATUS PassThrough(PDEVICE_OBJECT pDev, PIRP pIrp)
{
pIrp->IoStatus.Status =STATUS_SUCCESS;
pIrp->IoStatus.Information =0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

NTSTATUS MyDeviceIoControl(PDEVICE_OBJECT pDev, PIRP pIrp)
{
return STATUS_SUCCESS;
}

NTSTATUS HookPortInitial()
{
UINT_PTR Win32Base;
SIZE_TWin32Size;
ANSI_STRING Name;
if( GetMoudleBaseAndSize("win32k.sys",&Win32Base, &Win32Size) )
{
if(!FindKeServiceDescriptorTableShadow())
returnSTATUS_UNSUCCESSFUL;
}

RtlInitAnsiString(&Name,"KeServiceDescriptorTable");
gTableAddress =(PKESERVICE_TABLE_DESCRIPTOR)GetFuncAddrAndEATAddrInNtoskrnl(&Name);
if ( gTableAddress == NULL ||!MmIsAddressValid((PVOID)gTableAddress) )
{
returnSTATUS_UNSUCCESSFUL;
}


return STATUS_UNSUCCESSFUL;
}

VOID SetDeviceExtension(PDEVICE_OBJECT pDevObj)
{
PMYHOOKPORT_DEVICE_EXTENSION pDevExt =(PMYHOOKPORT_DEVICE_EXTENSION)pDevObj->DeviceExtension;

pDevExt->Undefined = 2;
pDevExt->pPrepareFilterRuleTable =NULL;
pDevExt->pSetFilterFunctions =NULL;
pDevExt->pSetFilterRule =NULL;

}

VOID MonitorKiFastCallHook()
{
return;
}

BOOL GetMoudleBaseAndSize(CONST CHAR *szModuleName, PUINT_PTRpBase, PSIZE_T pModuleSize)
{
PSYSTEM_MODULE_INFORMATIONpSysModuleInforBuf;
ULONG ulPageSize;
NTSTATUS status;
ULONG ReturnLength;
ULONG ModuleCount;
ULONG i;
BOOL bRet;

pSysModuleInforBuf = NULL;
ulPageSize = PAGE_SIZE;
bRet = FALSE;
do
{
if ( pSysModuleInforBuf !=NULL)
ExFreePool(pSysModuleInforBuf);

pSysModuleInforBuf =(PSYSTEM_MODULE_INFORMATION)ExAllocatePoolWithTag(NonPagedPool,ulPageSize, POOL_TAG);
if ( pSysModuleInforBuf ==NULL)
returnFALSE;
status =ZwQuerySystemInformation(SystemModuleInformation,pSysModuleInforBuf, ulPageSize,&ReturnLength);
if ( !NT_SUCCESS(status)&& status !=STATUS_INFO_LENGTH_MISMATCH)
{
bRet =FALSE;
gotoFREE_BUF;
}
ulPageSize += PAGE_SIZE;

}while ( !NT_SUCCESS(status) );

if ( szModuleName == NULL)
{
*pBase =(UINT_PTR)pSysModuleInforBuf->Module[0].Base;
*pModuleSize =pSysModuleInforBuf->Module[0].Size;
bRet = TRUE;
goto FREE_BUF;
}

ModuleCount =pSysModuleInforBuf->Count;
for ( i = 0; i < ModuleCount;i++)
{
char * pRet =strrchr(pSysModuleInforBuf->Module[i].ImageName,'\');
if ( pRet == NULL )
pRet =pSysModuleInforBuf->Module[i].ImageName;
else
pRet +=1;
if( !strcmp(pRet ,szModuleName) )
{
*pBase =(UINT_PTR)pSysModuleInforBuf->Module[i].Base;
*pModuleSize= pSysModuleInforBuf->Module[i].Size;
bRet =TRUE;
break;
}

}


FREE_BUF:
if ( pSysModuleInforBuf )
{
ExFreePool(pSysModuleInforBuf);
}
return bRet;
}

BOOL MemoryIsVaild(PVOID VirtualAddress, SIZE_T size)
{
PUCHAR cur, end;
cur = (PUCHAR)VirtualAddress;
end = (PUCHAR)( ((ULONG)VirtualAddress +(ULONG)(size - 1))&0xfffff000 + PAGE_SIZE);

do
{
if ( !MmIsAddressValid(cur))
returnFALSE;
cur = (PUCHAR)((ULONG)((ULONG)cur & 0xfffff000) +(ULONG)PAGE_SIZE);
} while (cur != end);
return TRUE;
}
BOOL FindKeServiceDescriptorTableShadow()
{
ANSI_STRING Name;
UINT_PTR nAddress1, nAddress2;
PUCHAR Cur, End;
PKESERVICE_TABLE_DESCRIPTOR pServiceTable;
BOOL bFinded = FALSE;

RtlInitAnsiString(&Name,"KeAddSystemServiceTable");
nAddress1 =GetFuncAddrAndEATAddrInNtoskrnl(&Name);
//在KeAddSystemServiceTable中寻找
if ( nAddress1 != 0&&MmIsAddressValid((PVOID)nAddress1))
{
End = (PUCHAR)nAddress1 +0x100;
for ( Cur = (PUCHAR)nAddress1;Cur < End; Cur++)
{
if (MemoryIsVaild(Cur, 2) )
if( *(PUSHORT)Cur == 0x888D )
if( MemoryIsVaild(Cur + 2, 4) )
{
pServiceTable= (PKESERVICE_TABLE_DESCRIPTOR)( *(PULONG)(Cur + 2));
if( MemoryIsVaild((PUCHAR)pServiceTable + 0x10, 4) )
if(MemoryIsVaild((PUCHAR)pServiceTable + 0x18, 4))
{
bFinded= TRUE;
break;
}
}
}
}
//在KeRemoveSystemServiceTable中寻找
else
{
RtlInitAnsiString(&Name,"KeRemoveSystemServiceTable");
nAddress2 =GetFuncAddrAndEATAddrInNtoskrnl(&Name);
if ( nAddress2 != 0&&MmIsAddressValid((PVOID)nAddress2))
{

End =(PUCHAR)nAddress2 + 0x100;
for ( Cur =(PUCHAR)nAddress2; Cur < End; Cur++)
{
if( MemoryIsVaild(Cur, 2) )
HookPort.sys分析二 hookport.sys引起蓝屏
if( *(PUSHORT)Cur == 0x8889 )
if( MemoryIsVaild(Cur + 2, 4) )
{
pServiceTable= (PKESERVICE_TABLE_DESCRIPTOR)( *(PULONG)(Cur + 2));
if( MemoryIsVaild((PUCHAR)pServiceTable + 0x10, 4) )
if(MemoryIsVaild((PUCHAR)pServiceTable + 0x18, 4))
{
bFinded= TRUE;
break;
}
}
}
}
else
{
if (nAddress1 )
{
nAddress2= nAddress1;
End= (PUCHAR)( (ULONG)nAddress2 & 0xfffff000 +0xffa);
for( Cur = (PUCHAR)nAddress1; Cur < End; Cur++)
{
if( *(PUSHORT)Cur == 0x888D )
{
pServiceTable= (PKESERVICE_TABLE_DESCRIPTOR)( *(PULONG)(Cur + 2));
if( MemoryIsVaild((PUCHAR)pServiceTable + 0x10, 4) )
if(MemoryIsVaild((PUCHAR)pServiceTable + 0x18, 4))
{
bFinded= TRUE;
break;
}
}

}
}
}

}

if ( bFinded == TRUE)
{
gShadowBase =pServiceTable[1].Base;
gShadowLimit =pServiceTable[1].Limit;
}

if ( gShadowBase == 0)
return FALSE;
return TRUE;
}

ULONG DisableProtectWriteCR0()
{
ULONG temp;
_asm push eax
_asm mov eax, CR0
_asm mov temp, eax
_asm and eax, 0xfffeffff
_asm mov CR0, eax
_asm pop eax
_asm cli
return temp;

}
UINT_PTR GetFuncAddrAndEATAddr(UINT_PTR ImageBase, PANSI_STRINGpFuncName, UINT_PTR nNewAddress, PUINT_PTR *outEatAddress)
{
ULONG ExportSize;
PULONG AddressOfNames;
PUSHORTAddressOfNameOrdinals;
PUINT_PTR AddressOfFunctions;
PIMAGE_EXPORT_DIRECTORY pExportVA;
LONG Low, High, Mid;
int nCompare;
ULONG nIndex;
UINT_PTR nRet;
pExportVA =(PIMAGE_EXPORT_DIRECTORY)RtlImageDirectoryEntryToData((PVOID)ImageBase,1, IMAGE_DIRECTORY_ENTRY_EXPORT,&ExportSize);
if( pExportVA == NULL )
return 0;

AddressOfNames =(PULONG)(pExportVA->AddressOfNames +ImageBase);
AddressO--fNameOrdinals =(PUSHORT)(pExportVA->AddressOfNameOrdinals +ImageBase);


Low = 0;
High = pExportVA->NumberOfNames -1;
do
{
Mid = ( Low + High ) / 2;
nCompare =strcmp(pFuncName->Buffer, (PCHAR)(ImageBase +AddressOfNames[Mid]) );
if ( nCompare <0 )
High = Mid -1;
else if ( nCompare> 0)
Low = Mid +1;
else
break;

} while ( High >= Low);

if ( Low > High)
return 0;
nIndex = (ULONG)AddressOfNameOrdinals[Mid];
if ( nIndex >=pExportVA->NumberOfFunctions)
return 0;

AddressOfFunctions =(PUINT_PTR)(pExportVA->AddressOfFunctions +ImageBase);
nRet = ImageBase +AddressOfFunctions[nIndex];
if ( nNewAddress )
{
OldCr0 =DisableProtectWriteCR0();
InterlockedExchange(&AddressOfFunctions[nIndex],nNewAddress - ImageBase);
ENABLE_WRITE_PROTECT(OldCr0);
}
*outEatAddress =&AddressOfFunctions[nIndex];
return nRet;

}

UINT_PTR GetFuncAddrAndEATAddrInNtoskrnl(PANSI_STRINGpFuncName)
{
if ( gImageBase == 0)
{
if( !GetMoudleBaseAndSize(NULL,&gImageBase, &gImageSize) )
{
gImageBase =0;
return0;
}
}
return GetFuncAddrAndEATAddr(gImageBase,pFuncName, 0, (PUINT_PTR *)&pFuncName);
}

NTSTATUS HookKiFastCallEntry()
{
ANSI_STRING FuncName;
UINT_PTR FuncAddress;
KSPIN_LOCK SpinLock;
KIRQL OldIrql;
ULONG tempOldCR0;
PULONG SSDTAddress;

RtlInitAnsiString(&FuncName,"ZwSetEvent");
FuncAddress =GetFuncAddrAndEATAddrInNtoskrnl(&FuncName);
if ( FuncAddress == 0 )
returnSTATUS_UNSUCCESSFUL;
gNtSetEventIndex = * (PULONG)((PUCHAR)FuncAddress+ 1);
KeInitializeSpinLock(&SpinLock);
OldIrql =KfAcquireSpinLock(&SpinLock);
_asm
{
push eax
push ebx
push edx
cli
mov eax, CR0
mov tempOldCR0, eax
and eax, 0xfffeffff
mov CR0, eax
}
SSDTAddress = gTableAddress[0].Base;
gOldNtSetEventAddress =(UINT_PTR)SSDTAddress[gNtSetEventIndex];
SSDTAddress[gNtSetEventIndex] =(ULONG)NewNtSetEvent;
_asm
{
mov eax, tempOldCR0
mov CR0, eax
sti
pop edx
pop ebx
pop eax
}
KfReleaseSpinLock(&SpinLock,OldIrql);
gMyValidHandle = (HANDLE)0x288C58F1;
ZwSetEvent(gMyValidHandle, NULL);

if ( gReturnAddress == 0)
{
if( gBufForJmp )
ExFreePool(gBufForJmp);
returnSTATUS_UNSUCCESSFUL;
}

if ( gFindedAddressEnd != 0)
{
KdPrint(("Hook KiFastCallokrn"));
return STATUS_SUCCESS;
}

return STATUS_SUCCESS;
}

VOID _declspec(naked) HookKiFastCallProcessForVista()
{
__asm
{
movedi, edi
pushfd
pushad
pushedi
pushedx
pusheax
callHookKiFastCallProcessReal
mov[esp+14h],eax//=edx 修改为处理后的函数地址
popad
popfd
subesp,ecx//被覆盖的两条指令
shrecx, 2
pushgFindedAddressEnd
retn// 跳回原函数
}
}

VOID _declspec(naked) HookKiFastCallProcessForNt()
{
__asm
{
movedi, edi
pushfd
pushad
pushedi
pushebx
pusheax
callHookKiFastCallProcessReal
mov[esp+10h],eax//=ebx 修改为处理后的函数地址
popad
popfd
subesp,ecx//被覆盖的两条指令
shrecx, 2
pushgFindedAddressEnd
retn// 跳回原函数
}
}


NTSTATUS NewNtSetEvent(HANDLE EventHandle, PULONGPreviousState)
{
PUCHAR HookFuncAddress;
KSPIN_LOCK SpinLock;
KIRQL OldIQL;
ULONG tempOldCR0;
PULONG SSDTAddress;
PUCHAR SearchCur;
BOOL bFinded = FALSE;
if ( EventHandle != gMyValidHandle ||ExGetPreviousMode() != KernelMode)
{
return((pFnSetEvent)gOldNtSetEventAddress)(EventHandle,PreviousState);
}
gBufForJmp =ExAllocatePoolWithTag(NonPagedPool,5, POOL_TAG);
if ( gBufForJmp == NULL)
{
return STATUS_SUCCESS;
}
*(PUCHAR)gBufForJmp = 0xE9;
//if ( *(PUSHORT)NtBuildNumber >=0x1770)
//HookFuncAddress =(PUCHAR)HookKiFastCallProcessForVista;
//else
HookFuncAddress =(PUCHAR)HookKiFastCallProcessForNt;
HookFuncAddress = (PUCHAR)(HookFuncAddress -(PUCHAR)gBufForJmp - 5);
*(PULONG)(gBufForJmp + 1) =(ULONG)HookFuncAddress;
KeInitializeSpinLock(&SpinLock);
OldIQL =KfAcquireSpinLock(&SpinLock);
_asm
{
push eax
push ecx
push edx
push esi
push edi
cli
mov eax, CR0
mov tempOldCR0, eax
and eax, 0xfffeffff
mov CR0, eax
}
//回复ZwSetEvent
SSDTAddress = gTableAddress[0].Base;
SSDTAddress[gNtSetEventIndex] =(ULONG)gOldNtSetEventAddress;
_asm
{
push eax
mov eax, [ebp + 4]
mov gReturnAddress, eax
pop eax
}

for ( SearchCur = gReturnAddress; SearchCur> gReturnAddress - 0x64; SearchCur--)
{
if (RtlEqualMemory(gForFindCode, SearchCur, 5) )
{
bFinded =TRUE;
break;
}
}

if ( bFinded )
{
gFindedAddressEnd = SearchCur +5;
gJmpFirst[0] = 0xE9;
*(PULONG)(gJmpFirst + 1) =gBufForJmp - gFindedAddressEnd;
RtlCopyMemory(SearchCur,gJmpFirst, 5);

}

_asm
{
mov eax, tempOldCR0
mov CR0, eax
sti
pop edi
pop esi
pop edx
pop ecx
pop eax
}
KfReleaseSpinLock(&SpinLock,OldIQL);

return STATUS_SUCCESS;

}


UINT_PTR HookKiFastCallProcessReal(ULONG ServiceIndex, UINT_PTRServiceFunAddr, PUINT_PTR ServiceTab)
{
return ServiceFunAddr;
}


//作用:根据索引调用过滤,并返回回调函数和回调函数参数以及过滤参数的个数
//只要一个过滤函数返回失败,则不能调用
NTSTATUS CallFilterFuncByIndex(ULONG nIndex, PULONGpParametersStartAddr, PULONG pCallBackArray, PULONGpUseForCallBackArray, PULONG pCallBackCount)
{
ULONG UseForCallBack;
ULONG CallBackCount = 0;
ULONG FilterFuncAddress;
NTSTATUS status;
ULONG CallBackTemp;

PFILTERFUN_RULE_TABLE pCur;

if ( nIndex >= 0x57)
return STATUS_SUCCESS;

if( gpFilterRuleTable == NULL)
{
if( pCallBackCount !=NULL)
*pCallBackCount=CallBackCount;
return STATUS_SUCCESS;
}

pCur = gpFilterRuleTable;

do
{
if(pCur->IsFilterFunFilledReady == 0)
continue;
if( ( FilterFuncAddress =pCur->FakeServiceRoutine[nIndex]) == 0 )
continue;

CallBackTemp = 0;
UseForCallBack = 0;
status =((pFnFilterFunc)FilterFuncAddress)(nIndex, pParametersStartAddr,&CallBackTemp,&UseForCallBack);
if( !NT_SUCCESS(status) )
returnstatus;
if( CallBackCount != 0&& pCallBackArray != 0&& CallBackCount <16)
{
CallBackCount++;
pCallBackArray[CallBackCount]= CallBackTemp;
pUseForCallBackArray[CallBackCount]= UseForCallBack;
}

pCur =pCur->pNext;

} while ( pCur != NULL);

if ( pCallBackCount == NULL)
return STATUS_SUCCESS;
*pCallBackCount = CallBackCount;
return STATUS_SUCCESS;
}

//被Hook的NtCreateKey函数
NTSTATUS HookNtCreateKey(
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING ClassOPTIONAL,
IN ULONG CreateOptions,
OUT PULONG DispositionOPTIONAL
)
{
NTSTATUS status, status1;
ULONG CallBackCount;
ULONG Parameters[7];
ULONG CallBack[16];//其实最多也就16个
ULONG UseForCallBack[16]; //也是最多16个
ULONG FuncAddress;
ULONG i;

status = CallFilterFuncByIndex(0, Parameters,CallBack, UseForCallBack, &CallBackCount);
if( status == 0xC0000503)
return STATUS_SUCCESS;
if( !NT_SUCCESS(status))
return status;

if ( (gNtCreateKeyIndex &(ULONG)0x00001000) != 0) //shadow ssdt
{
if( MmIsAddressValid((PVOID)(gServiceFilterInfoTable->SavedShadowSSDTServiceAddress[gNtCreateKeyIndex &0xfff]) ) )
FuncAddress =gServiceFilterInfoTable->SavedShadowSSDTServiceAddress[gNtCreateKeyIndex & 0xfff];
else
FuncAddress =gShadowBase[gNtCreateKeyIndex & 0xfff];
}
else // ssdt
{
if( MmIsAddressValid((PVOID)(gServiceFilterInfoTable->SavedSSDTServiceAddress[gNtCreateKeyIndex ]) ) )
FuncAddress =gServiceFilterInfoTable->SavedSSDTServiceAddress[gNtCreateKeyIndex ];
else
FuncAddress =gTableBase[gNtCreateKeyIndex];
}

status =((pFnNtCreateKey)FuncAddress)(KeyHandle, DesiredAccess,ObjectAttributes,TitleIndex,Class,CreateOptions,Disposition);
for ( i = 0; i < CallBackCount;i++)
{
status1 =((pFnCallBackFunc)(CallBack[i]))(0, Parameters, status,UseForCallBack[i]);
if ( !NT_SUCCESS(status1))
returnstatus1;
}

return status;
}

  

爱华网本文地址 » http://www.aihuau.com/a/25101014/229166.html

更多阅读

浏览器蓝屏怎么办 ie闪退打不开网页

浏览器蓝屏怎么办——简介微软发布kb2670838更新补丁后,部分双显卡笔记本(目前发现为载有AMD独显的笔记本)出现了打开浏览器蓝屏的现象,蓝屏代码为:igdpmd64.sys用户打开IE浏览器或为IE内核的浏览器会出现蓝屏现象这篇经验小编为主的

电脑开机就蓝屏重启解决方法 电脑一开机就蓝屏

电脑开机就蓝屏重启解决方法——简介近日微软推送8月份的更新补丁,通过系统或安全软件进行补丁更新后,可能会导致用户电脑重启后出现开机0xc0000005,0xc0000008e蓝屏,同时无法开机的现象,反复重新启动。影响系统:XP(SP3);vista_32/64(SP2);20

蓝屏故障:19 0x00000077

蓝屏故障:[19]0x00000077——简介在百度经验《蓝屏故障代码:[1]前因后果》首篇经验中已经概述了导致蓝屏的原因和解决思路。此文着重于具体的蓝屏出错代码的具体原因分析,虽然不能良方治百病,但也能触类旁通解疑惑。蓝屏故障:[19]0x000

蓝屏故障:11 0x0000007e

蓝屏故障:[11]0x0000007e——简介在百度经验《蓝屏故障代码:[1]前因后果》首篇经验中已经概述了导致蓝屏的原因和解决思路。此文着重于具体的蓝屏出错代码的具体原因分析,虽然不能良方治百病,但也能触类旁通解疑惑。蓝屏故障:[11]0x000

蓝屏故障:38 0x0000007A 精 反恐精英ol

蓝屏故障:[38]0x0000007A 精——简介在百度经验《蓝屏故障代码:[1]前因后果》首篇经验中已经概述了导致蓝屏的原因和解决思路。此文着重于蓝屏出错代码的具体原因分析,虽然不能良方治百病,但也能触类旁通解疑惑。蓝屏故障:[38]0x0000007

声明:《HookPort.sys分析二 hookport.sys引起蓝屏》为网友少年就要狂分享!如侵犯到您的合法权益请联系我们删除