none
the problem that the kernel-mode application communicates with the user-mode application RRS feed

  • Question

  • Hi ,you guys.My English is not good. so the following description may not be so perfect.

    I wrote a driver which allocates memory by using IoAllocate to share the data between user-mode application. In the user-mode application,I just send the IOCTL code "IOCTL_SHARE_MEMORY" to the driver.The driver receive the IOCTL code , and the begin allocating the memory.The following is the code:

    NTSTATUS DemoDevControl(IN PDEVICE_OBJECT DeviceObject,PIRP Irp){
    	NTSTATUS status = STATUS_SUCCESS;
    	PVOID pOutBuf = NULL ,pSysAddr = NULL,m_DMAMemory=NULL;
    	PMDL pMdl;
    	PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    	ULONG uControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    	//PHYSICAL_ADDRESS maxPhysicalAddress,m_DMAPhysicalMemory;
    	DBGPRINT(("DemoDevControl\n"));
    	switch(uControlCode){
    		case IOCTL_SHARE_MEMORY:
    			pOutBuf = Irp->AssociatedIrp.SystemBuffer;
    			DBGPRINT((" before IoAllocateMdl\r\n"));
            	pMdl = IoAllocateMdl(pSysAddr,10,FALSE,FALSE,NULL);
            	if(pMdl == NULL){
            		DBGPRINT(("IoAllocateMdl Sorry  Failed !\r\n"));
            		status = STATUS_UNSUCCESSFUL;
            		break;
            	}
            	DBGPRINT((" before MmBuildMdlForNonPagedPool\r\n"));
            	MmBuildMdlForNonPagedPool(pMdl);
            	DBGPRINT(("MmMapLockedPagesSpecifyCache\r\n"));
            	_try{
            	pOutBuf = MmMapLockedPagesSpecifyCache(
            		pMdl,
            		UserMode,
            		MmNonCached,
            		NULL,
            		FALSE,
            		NormalPagePriority
            		);
            	DBGPRINT(("is everything fine?\r\n"));
            	if(NULL == *(ULONG*)pOutBuf){
            		DBGPRINT(("Sorry  Failed !\r\n"));
            		status = STATUS_UNSUCCESSFUL;
            		IoFreeMdl(pMdl);
            		break;
            	} 
            	}_except(EXCEPTION_EXECUTE_HANDLER)
    			{
    				DBGPRINT(("MmMapLockedPagesSpecifyCache exception\n"));
    			}  
    				break;	
    			default:
    				break;
    	}
    	return status;
    }
    I setup the driver in Windows XP.And then I click the user-mode application to send the IOCTL code ,but the  system  

    popup an error windows says that  "'ox7c80168e'  the '0x00000000' memory referenced by the instruction . This memory cannot be 'written' " . but I checked the WinDbg outPut message,I didn't see any thing wrong with driver. 

    So,what's wrong with my code?

    Thursday, May 26, 2016 9:34 AM

Answers

  • You need to allocate a buffer. The MDL (Memory Descriptor List) just describes a buffer. Here is what you need to do:

    MmAllocatePagesForMdlEx

    MmGetSystemAddressForMdlSafe

    MmMapLockedPagesSpecifyCache

    You MUST be certain that you unmap the memory before the process terminates or you'll bugcheck. The best place to do that is when the handle is being closed

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Friday, May 27, 2016 4:54 AM
    Moderator

All replies

  • You need to allocate a buffer. The MDL (Memory Descriptor List) just describes a buffer. Here is what you need to do:

    MmAllocatePagesForMdlEx

    MmGetSystemAddressForMdlSafe

    MmMapLockedPagesSpecifyCache

    You MUST be certain that you unmap the memory before the process terminates or you'll bugcheck. The best place to do that is when the handle is being closed

     -Brian


    Azius Developer Training www.azius.com Windows device driver, internals, security, & forensics training and consulting. Blog at www.azius.com/blog

    Friday, May 27, 2016 4:54 AM
    Moderator
  • I've already modified my code followed your suggestion.

            but when the driver call  the MmMapLockedPagesSpecifyCache , it always return NULL.I do not know why,the following is my code:

    NTSTATUS DemoDevControl(IN PDEVICE_OBJECT DeviceObject,PIRP Irp){
    	NTSTATUS status = STATUS_SUCCESS;
    	PVOID pOutBuf = NULL ,pSysAddr = NULL,m_DMAMemory=NULL;
    	PMDL pMdl;
    	PHYSICAL_ADDRESS LowAddress,HighAddress;
    	SIZE_T TotalBytes = 1024 * 10;
    	PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
    	ULONG uControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
    	LowAddress.QuadPart = 0x0;
    	HighAddress.QuadPart = (ULONGLONG)-1;
    	DBGPRINT(("DemoDevControl\n"));
    	switch(uControlCode){
    		case IOCTL_SHARE_MEMORY:
            	pMdl = MmAllocatePagesForMdl(LowAddress,HighAddress,LowAddress,TotalBytes);
            	if(!pMdl){
            		status = STATUS_UNSUCCESSFUL;
            		DBGPRINT(("Sorry pMdl  Failed !\r\n"));
            		return status;
            	}
    
            	_try{
            	pOutBuf = MmMapLockedPagesSpecifyCache(
            		pMdl,
            		UserMode,
            		MmNonCached,
            		NULL,
            		FALSE,
            		NormalPagePriority
            		);
            	DBGPRINT(("is everything fine?\r\n"));
            	if(NULL == *(ULONG*)pOutBuf){
            		DBGPRINT(("Sorry  Failed !\r\n"));
            		status = STATUS_UNSUCCESSFUL;
            		IoFreeMdl(pMdl);
            		break;
            	} 
            	}_except(EXCEPTION_EXECUTE_HANDLER)
    			{
    				DBGPRINT(("MmMapLockedPagesSpecifyCache exception\n"));
    			}  
    				break;	
    			default:
    				break;
    	}
    	return status;
    }

    Friday, May 27, 2016 8:01 AM
  • Is the code simplified?  I see no completion of the IRP or any code to place the pOutBuf value into a location (i.e. the IOCTL's output buffer or the IOSTATUS information field) so that the value is returned to the user.

    Without this you are just leaking memory.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Friday, May 27, 2016 12:27 PM
  • Thank you ,I am new , I also noticed that ,but I don't know to finish it using code. I've founded a sample which add a line code  like this :
    pOutBuf = Irp->AssociatedIrp.SystemBuffer;
    is that right?
    Sunday, May 29, 2016 3:32 AM
  • Thank you ,I am new , I also noticed that ,but I don't know to finish it using code. I've founded a sample which add a line code  like this :
    pOutBuf = Irp->AssociatedIrp.SystemBuffer;
    is that right?

    If you do this then your statement:

    pOutBuf = MmMapLockedPagesSpecifyCache(...

    needs to be

    *pOutBuf = MmMapLockedPagesSpecifyCache(...

    In addition you will need to:

    1. Check the size of the output buffer to be sure is it >= sizeof(PULONG)
    2. At the end of the code before return status; set the IRP's IoStatus fields, and call IoCompleteRequest.


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Sunday, May 29, 2016 11:05 AM
  • All I show you is a part of my code.I've already done the rest job in the caller function. But id didn't work out either.I changed the pOutBuf to *pOutBuf ,and the MmMapLockedPagesSpecifyCache  throws an exception,the exception code is 0xc0000005 ,Access violations how could this happen? here the code are followed:

    NTSTATUS
    PtDispatch(
        IN PDEVICE_OBJECT    DeviceObject,
        IN PIRP              Irp
        )
    
    {
    	PIO_STACK_LOCATION  irpStack;
        NTSTATUS   status = STATUS_SUCCESS;
    
        UNREFERENCED_PARAMETER(DeviceObject);
        
        DBGPRINT(("==>Pt Dispatch begin\n"));
        irpStack = IoGetCurrentIrpStackLocation(Irp);
        
        switch (irpStack->MajorFunction)
        {
            case IRP_MJ_CREATE:
                break;
                
            case IRP_MJ_CLEANUP:
            	
                UnMapAndFreeMemory();
                break;
                
            case IRP_MJ_CLOSE:
                break;        
            
            case IRP_MJ_DEVICE_CONTROL:
            	DemoDevControl(DeviceObject,Irp);
            default:
                break;
        }
    
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
        DBGPRINT(("<== Pt Dispatch end\n"));
    
        return status;
    
    } 
    
    
    
    
    NTSTATUS DemoDevControl(IN PDEVICE_OBJECT DeviceObject,PIRP Irp){
        NTSTATUS status = STATUS_SUCCESS;
        PVOID pOutBuf = NULL ,pSysAddr = NULL,m_DMAMemory=NULL;
        PMDL pMdl;
        PHYSICAL_ADDRESS LowAddress,HighAddress;
        SIZE_T TotalBytes = 1024 * 10;
        PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
        ULONG uControlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
        LowAddress.QuadPart = 0x0;
        HighAddress.QuadPart = (ULONGLONG)-1;
        pOutBuf = Irp->AssociatedIrp.SystemBuffer;
        DBGPRINT(("DemoDevControl\n"));
        switch(uControlCode){
            case IOCTL_SHARE_MEMORY:
                pMdl = MmAllocatePagesForMdl(LowAddress,HighAddress,LowAddress,TotalBytes);
                if(!pMdl){
                    status = STATUS_UNSUCCESSFUL;
                    DBGPRINT(("Sorry pMdl  Failed !\r\n"));
                    return status;
                }
    
                _try{
                *(ULONG*)pOutBuf = MmMapLockedPagesSpecifyCache(
                    pMdl,
                    UserMode,
                    MmNonCached,
                    NULL,
                    FALSE,
                    NormalPagePriority
                    );
                DBGPRINT(("is everything fine?\r\n"));
                if(NULL == *(ULONG*)pOutBuf){
                    DBGPRINT(("Sorry  Failed !\r\n"));
                    status = STATUS_UNSUCCESSFUL;
                    IoFreeMdl(pMdl);
                    break;
                } 
                }_except(EXCEPTION_EXECUTE_HANDLER)
                {
                   
                    DbgPrint("Call to MmMapLocked failed due to exception 0x%0x\n",
    GetExceptionCode());
                }  
                    break;  
                default:
                    break;
        }
        return status;
    }
    
    
    
    VOID UnMapAndFreeMemory()
    {
    if(!pMdl)
    { return ;
    }
    DBGPRINT(("Clean Up\n"));
    // MmUnmapLockedPages
    MmUnmapLockedPages(pOutBuf,pMdl);
    // 
    MmFreePagesFromMdl(pMdl);
    // 
    IoFreeMdl(pMdl);
    
    }

    And also , My user-mode application code :

    #include "stdafx.h"
    
    int main()
    {
    	  PVOID pShareAddr = NULL;
    	  PDWORD dwRet = NULL;
    	  BOOL bRet;
    	  HANDLE hFile = CreateFileW(L"\\\\?\\Passthru",
    		GENERIC_READ|GENERIC_WRITE,
    		FILE_SHARE_READ,
    		NULL,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL
    	);
    	  
    	  if (hFile == INVALID_HANDLE_VALUE) {
    		  printf("create File faile:error %d\r\n",GetLastError());
    		  system("pause");
    		  return 0;
    	  }
    	  printf("create File successed!\r\n");
    
    	 bRet = DeviceIoControl(hFile, IOCTL_SHARE_MEMORY,NULL,0,pShareAddr,1024 * 10,dwRet,NULL);
    	 printf("Get there?");
    	 if (!bRet) {
    		 printf("DeivceIoControl Failuer ,err:%d\n",GetLastError());
    		 CloseHandle(hFile);
    		 system("pause");
    		 return 0;
    	 }
    	 //
    	 //
    	 //if (!bRet) {
    		// printf("DeivceIoControl Failuer ,err:%d\n", GetLastError());
    		// CloseHandle(hFile);
    		// system("pause");
    		// return 0;
    	 //}
    	 //
    	 //printf("ShareMemory:%s\n",pShareAddr);
    	 system("pause");
    	 return 1;
    }
    

    Monday, May 30, 2016 5:37 AM