Created
January 31, 2018 11:53
-
-
Save GitMirar/1fa76a2d01d14880e02c3f9f08f132e8 to your computer and use it in GitHub Desktop.
HookPort.sys ripped from http://www.aihuau.com/a/25101014/229166.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
直接粘源代码: | |
里面实现了一个简易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) ) | |
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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment