65.9K
CodeProject 正在变化。 阅读更多。
Home

在运行时拦截 .NET SQL 查询

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.83/5 (9投票s)

2010年8月16日

CPOL

3分钟阅读

viewsIcon

37157

在运行时拦截 .NET SQL 查询 - SQL Management Studio (SQL 管理工作室) 案例。

引言

SQL Server Management Studio (SQL Server 管理工作室) 专为管理员和/或用户与 SQL Server 对象进行快速交互而设计。我们可以通过单击相应的项目来查看这些对象,例如,获取视图或用户。

本文的目的是展示如何通过对汇编语言和指针的快速了解,在没有应用程序源代码的情况下提取有用的信息。您可以将本文应用于在运行时显示任何 .NET 系统的查询。逆向工程以获得乐趣。它也可以应用于 IIS 上的工作进程,用于在没有 Visual Studio 的情况下进行实时调试。

让我们开始吧。您将需要基本的 .NET 调试知识,以及运行时调试工具,如 Windbg。对于 .NET 环境的启发式知识,执行命令的自然方式是 SQLCommand 对象,但我们需要通过检查 Management Studio 进程是否实例化了这个类来确认这一点。让我们开始吧。

步骤

  1. 打开 SQL Server Management Studio (SQL Server 管理工作室)。
  2. 登录到 SQL Server 并执行一些操作,例如查看对象或数据库。
  3. 打开 Windows 调试器工具并附加 SQL Server Management Studio (SQL Server 管理工作室) 进程
  4. 附加后,我们可以在 Windows 调试器中找到一个命令行。
  5. 有一个有用的调试助手,我们可以通过使用它来加载
  6. .loadby sos mscorwks

    SOS WinDbg 扩展允许在低级别探索 .NET 对象,基于正确的 mscorwks。

  7. Execute
  8. !dumpheap -type SqlCommand -stat

    转储 SqlCommand 类型的 .NET 堆 (-type),并获取其统计信息 (-stat)。

  9. 现在我们知道了 .NET 方法表的位置,对于 SqlCommand; 继续探索它封装了哪些方法。使用
  10. !dumpmt -md 6523db08

    解释该命令:给定一个方法表代码,转储方法描述。

  11. 很好,我们有了方法列表及其入口点。许多 .NET SQL 命令使用 ExecuteReader 进行查询执行。我们可以在此搜索
  12. 好的,我们找到了。我们找到了这个函数的入口点。让我们在那里设置一个断点。使用
  13. Bp 651f9c24

    然后按 F5 继续 Management Studio (管理工作室) 执行。

  14. 在调试器仍然附加的情况下,玩转 Management Studio (管理工作室)。通过这样做,您将观察到 Management Studio (管理工作室) 冻结,发生了什么?断点已经被触发。
  15. 现在再次进入 WinDbg
  16. 是的,我们可以确认 Windbg 已经按预期停止了。
  17. 我们可以开始探索托管堆栈对象。要做到这一点,请使用
  18. !dso

    转储堆栈对象

  19. 太棒了!!!现在我们有 SQL 命令的一部分,我们可以观察到堆栈顶部的 SqlCommand。为什么不看看内容呢?要做到这一点,我们可以使用
  20. !do 0c51f004

    解释:!do=转储给定地址的对象,在本例中为 0c51f004。

  21. 在那里转储了有趣的信息,命令文本就在那里。但它位于哪里?答案在偏移量中。我们需要获取当前 SqlCommand+10 的指针,并显示其中包含的字符串 (CommandText)
  22. !do poi(0c51f004+10)

    解释:!do=转储对象,给定指向 0c51f004+10 位置的指针。不错,我们得到了我们期望的。

  23. 0c51f004 是一个固定地址,但这个地址包含哪些记录?让我们回顾一下;只需执行
  24. r

    以显示处理器记录。

  25. 好的,我们可以试试这个
  26. !do poi(ecx+10)

  27. 但正如您所观察到的,我们有很多不是很有用的信息。我们只需要打印字符串查询。我们可以做以下技巧
  28. .printf "%mu",poi(ecx+10)+c

  29. 您可能在问:为什么使用 printf?为什么 %mu? poi(ecx+10)+c? printf 打印一个以 0 结尾的字符串,%mu 打印一个 Unicode 字符串,poi(ecx+10) 很清楚,但为什么 +c?因为字符串类的第一个字符从 +c 偏移量开始。您可以查看另一篇文章来澄清这一点:https://codeproject.org.cn/KB/miscctrl/extractstringprocess.aspx
  30. 我们需要对执行的每个命令都这样做吗?答案是否定的。这就是为什么 WinDbg 具有条件断点的原因。记住我们中断了 SqlReader 命令执行,我们可以使用
  31. bp eip ".printf \"\\n%mu\",poi(ecx+10)+c;gc"

    在当前的 eip 地址(当前执行地址)中断,一旦停止,执行双引号之间的命令(我们对此进行了解释)。完成此操作后,只需按 F5 即可,然后尽情玩转 Management Studio (管理工作室) 并查看 SQL 命令!!!

© . All rights reserved.