Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
0
//----------------------------------------------------------------------
//
// 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
}
Exemplo n.º 5
0
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;
}
Exemplo n.º 6
0
/**
*  设置钩子函数
*
*/
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
//------------------------------------------------------------------------------------
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;
}
Exemplo n.º 9
0
//----------------------------------------------------------------------
//
// 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
}
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
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;
}
Exemplo n.º 16
0
/*
 * 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