Dear Sirs: Is there any tip and trick to gather the debug information from the kernel-mode driver (eg: the output string of "DbgPrint") without using the kernel debugger (SoftwareICE or WinDebug) ???
Posted on 2001-04-22 07:57:00 by rl
Yes there is. You've got to start the program yourself, however, or get DEBUG access another way, (Probably easy, just never tried it.) You use WaitForDebugEvent API to wait for the OUTPUT_DEBUG_STRING_EVENT event, then respond to that. As an example for using the debugging API's, use this program that I wrote as a crashguard for s3's Cinchy Server. All it does is close and restart the program if it causes an exception, but you get the idea.

.model flat, stdcall
option casemap :none   ; case sensitive

      include \masm32\include\
      include \masm32\include\
      include \masm32\include\
      includelib \masm32\lib\user32.lib
      includelib \masm32\lib\kernel32.lib

DebugThread PROTO :DWORD

ProcessInfo         PROCESS_INFORMATION    <0>
StartupInfo         STARTUPINFO            <0>
DebugEvent          DEBUG_EVENT            <0>
szPathName1         db                     "Server.exe", 0
szKernel32          db                     "Kernel32.dll", 0
szProcName          db                     "RegisterServiceProcess", 0

ThreadID            dd ?
ThreadHwnd          dd ?
RSP                 dd ?



; Try to hide ourselves so we don't worry the user by not 
; responding to Ctrl-Alt-Del. (No messageloop 
; implemented,we just close when the main program is closed.

    invoke  GetModuleHandle, addr szKernel32
    or eax, eax
    jz NoHide
    invoke  GetProcAddress, eax, addr szProcName
    or eax, eax
    jz NoHide
    mov , eax
    push 1
    push 0
    call RSP

; fill some StartUpInfo fields (only si_cb is enough for now)
    mov    StartupInfo.cb, sizeof STARTUPINFO


; Create thread to handle Debug loop
    invoke  CreateThread, NULL, 0, offset DebugThread, 0, 0, offset ThreadID
    mov    ThreadHwnd, eax
; We don't do anything until the thread exits 
    invoke WaitForSingleObject, ThreadHwnd, INFINITE

; If the thread exits, there is a serious error in the app we're debugging. Kill it
; and then start it again.
    invoke TerminateProcess, DebugEvent.dwProcessId, 0

jmp @B

; The main debugging callback proc. As it's a callback, preserve all the important registers.

DebugThread proc uses ebx ecx edx esi edi Param :DWORD

    invoke CreateProcess, NULL, offset szPathName1, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS+NORMAL_PRIORITY_CLASS, NULL, NULL, offset StartupInfo, offset ProcessInfo
    .if eax != TRUE
        invoke ExitProcess, 0

    invoke WaitForDebugEvent, offset DebugEvent, INFINITE
    .if DebugEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT

        ; ContinueDebugEvent just closes the handle to the process so the process object can be freed.
        ; The EXIT_PROCESS_DEBUG_EVENT message means the app was terminated by user, so we can exit as well.
        invoke ContinueDebugEvent, DebugEvent.dwProcessId, DebugEvent.dwThreadId, DBG_CONTINUE
        invoke ExitProcess, 0
    .elseif DebugEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT

        ; Check if the exception wasn't a breakpoint, I've noticed a breakpoint occurs after
        ; loading user32.dll, and we don't want to exit then. Since it was an exception, we
        ; do have to resume the thread.
        .if DebugEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
            invoke ResumeThread, DebugEvent.dwThreadId
            invoke ExitThread, -1    ; exit thread and restart the app we're watching

    invoke ContinueDebugEvent, DebugEvent.dwProcessId, DebugEvent.dwThreadId, DBG_CONTINUE
    jmp DebugLoop

DebugThread endp

end start
This should help! Edited: Added some linebreaks and removed useless ret in DebugThread. This message was edited by Qweerdy, on 4/22/2001 8:40:52 AM
Posted on 2001-04-22 08:37:00 by Qweerdy