Question

I have a third party kernel mode driver that is controlled by a windows service that I wrote in C++. The service initialization code appears to run perfectly, but when the service thread is run it encounters an exception that appears to indicate stack or heap corruption (it varies depending on the circumstances of debugging). The exception occurs in an address that is "not in any loaded module", making it almost impossible to tell what happened. Running in windbg with application verifier as an admin gives this after analyze -v:

Breakpoint 0 hit
eax=001ffb04 ebx=7ffda000 ecx=001ffb04 edx=002e1b34 esi=00000000 edi=001ff8a4
eip=00282051 esp=001ff76c ebp=001ff8b4 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000282
MyService!CServiceBase::Run+0x71:
00282051 8bf4            mov     esi,esp
0:000> g
Detected memory leaks!
Dumping objects ->
{53} normal block at 0x058BFFF0, 8 bytes long.
 Data: <  (     > C0 15 28 00 04 FB 1F 00 
Object dump complete.
(4e6c.4e9c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000001 ebx=7ffda000 ecx=bffefce9 edx=002f8950 esi=00000000 edi=001ff8a4
eip=bfe1045d esp=001ff778 ebp=001ff8b4 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
bfe1045d ??              ???

The _crtdbg "memory leaks" I believe are objects that I allocated during service initialization that will not be freed until service stop.

0:000> !analyze -v
*******************************************************************************
*                                                                             *
*                        Exception Analysis                                   *
*                                                                             *
*******************************************************************************

Current verifier stop:
APPLICATION_VERIFIER_LUAPRIV_OK_OBJECT_DUMP (3317)
The application was able to access the object's security descriptor.
The application was granted the requested access to this object. A standard user should also be able to access this object. 
Arguments:
Arg1: 6d101d5c, Object Name 
Arg2: 0012019f, Access Requested 
Arg3: 05156f60, Security Descriptor 
Arg4: 05986fa0, String Security Descriptor 

Previous verifier stop:
APPLICATION_VERIFIER_LUAPRIV_OK_OBJECT_GRANT (331e)
Safe Object.
The application opened an object (such as a file or registry key) and requested access that is granted to at least one non-privileged entity (listed). This suggests that the same operation will work when attempted by non-privileged/standard users. 
Arguments:
Arg1: 6d101d5c, Object Type 
Arg2: 05148fd8, Object Name 
Arg3: 05156f8c, Access Control Entry 
Arg4: 00000000, N/A 
*** WARNING: Unable to verify checksum for ...nfapi.dll

FAULTING_IP: 
+0
bfe1045d ??              ???

EXCEPTION_RECORD:  ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: bfe1045d
   ExceptionCode: c0000005 (Access violation)
  ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000000
   Parameter[1]: bfe1045d
Attempt to read from address bfe1045d

FAULTING_THREAD:  00004e9c

DEFAULT_BUCKET_ID:  BAD_INSTRUCTION_PTR

PROCESS_NAME:  MyService.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - The instruction at 0x%08lx referenced memory at 0x%08lx. The memory could not be %s.

EXCEPTION_PARAMETER1:  00000000

EXCEPTION_PARAMETER2:  bfe1045d

READ_ADDRESS:  bfe1045d 

FOLLOWUP_IP: 
MyService!main+71 [.....svc.cpp @ 51]
00282d81 83c404          add     esp,4

FAILED_INSTRUCTION_ADDRESS: 
+9
bfe1045d ??              ???

NTGLOBALFLAG:  2000100

APPLICATION_VERIFIER_FLAGS:  80c43267

APP:  myservice.exe

IP_ON_HEAP:  7ffda000
The fault address in not in any loaded module, please check your build's rebase
log at <releasedir>\bin\build_logs\timebuild\ntrebase.log for module which may
contain the address if it were loaded.

PRIMARY_PROBLEM_CLASS:  BAD_INSTRUCTION_PTR

BUGCHECK_STR:  APPLICATION_FAULT_BAD_INSTRUCTION_PTR_INVALID_POINTER_READ

FRAME_ONE_INVALID: 1

LAST_CONTROL_TRANSFER:  from 7ffda000 to bfe1045d

STACK_TEXT:  
WARNING: Frame IP not in any known module. Following frames may be wrong.
001ff774 7ffda000 cccccccc cccccccc cccccccc 0xbfe1045d
001ff8b4 00282d81 001ffb04 bfe107a5 00000000 0x7ffda000
001ffb4c 002aac69 00000001 05868fa8 0586af60 MyService!main+0x71
001ffb98 002aab2f 001ffbac 75fbd2e9 7ffda000 MyService!__tmainCRTStartup+0x129
001ffba0 75fbd2e9 7ffda000 001ffbec 77691603 MyService!mainCRTStartup+0xf
001ffbac 77691603 7ffda000 762ef334 00000000 KERNEL32!BaseThreadInitThunk+0xe
001ffbec 776915d6 002aab20 7ffda000 00000000 ntdll!__RtlUserThreadStart+0x23
001ffc04 00000000 002aab20 7ffda000 00000000 ntdll!_RtlUserThreadStart+0x1b


FAULTING_SOURCE_LINE:  .....svc.cpp

FAULTING_SOURCE_FILE:  .....svc.cpp

FAULTING_SOURCE_LINE_NUMBER:  51

FAULTING_SOURCE_CODE:  
    47: {
    48:     try
    49:     {
    50:         CSampleService service(SVCNAME, TRUE, TRUE, TRUE);
>   51:         if (!CServiceBase::Run(service))
    52:         {
    53:             printf("Service failed to run w/err 0x%08lx\n", GetLastError());
    54:         }
    55:         return 0;
    56:     } catch (char *str )


SYMBOL_STACK_INDEX:  2

SYMBOL_NAME:  myservice!main+71

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: MyService

IMAGE_NAME:  MyService.exe

DEBUG_FLR_IMAGE_TIMESTAMP:  530b8caa

STACK_COMMAND:  ~0s ; kb

FAILURE_BUCKET_ID:  BAD_INSTRUCTION_PTR_c0000005_MyService.exe!main

BUCKET_ID:  APPLICATION_FAULT_BAD_INSTRUCTION_PTR_INVALID_POINTER_READ_BAD_IP_myservice!main+71

Followup: MachineOwner
---------

The difficulty here is that windows service startup code cannot be debugged directly, you have to skip the service start code and step into the initialization code. After the service starts you can attach to the process to debug, but this exception is thrown before the service starts successfully but after the initialization code is completed. If I step past the end of the initialization code the call stack is only hex addresses and the code is assembly in ntdll.dll. I can see that something is being corrupted in memory that later is used in service run but I can't detect what that is, all of the local and global variables appear to be correct completely through the initialization code. The third party code runs successfully as an exe, and the service starts successfully if I do not call the third party code. When run from a command line the service start times out, which can occur if an exception occurs.

int main(int argc, char *argv[]) 
{
    try
    {
        CSampleService service(SVCNAME, TRUE, TRUE, TRUE);
        if (!CServiceBase::Run(service))
        {
            printf("Service failed to run w/err 0x%08lx\n", GetLastError());
        }
        return;
    } catch (char *str )
    {
        char sMessage[MAX_PATH];
        sprintf_s(sMessage,"Service failed to run, exception=%s", str);
        SvcReportEvent(sMessage, 0);
    }
    catch (...)
    {
        char sMessage[MAX_PATH];
        sprintf_s(sMessage,"Service failed to run, exception occured");
        SvcReportEvent(sMessage, 0);
    }
} 

EDIT: I have now solved the problem. I used Windbg in postportem mode (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\servicename.exe Debugger (string) set to "C:\Program Files\Debugging Tools for Windows (x86)\windbg.exe"), set my service to be interactive by ORing SERVICE_INTERACTIVE_PROCESS with the service type. I used __debugbreak() statements to break into the debugger in ServiceMain, which brought up an odd fullscreen mode window with only windbg running after an "interactive mode prompt" dialog. Once there, I was able to debug the running service itself, immediately after startup. It turned out the service did have a mistake in it that caused the stack overflow, which I was able to see and correct. Thank you, everyone!

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top