NTSTATUS ChangeServiceTableMemoryFlags() { // Map the memory into our domain and change the permissions on the memory page by using a MDL g_MappedSystemCallTableMDL = IoAllocateMdl( KeServiceDescriptorTable.ServiceTableBase, // starting virtual address KeServiceDescriptorTable.NumberOfServices*4, // size of buffer FALSE, // not associated with an IRP FALSE, // charge quota, should be FALSE NULL // IRP * should be NULL ); if(!g_MappedSystemCallTableMDL) { DbgPrint("MDL could not be allocated..."); return STATUS_UNSUCCESSFUL; } else { DbgPrint("The MDL is at 0x%x\n", g_MappedSystemCallTableMDL); } // MmBuildMdlForNonPagedPool fills in the corresponding physical page array // of a given MDL for a buffer in nonpaged system space (pool). MmBuildMdlForNonPagedPool(g_MappedSystemCallTableMDL); // MDL's are supposed to be opaque, but this is the only way we know of getting to these flags... g_MappedSystemCallTableMDL->MdlFlags = g_MappedSystemCallTableMDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; // finish off the mapping... g_MappedSystemCallTable = MmMapLockedPages(g_MappedSystemCallTableMDL, KernelMode); return STATUS_SUCCESS; }
static NTSTATUS TryToSatisfyRecvRequestFromBuffer( PAFD_FCB FCB, PAFD_RECV_INFO RecvReq, PUINT TotalBytesCopied ) { UINT i, BytesToCopy = 0, FcbBytesCopied = FCB->Recv.BytesUsed, BytesAvailable = FCB->Recv.Content - FCB->Recv.BytesUsed; PAFD_MAPBUF Map; *TotalBytesCopied = 0; AFD_DbgPrint(MID_TRACE,("Called, BytesAvailable = %u\n", BytesAvailable)); if( CantReadMore(FCB) ) return STATUS_SUCCESS; if( !BytesAvailable ) return STATUS_PENDING; Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount); AFD_DbgPrint(MID_TRACE,("Buffer Count: %u @ %p\n", RecvReq->BufferCount, RecvReq->BufferArray)); for( i = 0; RecvReq->BufferArray && BytesAvailable && i < RecvReq->BufferCount; i++ ) { BytesToCopy = MIN( RecvReq->BufferArray[i].len, BytesAvailable ); if( Map[i].Mdl ) { Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode ); AFD_DbgPrint(MID_TRACE,("Buffer %u: %p:%u\n", i, Map[i].BufferAddress, BytesToCopy)); RtlCopyMemory( Map[i].BufferAddress, FCB->Recv.Window + FcbBytesCopied, BytesToCopy ); MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl ); *TotalBytesCopied += BytesToCopy; FcbBytesCopied += BytesToCopy; BytesAvailable -= BytesToCopy; if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) FCB->Recv.BytesUsed += BytesToCopy; } } /* Issue another receive IRP to keep the buffer well stocked */ RefillSocketBuffer(FCB); return STATUS_SUCCESS; }
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; }
//---------------------------------------------------------------------- // // RegmonMapServiceTable // // If we are running on Whistler then we have // to double map the system service table to get around the // fact that the system service table is write-protected on systems // with > 128MB memory. Since there's no harm in always double mapping, // we always do it, regardless of whether or not we are on Whistler. // //---------------------------------------------------------------------- PVOID * RegmonMapServiceTable( SERVICE_HOOK_DESCRIPTOR **HookDescriptors ) { // // Allocate an array to store original function addresses in. This // makes us play well with other hookers. // *HookDescriptors = (SERVICE_HOOK_DESCRIPTOR *) ExAllocatePool( NonPagedPool, KeServiceDescriptorTable->Limit * sizeof(SERVICE_HOOK_DESCRIPTOR)); if( !*HookDescriptors ) { return NULL; } memset( *HookDescriptors, 0, KeServiceDescriptorTable->Limit * sizeof(SERVICE_HOOK_DESCRIPTOR)); // // Build an MDL that describes the system service table function // pointers array. // KdPrint(("Reglib: KeServiceDescriptorTable: %I64x Pointers: %I64x Limit: %d\n", KeServiceDescriptorTable, KeServiceDescriptorTable->ServicePointers, KeServiceDescriptorTable->Limit )); KeServiceTableMdl = MmCreateMdl( NULL, KeServiceDescriptorTable->ServicePointers, KeServiceDescriptorTable->Limit * sizeof(PVOID)); if( !KeServiceTableMdl ) { return NULL; } // // Fill in the physical pages and then double-map the description. Note // that MmMapLockedPages is obsolete as of Win2K and has been replaced // with MmMapLockedPagesSpecifyCache. However, we use the same driver // on all NT platforms, so we use it anyway. // MmBuildMdlForNonPagedPool( KeServiceTableMdl ); KeServiceTableMdl->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; #if defined(_M_IA64) return MmMapLockedPagesSpecifyCache( KeServiceTableMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority ); #else return MmMapLockedPages( KeServiceTableMdl, KernelMode ); #endif }
NTSTATUS initMDL() { // map memory into our domain g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // change MDL permissions g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); MDLinit = TRUE; return STATUS_SUCCESS; }
/** * 设置钩子函数 * */ NTSTATUS sstHook_OpenProcess() { if(m_MDL == NULL) { m_MDL = MmCreateMdl(NULL,KeServiceDescriptorTable->ServiceTableBase,KeServiceDescriptorTable->NumberOfService*4); if(!m_MDL) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(m_MDL); m_MDL->MdlFlags = m_MDL->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; m_Mapped = (PVOID *)MmMapLockedPages(m_MDL, KernelMode); HOOK_SYSCALL(ZwOpenProcess,MyNtOpenProcess,pOriNtOpenProcess); g_openProcessId = (ULONG)SYSTEMSERVICE(ZwOpenProcess); return STATUS_SUCCESS; } UpdateService(SYSCALL_INDEX(ZwOpenProcess),(PVOID)MyNtOpenProcess); return STATUS_SUCCESS; }
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; }
//------------------------------------------------------------------------------------ NTSTATUS UnProtectSSDT(PVOID **MappedSystemCallTable) { PMDL g_pmdlSystemCall ; g_pmdlSystemCall = IoAllocateMdl(KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4 , FALSE , FALSE ,NULL); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // Change the flags of the MDL g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; *MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); IoFreeMdl(g_pmdlSystemCall); return STATUS_SUCCESS; }
//---------------------------------------------------------------------- // // RegmonMapMem // // Double maps memory for writing. // //---------------------------------------------------------------------- PVOID RegmonMapMem( PVOID Pointer, ULONG Length, PMDL *MapMdl ) { *MapMdl = MmCreateMdl( NULL, Pointer, Length ); if( !(*MapMdl)) { return NULL; } MmBuildMdlForNonPagedPool( *MapMdl ); (*MapMdl)->MdlFlags |= MDL_MAPPED_TO_SYSTEM_VA; #if defined(_M_IA64) return MmMapLockedPagesSpecifyCache( *MapMdl, KernelMode, MmCached, NULL, FALSE, NormalPagePriority ); #else return MmMapLockedPages( *MapMdl, KernelMode ); #endif }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING theRegistryPath) { DriverObject->DriverUnload = OnUnload; DbgPrint("Driver cargado"); ZwOpenProcessIni =(TypZwOpenProc)(SYSTEMSERVICE(ZwOpenProcess)); //Creamos la MDL para deshabilitar la protección de memoria g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices*4); if(!g_pmdlSystemCall) return STATUS_UNSUCCESSFUL; MmBuildMdlForNonPagedPool(g_pmdlSystemCall); g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); DbgPrint("Hookeando..."); HOOK_SYSCALL( ZwOpenProcess, NewZwOpenProcess, ZwOpenProcessIni ); return STATUS_SUCCESS; }
static NTSTATUS NTAPI SatisfyPacketRecvRequest( PAFD_FCB FCB, PIRP Irp, PAFD_STORED_DATAGRAM DatagramRecv, PUINT TotalBytesCopied ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp ); PAFD_RECV_INFO RecvReq = GetLockedData(Irp, IrpSp); UINT BytesToCopy = 0, BytesAvailable = DatagramRecv->Len, AddrLen = 0; PAFD_MAPBUF Map; BOOLEAN ExtraBuffers = CheckUnlockExtraBuffers(FCB, IrpSp); Map = (PAFD_MAPBUF)(RecvReq->BufferArray + RecvReq->BufferCount + (ExtraBuffers ? EXTRA_LOCK_BUFFERS : 0)); BytesToCopy = MIN( RecvReq->BufferArray[0].len, BytesAvailable ); AFD_DbgPrint(MID_TRACE,("BytesToCopy: %u len %u\n", BytesToCopy, RecvReq->BufferArray[0].len)); if( Map[0].Mdl ) { /* Copy the address */ if( ExtraBuffers && Map[1].Mdl && Map[2].Mdl ) { AFD_DbgPrint(MID_TRACE,("Checking TAAddressCount\n")); if( DatagramRecv->Address->TAAddressCount != 1 ) { AFD_DbgPrint (MIN_TRACE, ("Wierd address count %d\n", DatagramRecv->Address->TAAddressCount)); } AFD_DbgPrint(MID_TRACE,("Computing addr len\n")); AddrLen = MIN(DatagramRecv->Address->Address->AddressLength + sizeof(USHORT), RecvReq->BufferArray[1].len); AFD_DbgPrint(MID_TRACE,("Copying %u bytes of address\n", AddrLen)); Map[1].BufferAddress = MmMapLockedPages( Map[1].Mdl, KernelMode ); AFD_DbgPrint(MID_TRACE,("Done mapping, copying address\n")); RtlCopyMemory( Map[1].BufferAddress, &DatagramRecv->Address->Address->AddressType, AddrLen ); MmUnmapLockedPages( Map[1].BufferAddress, Map[1].Mdl ); AFD_DbgPrint(MID_TRACE,("Copying address len\n")); Map[2].BufferAddress = MmMapLockedPages( Map[2].Mdl, KernelMode ); *((PINT)Map[2].BufferAddress) = AddrLen; MmUnmapLockedPages( Map[2].BufferAddress, Map[2].Mdl ); } AFD_DbgPrint(MID_TRACE,("Mapping data buffer pages\n")); Map[0].BufferAddress = MmMapLockedPages( Map[0].Mdl, KernelMode ); AFD_DbgPrint(MID_TRACE,("Buffer %d: %p:%u\n", 0, Map[0].BufferAddress, BytesToCopy)); RtlCopyMemory( Map[0].BufferAddress, DatagramRecv->Buffer, BytesToCopy ); MmUnmapLockedPages( Map[0].BufferAddress, Map[0].Mdl ); *TotalBytesCopied = BytesToCopy; } if (*TotalBytesCopied == DatagramRecv->Len) { /* We copied the whole datagram */ Status = Irp->IoStatus.Status = STATUS_SUCCESS; } else { /* We only copied part of the datagram */ Status = Irp->IoStatus.Status = STATUS_BUFFER_OVERFLOW; } Irp->IoStatus.Information = *TotalBytesCopied; if (!(RecvReq->TdiFlags & TDI_RECEIVE_PEEK)) { FCB->Recv.Content -= DatagramRecv->Len; ExFreePool( DatagramRecv->Address ); ExFreePool( DatagramRecv ); } AFD_DbgPrint(MID_TRACE,("Done\n")); return Status; }
NTSTATUS MapPhysicalMemory( VOID* InputBuffer, ULONG InputBufferLength, ULONG OutputBufferLength, ULONG* BytesReturned ) { PHYSICAL_ADDRESS phyAddr; //PPHYMEM_MEM pMem; PHYSICAL_MEMORY *physicalMemory; PVOID pvk, pvu; //DbgPrint("[PUSH] MapPhysicalMemory"); if (InputBufferLength != sizeof(PHYSICAL_MEMORY) || OutputBufferLength != sizeof(PVOID)) return STATUS_INVALID_PARAMETER; physicalMemory=(PHYSICAL_MEMORY*)InputBuffer; phyAddr.QuadPart=(ULONGLONG)physicalMemory->pvAddr; //get mapped kernel address pvk=MmMapIoSpace(phyAddr, physicalMemory->dwSize, MmNonCached); if (pvk) { //allocate mdl for the mapped kernel address PMDL pMdl=IoAllocateMdl(pvk, physicalMemory->dwSize, FALSE, FALSE, NULL); if (pMdl) { PMAPINFO pMapInfo; //build mdl and map to user space MmBuildMdlForNonPagedPool(pMdl); pvu=MmMapLockedPages(pMdl, UserMode); //insert mapped infomation to list pMapInfo=(PMAPINFO)ExAllocatePool(\ NonPagedPool, sizeof(MAPINFO)); pMapInfo->pMdl=pMdl; pMapInfo->pvk=pvk; pMapInfo->pvu=pvu; pMapInfo->memSize=physicalMemory->dwSize; PushEntryList(&lstMapInfo, &pMapInfo->link); DbgPrint("Map physical 0x%x to virtual 0x%x, size %u", \ physicalMemory->pvAddr, pvu, physicalMemory->dwSize); RtlCopyMemory(InputBuffer, &pvu, sizeof(PVOID)); *BytesReturned = sizeof(PVOID); return STATUS_SUCCESS; } else { //allocate mdl error, unmap the mapped physical memory MmUnmapIoSpace(pvk, physicalMemory->dwSize); return STATUS_INSUFFICIENT_RESOURCES; } } else return STATUS_INSUFFICIENT_RESOURCES; }
static NTSTATUS NTAPI SendComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { NTSTATUS Status = Irp->IoStatus.Status; PAFD_FCB FCB = (PAFD_FCB)Context; PLIST_ENTRY NextIrpEntry; PIRP NextIrp = NULL; PIO_STACK_LOCATION NextIrpSp; PAFD_SEND_INFO SendReq = NULL; PAFD_MAPBUF Map; UINT TotalBytesCopied = 0, TotalBytesProcessed = 0, SpaceAvail, i; UINT SendLength, BytesCopied; BOOLEAN HaltSendQueue; UNREFERENCED_PARAMETER(DeviceObject); /* * The Irp parameter passed in is the IRP of the stream between AFD and * TDI driver. It's not very usefull to us. We need the IRPs of the stream * between usermode and AFD. Those are chained from * FCB->PendingIrpList[FUNCTION_SEND] and you'll see them in the code * below as "NextIrp" ('cause they are the next usermode IRP to be * processed). */ AFD_DbgPrint(MID_TRACE,("Called, status %x, %u bytes used\n", Irp->IoStatus.Status, Irp->IoStatus.Information)); if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; ASSERT(FCB->SendIrp.InFlightRequest == Irp); FCB->SendIrp.InFlightRequest = NULL; /* Request is not in flight any longer */ if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } RetryDisconnectCompletion(FCB); SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } if( !NT_SUCCESS(Status) ) { /* Complete all following send IRPs with error */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = 0; if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } RetryDisconnectCompletion(FCB); SocketStateUnlock( FCB ); return STATUS_SUCCESS; } RtlMoveMemory( FCB->Send.Window, FCB->Send.Window + Irp->IoStatus.Information, FCB->Send.BytesUsed - Irp->IoStatus.Information ); TotalBytesProcessed = 0; SendLength = Irp->IoStatus.Information; HaltSendQueue = FALSE; while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && SendLength > 0) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); TotalBytesCopied = (ULONG_PTR)NextIrp->Tail.Overlay.DriverContext[3]; ASSERT(TotalBytesCopied != 0); /* If we didn't get enough, keep waiting */ if (TotalBytesCopied > SendLength) { /* Update the bytes left to copy */ TotalBytesCopied -= SendLength; NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)TotalBytesCopied; /* Update the state variables */ FCB->Send.BytesUsed -= SendLength; TotalBytesProcessed += SendLength; SendLength = 0; /* Pend the IRP */ InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND], &NextIrp->Tail.Overlay.ListEntry); HaltSendQueue = TRUE; break; } ASSERT(NextIrp->IoStatus.Information != 0); NextIrp->IoStatus.Status = Irp->IoStatus.Status; FCB->Send.BytesUsed -= TotalBytesCopied; TotalBytesProcessed += TotalBytesCopied; SendLength -= TotalBytesCopied; (void)IoSetCancelRoutine(NextIrp, NULL); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp); IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT); } ASSERT(SendLength == 0); if ( !HaltSendQueue && !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = FCB->PendingIrpList[FUNCTION_SEND].Flink; NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); AFD_DbgPrint(MID_TRACE,("SendReq @ %p\n", SendReq)); SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; TotalBytesCopied = 0; /* Count the total transfer size */ SendLength = 0; for (i = 0; i < SendReq->BufferCount; i++) { SendLength += SendReq->BufferArray[i].len; } /* Make sure we've got the space */ if (SendLength > SpaceAvail) { /* Blocking sockets have to wait here */ if (SendLength <= FCB->Send.Size && !((SendReq->AfdFlags & AFD_IMMEDIATE) || (FCB->NonBlocking))) { FCB->PollState &= ~AFD_EVENT_SEND; NextIrp = NULL; } /* Check if we can send anything */ if (SpaceAvail == 0) { FCB->PollState &= ~AFD_EVENT_SEND; /* We should never be non-overlapped and get to this point */ ASSERT(SendReq->AfdFlags & AFD_OVERLAPPED); NextIrp = NULL; } } if (NextIrp != NULL) { for( i = 0; i < SendReq->BufferCount; i++ ) { BytesCopied = MIN(SendReq->BufferArray[i].len, SpaceAvail); Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode ); RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, Map[i].BufferAddress, BytesCopied ); MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl ); TotalBytesCopied += BytesCopied; SpaceAvail -= BytesCopied; FCB->Send.BytesUsed += BytesCopied; } NextIrp->IoStatus.Information = TotalBytesCopied; NextIrp->Tail.Overlay.DriverContext[3] = (PVOID)NextIrp->IoStatus.Information; } } if (FCB->Send.Size - FCB->Send.BytesUsed != 0 && !FCB->SendClosed && IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND])) { FCB->PollState |= AFD_EVENT_SEND; FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } else { FCB->PollState &= ~AFD_EVENT_SEND; } /* Some data is still waiting */ if( FCB->Send.BytesUsed ) { Status = TdiSend( &FCB->SendIrp.InFlightRequest, FCB->Connection.Object, 0, FCB->Send.Window, FCB->Send.BytesUsed, SendComplete, FCB ); } else { /* Nothing is waiting so try to complete a pending disconnect */ RetryDisconnectCompletion(FCB); } SocketStateUnlock( FCB ); return STATUS_SUCCESS; }
static STDCALL NTSTATUS MapPhysicalMemoryToLinearSpace(PVOID pPhysAddress,ULONG PhysMemSizeInBytes,PVOID *PhysMemLin){ alloc_priv* alloclisttmp; PMDL Mdl=NULL; PVOID SystemVirtualAddress=NULL; PVOID UserVirtualAddress=NULL; PHYSICAL_ADDRESS pStartPhysAddress; OutputDebugString ("dhahelper: entering MapPhysicalMemoryToLinearSpace"); #ifdef _WIN64 pStartPhysAddress.QuadPart = (ULONGLONG)pPhysAddress; #else pStartPhysAddress.QuadPart = (ULONGLONG)(ULONG)pPhysAddress; #endif #ifndef NO_SEH __try { #endif SystemVirtualAddress=MmMapIoSpace(pStartPhysAddress,PhysMemSizeInBytes, /*MmWriteCombined*/MmNonCached); if(!SystemVirtualAddress){ OutputDebugString("dhahelper: MmMapIoSpace failed"); return STATUS_INVALID_PARAMETER; } OutputDebugString("dhahelper: SystemVirtualAddress 0x%x",SystemVirtualAddress); Mdl=IoAllocateMdl(SystemVirtualAddress, PhysMemSizeInBytes, FALSE, FALSE,NULL); if(!Mdl){ OutputDebugString("dhahelper: IoAllocateMdl failed"); return STATUS_INSUFFICIENT_RESOURCES; } OutputDebugString("dhahelper: Mdl 0x%x",Mdl); MmBuildMdlForNonPagedPool(Mdl); #ifdef _WIN64 UserVirtualAddress = (PVOID)(((ULONGLONG)PAGE_ALIGN(MmMapLockedPages(Mdl,UserMode))) + MmGetMdlByteOffset(Mdl)); #else UserVirtualAddress = (PVOID)(((ULONG)PAGE_ALIGN(MmMapLockedPages(Mdl,UserMode))) + MmGetMdlByteOffset(Mdl)); #endif if(!UserVirtualAddress){ OutputDebugString("dhahelper: MmMapLockedPages failed"); return STATUS_INSUFFICIENT_RESOURCES; } OutputDebugString("dhahelper: UserVirtualAddress 0x%x",UserVirtualAddress); #ifndef NO_SEH }__except(EXCEPTION_EXECUTE_HANDLER){ NTSTATUS ntStatus; ntStatus = GetExceptionCode(); OutputDebugString("dhahelper: MapPhysicalMemoryToLinearSpace failed due to exception 0x%0x\n", ntStatus); return ntStatus; } #endif OutputDebugString("dhahelper: adding data to internal allocation list"); alloclisttmp=MmAllocateNonCachedMemory((alloccount+1)*sizeof(alloc_priv)); if(!alloclisttmp){ OutputDebugString("dhahelper: not enough memory to create temporary allocation list"); MmUnmapLockedPages(UserVirtualAddress, Mdl); IoFreeMdl(Mdl); return STATUS_INSUFFICIENT_RESOURCES; } if(alloccount){ memcpy(alloclisttmp,alloclist,alloccount * sizeof(alloc_priv)); MmFreeNonCachedMemory(alloclist,alloccount*sizeof(alloc_priv)); } alloclist=alloclisttmp; alloclist[alloccount].Mdl=Mdl; alloclist[alloccount].SystemVirtualAddress=SystemVirtualAddress; alloclist[alloccount].UserVirtualAddress=UserVirtualAddress; alloclist[alloccount].PhysMemSizeInBytes=PhysMemSizeInBytes; ++alloccount; *PhysMemLin=UserVirtualAddress; OutputDebugString("dhahelper: leaving MapPhysicalMemoryToLinearSpace"); return STATUS_SUCCESS; }
static NTSTATUS NTAPI SendComplete ( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { NTSTATUS Status = Irp->IoStatus.Status; PAFD_FCB FCB = (PAFD_FCB)Context; PLIST_ENTRY NextIrpEntry; PIRP NextIrp = NULL; PIO_STACK_LOCATION NextIrpSp; PAFD_SEND_INFO SendReq = NULL; PAFD_MAPBUF Map; UINT TotalBytesCopied = 0, TotalBytesProcessed = 0, SpaceAvail, i; /* * The Irp parameter passed in is the IRP of the stream between AFD and * TDI driver. It's not very usefull to us. We need the IRPs of the stream * between usermode and AFD. Those are chained from * FCB->PendingIrpList[FUNCTION_SEND] and you'll see them in the code * below as "NextIrp" ('cause they are the next usermode IRP to be * processed). */ AFD_DbgPrint(MID_TRACE,("Called, status %x, %d bytes used\n", Irp->IoStatus.Status, Irp->IoStatus.Information)); if( !SocketAcquireStateLock( FCB ) ) return STATUS_FILE_CLOSED; ASSERT(FCB->SendIrp.InFlightRequest == Irp); FCB->SendIrp.InFlightRequest = NULL; /* Request is not in flight any longer */ if( FCB->State == SOCKET_STATE_CLOSED ) { /* Cleanup our IRP queue because the FCB is being destroyed */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); NextIrp->IoStatus.Status = STATUS_FILE_CLOSED; NextIrp->IoStatus.Information = 0; UnlockBuffers(SendReq->BufferArray, SendReq->BufferCount, FALSE); if( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } RetryDisconnectCompletion(FCB); SocketStateUnlock( FCB ); return STATUS_FILE_CLOSED; } if( !NT_SUCCESS(Status) ) { /* Complete all following send IRPs with error */ while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); NextIrp->IoStatus.Status = Status; NextIrp->IoStatus.Information = 0; if ( NextIrp->MdlAddress ) UnlockRequest( NextIrp, IoGetCurrentIrpStackLocation( NextIrp ) ); (void)IoSetCancelRoutine(NextIrp, NULL); IoCompleteRequest( NextIrp, IO_NETWORK_INCREMENT ); } RetryDisconnectCompletion(FCB); SocketStateUnlock( FCB ); return STATUS_SUCCESS; } RtlMoveMemory( FCB->Send.Window, FCB->Send.Window + FCB->Send.BytesUsed, FCB->Send.BytesUsed - Irp->IoStatus.Information ); TotalBytesProcessed = 0; while (!IsListEmpty(&FCB->PendingIrpList[FUNCTION_SEND]) && TotalBytesProcessed != Irp->IoStatus.Information) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); TotalBytesCopied = 0; for( i = 0; i < SendReq->BufferCount; i++ ) TotalBytesCopied += SendReq->BufferArray[i].len; NextIrp->IoStatus.Status = Irp->IoStatus.Status; NextIrp->IoStatus.Information = TotalBytesCopied; TotalBytesProcessed += TotalBytesCopied; (void)IoSetCancelRoutine(NextIrp, NULL); UnlockBuffers( SendReq->BufferArray, SendReq->BufferCount, FALSE ); if (NextIrp->MdlAddress) UnlockRequest(NextIrp, NextIrpSp); IoCompleteRequest(NextIrp, IO_NETWORK_INCREMENT); } ASSERT(TotalBytesProcessed == Irp->IoStatus.Information); FCB->Send.BytesUsed -= TotalBytesProcessed; while( !IsListEmpty( &FCB->PendingIrpList[FUNCTION_SEND] ) ) { NextIrpEntry = RemoveHeadList(&FCB->PendingIrpList[FUNCTION_SEND]); NextIrp = CONTAINING_RECORD(NextIrpEntry, IRP, Tail.Overlay.ListEntry); NextIrpSp = IoGetCurrentIrpStackLocation( NextIrp ); SendReq = GetLockedData(NextIrp, NextIrpSp); Map = (PAFD_MAPBUF)(SendReq->BufferArray + SendReq->BufferCount); AFD_DbgPrint(MID_TRACE,("SendReq @ %x\n", SendReq)); SpaceAvail = FCB->Send.Size - FCB->Send.BytesUsed; TotalBytesCopied = 0; for( i = 0; i < SendReq->BufferCount; i++ ) { if (SpaceAvail < SendReq->BufferArray[i].len) { InsertHeadList(&FCB->PendingIrpList[FUNCTION_SEND], &NextIrp->Tail.Overlay.ListEntry); NextIrp = NULL; break; } Map[i].BufferAddress = MmMapLockedPages( Map[i].Mdl, KernelMode ); RtlCopyMemory( FCB->Send.Window + FCB->Send.BytesUsed, Map[i].BufferAddress, SendReq->BufferArray[i].len ); MmUnmapLockedPages( Map[i].BufferAddress, Map[i].Mdl ); TotalBytesCopied += SendReq->BufferArray[i].len; SpaceAvail -= SendReq->BufferArray[i].len; } if (NextIrp != NULL) { FCB->Send.BytesUsed += TotalBytesCopied; } else break; } if (FCB->Send.Size - FCB->Send.BytesUsed != 0 && !FCB->SendClosed) { FCB->PollState |= AFD_EVENT_SEND; FCB->PollStatus[FD_WRITE_BIT] = STATUS_SUCCESS; PollReeval( FCB->DeviceExt, FCB->FileObject ); } else { FCB->PollState &= ~AFD_EVENT_SEND; } /* Some data is still waiting */ if( FCB->Send.BytesUsed ) { Status = TdiSend( &FCB->SendIrp.InFlightRequest, FCB->Connection.Object, 0, FCB->Send.Window, FCB->Send.BytesUsed, &FCB->SendIrp.Iosb, SendComplete, FCB ); } else { /* Nothing is waiting so try to complete a pending disconnect */ RetryDisconnectCompletion(FCB); } SocketStateUnlock( FCB ); return STATUS_SUCCESS; }
/* * DriverEntry initializes the driver and is the first routine called by the * system after the driver is loaded. DriverEntry specifies the other entry * points in the function driver, such as EvtDevice and DriverUnload. * * @param DriverObject - represents the instance of the function driver that is loaded * into memory. DriverEntry must initialize members of DriverObject before it * returns to the caller. DriverObject is allocated by the system before the * driver is loaded, and it is released by the system after the system unloads * the function driver from memory. * @param RegistryPath - represents the driver specific path in the Registry. * The function driver can use the path to store driver related data between * reboots. The path does not store hardware instance specific data. * * @return STATUS_SUCCESS if successful, STATUS_UNSUCCESSFUL otherwise */ NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath ) { // Local variables NTSTATUS status; PDEVICE_EXTENSION devExt; PDEVICE_OBJECT devObj; UNICODE_STRING devName; UNICODE_STRING linkName; int counter; DbgPrint("%s - version %s", NAME, VERSION); DbgPrint("Built %s %s\n", __DATE__, __TIME__); // Set the basic dispatch routines for all IRPs handled for (counter = 0; counter < IRP_MJ_MAXIMUM_FUNCTION; counter++) { pDriverObject->MajorFunction[counter] = OutboundDispatchPassDown; } // Set a specific dispatch routine for read requests pDriverObject->MajorFunction[IRP_MJ_READ] = OutboundDispatchRead; // Hook the keyboard stack status = OutboundHookKeyboard(pDriverObject); if (!NT_SUCCESS(status)) DbgPrint("Error hooking the keyboard.\n"); else DbgPrint("Successfully hooked the keyboard.\n"); // Save old system call locations OldZwWriteFile = (ZWWRITEFILE)(SYSTEMSERVICE(ZwWriteFile)); OldZwCreateFile = (ZWCREATEFILE)(SYSTEMSERVICE(ZwCreateFile)); //***Begin HideProcessHookMDL SSDT hook code*** // Map the memory into our domain so we can change the permissions on the MDL. g_pmdlSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase, KeServiceDescriptorTable.NumberOfServices * 4); if(!g_pmdlSystemCall) { DbgPrint("Failed mapping memory..."); return STATUS_UNSUCCESSFUL; } MmBuildMdlForNonPagedPool(g_pmdlSystemCall); // Change the flags of the MDL g_pmdlSystemCall->MdlFlags = g_pmdlSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA; MappedSystemCallTable = MmMapLockedPages(g_pmdlSystemCall, KernelMode); //TODO: use MmMapLockedPagesSpecifyCache instead, MmMapLockedPages is obselete according to OACR // Hook the system call _asm{cli} HOOK_SYSCALL(ZwWriteFile, NewZwWriteFile, OldZwWriteFile); HOOK_SYSCALL(ZwCreateFile, NewZwCreateFile, OldZwCreateFile); _asm{sti} //***End HideProcessHookMDL SSDT hook code*** // Set the driver unload routine pDriverObject->DriverUnload = Unload; return STATUS_SUCCESS; } // DriverEntry