欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > OutputDebugString函数分析

OutputDebugString函数分析

2024/10/26 13:33:15 来源:https://blog.csdn.net/sitelist/article/details/142716308  浏览:    关键词:OutputDebugString函数分析

OutputDebugString函数分析

第一部分:位置base/win32/client/debug.c
F:\srv03rtm\base\win32/client/debug.c:379:OutputDebugStringW(
F:\srv03rtm\base\win32/client/debug.c:387:    UNICODE thunk to OutputDebugStringA
F:\srv03rtm\base\win32/client/debug.c:401:    OutputDebugStringA (AnsiString.Buffer);
F:\srv03rtm\base\win32/client/debug.c:543:OutputDebugStringA(
F:\srv03rtm\base\win32/client/debug.c:688:            DbgPrint("\nOutputDebugString faulted during output\n");


第二部分:输出到vc调试器或者内核调试器windbg
VOID
APIENTRY
OutputDebugStringA(
    IN LPCSTR lpOutputString
    )

/*++

Routine Description:

    This function allows an application to send a string to its debugger
    for display.  If the application is not being debugged, but the
    system debugger is active, the system debugger displays the string.
    Otherwise, this function has no effect.
此函数允许应用程序将字符串发送到其调试器
用于显示。
如果应用程序未被调试,但
系统调试器处于活动状态,系统调试器将显示字符串。
 
否则,此功能无效。

Arguments:

    lpOutputString - Supplies the address of the debug string to be sent
        to the debugger.

Return Value:

    None.

--*/

{
    ULONG_PTR ExceptionArguments[2];
    DWORD WaitStatus;

    //提出一个例外。如果正在调试APP,调试器
会抓住并处理这件事。否则,内核调试器将被调用。
    // Raise an exception. If APP is being debugged, the debugger
    // will catch and handle this. Otherwise, kernel debugger is
    // called.
    //

    try {
        ExceptionArguments[0] = strlen (lpOutputString)+1;
        ExceptionArguments[1] = (ULONG_PTR)lpOutputString;
        RaiseException (DBG_PRINTEXCEPTION_C,0,2,ExceptionArguments);
    } except (EXCEPTION_EXECUTE_HANDLER) {

        //我们捕获了调试异常,因此没有用户模式
调试器。
        //如果有DBWIN正在运行,请发送字符串
如果没有,请使用DbgPrint将其发送到内核
调试器。
        //DbgPrint一次只能处理511个字符
时间,所以用力喂它。
        // We caught the debug exception, so there's no user-mode
        // debugger.  If there is a DBWIN running, send the string
        // to it.  If not, use DbgPrint to send it to the kernel
        // debugger.  DbgPrint can only handle 511 characters at a
        // time, so force-feed it.
        //

        char   szBuf[512];
        size_t cchRemaining;
        LPCSTR pszRemainingOutput;
        DWORD OldError;

        HANDLE SharedFile = NULL;
        LPSTR SharedMem = NULL;
        HANDLE AckEvent = NULL;
        HANDLE ReadyEvent = NULL;

        static HANDLE DBWinMutex = NULL;
        static BOOLEAN CantGetMutex = FALSE;

        OldError = GetLastError ();

        //
        // look for DBWIN.
        //

        if (!DBWinMutex && !CantGetMutex) {
            HANDLE MutexHandle;

            MutexHandle = CreateDBWinMutex();
            if (MutexHandle == NULL) {
                CantGetMutex = TRUE;
            } else {
                if (InterlockedCompareExchangePointer (&DBWinMutex, MutexHandle, NULL) != NULL) {
                    CloseHandle (MutexHandle);
                }
            }
        }

        if (DBWinMutex) {

            WaitStatus = WaitForSingleObject(DBWinMutex, DBWIN_TIMEOUT);

            if (WaitStatus ==  WAIT_OBJECT_0 || WaitStatus == WAIT_ABANDONED) {

                SharedFile = OpenFileMapping(FILE_MAP_WRITE, FALSE, "DBWIN_BUFFER");

                if (SharedFile) {

                    SharedMem = MapViewOfFile (SharedFile,
                                               FILE_MAP_READ|FILE_MAP_WRITE, 0, 0, 0);
                    if (SharedMem) {

                        AckEvent = OpenEvent(SYNCHRONIZE, FALSE,
                                             "DBWIN_BUFFER_READY");
                        if (AckEvent) {
                            ReadyEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE,
                                                   "DBWIN_DATA_READY");
                        }
                    }
                }

                if (!ReadyEvent) {
                    ReleaseMutex(DBWinMutex);
                }
            }

        }

        try {
            pszRemainingOutput = lpOutputString;
            cchRemaining = strlen(pszRemainingOutput);

            while (cchRemaining > 0) {
                int used;

                if (ReadyEvent && WaitForSingleObject(AckEvent, DBWIN_TIMEOUT)
                                                            == WAIT_OBJECT_0) {

                    *((DWORD *)SharedMem) = GetCurrentProcessId();

                    used = (int)((cchRemaining < 4095 - sizeof(DWORD)) ?
                                         cchRemaining : (4095 - sizeof(DWORD)));

                    RtlCopyMemory(SharedMem+sizeof(DWORD),
                                  pszRemainingOutput,
                                  used);
                    SharedMem[used+sizeof(DWORD)] = 0;
                    SetEvent(ReadyEvent);

                } else {
                    used = (int)((cchRemaining < sizeof(szBuf) - 1) ?
                                           cchRemaining : (int)(sizeof(szBuf) - 1));

                    RtlCopyMemory(szBuf, pszRemainingOutput, used);
                    szBuf[used] = 0;
                    DbgPrint("%s", szBuf);
                }

                pszRemainingOutput += used;
                cchRemaining       -= used;

            }
        } except (EXCEPTION_EXECUTE_HANDLER) {
            DbgPrint("\nOutputDebugString faulted during output\n");
        }

        if (AckEvent) {
            CloseHandle(AckEvent);
        }

        if (SharedMem) {
            UnmapViewOfFile(SharedMem);
        }

        if (SharedFile) {
            CloseHandle(SharedFile);
        }

        if (ReadyEvent) {
            CloseHandle(ReadyEvent);
            ReleaseMutex(DBWinMutex);
        }

        SetLastError (OldError);
    }
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com