如何在 Windows 中拦截 DNS 查询

2024-04-26

我正在研究如何在 Windows 中拦截 DNS 查询, 以一种不需要将 DLL 注入到每个进程中的方式,并且理想情况下能够根据发出查询的进程做出决策,因此简单的 DNS 代理服务器是不够的。

从表面上看,DNS 查询所采用的路径如下所示, 某些应用程序从 ws2_32.dll(或 dnsapi.dll 中的 DnsQuery)调用 gethostbyname

[dll 做了一些事情]

最终调用 dnsrslvr.dll 中的某些内容,该 dll 在 svshost 进程中作为名为“Dnscache”的服务运行,该服务根据 TaskExplorer 从 DNS 服务器在端口 53 上发送和接收 UDP 数据包

所以我想做的是在“Dnscache”服务之前拦截一些软件的 dns 查询,或者用自己的服务替换该服务。

所以我的问题是:这里的聪明人之一是否知道公共 DNS 查询 API 和 Dnscache 服务之间会发生什么,以及两者之间的最佳位置是什么?


你可以这样做标注驱动程序 https://learn.microsoft.com/en-us/windows-hardware/drivers/network/callout-driver。 您可以在 FWPM_LAYER_DATAGRAM_DATA_V4 的标注中捕获、解析和编辑 DNS 数据包。

这是FWPM_LAYER_DATAGRAM_DATA_V4回调的代码,用于获取DNS查询名称。

void NTAPI
CoDatagramDataV4(
IN  const FWPS_INCOMING_VALUES* inFixedValues,
IN  const FWPS_INCOMING_METADATA_VALUES* inMetaValues,
IN  VOID*                       packet,
IN  const void*                 classifyContext,
IN  const FWPS_FILTER*          filter,
IN  UINT64                      flowContext,
OUT FWPS_CLASSIFY_OUT*          classifyOut
){
    classifyOut->actionType = FWP_ACTION_PERMIT;

    if (inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_PROTOCOL].value.uint8 != IPPROTO_UDP
        inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_IP_REMOTE_PORT].value.uint16 != 53 ||
        inFixedValues->incomingValue[FWPS_FIELD_DATAGRAM_DATA_V4_DIRECTION].value.uint32 != FWP_DIRECTION_INBOUND)
    {
        // This can be filtered by FwpmFilterAdd in ring3.
        return;
    }
    PNET_BUFFER pNetBuffer = NET_BUFFER_LIST_FIRST_NB((PNET_BUFFER_LIST)packet);
    if (pNetBuffer == NULL)
    {
        PVOID pDataBuffer0 = ExAllocatePoolWithTag(NonPagedPool, nDataLength, TAG_NAME_CALLOUT);
        if (pDataBuffer0)
        {
            PVOID pDataBuffer = NdisGetDataBuffer(pNetBuffer, nDataLength, pDataBuffer0, 1, 0);
            if (pDataBuffer)
            {
                PCHAR  pszQuery = (PCHAR)pDataBuffer + 12/*sizeof DNS header*/;
                CHAR   szQueryName[MAX_DOMAIN_NAME_LEN] = { 0 };
                CHAR   cbLabel = pQuery[0];
                UINT32 nLen = 1;
                while (cbLabel != 0)
                {
                    for (CHAR i = 0; i < cbLabel; i++)
                    {
                        szQueryName[nLen - 1] = pszQuery[nLen]; nLen++;
                    }
                    cbLabel = pszQuery[nLen];
                    szQueryName[nLen - 1] = cbLabel != 0 ? '.' : 0;
                    nLen++;
                }
                // Here szQueryName is DNS query name such as 'www.google.com'.
            }
        }
        ExFreePoolWithTag(pDataBuffer0, 'Tsnd');
    }
}

And you can check the DNS structure by using wireshark like this. enter image description here

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 Windows 中拦截 DNS 查询 的相关文章

  • 以编程方式或使用清单 (MinGW) 将“覆盖高 DPI 缩放”设置为“系统(增强)”

    我尝试了所有可能的组合gdiScaling and dpiAware 仍然没有运气 如果我手动右键单击 app exe 并将 覆盖高 DPI 缩放 设置为 系统 增强 效果很好
  • 向 Windows 任务栏缩略图添加按钮 JavaFX?

    这个问题已经闲置一年多了 我的问题仍然没有解决方案 我编辑此内容是为了澄清我的问题并引起人们对它的新关注 如果您使用 Windows 您可能知道将程序图标悬停在任务栏上时显示的小预览图像 缩略图 某些程序 例如 Spotify Git 扩展
  • 如何在 Windows 中将 Electron 应用程序部署为可执行文件或可安装文件?

    我想生成一个独特的 exe文件来执行应用程序或 msi安装应用程序 怎么做 您可以使用以下方式打包您的程序电子包装机 https github com maxogden electron packager然后使用以下命令构建单个安装 EXE
  • C# 同步进程启动

    我正在尝试从一段代码启动一个进程 但我希望代码暂停执行 直到进程完成并退出 目前 我正在使用 System Diagnostics Process Start 类来启动 特别是 卸载程序 并且之后执行的代码确实依赖于安装程序卸载程序在恢复执
  • NGinx 域名重定向

    假设我有一个名为 xyz co 的网站 我还有其他具有相同前缀的域名 例如 xyz com xyz it xyz co it 现在 nginx 与端口 80 的 nginx conf 中的 server name xyz co 配合得很好
  • 是否可以为 IP 地址而不是域名提供 SSL 证书? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我希望我的网站使用类似的 URLhttp 192 0 2 2 and https 192 0 2 2 用于静态内容 以避免请求中不必要的
  • 捕获由纯 C++ dll 中的 MFC 应用程序生成的 Windows 消息

    首先 这可能吗 我有一个与某些硬件接口的第三方 dll 它是用MFC编写的 我 从 dll 供应商处 收到了一个示例 Visual Studio 2010 解决方案 该解决方案只有一个项目 调用相关第三方 dll 的 MFC 应用程序 ex
  • 根据 TCP 的 C++ 函数

    我正在使用 recv 函数 C 来获取有关网络问题的指示 在这种情况下它返回负值 看这里 https www rfc editor org rfc rfc1122 page 100 https www rfc editor org rfc
  • Windows下如何分配非分页内存

    当我使用 cudaHostAlloc 时 它将分配非分页 固定 页面锁定 内存 我想知道如何在没有 cuda 的情况下仅使用 Windows SDK 来做到这一点 None
  • 如何使用 wamp 在 Windows 上烘焙 cakephp 2.0 应用程序

    我想在Windows系统上烤蛋糕php项目 我正在使用 wamp 服务器来运行 PHP mysql 我已经浏览过 cakephp 网站上的视频投射 并设置了环境设置 按照演示给出命令 蛋糕 后 最后我收到一条消息说 php 不被识别为内部或
  • 获取已连接 USB 设备的端口名称

    当USB设备连接到计算机时 如何使用C 代码获取它所连接的端口名称 我找到了很多方法来查找 USB 何时连接 断开 驱动器号 路径 设备 ID 等 但没有找到任何明确的示例来说明如何知道它连接到哪个端口 我看到了一种可能的解释 但这涉及很多
  • cygwin winsymlinks:本机不起作用

    我现在和 cygwin 斗争了很长一段时间 我广泛搜索了如何让 cygwin 创建 Windows 风格的符号链接 我尝试了以下方法 export CYGWIN winsymlinks native export CYGWIN winsym
  • 如何为 Windows 和 macOS 更新 PyQT5 应用程序?

    我有一个使用 PyQT5 为 Windows 和 macOS 构建的应用程序 目前 用户通过单击按钮检查更新 当有可用的新更新时 我将它们重定向到浏览器到我的服务器以下载最新的 exe Windows 或 pkg macOS 问题在于 如果
  • Windows 7 VM 上的 Android Studio 虚拟设备不兼容

    我的计算机上有一个 VirtualBox VM 该 VM 运行 Windows 7 64 位 我在该虚拟机上安装了 Android Studio 我只有基本的 Hello World 应用程序 当我尝试运行 AVD 时 我收到以下消息 运行
  • :: 右侧的非法标记

    我有以下模板声明 template
  • QT 应用程序运行时错误?

    我已经在 Windows 7 的 Qt5 1 上开发了一个应用程序 现在我想分发它 由于我使用了 MINGW 编译器 因此无法静态构建它 我使用dependency walker找出所有dll并打包 当我在未安装 QT 开发环境的计算机上运
  • 批处理:在特定程序中打开特定文件?

    当记事本是 txt 文件的默认程序时 如何告诉 Windows 在写字板中打开 C test test txt 接受的答案对我不起作用 我不确定这是因为我试图运行的程序 还是因为路径中有空格 即使我用引号引起来 或者其他原因 不管怎样 我可
  • 如何使用 Windows forfiles 命令的完整路径运行命令?

    我正在尝试运行以下命令 forfiles p Schemas m xsd c cmd c C Program Files x86 Microsoft SDKs Windows v10 0A bin NETFX 4 6 1 Tools xsd
  • 预注册 ATL 窗口类

    我在一个项目中使用了 ATL 和 WTL 的组合 并从中派生了我自己的类CWindowImpl 看起来像这样 class CMyControl public CWindowImpl
  • 如何在 C# 中从工作线程发布 UI 消息

    我正在用 C 编写一个简单的 winforms 应用程序 我创建了一个工作线程 我希望主窗口响应线程完成其工作 只需更改文本字段中的一些文本 testField Text Ready 我尝试了事件和回调 但它们都在调用线程的上下文中执行 并

随机推荐