Windows drivers - shared memory from user mode->kernel mode - windows

I'm messing around with some driver development and I'm having an issue getting some of my code to work. I'm not sure if it's a quirk with the API that I'm unaware of or what.
I have a user app that has created a named shared object under BaseNamedObjects with CreateFileMapping, MapViewOfFile, etc. I'm trying to read this shared object inside of my driver code using ZwOpenSection and ZwMapViewOfSection
The problem code is below:
char *sharedData = NULL;
SIZE_T vs = 256;
InitializeObjectAttributes(&myAttributes,&sectionName,OBJ_KERNEL_HANDLE,NULL,NULL);
ZwOpenSection(&sectionHandle,SECTION_MAP_READ,&myAttributes)
ZwMapViewOfSection(&sectionHandle, ZwGetCurrentProcess(), (PVOID *)sharedData, 0, 256,
NULL, &vs, ViewUnmap, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
The call to ZwOpenSection completes successfully and I get the object properly, but the second call fails. The status returned says it's an issue with the ninth parameter, but I've tried every combination I could think of with nothing to show for it, so I'm not sure if it's an issue with a different parameter causing the 9th to be "incorrect" or if I'm missing something else
Thanks.

Is the access permission with which the section was created the same as the one you have passed here?
MEM_COMMIT is not allowed in a direct call in this function. If you still want to commit and reserve pages, try calling the virtualalloc(), otherwise just pass NULL in the 8th parameter.

Related

Crash while accessing Address passed via ioctl in linux kernel

I am passing pointer to below structure through ioctl.
typedef struct myparam_t {
int i;
char *myname;
}myparam;
I allocate memory for myname in the user space before passing the argument.
In the ioctl implementation at kernel space I use copy_from_user() to copy the argument in kspace variable (say kval). call is like copy_from_user(kval,uval,sizeof(myparam)); kval & uval are of myparam * type.
Now in ioctl function I have check like -
if (uval->myname != NULL) {
}
I thought this will result in to kernel crash or panic due to page fault.
However I see different behaviour with different version of kernel.
With 4.1.21 kernel I see no issue with NULL check, But with 4.10.17 kernel I see a page fault that results in to kernel panic.
My question is what might make NULL check working in kernel 4.1.21 ?
Is there a way I can make same code working for 4.10.17 as well ?
Note that I am facing this issue as part of kernel migration. We are trying to migrate from version 4.1.21 to 4.10.17. There may be many instance of such usage in our code base. Hence, if possible, I'd prefer to put a patch in kernel to fix the issue, rather than fixing all such instance.
Thanks
Dipak.

Custom windows credential provider crashes with Exception code: 0xc0000374

I have developed a custom credential provider. This credential provider uses 1) camera 2) facial sdk to match the user. Once the user is matched account name is populated and CredentialsChanged signal is triggered. I have customized samplehardwareeventcredentialprovider
to achieve this functionality. This works fine with few of the machine ( all windows 10). When I tried to execute this another machine ( different brand), I get the following exception randomly and makes the screen go black , unstable login screen. All the dependencies are in place but it is not stable at all.
I have turned off the winbio service, disabled many of default credential providers but I face the same issue.
My Flow:
I initiate the facial identification flow in CSampleCredential::Initialize api and once it is identified, update the value for rgFieldStrings[SFI_USERNAME]
In the following method, after completing CSampleCredential::Initialize , I use CSampleProvider::OnConnectStatusChanged method to trigger login window. If everything works as expected, it launches login window with user name auto populated. The entire flow works file, but it is not stable in few machine.
HRESULT CSampleProvider::SetUsageScenario(
__in CREDENTIAL_PROVIDER_USAGE_SCENARIO cpus,
__in DWORD dwFlags
)
Am I doing something fundamentally wrong here?
Any pointers will be helpful! Thanks
I generated localdump by following Steps to Catch a Simple “Crash Dump” of a Crashing Process
By analyzing the log, it was evident that there was a heap corruption. By mistake, malloc allocation was done for the size of 4. Actually this allocation should be of size 260. When the memory is accessed beyond this size, it was triggering the random crash based on the input data.
Original code with bug:
uint8_t* data = (uint8_t*)malloc(sizeof(MAX_PATH));
Fixed code:
uint8_t* data = (uint8_t*)malloc(MAX_PATH*sizeof(uint8_t));

Access hardware from user process

I have a driver that runs in the kernel of a Windows Embedded Compact 2013. The driver is loaded with the "Drivers\BuiltIn" registry key. It accesses a set of HW-registers that are mapped with MmMapIoSpace.
The access to the hardware has some problems. That's why I would like to develop the hardware access in a user mode program and debug the problems. I created a program with VS2013 for that purpose. That's the way we used to go with Windows CE 5.0.
The driver maps the physical address with MmMapIoSpace to the process address space. My program should do the same or something similar. Unfortunately this doesn't work in my program. MmMapIoSpace returns NULL, LastError=87 (invalid parameters). Even CreateStaticMapping returns NULL.
How can I access memory mapped register in WEC2013 without building a new platform for each iteration?
MmMapIoSpace doesn't work in applications anymore since WinCE6.
You maybe could create a driver which maps your hw-register to your user process. Your user process would then obtain this pointer by an ioctl call to this driver.
We mapped some external memory to an application with this method.
VirtualAllocCopyEx() can create a mapping to a specified process.
Hope, this helps. Greetings.
Corresponding to timmfs answer I implemented this code in the driver's XXX_IOControl function:
PHYSICAL_ADDRESS PhysAddress = { 0 };
PhysAddress.LowPart = phys_address;
PVOID pRegister = MmMapIoSpace(PhysAddress, phys_size, FALSE);
HANDLE hCallerProcess = (HANDLE)GetCallerVMProcessId();
HANDLE hCurrentProcess = (HANDLE)GetCurrentProcessId();
PVOID UserSpaceAddress = VirtualAllocCopyEx(hCurrentProcess, hCallerProcess, pRegister, shys_size, PAGE_NOCACHE);
This excerpt shows some solutions for pitfalls I met. So I show how I get all the parameters.

How to get process memory usage WINAPI

I have the problem . I am trying to get process memory usage , but unfortunatly some process always returning the same value in my case - 3276. How can I get the real amount of memory using by the process. Thanks in advance.
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
PROCESS_MEMORY_COUNTERS memCounter;
BOOL result = GetProcessMemoryInfo(hProcess,
&memCounter,
sizeof( memCounter ));
char procID[20];
char procMem[100];
sprintf_s(procMem, "%d",(memCounter.WorkingSetSize/1024/1024));
if (!(strcmp(procMem,"3276"))) {
strcpy(procMem, "<unavaliable>");
}
sprintf_s(procID, "%d",entry.th32ProcessID);
You are not checking the return values for errors. You simply must do that. Clearly one of them is failing. Is it OpenProcess, or is it GetProcessMemoryInfo? How can we tell without any error checking. Read the documentation for the function and follow the instructions there given to check for errors.
Once you identify which function is failing you can try to work out why. In case of failure, both of these functions will set the last error value and so you can call GetLastError to discern what went wrong.
Quite possibly OpenProcess is failing because you are asking for too many access rights. All you need is PROCESS_QUERY_INFORMATION | PROCESS_VM_READ. Another possible failure mode is that some system processes will not give up this information. Ultimately you need to perform error checking to diagnose the specific problem.

IoGetDeviceObjectPointer() fails with no return status

This is my code:
UNICODE_STRING symbol;
WCHAR ntNameBuffer[128];
swprintf(ntNameBuffer, L"\\Device\\Harddisk1\\Partition1");
RtlInitUnicodeString(&symbol, ntNameBuffer);
KdPrint(("OSNVss:symbol is %ws\n",symbol.Buffer));
status = IoGetDeviceObjectPointer(&symbol,
FILE_READ_DATA,
&pDiskFileObject,
&pDiskDeviceObject);
My driver is next-lower-level of \\Device\\Harddisk1\\Partition1.
When I call IoGetDeviceObjectPointer it will fail and no status returns and it not continue do remaining code.
When I use windbg debug this, it will break with a intelpm.sys;
If I change the objectname to "\\Device\\Harddisk1\\Partition2" (the partition2 is really existing), it will success call
If I change objectname to "\\Device\\Harddisk1\\Partition3", (the partition3 is not existing), it failed and return status = 0xc0000034, mean objectname is not existing.
Does anybody know why when I use object "\\Device\\Harddisk1\\Partition1" it fails and no return status? thanks very much!
First and foremost: what are you trying to achieve and what driver model are you using? What bitness, what OS versions are targeted and on which OS version does it fail? Furthermore: you are at the correct IRQL for the call and is running inside a system thread, right? From which of your driver's entry points (IRP_MJ_*, DriverEntry ...) are you calling this code?
Anyway, was re-reading the docs on this function. Noting in particular the part:
The IoGetDeviceObjectPointer routine returns a pointer to the top object in the named device object's stack and a pointer to the
corresponding file object, if the requested access to the objects can
be granted.
and:
IoGetDeviceObjectPointer establishes a "connection" between the caller
and the next-lower-level driver. A successful caller can use the
returned device object pointer to initialize its own device objects.
It can also be used as as an argument to IoAttachDeviceToDeviceStack,
IoCallDriver, and any routine that creates IRPs for lower drivers. The
returned pointer is a required argument to IoCallDriver.
You don't say, but if you are doing this on a 32bit system, it may be worthwhile tracking down what's going on with IrpTracker. However, my guess is that said "connection" or rather the request for it gets somehow swallowed by the next-lower-level driver or so.
It is also hard to say what kind of driver you are writing here (and yes, this can be important).
Try not just breaking at a particular point before or after the fact but rather follow the stack that the IRP would travel downwards in the target device object's stack.
But thinking about it, you probably aren't attached to the stack at all (for whatever reason). Could it be that you actually should be using IoGetDiskDeviceObject instead, in order to get the actual underlying device object (at the bottom of the stack) and not a reference to the top-level object attached?
Last but not least: don't forget you can also ask this question over on the OSR mailing lists. There are plenty of seasoned professionals there who may have run into the exact same problem (assuming you are doing all of the things correct that I asked about).
thanks everyone , I solve this problem; what cause this problem is it becoming synchronous; when I
call IoGetDeviceObjectPointer , it will generate an new Irp IRP_MJ_WRITER which pass though from high level, when this irp reach my driver, my thread which handle IRP is the same thread whilch call IoGetDeviceObjectPointer ,so it become drop-dead halt;

Resources