WinDebug查看C#程序运行内存中的数据库连接字符串

笔记哥 / 04-17 / 8点赞 / 0评论 / 506阅读
> > > 真巧,昨天刷到了大佬“一线码农”的视频,大概就是讲的有人找他破解一个混淆加密的数据库连接字符串,然后大佬也提供了方案就是用WinDebug查看内存中的数据。这其实本质上就是一个用WinDebug查看对象字符串字段具体内容的需求,为啥要取这个标题?当然是骗人点进来啦 > 目录 - 准备工作(环境) - 编写demo代码 - 程序启动后转储为dump文件 - WinDebug分析DUMP文件 - 加载sos符号 - 寻找SqlConnection对象 - 查看实例细节 - 查看连接字符串 #### 准备工作(环境) - .net 8 - visual studio 2022 - sql server (非必须) #### 编写demo代码 ```csharp SqlConnection sqlConnection = new SqlConnection(); sqlConnection.ConnectionString = "server=127.0.0.1;database=****;uid=sa;pwd=123456;Pooling=true;TrustServerCertificate=True;"; try { sqlConnection.Open(); SqlCommand command = sqlConnection.CreateCommand(); command.Connection = sqlConnection; command.CommandText = "SELECT * FROM FAB_OHT"; var reader = command.ExecuteReader(); while (reader.Read()) { Console.WriteLine(reader["OHT_ID"].ToString()); } } finally { sqlConnection.Close(); } Console.Read(); ``` #### 程序启动后转储为dump文件 ![image](https://cdn.res.knowhub.vip/c/2504/18/94eafbc8.png?G1cAAETn9LwUqAjLvtMdbIlTE20GLNIIKiWs13vO2jfR9wcYmp%2fR%2boz94TetzyApbCYgMCorUhAXg1VXRxJxU%2fdLPa8R) #### WinDebug分析DUMP文件 在WinDebug中导入Dump文件 ##### 加载sos符号 ```csharp .load C:\Users\bruce.qiu\.dotnet\sos\sos.dll ``` ##### 寻找SqlConnection对象 ```csharp !dumpheap -type Microsoft.Data.SqlClient.SqlConnection ``` ![image](https://cdn.res.knowhub.vip/c/2504/18/0fcbaa4c.png?G1cAAETn9LwUKMCSfac72BKnJtoMWKQRVEpYr%2fectW%2bi708wrD6j9Zn7w29an0miHCEgMJwNJcgloQ5RjyKCMDY11DUS) 可以看到Microsoft.Data.SqlClient.SqlConnection的类型方法表对应的地址为 **7ff995723580** ,然后看到上面的类型只有一个对应的方法表是这个,可以断定这个类型实例就是代码中的SqlConnection实例。 ##### 查看实例细节 实例的地址为 **017ce380b030** ```csharp !do 017ce380b030 ``` ![image](https://cdn.res.knowhub.vip/c/2504/18/b41edc08.png?G1cAAMT0bJxoe6rENvqh%2f4lHQjNgkUZQKWG93nv3aUTf72BofGYfy8%2bH3%2fSxnCSxmYDAyKwIQYpYqtBcc4CwGEO5xD0d) 找到对象实例的连接字符的对象地址。 ##### 查看连接字符串 ```csharp !do 000001bd757e04c0 ``` ![image](https://cdn.res.knowhub.vip/c/2504/18/4180d5e2.png?G1cAAGQ9a5zoq1Lb6IbeJQ4JzYBFGkGlhPV6792nAXx%2fMLLmZ%2fax4nz4TR8rgATNiIGRCypSoEomLmaoiUnRxSt53jMA) 可以看到字符串的基本结构,除了方法表和对象头之外,包含了字符串长度,首字符。 可以看到字符串首字符的偏移为c,也就是0xC,大概就是该对象的第12位开始就是字符串的具体内容。 ```csharp .printf "%mu", 000001bd757e04c0+0xC ``` ![image](https://cdn.res.knowhub.vip/c/2504/18/852397c5.png?G1YAAMTsdJzIJyKq26hD2jvFHc2ARBZBpYT1es9Z%2byb6fheIxme0Pn1%2f%2bEvr04kTzFhIIBmK4LmwaQJf0JA5wURrjWs4) 这个命令就是从字符串的地址开始,取内容的偏移, 后面的+0xC就是移动了相应的偏移,偏移则是图中的offset. 至于为什么正好取到字符串长度而不越界,是因为调试器会根据字符串对象存储的长度来安全的截取长度。