www.pudn.com > He4Hook215b6.rar > Misc.cpp
#include "Misc.h"
#ifdef __MISC_USE_KHEAP
KHEAP hKHeapMiscDefault = NULL;
#endif //__MISC_USE_KHEAP
//
// Функции для работы с памятью
//
BOOLEAN AllocateSharedMemory(PSHARED_MEMORY lpSharedMemory, POOL_TYPE PoolType, ULONG dwSizeRegion)
{
if (!_MmIsAddressValid(lpSharedMemory))
return FALSE;
if (!dwSizeRegion)
return FALSE;
memset(lpSharedMemory, 0, sizeof(SHARED_MEMORY));
#ifndef __MISC_USE_KHEAP
lpSharedMemory->m_lpKernelMemory = ExAllocatePool(PoolType, dwSizeRegion);
#else
lpSharedMemory->m_lpKernelMemory = (CHAR*) _AllocatePoolFromKHeap(hKHeapMiscDefault, dwSizeRegion);
#endif //!__MISC_USE_KHEAP
if (!lpSharedMemory->m_lpKernelMemory)
return FALSE;
lpSharedMemory->m_Mdl = IoAllocateMdl(lpSharedMemory->m_lpKernelMemory, dwSizeRegion, FALSE, FALSE, NULL);
if (!lpSharedMemory->m_Mdl)
{
#ifndef __MISC_USE_KHEAP
ExFreePool(lpSharedMemory->m_lpKernelMemory);
#else
FreePoolToKHeap(hKHeapMiscDefault, lpSharedMemory->m_lpKernelMemory);
#endif //!__MISC_USE_KHEAP
memset(lpSharedMemory, 0, sizeof(SHARED_MEMORY));
return FALSE;
}
MmBuildMdlForNonPagedPool(lpSharedMemory->m_Mdl);
lpSharedMemory->m_lpUserPage = MmMapLockedPages(lpSharedMemory->m_Mdl, UserMode);
lpSharedMemory->m_lpUserMemory = (PVOID) (((ULONG)PAGE_ALIGN(lpSharedMemory->m_lpUserPage))+MmGetMdlByteOffset(lpSharedMemory->m_Mdl));
if (!_MmIsAddressValid(lpSharedMemory->m_lpUserMemory))
{
MmUnmapLockedPages(lpSharedMemory->m_lpUserPage, lpSharedMemory->m_Mdl);
IoFreeMdl(lpSharedMemory->m_Mdl);
#ifndef __MISC_USE_KHEAP
ExFreePool(lpSharedMemory->m_lpKernelMemory);
#else
FreePoolToKHeap(hKHeapMiscDefault, lpSharedMemory->m_lpKernelMemory);
#endif //!__MISC_USE_KHEAP
memset(lpSharedMemory, 0, sizeof(SHARED_MEMORY));
return FALSE;
}
lpSharedMemory->m_dwSizeRegion = dwSizeRegion;
return TRUE;
}
BOOLEAN FreeSharedMemory(PSHARED_MEMORY lpSharedMemory)
{
if (!_MmIsAddressValid(lpSharedMemory))
return FALSE;
if (!_MmIsAddressValid(lpSharedMemory->m_lpUserMemory))
return FALSE;
if (!_MmIsAddressValid(lpSharedMemory->m_lpKernelMemory))
return FALSE;
MmUnmapLockedPages(lpSharedMemory->m_lpUserPage, lpSharedMemory->m_Mdl);
IoFreeMdl(lpSharedMemory->m_Mdl);
#ifndef __MISC_USE_KHEAP
ExFreePool(lpSharedMemory->m_lpKernelMemory);
#else
FreePoolToKHeap(hKHeapMiscDefault, lpSharedMemory->m_lpKernelMemory);
#endif //!__MISC_USE_KHEAP
memset(lpSharedMemory, 0, sizeof(SHARED_MEMORY));
return TRUE;
}
PVOID
MapUserAddressToKernel(
IN PVOID pUserModeAddress,
IN ULONG ulSize,
OUT PMDL* ppMdl
)
{
PMDL pUserModeMdl = NULL;
PVOID pMappedKernelAddr = NULL;
if (ppMdl == NULL)
return NULL;
__try
{
pUserModeMdl = IoAllocateMdl(pUserModeAddress, ulSize, FALSE, FALSE, NULL);
if (pUserModeMdl != NULL)
{
MmProbeAndLockPages(pUserModeMdl, KernelMode, IoModifyAccess);
pMappedKernelAddr = MmMapLockedPages(pUserModeMdl, KernelMode);
if (pMappedKernelAddr != NULL)
{
pMappedKernelAddr = (PVOID) (((ULONG)PAGE_ALIGN(pMappedKernelAddr))+MmGetMdlByteOffset(pUserModeMdl));
*ppMdl = pUserModeMdl;
}
else
{
UnmapMappedKernelAddress(pUserModeMdl);
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
if (pUserModeMdl != NULL)
IoFreeMdl(pUserModeMdl);
pMappedKernelAddr = NULL;
}
return pMappedKernelAddr;
}
VOID
UnmapMappedKernelAddress(
IN PMDL pMdl
)
{
if (pMdl == NULL)
return;
MmUnlockPages(pMdl);
IoFreeMdl(pMdl);
}
BOOLEAN IsBadWritePtr(PVOID Address, ULONG Length, ULONG Alignment)
{
__try
{
ProbeForWrite(Address, Length, Alignment);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return TRUE;
}
return FALSE;
}
BOOLEAN _MmIsAddressValid(PVOID Address)
{
if (!Address)
return FALSE;
return MmIsAddressValid(Address);
}
//
// функции для работы с объектами ядра
//
//----------------------------------------------------------------------
//
// GetPointer
//
// Translates a handle to an object pointer.
//
//----------------------------------------------------------------------
POBJECT GetPointer(HANDLE handle)
{
POBJECT pKey;
NTSTATUS NtStatus;
//
// Ignore null handles
//
if (!handle && KeGetCurrentIrql() != PASSIVE_LEVEL)
return NULL;
//
// Get the pointer the handle refers to
//
NtStatus = ObReferenceObjectByHandle(handle, 0, NULL, KernelMode, &pKey, NULL);
if (NtStatus != STATUS_SUCCESS)
{
DbgPrintMisc(("He4hookInv: GetPointer: Error %08x getting key pointer\n", NtStatus));
pKey = NULL;
}
return pKey;
}
//----------------------------------------------------------------------
//
// ReleasePointer
//
// Dereferences the object.
//
//----------------------------------------------------------------------
VOID ReleasePointer(POBJECT object)
{
if (object && KeGetCurrentIrql() == PASSIVE_LEVEL)
ObDereferenceObject(object);
}
ULONG GetObjectName(HANDLE hObject, PWSTR lpwszName, ULONG dwSize)
{
CHAR *tmpname;//[0x400];
PUNICODE_STRING fullUniName;
NTSTATUS NtStatus;
ULONG dwObjectNameLen = 0; //(by bytes)
DbgPrintMisc(("He4hookInv: GetObjectName started!!!!!!!\n"));
if (!lpwszName || !dwSize || KeGetCurrentIrql() > PASSIVE_LEVEL)
return 0;
//
// Translate the hkey into a pointer
//
lpwszName[0] = 0;
#ifndef __MISC_USE_KHEAP
tmpname = (CHAR*) ExAllocatePool(NonPagedPool, dwSize+sizeof(UNICODE_STRING));
#else
tmpname = (CHAR*) _AllocatePoolFromKHeap(hKHeapMiscDefault, dwSize+sizeof(UNICODE_STRING));
#endif //!__MISC_USE_KHEAP
if (!_MmIsAddressValid(tmpname))
return 0;
tmpname[0] = 0;
NtStatus = ZwQueryObject(hObject, NameObjectInfo, tmpname, dwSize+sizeof(UNICODE_STRING), NULL);
if (NT_SUCCESS(NtStatus))
{
fullUniName = &(((PNAME_OBJECT_INFO)tmpname)->Name);
dwObjectNameLen = fullUniName->Length;
if (dwSize < (sizeof(WCHAR)+dwObjectNameLen))
{
DbgPrintMisc(("He4hookInv: GetObjectName ended - ERROR!!!!!!!\n"));
#ifndef __MISC_USE_KHEAP
ExFreePool(tmpname);
#else
FreePoolToKHeap(hKHeapMiscDefault, tmpname);
#endif //!__MISC_USE_KHEAP
return 0;
}
// memset(lpwszName, 0, (sizeof(WCHAR)+fullUniName->Length));
memcpy(lpwszName, fullUniName->Buffer, dwObjectNameLen);
lpwszName[dwObjectNameLen/sizeof(WCHAR)] = 0;
}
#ifndef __MISC_USE_KHEAP
ExFreePool(tmpname);
#else
FreePoolToKHeap(hKHeapMiscDefault, tmpname);
#endif //!__MISC_USE_KHEAP
DbgPrintMisc(("He4hookInv: GetObjectName ended - OK!!!!!!!\n"));
return dwObjectNameLen;
}
ULONG GetObjectNameByObjectAttributes(POBJECT_ATTRIBUTES ObjectAttributes, PWSTR fullPathName, ULONG nfullPathNameSize)
{
ULONG dwDirSize, dwNtPathNameLen;
int nObjectNameLen = 0;
PWSTR DosPathName;
NTSTATUS NtStatus;
PWSTR pwszObjectName = NULL;
if (
!_MmIsAddressValid(ObjectAttributes) ||
!_MmIsAddressValid(fullPathName) ||
!nfullPathNameSize
)
return 0;
fullPathName[0] = 0;
dwDirSize = 0;
if (_MmIsAddressValid(ObjectAttributes->ObjectName))
{
if (ObjectAttributes->ObjectName->Length != 0)
{
if (_MmIsAddressValid(ObjectAttributes->ObjectName->Buffer))
{
pwszObjectName = ObjectAttributes->ObjectName->Buffer;
nObjectNameLen = ObjectAttributes->ObjectName->Length;
}
}
}
#ifndef __MISC_USE_KHEAP
DosPathName = (PWSTR) ExAllocatePool(NonPagedPool, nfullPathNameSize);
#else
DosPathName = (PWSTR) _AllocatePoolFromKHeap(hKHeapMiscDefault, nfullPathNameSize);
#endif //!__MISC_USE_KHEAP
// DosPathName = (PWSTR)_AllocatePoolFromKHeap(hKHeapFSDefault, nfullPathNameSize);
if (DosPathName == NULL)
return 0;
DosPathName[0] = 0;
DbgPrintMisc((" GetFileNameByObjectAttributes: Attributes => %08x !!!\n", ObjectAttributes->Attributes));
if (ObjectAttributes->RootDirectory)
{
dwDirSize = GetObjectName(ObjectAttributes->RootDirectory, DosPathName, nfullPathNameSize);
}
if (dwDirSize > 3 && pwszObjectName != NULL)
{
if (
DosPathName[(dwDirSize/sizeof(WCHAR))-1] == L'\\' &&
(pwszObjectName[0] == L'\\' || pwszObjectName[0] == L'/')
)
{
DosPathName[(dwDirSize/sizeof(WCHAR))-1] = 0;
dwDirSize -= sizeof(WCHAR);
}
else
{
if (
DosPathName[(dwDirSize/sizeof(WCHAR))-1] != L'\\' &&
(pwszObjectName[0] != L'\\' || pwszObjectName[0] != L'/')
)
{
if (dwDirSize <= (nfullPathNameSize-2*sizeof(WCHAR)))
{
DosPathName[(dwDirSize/sizeof(WCHAR))] = L'\\';
DosPathName[(dwDirSize/sizeof(WCHAR))+1] = 0;
dwDirSize += sizeof(WCHAR);
}
}
}
}
if (pwszObjectName != NULL)
{
if (nfullPathNameSize > (nObjectNameLen+dwDirSize))
{
memcpy(((PCHAR)DosPathName+dwDirSize), pwszObjectName, nObjectNameLen);
((PWSTR)((PCHAR)DosPathName+dwDirSize))[nObjectNameLen/sizeof(WCHAR)] = 0;
}
}
dwNtPathNameLen = DosPathNameToNtPathName(DosPathName, fullPathName, nfullPathNameSize, 255, NULL);
#ifndef __MISC_USE_KHEAP
ExFreePool(DosPathName);
#else
FreePoolToKHeap(hKHeapMiscDefault, DosPathName);
#endif //!__MISC_USE_KHEAP
//FreePoolToKHeap(hKHeapFSDefault, DosPathName);
return dwNtPathNameLen;
}
ULONG GetObjectNameByFileObject(PFILE_OBJECT fileObject, PWSTR fullPathName, ULONG nfullPathNameSize)
{
ULONG pathLen, dwVolumeLen;
PWSTR pathOffset;
PFILE_OBJECT relatedFileObject;
// ANSI_STRING componentName;
PDEVICE_OBJECT pDeviceObject;
PUNICODE_STRING fullUniName;
UNICODE_STRING FileNameUnicodeString;
ULONG dwFreeSize = nfullPathNameSize;
ULONG dwFullPathLen = 0;
if (
KeGetCurrentIrql() > PASSIVE_LEVEL ||
!_MmIsAddressValid(fileObject) ||
!_MmIsAddressValid(fullPathName) ||
!fileObject
)
return 0;
fullPathName[0] = 0;
dwVolumeLen = 0;
__try
{
pDeviceObject = GetVolumeDeviceObject(fileObject);
if (pDeviceObject == NULL)
{
pDeviceObject = IoGetRelatedDeviceObject(fileObject);
}
fullUniName = (PUNICODE_STRING)fullPathName;
fullUniName->MaximumLength = (USHORT)(nfullPathNameSize*sizeof(WCHAR) - sizeof(UNICODE_STRING));
if (NT_SUCCESS(ObQueryNameString(pDeviceObject, (POBJECT_NAME_INFORMATION)fullUniName, fullUniName->MaximumLength, &pathLen)))
{
dwVolumeLen = fullUniName->Length;
memmove(fullPathName, fullUniName->Buffer, dwVolumeLen);
fullPathName[dwVolumeLen/sizeof(WCHAR)] = 0;
}
else
{
return 0;
}
// strcat(fullPathName, "\\");
dwFreeSize -= dwVolumeLen;
if (!fileObject->FileName.Length || fileObject->FileName.Length > dwFreeSize)
{
// RtlInitUnicodeString(&FileNameUnicodeString, fullPathName);
// RtlUnicodeStringToAnsiString( &componentName, &FileNameUnicodeString, TRUE );
// DbgPrint ("%s\n", componentName.Buffer);
// RtlFreeAnsiString( &componentName );
return wcslen(fullPathName)*sizeof(WCHAR);
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
__try
{
pathLen = fileObject->FileName.Length/sizeof(WCHAR) + 1;
relatedFileObject = fileObject->RelatedFileObject;
if (fileObject->FileName.Buffer[0] != L'\\' )
{
while (relatedFileObject)
{
if ((pathLen + relatedFileObject->FileName.Length/sizeof(WCHAR) + 1) >= dwFreeSize)
{
break;
}
pathLen += relatedFileObject->FileName.Length/sizeof(WCHAR) + 1;
relatedFileObject = relatedFileObject->RelatedFileObject;
}
}
if (dwFreeSize == nfullPathNameSize)
wcscpy(fullPathName, L"\\");
pathOffset = fullPathName + dwVolumeLen/sizeof(WCHAR) - 1 + pathLen - fileObject->FileName.Length/sizeof(WCHAR);
memcpy(pathOffset, fileObject->FileName.Buffer, fileObject->FileName.Length);
pathOffset[fileObject->FileName.Length/sizeof(WCHAR)] = 0;
relatedFileObject = fileObject->RelatedFileObject;
if (fileObject->FileName.Buffer[0] != L'\\')
{
while (relatedFileObject)
{
*(pathOffset - 1) = L'\\';
pathOffset -= relatedFileObject->FileName.Length/sizeof(WCHAR) + 1;
if (pathOffset <= fullPathName)
{
break;
}
memcpy(pathOffset, relatedFileObject->FileName.Buffer, relatedFileObject->FileName.Length);
relatedFileObject = relatedFileObject->RelatedFileObject;
}
}
dwFullPathLen = wcslen(fullPathName)*sizeof(WCHAR);
// if (fullPathName[dwVolumeLen/sizeof(WCHAR)] == L'\\' && fullPathName[dwVolumeLen/sizeof(WCHAR)+1] == L'\\')
// {
// memmove(&fullPathName[dwVolumeLen/sizeof(WCHAR)], &fullPathName[dwVolumeLen/sizeof(WCHAR)+1], pathLen*sizeof(WCHAR));
// }
pathOffset = wcsstr(fullPathName, L"\\\\");
while (pathOffset)
{
memmove(pathOffset, &pathOffset[1], wcslen(pathOffset)*sizeof(WCHAR));
pathOffset = wcsstr(pathOffset, L"\\\\");
}
// RtlInitUnicodeString(&FileNameUnicodeString, fullPathName);
// RtlUnicodeStringToAnsiString( &componentName, &FileNameUnicodeString, TRUE );
// DbgPrint ("%s\n", componentName.Buffer);
// RtlFreeAnsiString( &componentName );
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrintMisc(("GetFullPath: EXCEPTION\n"));
}
return dwFullPathLen;
}
PVOID GetObjectByPath(PWSTR pwszObjectName, PVOID pObjectType)
{
PVOID pObject = NULL;
UNICODE_STRING DeviceName;
NTSTATUS NtStatus = 0;
// ANSI_STRING FileNameAnsi;
if (!pwszObjectName || KeGetCurrentIrql() > PASSIVE_LEVEL)
return pObject;
RtlInitUnicodeString(&DeviceName, pwszObjectName);
// RtlUnicodeStringToAnsiString(&FileNameAnsi, &DeviceName, TRUE);
// if (strlen(FileNameAnsi.Buffer))
// DbgPrint ("%s\n", FileNameAnsi.Buffer);
// RtlFreeAnsiString(&FileNameAnsi);
__try
{
NtStatus = ObReferenceObjectByName(&DeviceName, OBJ_CASE_INSENSITIVE, NULL, 0, (POBJECT_TYPE)pObjectType, KernelMode, NULL, (PVOID*)&pObject);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
NtStatus = STATUS_ACCESS_VIOLATION;
// DbgPrint ("EXCEPTION into ObReferenceObjectByName\n");
}
//NTSYSAPI
//NTSTATUS
//NTAPI
//ObReferenceObjectByName(
// IN PUNICODE_STRING ObjectPath,
// IN ULONG Attributes,
// IN PACCESS_STATE PassedAccessState OPTIONAL,
// IN ACCESS_MASK DesiredAccess OPTIONAL,
// IN POBJECT_TYPE ObjectType,
// IN KPROCESSOR_MODE AccessMode,
// IN OUT PVOID ParseContext OPTIONAL,
// OUT PVOID *ObjectPtr
// );
if (NT_SUCCESS(NtStatus))
{
ObDereferenceObject((PVOID)pObject);
}
// DbgPrint ("He4HookInv: GetObjectByPath: pObject = %08X!!!\n", pObject);
return pObject;
}
POBJECT_NAME GetNameOfObject(PVOID pObject)
{
POBJECT_NAME pObjectName = NULL;
POBJECT_HEADER pObjectHdr;
if (_MmIsAddressValid(pObject))
{
pObjectHdr = (POBJECT_HEADER) ((PBYTE)pObject - SIZE_OF_OBJECT_HEADER);
if (_MmIsAddressValid(pObjectHdr))
{
if (pObjectHdr->SubHeaderInfo.NameOffset != 0)
{
pObjectName = (POBJECT_NAME) ((PBYTE)pObjectHdr - pObjectHdr->SubHeaderInfo.NameOffset);
}
}
}
return pObjectName;
}
//
// функции для работы с объектами файловых систем
//
BOOLEAN GetFileNameNative(HANDLE hObject, PWSTR lpwszName, ULONG dwSize)
{
PFILE_OBJECT pFileObject;
PDEVICE_OBJECT pDeviceObject;
BOOLEAN bRes = FALSE;
PFILE_NAME_INFORMATION FileName;
FileName = (PFILE_NAME_INFORMATION) ExAllocatePool(NonPagedPool, 2*dwSize);
if (!_MmIsAddressValid(FileName))
return bRes;
pFileObject = (PFILE_OBJECT) GetPointer(hObject);
if (_MmIsAddressValid(pFileObject))
{
pDeviceObject = IoGetRelatedDeviceObject(pFileObject);
if (_MmIsAddressValid(pDeviceObject))
{
bRes = FilemonQueryFileName(pDeviceObject, pFileObject, FileName, dwSize);
if (bRes)
{
memset(lpwszName, 0, dwSize);
memcpy(lpwszName, FileName->FileName, FileName->FileNameLength);
}
}
ReleasePointer((POBJECT)pFileObject);
}
ExFreePool(FileName);
return bRes;
}
NTSTATUS FilemonQueryFileNameComplete(PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context)
{
//
// Copy the status information back into the "user" IOSB.
//
*Irp->UserIosb = Irp->IoStatus;
// if( !NT_SUCCESS(Irp->IoStatus.Status) ) {
//
// DbgPrint((" ERROR ON IRP: %x\n", Irp->IoStatus.Status ));
// }
//
// Set the user event - wakes up the mainline code doing this.
//
KeSetEvent(Irp->UserEvent, 0, FALSE);
//
// Free the IRP now that we are done with it.
//
IoFreeIrp(Irp);
//
// We return STATUS_MORE_PROCESSING_REQUIRED because this "magic" return value
// tells the I/O Manager that additional processing will be done by this driver
// to the IRP - in fact, it might (as it is in this case) already BE done - and
// the IRP cannot be completed.
//
return STATUS_MORE_PROCESSING_REQUIRED;
}
//----------------------------------------------------------------------
//
// FilemonQueryFileName
//
// This function retrieves the "standard" information for the
// underlying file system, asking for the filename in particular.
//
//----------------------------------------------------------------------
BOOLEAN FilemonQueryFileName(PDEVICE_OBJECT DeviceObject,
PFILE_OBJECT FileObject,
PFILE_NAME_INFORMATION FileName, ULONG FileNameLength)
{
PIRP irp;
KEVENT event;
IO_STATUS_BLOCK IoStatusBlock;
PIO_STACK_LOCATION ioStackLocation;
// DbgPrint(("Getting file name for %x\n", FileObject));
//
// Initialize the event
//
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
//
// Allocate an irp for this request. This could also come from a
// private pool, for instance.
//
irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
if (!irp)
{
//
// Failure!
//
return FALSE;
}
//
// Build the IRP's main body
//
irp->AssociatedIrp.SystemBuffer = FileName;
irp->UserEvent = &event;
irp->UserIosb = &IoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = FileObject;
irp->RequestorMode = KernelMode;
irp->Flags = 0;
//
// Set up the I/O stack location.
//
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_QUERY_INFORMATION;
ioStackLocation->DeviceObject = DeviceObject;
ioStackLocation->FileObject = FileObject;
ioStackLocation->Parameters.QueryFile.Length = FileNameLength;
ioStackLocation->Parameters.QueryFile.FileInformationClass = FileNameInformation;
//
// Set the completion routine.
//
IoSetCompletionRoutine(irp, FilemonQueryFileNameComplete, 0, TRUE, TRUE, TRUE);
//
// Send it to the FSD
//
(void) IoCallDriver(DeviceObject, irp);
//
// Wait for the I/O
//
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
//
// Done! Note that since our completion routine frees the IRP we cannot
// touch the IRP now.
//
return NT_SUCCESS( IoStatusBlock.Status );
}
NTSTATUS
NativeQueryDirectoryFileComplete(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{
*Irp->UserIosb = Irp->IoStatus;
KeSetEvent(Irp->UserEvent, 0, FALSE);
IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
NativeQueryDirectoryFile(
PDRIVER_DISPATCH pMajorFunction,
PDEVICE_OBJECT pDeviceObject,
PFILE_OBJECT pFileObject,
PIO_STATUS_BLOCK pIoStatusBlock,
PVOID Buffer,
ULONG BufferLength,
FILE_INFORMATION_CLASS DirectoryInfoClass,
BOOLEAN ByOne,
PUNICODE_STRING pSearchTemplate,
BOOLEAN Reset,
BOOLEAN Index,
ULONG dwIndex
)
{
PIRP irp;
KEVENT event;
PIO_STACK_LOCATION ioStackLocation;
PQUERY_DIRECTORY pQueryDir;
KeInitializeEvent(&event, SynchronizationEvent, FALSE);
irp = IoAllocateIrp(pDeviceObject->StackSize, FALSE);
if (!irp)
return STATUS_NO_MEMORY;
irp->MdlAddress = NULL;
irp->UserBuffer = Buffer;
irp->AssociatedIrp.SystemBuffer = Buffer;
irp->UserEvent = &event;
irp->UserIosb = pIoStatusBlock;
irp->Tail.Overlay.Thread = PsGetCurrentThread();
irp->Tail.Overlay.OriginalFileObject = pFileObject;
irp->RequestorMode = KernelMode;
irp->Flags = 0;
ioStackLocation = IoGetNextIrpStackLocation(irp);
ioStackLocation->MajorFunction = IRP_MJ_DIRECTORY_CONTROL;
ioStackLocation->MinorFunction = IRP_MN_QUERY_DIRECTORY;
ioStackLocation->DeviceObject = pDeviceObject;
ioStackLocation->FileObject = pFileObject;
ioStackLocation->Flags = 0;
if (ByOne)
ioStackLocation->Flags |= SL_RETURN_SINGLE_ENTRY;
if (Reset)
ioStackLocation->Flags |= SL_RESTART_SCAN;
if (Index)
ioStackLocation->Flags |= SL_INDEX_SPECIFIED;
pQueryDir = (PQUERY_DIRECTORY)&ioStackLocation->Parameters;
pQueryDir->Length = BufferLength;
pQueryDir->FileName = pSearchTemplate;
pQueryDir->FileInformationClass = DirectoryInfoClass;
pQueryDir->FileIndex = dwIndex;
IoSetCompletionRoutine(irp, NativeQueryDirectoryFileComplete, 0, TRUE, TRUE, TRUE);
if (pMajorFunction == NULL)
{
(void) IoCallDriver(pDeviceObject, irp);
}
else
{
--(irp->CurrentLocation);
if (irp->CurrentLocation <= 0)
{
KeBugCheckEx(NO_MORE_IRP_STACK_LOCATIONS, (ULONG)irp, 0, 0, 0);
}
--(irp->Tail.Overlay.CurrentStackLocation);
irp->Tail.Overlay.CurrentStackLocation->DeviceObject = pDeviceObject;
pMajorFunction(pDeviceObject, irp);
}
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0);
return pIoStatusBlock->Status;
}
PDEVICE_OBJECT GetVolumeDeviceObject(PFILE_OBJECT pFileObject)
{
PDEVICE_OBJECT pVolumeDeviceObject = NULL;
if (pFileObject != NULL)
{
if (pFileObject->Vpb != NULL)
{
pVolumeDeviceObject = pFileObject->Vpb->RealDevice;
}
else
{
if (pFileObject->DeviceObject != NULL && pFileObject->DeviceObject->Vpb != NULL)
pVolumeDeviceObject = pFileObject->DeviceObject->Vpb->RealDevice;
}
}
return pVolumeDeviceObject;
}
//
// разное
//
BOOLEAN GetDirectoryFromPath(PWSTR lpwszFullFileName, ULONG dwSize)
{
ULONG i;
if (!_MmIsAddressValid(lpwszFullFileName) || !dwSize)
return FALSE;
i = dwSize;
while(1)
{
if (i == 0)
break;
if (lpwszFullFileName[i] == L'\\')
{
lpwszFullFileName[i] = 0;
break;
}
--i;
}
return TRUE;
}
BOOLEAN GetDirectoryFromPathA(CHAR *lpszFullFileName, ULONG dwSize)
{
ULONG i;
if (!_MmIsAddressValid(lpszFullFileName) || !dwSize)
return FALSE;
i = dwSize;
while(1)
{
if (i == 0)
break;
if (lpszFullFileName[i] == '\\')
{
lpszFullFileName[i] = 0;
break;
}
--i;
}
return TRUE;
}
int GetToken(WCHAR *lpInBuf, int dwInBufSize, WCHAR *lpOutBuf, int dwOutBufSize, WCHAR *lpDeliver, int nDeliverCount, int nNumber)
{
int Count = 0, k, i, j;
BOOLEAN bFlagExit;
if (!lpOutBuf || !lpInBuf || !lpDeliver)
return 0;
*lpOutBuf = 0;
// memset(lpOutBuf, 0, sizeof(WCHAR)*dwOutBufSize);
for (i=0; i= dwInBufSize)
{
++j;
break;
}
}
lpOutBuf[j] = 0;
return j;
}
}
return 0;
}
NTQUERYDIRECTORYOBJECT GetPtrToZwQueryDirectoryObject(void)
{
static NTQUERYDIRECTORYOBJECT pFn = NULL;
LPSSDT lpSSDT;
LPSSD lpSSD;
ULONG dwNtBuildNumber;
if (pFn == NULL)
{
lpSSDT = (LPSSDT) KeServiceDescriptorTable;
lpSSD = &(lpSSDT->SystemServiceDescriptors[0]);
dwNtBuildNumber = (*NtBuildNumber) & 0x00ffffff;
switch (dwNtBuildNumber)
{
case 1381: // WinNT 4.0
pFn = (NTQUERYDIRECTORYOBJECT) *((PVOID*)(lpSSD->lpSystemServiceTableAddressTable)+0x66);
break;
case 2195: // Win2K
pFn = (NTQUERYDIRECTORYOBJECT) *((PVOID*)(lpSSD->lpSystemServiceTableAddressTable)+0x7e);
break;
default:
if (dwNtBuildNumber >= 1946)
pFn = (NTQUERYDIRECTORYOBJECT) *((PVOID*)(lpSSD->lpSystemServiceTableAddressTable)+0x7e);
else
pFn = NULL;
break;
}
}
return pFn;
}
//
// оптимизация по скорости
//
SHARED_MEMORY* InitQueryObjectNameType(void)
{
BOOLEAN bRes;
SHARED_MEMORY* pSharedBuffer = NULL;
#ifdef __MISC_USE_KHEAP
pSharedBuffer = (SHARED_MEMORY*)_AllocatePoolFromKHeap(hKHeapMiscDefault, sizeof(SHARED_MEMORY));
#else
pSharedBuffer = ExAllocatePool(NonPagedPool, sizeof(SHARED_MEMORY));
#endif
if (pSharedBuffer != NULL)
{
bRes = AllocateSharedMemory(pSharedBuffer, NonPagedPool, 2048+4+4);
if (bRes == FALSE)
{
#ifdef __MISC_USE_KHEAP
FreePoolToKHeap(hKHeapMiscDefault, pSharedBuffer);
#else
ExFreePool(pSharedBuffer);
#endif
pSharedBuffer = NULL;
}
}
return pSharedBuffer;
}
//
// оптимизация по скорости
//
void DeinitQueryObjectNameType(SHARED_MEMORY* pSharedBuffer)
{
if (_MmIsAddressValid(pSharedBuffer))
{
FreeSharedMemory(pSharedBuffer);
#ifdef __MISC_USE_KHEAP
FreePoolToKHeap(hKHeapMiscDefault, pSharedBuffer);
#else
ExFreePool(pSharedBuffer);
#endif
}
}
BOOLEAN QueryObjectNameType(PVOID pObjTypeInfo, ULONG dwSizeOfObjTypeInfo, HANDLE hDir, PWSTR pwszObjectName, SHARED_MEMORY* pSharedBuffer)
{
CHAR* Buf;
POBJECT_NAMETYPE_INFO pObjName;
ULONG* pObjectIndex = 0;
ULONG* pLengthReturned = 0;
ULONG Index = 0;
BOOLEAN bFirst = TRUE;
int i;
NTQUERYDIRECTORYOBJECT pZwQueryDirectoryObject = 0;
if (
!_MmIsAddressValid(pObjTypeInfo) ||
!_MmIsAddressValid(pwszObjectName) ||
!_MmIsAddressValid(pSharedBuffer)
)
return FALSE;
pZwQueryDirectoryObject = GetPtrToZwQueryDirectoryObject();
if (!_MmIsAddressValid(pZwQueryDirectoryObject))
{
return FALSE;
}
Buf = (CHAR*)pSharedBuffer->m_lpUserMemory;
pObjName = (POBJECT_NAMETYPE_INFO) Buf;
pObjectIndex = (ULONG*)(Buf+2048);
pLengthReturned = (ULONG*)(Buf+2048+4);
while (pZwQueryDirectoryObject(hDir, Buf, 2048, ObjectArray, bFirst, pObjectIndex, pLengthReturned) >= 0)
{
bFirst = FALSE;
for (i=0; Index<*pObjectIndex; ++Index, ++i)
{
if (!_wcsnicmp(pObjName[i].ObjectName.Buffer, pwszObjectName, pObjName[i].ObjectName.Length/sizeof(WCHAR)))
{
*pObjectIndex = Index;
if (pZwQueryDirectoryObject(hDir, Buf, dwSizeOfObjTypeInfo, ObjectByOne, bFirst, pObjectIndex, pLengthReturned) == STATUS_SUCCESS)
{
memcpy(pObjTypeInfo, Buf, *pLengthReturned);
((POBJECT_NAMETYPE_INFO)pObjTypeInfo)->ObjectName.Buffer = (PWSTR)((DWORD)pObjTypeInfo+((DWORD)(pObjName->ObjectName.Buffer)-(DWORD)pObjName));
((POBJECT_NAMETYPE_INFO)pObjTypeInfo)->ObjectType.Buffer = (PWSTR)((DWORD)pObjTypeInfo+((DWORD)(pObjName->ObjectType.Buffer)-(DWORD)pObjName));
return TRUE;
}
return FALSE;
}
}
}
return FALSE;
}
ULONG DosPathNameToNtPathName(PWSTR pwszDosPath, PWSTR pwszNtPath, ULONG dwSizeNtPathByBytes, ULONG dwRecursiveDeep, PULONG pdwObjectSizeByBytes)
{
ULONG dwSizeOfNtPath = 0;
ULONG dwSizeOfDosPath;
PWSTR pwszCurrentDir, pwszPtrCurDir;
PWSTR pwszPtrDosPath, pwszPtr;
UNICODE_STRING dirString;
OBJECT_ATTRIBUTES dirAttr;
HANDLE hDir;
NTSTATUS NtStatus;
char Buf[512];
POBJECT_NAMETYPE_INFO pObjName = (POBJECT_NAMETYPE_INFO) Buf;
ULONG dwRestDosPath, dwFreeCurDir, dwSizeToken;
ULONG _dwSizeNtPathByBytes = dwSizeNtPathByBytes;
HANDLE hSymLink;
UNICODE_STRING SymLinkString;
OBJECT_ATTRIBUTES SymAttr;
ULONG dwSizeSymLinkObj = 0;
PWSTR pwszNewNtPath;
SHARED_MEMORY* pSharedBuffer = NULL;
// return dwSizeOfNtPath;
DbgPrintMisc(("DosPathNameToNtPathName - start\n"));
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
return dwSizeOfNtPath;
if (!_MmIsAddressValid(pwszNtPath))
return dwSizeOfNtPath;
memset(pwszNtPath, 0, dwSizeNtPathByBytes);
dwSizeOfDosPath = wcslen(pwszDosPath);
if (dwSizeOfDosPath <= 1)
return dwSizeOfNtPath;
#ifdef __MISC_USE_KHEAP
pwszCurrentDir = (PWSTR)_AllocatePoolFromKHeap(hKHeapMiscDefault, sizeof(L"\\??\\")+(dwSizeOfDosPath+1)*sizeof(WCHAR));
#else
pwszCurrentDir = ExAllocatePool(NonPagedPool, sizeof(L"\\??\\")+(dwSizeOfDosPath+1)*sizeof(WCHAR));
#endif
if(!pwszCurrentDir)
return dwSizeOfNtPath;
memset(pwszCurrentDir, 0, sizeof(L"\\??\\")+(dwSizeOfDosPath+1)*sizeof(WCHAR));
if (pwszDosPath[1] == L':')
wcscpy(pwszCurrentDir, L"\\??");
else
wcscpy(pwszCurrentDir, L"\\");
wcscpy(pwszNtPath, L"\\");
pSharedBuffer = InitQueryObjectNameType(); // need for optimize by speed QueryObjectNameType() !!!!!!!
RtlInitUnicodeString(&dirString, pwszCurrentDir);
InitializeObjectAttributes(&dirAttr, &dirString, OBJ_CASE_INSENSITIVE, NULL, NULL);
NtStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &dirAttr);
if (NtStatus == STATUS_SUCCESS)
{
// хрен его знает - NT понимает оба разделителя '\', '/'
// однако путь до ядра доходит вроде уже обработанный и все разделители
// в нем '\'. однако я не уверен - поэтому добавил эту вещь.
pwszPtr = pwszDosPath;
while (*pwszPtr)
{
if (*pwszPtr == L'/')
*pwszPtr = L'\\';
++pwszPtr;
}
if (pwszDosPath[1] == L':')
wcscat(pwszCurrentDir, L"\\");
pwszPtrCurDir = pwszCurrentDir + wcslen(pwszCurrentDir);
pwszPtrDosPath = pwszDosPath;
if (pwszPtrDosPath[0] == L'\\')
++pwszPtrDosPath;
dwFreeCurDir = ((sizeof(L"\\??\\")/sizeof(WCHAR))+dwSizeOfDosPath+1) - (pwszPtrCurDir - pwszCurrentDir);
dwRestDosPath = dwSizeOfDosPath - (pwszPtrDosPath - pwszDosPath);
while ((dwSizeToken = GetToken(pwszPtrDosPath, dwRestDosPath, pwszPtrCurDir, dwFreeCurDir, L"\\", 1, 0)))
{
dwFreeCurDir -= dwSizeToken;
if (dwFreeCurDir != 0)
--dwFreeCurDir;//sizeof(L'\\');
dwRestDosPath -= dwSizeToken;
if (dwRestDosPath != 0)
--dwRestDosPath;//sizeof(L'\\');
if (QueryObjectNameType(Buf, sizeof(Buf), hDir, pwszPtrCurDir, pSharedBuffer))
{
if (!wcsncmp(pObjName->ObjectType.Buffer, L"Directory", pObjName->ObjectType.Length/sizeof(WCHAR)))
{
if (_dwSizeNtPathByBytes < ((wcslen(pObjName->ObjectName.Buffer)+2)*sizeof(WCHAR)))
{
dwSizeOfNtPath = 0;
break;
}
wcscat(pwszNtPath, pObjName->ObjectName.Buffer);
wcscat(pwszNtPath, L"\\");
_dwSizeNtPathByBytes -= ((wcslen(pObjName->ObjectName.Buffer)+1)*sizeof(WCHAR));
ZwClose(hDir);
RtlInitUnicodeString(&dirString, pwszCurrentDir);
InitializeObjectAttributes(&dirAttr, &dirString, OBJ_CASE_INSENSITIVE, NULL, NULL);
NtStatus = ZwOpenDirectoryObject(&hDir, DIRECTORY_QUERY, &dirAttr);
if (NtStatus != STATUS_SUCCESS)
{
dwSizeOfNtPath = 0;
break;
}
}
else
{
if (!wcsncmp(pObjName->ObjectType.Buffer, L"SymbolicLink", pObjName->ObjectType.Length/sizeof(WCHAR)))
{
dwSizeOfNtPath = 0;
RtlInitUnicodeString(&SymLinkString, pObjName->ObjectName.Buffer);
InitializeObjectAttributes(&SymAttr, &SymLinkString, OBJ_CASE_INSENSITIVE, hDir, NULL);
if (ZwOpenSymbolicLinkObject(&hSymLink, SYMBOLIC_LINK_QUERY, &SymAttr) == STATUS_SUCCESS)
{
SymLinkString.Buffer = (PWSTR)pwszNtPath;
SymLinkString.Length = 0;
SymLinkString.MaximumLength = (WORD)dwSizeNtPathByBytes - wcslen(pwszPtrDosPath)*sizeof(WCHAR);
if (ZwQuerySymbolicLinkObject(hSymLink, &SymLinkString, &dwSizeSymLinkObj) == STATUS_SUCCESS)
{
if (pwszNtPath[0] == L'\\' && memcmp(pwszDosPath, pwszNtPath, SymLinkString.Length))
{
if (_dwSizeNtPathByBytes < (wcslen(pwszPtrDosPath+dwSizeToken)*sizeof(WCHAR)))
{
dwSizeOfNtPath = 0;
ZwClose(hSymLink);
break;
}
wcscat(pwszNtPath, pwszPtrDosPath+dwSizeToken);
#ifdef __MISC_USE_KHEAP
pwszNewNtPath = (PWSTR) _AllocatePoolFromKHeap(hKHeapMiscDefault, dwSizeNtPathByBytes);
#else
pwszNewNtPath= (PWSTR) ExAllocatePool(NonPagedPool, dwSizeNtPathByBytes);
#endif
if (pwszNewNtPath)
{
DbgPrintMisc(("DosPathNameToNtPathName - recursive start\n"));
if (dwRecursiveDeep != 0)
{
dwSizeOfNtPath = DosPathNameToNtPathName(pwszNtPath, pwszNewNtPath, dwSizeNtPathByBytes, --dwRecursiveDeep, pdwObjectSizeByBytes);
if (dwSizeOfNtPath)
{
wcscpy(pwszNtPath, pwszNewNtPath);
}
}
#ifdef __MISC_USE_KHEAP
FreePoolToKHeap(hKHeapMiscDefault, pwszNewNtPath);
#else
ExFreePool(pwszNewNtPath);
#endif
}
}
}
ZwClose(hSymLink);
}
break;
}
else // не директория и не ссылка
{
if (_MmIsAddressValid(pdwObjectSizeByBytes)) // возвращается длина имени объекта которому принадлежит остаток пути
{
*pdwObjectSizeByBytes = wcslen(pwszNtPath)*sizeof(WCHAR);
}
wcscat(pwszNtPath, pwszPtrDosPath);
dwSizeOfNtPath = wcslen(pwszNtPath)*sizeof(WCHAR);
break;
}
}
}
else
{
dwSizeOfNtPath = 0;
break;
}
wcscat(pwszPtrCurDir, L"\\");
pwszPtrCurDir += dwSizeToken + 1; // add wcslen(L"\\");
pwszPtrDosPath += dwSizeToken + 1;
}
ZwClose(hDir);
}
DeinitQueryObjectNameType(pSharedBuffer);
#ifdef __MISC_USE_KHEAP
FreePoolToKHeap(hKHeapMiscDefault, pwszCurrentDir);
#else
ExFreePool(pwszCurrentDir);
#endif
DbgPrintMisc(("DosPathNameToNtPathName - end\n"));
return dwSizeOfNtPath;
}
VOID FlushInstuctionCache(VOID)
{
ULONG pNextInstr;
// __asm _emit 0eah // data into code
__asm
{
push eax
mov eax, offset __NextInstr
mov [pNextInstr], eax
pop eax
jmp dword ptr [pNextInstr]
}
__NextInstr:
return;
}
//PDEVICE_OBJECT GetOwnDeviceObject(PDEVICE_OBJECT DeviceObject)
//{
// __asm int 1h
// while (_MmIsAddressValid(DeviceObject))
// {
// if (_MmIsAddressValid(DeviceObject->DeviceObjectExtension))
// {
// if (_MmIsAddressValid(DeviceObject->DeviceObjectExtension->DeviceObject))
// {
// __asm int 1h
// if (DeviceObject != DeviceObject->DeviceObjectExtension->DeviceObject)
// DeviceObject = DeviceObject->DeviceObjectExtension->DeviceObject;
// else
// break;
// }
// else
// break;
// }
// else
// {
// break;
// }
// }
//
// return DeviceObject;
//}
PDEVICE_OBJECT GetOwnDeviceObject(PDEVICE_OBJECT DeviceObject)
{
PDRIVER_OBJECT pDriverObject;
PDEVICE_OBJECT pDevice, pDeviceAttached;
BOOLEAN bFind = FALSE;
#if 0
if (!_MmIsAddressValid(DeviceObject))
return NULL;
pDriverObject = DeviceObject->DriverObject;
if (!_MmIsAddressValid(pDriverObject))
return NULL;
pDevice = pDriverObject->DeviceObject;
while (_MmIsAddressValid(pDevice))
{
pDeviceAttached = pDevice;
while (_MmIsAddressValid(pDeviceAttached))
{
if (pDeviceAttached->AttachedDevice == DeviceObject)
{
DeviceObject = GetOwnDeviceObject(pDeviceAttached);
bFind = TRUE;
break;
}
pDeviceAttached = pDeviceAttached->AttachedDevice;
}
if (bFind == TRUE)
break;
pDevice = pDevice->NextDevice;
}
#endif
if (!DeviceObject)
return NULL;
pDriverObject = DeviceObject->DriverObject;
if (!pDriverObject)
return NULL;
pDevice = pDriverObject->DeviceObject;
while (pDevice)
{
pDeviceAttached = pDevice;
while (pDeviceAttached)
{
if (pDeviceAttached->AttachedDevice == DeviceObject)
{
DeviceObject = GetOwnDeviceObject(pDeviceAttached);
bFind = TRUE;
break;
}
pDeviceAttached = pDeviceAttached->AttachedDevice;
}
if (bFind == TRUE)
break;
pDevice = pDevice->NextDevice;
}
return DeviceObject;
}
PDEVICE_OBJECT GetOwnDeviceObjectFromIrp(PIRP pIrp)
{
PDEVICE_OBJECT pDevice = NULL;
CHAR CurrentLocation;
PIO_STACK_LOCATION CurrentIrpStack;
if (pIrp == NULL)
return pDevice;
CurrentLocation = pIrp->CurrentLocation;
CurrentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
pDevice = CurrentIrpStack->DeviceObject;
while (--CurrentLocation)
{
--CurrentIrpStack;
if (CurrentIrpStack->DeviceObject != NULL)
pDevice = CurrentIrpStack->DeviceObject;
}
return pDevice;
}
NTSTATUS DefaultDriverObjectDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_INVALID_DEVICE_REQUEST;
}
PDRIVER_OBJECT CreateInvisibleDriverObject(PVOID pBaseAddress, ULONG dwDriverSize, HANDLE hSystemImage, PDRIVER_INITIALIZE DriverEntry)
{
NTSTATUS NtStatus;
OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR DriverName[] = L"\\Driver\\HiddenDriver";
UNICODE_STRING UniDriverName;
PDRIVER_OBJECT pObjectBody = NULL;
HANDLE hDriver;
int i;
RtlInitUnicodeString(&UniDriverName, DriverName);
InitializeObjectAttributes(&ObjectAttributes, NULL/*&UniDriverName*/, OBJ_PERMANENT, NULL, NULL);
NtStatus = ObCreateObject(KernelMode, (POBJECT_TYPE)IoDriverObjectType, &ObjectAttributes,
KernelMode, 0, sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION),
0, 0, (PVOID*)&pObjectBody);
if (NtStatus != STATUS_SUCCESS)
{
DbgPrint ("CreateInvisibleDriverObject: NtStatus = %08x \n", NtStatus);
return NULL;
}
memset(pObjectBody, 0, sizeof(DRIVER_OBJECT) + sizeof(DRIVER_EXTENSION));
pObjectBody->DriverExtension = (PDRIVER_EXTENSION)((PCHAR)pObjectBody + sizeof(DRIVER_OBJECT));
pObjectBody->DriverExtension->DriverObject = pObjectBody; // ??????
pObjectBody->DriverStart = pBaseAddress;
pObjectBody->DriverSize = dwDriverSize;
pObjectBody->DriverSection = hSystemImage;
pObjectBody->DriverInit = DriverEntry;
for (i = 0; iMajorFunction[i] = DefaultDriverObjectDispatch;
pObjectBody->Type = IO_TYPE_DRIVER;
pObjectBody->Size = sizeof(DRIVER_OBJECT);
NtStatus = ObInsertObject(pObjectBody, NULL, 1, 0, 0, &hDriver);
if (NtStatus != STATUS_SUCCESS)
{
// delete object
DbgPrint ("CreateInvisibleDriverObject: NtStatus = %08x \n", NtStatus);
return NULL;
}
return pObjectBody;
}
HANDLE LoadDevice(PWSTR pwszDeviceFileName)
{
SYSTEM_LOAD_DRIVER LoadDriverInfo;
NTSTATUS NtStatus;
if (pwszDeviceFileName == NULL)
return NULL;
memset(&LoadDriverInfo, 0, sizeof(LoadDriverInfo));
RtlInitUnicodeString(&LoadDriverInfo.usImageFile, pwszDeviceFileName);
NtStatus = ZwSetSystemInformation(SystemLoadDriver, &LoadDriverInfo, sizeof(LoadDriverInfo));
DbgPrint ("Loadevice: \n pBaseAddress = %08x\n hSystemImage = %08x\n pEntryPoint = %08x\n pDirectoryEntry = %08x\n",
LoadDriverInfo.pBaseAddress, LoadDriverInfo.hSystemImage, LoadDriverInfo.pEntryPoint, LoadDriverInfo.pDirectoryEntry);
// if (NtStatus == STATUS_SUCCESS)
// *((CHAR*)LoadDriverInfo.pBaseAddress) = 'M';
return LoadDriverInfo.hSystemImage;
}
NTSTATUS UnloadDevice(HANDLE hSystemImage)
{
SYSTEM_UNLOAD_DRIVER UnLoadDriverInfo;
NTSTATUS NtStatus;
UnLoadDriverInfo.hSystemImage = hSystemImage;
NtStatus = ZwSetSystemInformation(SystemUnloadDriver, &UnLoadDriverInfo, sizeof(UnLoadDriverInfo));
return NtStatus;
}
BOOLEAN DeleteItemFromQueryDirectoryBuffer(PFQD_SmallCommonBlock pQueryDirPrev, PFQD_SmallCommonBlock pQueryDir, PVOID Buffer, ULONG BufferLength, PIO_STATUS_BLOCK IoStatusBlock, FILE_INFORMATION_CLASS DirectoryInfoClass, NTSTATUS* NtStatus)
{
BOOLEAN bRes = FALSE;
PFQD_SmallCommonBlock pQueryDirSave;
ULONG dwSizeItem;
if (pQueryDir->NextEntryOffset == 0)
{
if (pQueryDir != Buffer)
{
pQueryDirPrev->NextEntryOffset = 0;
if (_MmIsAddressValid(IoStatusBlock))
{
dwSizeItem = 0;
switch (DirectoryInfoClass)
{
case 0:
dwSizeItem = (SIZE_OF_FILE_NAMES_INFORMATION + ((PFILE_NAMES_INFORMATION)pQueryDir)->FileNameLength);
break;
case FileDirectoryInformation:
dwSizeItem = (SIZE_OF_FILE_DIRECTORY_INFORMATION + ((PFILE_DIRECTORY_INFORMATION)pQueryDir)->CommonBlock.FileNameLength);
break;
case FileFullDirectoryInformation:
dwSizeItem = (SIZE_OF_FILE_FULL_DIR_INFORMATION + ((PFILE_FULL_DIR_INFORMATION)pQueryDir)->CommonBlock.FileNameLength);
break;
case FileBothDirectoryInformation:
dwSizeItem = (SIZE_OF_FILE_BOTH_DIR_INFORMATION + ((PFILE_BOTH_DIR_INFORMATION)pQueryDir)->CommonBlock.FileNameLength);
break;
}
if (IoStatusBlock->Information > dwSizeItem)
{
IoStatusBlock->Information -= dwSizeItem;
// memset(pQueryDir, 0, dwSizeItem);
}
else
{
*NtStatus = STATUS_NO_MORE_FILES;
IoStatusBlock->Status = STATUS_NO_MORE_FILES;
IoStatusBlock->Information = 0;
}
}
}
else
{
*NtStatus = STATUS_NO_MORE_FILES;
if (_MmIsAddressValid(IoStatusBlock))
{
IoStatusBlock->Status = STATUS_NO_MORE_FILES;
IoStatusBlock->Information = 0;
}
}
bRes = TRUE;
}
else
{
pQueryDirSave = pQueryDir;
if (_MmIsAddressValid(IoStatusBlock))
{
if (IoStatusBlock->Information >= pQueryDir->NextEntryOffset)
IoStatusBlock->Information -= pQueryDir->NextEntryOffset;
else
IoStatusBlock->Information = 0;
}
pQueryDir = (PFQD_SmallCommonBlock)((CHAR*)pQueryDir + pQueryDir->NextEntryOffset);
memmove(pQueryDirSave, pQueryDir, BufferLength - ((CHAR*)pQueryDir-(CHAR*)Buffer));
}
return bRes;
}
LPSSDT FindShadowTable(void)
{
BYTE* pCheckArea = (BYTE*) KeAddSystemServiceTable;
int i;
PSRVTABLE pSrvTable = NULL;
for (i=0; i<100; i++)
{
__try
{
pSrvTable = *(PSRVTABLE*)pCheckArea;
if (
!MmIsAddressValid(pSrvTable) ||
(pSrvTable == KeServiceDescriptorTable) ||
(memcmp(pSrvTable, KeServiceDescriptorTable, sizeof (*pSrvTable)) != 0)
)
{
pCheckArea++;
pSrvTable = NULL;
}
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pSrvTable = NULL;
}
if (pSrvTable)
break;
}
if (pSrvTable == NULL)
{
pSrvTable = (PSRVTABLE)((char*)KeServiceDescriptorTable-0x230);
if (MmIsAddressValid(pSrvTable))
{
__try
{
if (memcmp(pSrvTable, KeServiceDescriptorTable, sizeof (*pSrvTable)) != 0)
pSrvTable = NULL;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
pSrvTable = NULL;
}
}
else
{
pSrvTable = NULL;
}
}
return (LPSSDT)pSrvTable;
}
#if 0
ULONG GetFullPathbyFileObjectA(PFILE_OBJECT fileObject, PCHAR fullPathName, ULONG nfullPathNameSize)
{
ULONG pathLen;
PCHAR pathOffset;
PFILE_OBJECT relatedFileObject;
ANSI_STRING componentName;
PDEVICE_OBJECT pDeviceObject;
PUNICODE_STRING fullUniName;
ULONG dwFreeSize = nfullPathNameSize;
if (!fullPathName || !nfullPathNameSize)
return 0;
fullPathName[0] = 0;
try
{
if (fileObject == 0)
{
return 0;
}
pDeviceObject = GetVolumeDeviceObject(fileObject);
if (pDeviceObject == NULL)
{
pDeviceObject = IoGetRelatedDeviceObject(fileObject);
}
fullUniName = (PUNICODE_STRING)_AllocatePoolFromKHeap(hKHeapDHDefault, nfullPathNameSize*sizeof(WCHAR)+sizeof(UNICODE_STRING));
fullUniName->MaximumLength = (USHORT)nfullPathNameSize*sizeof(WCHAR);
if (NT_SUCCESS(ObQueryNameString(pDeviceObject, (POBJECT_NAME_INFORMATION)fullUniName, fullUniName->MaximumLength, &pathLen)))
{
RtlUnicodeStringToAnsiString( &componentName, fullUniName, TRUE );
if (componentName.Buffer[0])
{
strncatZ(fullPathName, componentName.Buffer, fullUniName->MaximumLength - 2);
DbgPrint ("%s\n", fullPathName);
}
RtlFreeAnsiString(&componentName);
}
else
{
return 0;
}
if (!fileObject->FileName.Length || fileObject->FileName.Length > nfullPathNameSize)
{
return strlen(fullPathName);
}
// strcat(fullPathName, "\\");
dwFreeSize -= strlen(fullPathName);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
return 0;
}
try
{
pathLen = fileObject->FileName.Length/sizeof(WCHAR) + 1;
relatedFileObject = fileObject->RelatedFileObject;
if (fileObject->FileName.Buffer[0] != L'\\' )
{
while (relatedFileObject)
{
if ((pathLen + relatedFileObject->FileName.Length/sizeof(WCHAR) + 1) >= dwFreeSize)
{
break;
}
pathLen += relatedFileObject->FileName.Length/sizeof(WCHAR) + 1;
relatedFileObject = relatedFileObject->RelatedFileObject;
}
}
if (dwFreeSize == nfullPathNameSize)
sprintf(fullPathName, "\\");
pathOffset = fullPathName + strlen(fullPathName) - sizeof(char) + pathLen - fileObject->FileName.Length/sizeof(WCHAR);
RtlUnicodeStringToAnsiString( &componentName, &fileObject->FileName, TRUE );
strncpy( pathOffset, componentName.Buffer, componentName.Length + 1 );
RtlFreeAnsiString( &componentName );
relatedFileObject = fileObject->RelatedFileObject;
if (fileObject->FileName.Buffer[0] != L'\\')
{
while (relatedFileObject)
{
*(pathOffset - 1) = '\\';
pathOffset -= relatedFileObject->FileName.Length/sizeof(WCHAR) + 1;
if (pathOffset <= fullPathName)
{
break;
}
RtlUnicodeStringToAnsiString(&componentName, &relatedFileObject->FileName, TRUE);
strncpy(pathOffset, componentName.Buffer, componentName.Length);
RtlFreeAnsiString(&componentName);
relatedFileObject = relatedFileObject->RelatedFileObject;
}
}
}
except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint ("He4Hook: GetFullPath: EXCEPTION\n");
}
// __asm int 1h
return strlen(fullPathName);
}
#endif //0