OutputDebugString函数分析

news2024/10/5 18:25:10

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);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2190307.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】进程周边之优先级

目录 一、优先级 1.为什么要有进程优先级&#xff1f; 2.什么是进程优先级&#xff1f; 3.优先级的初始设定 3.1 PRI 和 NI 3.2如何修改优先级&#xff1f;&#xff08;sudo/root&#xff09; 3.2.1 概念&#xff1a; 3.2.2 如何查看进程的优先级&#xff1f; 3.3.3 或…

【深度学习】自动微分——Autodiff or Autograd?

论文 [1].CSC321 Lecture 10: Automatic Differentiation [2].Automatic Differentiation in Machine Learning:a Survey 关键点总结&#xff1a; 雅可比矩阵&#xff1a;对于多变量函数 y ⃗ f ( x ⃗ ) \vec{y} f(\vec{x}) y ​f(x )&#xff0c;其梯度矩阵&#xff08;…

GPT新功能Canvas!对普通用户最友好的功能!

原文链接&#xff1a;GPT4新功能Canvas!对普通用户最友好的功能&#xff01; ChatGPT更新了一个极度优雅&#xff0c;对普通人极度友好的功能。 而且&#xff0c;顺带&#xff0c;又碾死了一批AI赛道里&#xff0c;做AI文本编辑和Code Copilot的初创企业&#xff0c;一波端掉…

自动驾驶核心技术:感知融合、规划决策、控制执行

1、前言 简单来说&#xff0c;实现自动驾驶需要解决三个核心问题&#xff1a;“我在哪?我要去哪?我该如何去?”能完整解决这三个问题就是真正的自动驾驶。 目前&#xff0c;自动驾驶汽车关键技术主要包括环境感知、精准定位、决策与规划、控制与执行、高精地图与车联网V2X以…

ZYNQ:GPIO 之 MIO 按键中断实验

实验目的 使用底板上的 PS 端的用户按键 PS_KEY1 通过中断控制核心板上 LED2 的亮灭 简介 Zynq 芯片的 PS 部分是基于使用双核 Cortex-A9 处理器和 GIC pl390 中断控制器的 ARM 架构。中断结 构与 CPU 紧密链接&#xff0c;并接受来自 I/O 外设&#xff08;IOP&#xff09…

P4240 毒瘤之神的考验

毒瘤之神的考验 - 洛谷 定义 猜想与有关 发现上式1-1 上下两边乘gcd(i,j)有 带入1-1有 化简 n<m 经典代换Tke eT/k 然后化简不了了 这个时候我们可以把一部分看出一个整体 分析这两个函数&#xff0c;发现f(x) 可以在下预处理出来 g(x,y)有以下递推式 因此也可以在下处理…

三、流程控制

流程控制 选择结构&#xff08;if-else&#xff09;选择结构&#xff08;when&#xff09;循环结构&#xff08;for&#xff09;循环结构&#xff08;while&#xff09; 经过前面的学习&#xff0c;我们知道&#xff0c;程序都是从上往下依次运行的&#xff0c;但是&#xff0c…

事件抽取(Event Extraction, EE)

一、引言 事件抽取&#xff08;Event Extraction, EE&#xff09;是信息抽取领域中的一个重要任务&#xff0c;旨在从非结构化文本中识别和抽取事件相关的信息。事件抽取通常包括识别事件触发词、事件类型以及事件中的参与者、时间、地点等元素&#xff0c;最终将这些信息结构…

【进阶OpenCV】 (4)--图像拼接

文章目录 图像拼接1. 读取图片2. 计算图片特征点及描述符3. 建立暴力匹配器4. 特征匹配5. 透视变换6. 图像拼接 总结 图像拼接 图像拼接是一项将多张有重叠部分的图像&#xff08;这些图像可能是不同时间、不同视角或者不同传感器获得的&#xff09;拼成一幅无缝的全景图或高分…

论文翻译 | Model-tuning Via Prompts Makes NLP Models Adversarially Robust

摘要 近年来&#xff0c;NLP从业者集中于以下实践:(i)导入现成的预训练(掩码)语言模型;(ii)在CLS令牌的隐藏表示(随机初始化权重)上附加多层感知器;(iii)在下游任务(MLP-FT)上微调整个模型。这一过程在标准的NLP基准上产生了巨大的收益&#xff0c;但这些模型仍然很脆弱&#x…

mysql单表查询·3

准备好表 create table product(id int primary key,name varchar(32),price double,category varchar(32) ); # 插入数据 INSERT INTO product(id,name,price,category) VALUES(1,联想,5000,c001); INSERT INTO product(id,name,price,category) VALUES(2,海尔,3000,c001); I…

加密与安全_HOTP一次性密码生成算法

文章目录 HOTP 的基础原理HOTP 的工作流程HOTP 的应用场景HOTP 的安全性安全性增强措施Code生成HOTP可配置项校验HOTP可拓展功能计数器&#xff08;counter&#xff09;计数器在客户端和服务端的作用计数器的同步机制客户端和服务端中的计数器表现服务端如何处理计数器不同步计…

好用的苹果笔推荐!五大高品质王者款!附避坑宝典助你选购无忧!

现在平板和电容笔在一定程度上可以替代传统的笔和纸&#xff0c;很多用户在购置iPad后&#xff0c;急需找到一款好用的电容笔。但由于苹果原装笔的价格太过高昂&#xff0c;让许多人不得不选择平替电容笔&#xff01;下面我就为大家推荐五款高品质的电容笔&#xff0c;并分享几…

单细胞hdWGCNA分析学习和整理

hdWGCNA的分析逻辑是跟bulkRNA数据中的WGCNA基本一样&#xff0c;只是hdWGCNA中多了一步metacell过程&#xff0c;有助于减少无用的信息(单细胞数据有很多零值&#xff0c;会影响分析结果)。 WGCNA的基础信息可见既往推文: https://mp.weixin.qq.com/s/2Q37RcJ1pBy_WO1Es8upIg…

二分查找算法专题(2)

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a; 优选算法专题 对于二分查找算法不是很了解或者只了解一部分的小伙伴一定要去看下面这篇博客&#xff1a;二分查找算法的介绍与另外一种查找方…

【EcoNAS: Finding Proxies for Economical Neural Architecture Search】读后感

鄙人近日阅读了来自 CVPR2020 的一篇论文, 在这里与大家分享一下读后感, 有些东西可能不一定正确, 还望大家指正. Exploration Study 进化算法是 NAS 中一种常用的搜索算法, 使用进化算法时, 如果将每一个候选网络训练到完全收敛来评估性能的话, 需要耗费大量的资源 (时间, G…

现代身份和访问管理 IAM 如何降低风险

您的公司是否仍在使用 1998 年时的身份管理系统&#xff1f;仅凭用户名和密码就能登录本地网络并访问几乎所有资源吗&#xff1f; 虽然大多数企业已经转向现代身份和访问管理(IAM) 平台&#xff0c;但成千上万的企业和其他组织仍然依赖过时的用户名/密码系统。 如果你看一下传…

Ubuntu18.04配置OpenPCDet并运行demo过程记录

一、概述 因为最近需要配置OpenPCDet&#xff0c;发现在配置过程中存在诸多的问题需要解决&#xff0c;将过程中所遇到的问题进行记录保存。 二、具体配置过程 &#xff08;一&#xff09;参考链接 因为中间遇到了很多问题&#xff0c;参考了很多不少相应的博客进行问题解决。…

【Unity】unity安卓打包参数(个人复习向/有不足之处欢迎指出/侵删)

1.Texture Compression 纹理压缩 设置发布后的纹理压缩格式 Use Player Settings:使用在播放器设置中设置的纹理压缩格式 ETC&#xff1a;使用ETC格式&#xff08;兼容&#xff09; ETC2&#xff1a;使用ETC2格式&#xff08;很多设备不支持&#xff09; ASTC&#xff1a;使用…

使用JavaScript写一个网页端的四则运算器

目录 style(内联样式表部分) body部分 html script 总的代码 网页演示 style(内联样式表部分) <style>body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f0f0f0;}.calculator {…