Re: User-land Callback From Driver



You should not directly call a user mode function from a driver. Second,
you are not running at PASSIVE_LEVEL you are running at DISPATCH_LEVEL
(since you grabbed a spinlock). You are also using a couple of
undocumented routines ExAcquireRundownProtection/ExReleaseRundownProtection
without knowing the rules about them. Finally you are using a member of
EPROCESS a structure that changes fairly often, so relying on the position
of any field in it is not going to work.

Sorry, but the code you have here should all be dumped. Use the inverted
call IOCTL stuff, and forget this garbage of trying to call directly.



--
Don Burn (MVP, Windows DDK)
Windows 2k/XP/2k3 Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr
Remove StopSpam to reply



"L. Spiro" <LSpiro@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:CA96DD4E-68DA-454B-80C4-E550E00C4296@xxxxxxxxxxxxxxxx
I have a driver function callback registered with
PsSetCreateProcessNotifyRoutine().
It works.

But I want to pass the event on to a user-mode function my application
registers with the driver.

My application gives my driver its process ID (which the driver uses to
get
its EPROCESS), the address of the function to call, and a user parameter
to
pass to it.

When my driver tries to call this routine I get a blue death of screen.



The driver is running at PASSIVE_LEVEL, and I was under the impression
that
the driver is able to call user-land functions. Am I wrong about this?



I use the EPROCESS of my application inside the driver callback to go into
the context of my application before calling its callback. Here is my
code:







VOID ZZZ_CreateProcCallback( IN HANDLE hParentId, IN HANDLE hProcessId, IN
BOOLEAN bCreate ) {
KSPIN_LOCK_PARM kplpSkin;
PEPROCESS CurrentProcess, OpeningProcess;
#ifndef __USE_OLD__
KAPC_STATE pState = { 0 };
#endif

KeAcquireSpinLockByOs( &g_kslProcListSpinLock, &kplpSkin );

DbgPrint( "Process Created.\n" );

if ( g_pcCatcher.peProcess ) {
// If the process being closed is the process that has requested to be
notified when processes open
// and close, just handle it and leave.
if ( !bCreate && g_pcCatcher.dwId == (DWORD)hProcessId ) {
DbgPrint( "The process that wants to be notified is closing.\n" );
ZZZ_UnsetProcListUserData();
}
else {
// Otherwise the notify process is still open.
// We know for sure it is safe to go there. We just hope it gave us a
truly valid
// callback pointer or else a blue screen will result (but I always give
a valid
// pointer so who cares)?
// Try to go there.

// Only if there is something to call.
if ( g_pcCatcher.pfCallback ) {

// Get the EPROCESS of the process being created because we need to pass
it to the
// callback function.
// This is actually optional so do not fail if it fails.
if ( !NT_SUCCESS( PsLookupProcessByProcessId( hProcessId,
&OpeningProcess ) ) ) {
DbgPrint( "Failed to look up the EPROCESS of the target.\n" );
OpeningProcess = NULL;
}

// Prevent the notified process from closing.
if ( ExAcquireRundownProtection( &g_pcCatcher.peProcess->RundownProtect
) ) {

DbgPrint( "Call it.\n" );
// Go into its address space (only if needed).
CurrentProcess = PsGetCurrentProcess();
if ( g_pcCatcher.peProcess != CurrentProcess ) {
EnterProcess( g_pcCatcher.peProcess );
DbgPrint( "Changed.\n" );
}

// While here, call the function it wanted us to call.
_SEH_TRY {
g_pcCatcher.pfCallback( OpeningProcess, (DWORD)hParentId,
(DWORD)hProcessId, bCreate, g_pcCatcher.dwUserParm );
}
_SEH_HANDLE {}
_SEH_END;


// GET OUT OF HERE!!
if ( g_pcCatcher.peProcess != CurrentProcess ) {
LeaveProcess();
}

// Give it back the ability to close.
ExReleaseRundownProtection( &g_pcCatcher.peProcess->RundownProtect );
}
// If dereference the opening process if we referenced it.
if ( OpeningProcess ) { ObDereferenceObject( OpeningProcess ); }
}
}
}

KeReleaseSpinLockByOs( &g_kslProcListSpinLock, &kplpSkin );
}





It works until g_pcCatcher.pfCallback is called.
My user-mode function is just a stub for now which calls MessageBox() to
let
me know it worked. Hopefully this is not the actual problem.

Are there any other restrictions I should be minding in my user-mode code,
or is it just impossible to call any user-mode code from here?


L. Spiro


.



Relevant Pages

  • Re: Returning Properly from Assembly .lib
    ... DbgPrint in you ASM file. ... which I have linked into my driver via a .lib file. ... the .asm file simpy calls a CPUID function and returns. ...
    (microsoft.public.development.device.drivers)
  • Re: User-land Callback From Driver
    ... EPROCESS a structure that changes fairly often, ... Windows 2k/XP/2k3 Filesystem and Driver Consulting ... I use the EPROCESS of my application inside the driver callback to go into ... DbgPrint("Process Created.\n"); ...
    (microsoft.public.development.device.drivers)
  • Re: User-land Callback From Driver
    ... Windows 2k/XP/2k3 Filesystem and Driver Consulting ... EPROCESS a structure that changes fairly often, ... DbgPrint("Process Created.\n"); ...
    (microsoft.public.development.device.drivers)
  • User-land Callback From Driver
    ... registers with the driver. ... I use the EPROCESS of my application inside the driver callback to go into ... DbgPrint("Process Created.\n"); ... My user-mode function is just a stub for now which calls MessageBoxto let ...
    (microsoft.public.development.device.drivers)
  • Re: User-land Callback From Driver
    ... Why should someone document for you an undocumented routine you have no good ... Windows 2k/XP/2k3 Filesystem and Driver Consulting ... EPROCESS a structure that changes fairly often, ... DbgPrint("Process Created.\n"); ...
    (microsoft.public.development.device.drivers)