【发布时间】:2021-03-20 10:00:39
【问题描述】:
【问题讨论】:
标签: sql-server ssms .net-assembly sandbox sqlclr
【问题讨论】:
标签: sql-server ssms .net-assembly sandbox sqlclr
如何在另一个 SQL Server 实例上进行逆向工程和/或重现它们的答案在于 SQL Server 中的程序集以字节形式存储在表中:sys.assembly_files。当您拥有这些字节时,您可以通过以下方式在另一个服务器实例上部署:
CREATE ASSEMBLY YourAssemblyName
FROM the-assembly-bytes-from-the-table
WITH PERMISSION_SET = ...
对于逆向工程,您可以从 - 例如 - C# 控制台应用程序中读取字节,然后从字节中创建 FileStream 并将 FileStream 作为 .dll 文件写入磁盘:
static void Main(string[] args)
{
string connString = "server=someServer;database=someDb;uid=<uid>;pwd=<pwd>;";
string cmdString = "SELECT content FROM sys.assembly_files WHERE assembly_id = 65540 AND
file_id = 1";
string filePath = @"<some-path-and-filename>";
SqlBytes bytes;
using (SqlConnection conn = new SqlConnection(connString))
{
conn.Open();
using (SqlCommand cmd = conn.CreateCommand())
{
cmd.CommandText = cmdString;
cmd.CommandType = System.Data.CommandType.Text;
SqlDataReader reader = cmd.ExecuteReader();
reader.Read();
bytes = reader.GetSqlBytes(0);
}
}
// write the byte stream out to disk
FileStream bytestream = new FileStream(filePath, FileMode.CreateNew);
bytestream.Write(bytes.Value, 0, (int)bytes.Length);
bytestream.Close();
}
在上面的代码中,我通过在 sys.assemblies 中查找程序集的名称来确定程序集的 ID。
将字节写入 dll 后,您可以使用 dotPeek 等工具对 dll 进行逆向工程。
【讨论】:
您可以通过在对象资源管理器中右键单击它(即问题中的屏幕截图)并选择“将程序集编写为...”,在 SSMS 中编写程序集本身的脚本。
但是,这只会获取程序集,而不是 T-SQL 包装对象,这些对象将程序集中的方法公开为 T-SQL 存储过程、函数等。您可以使用我在其他 S.O. 中发布的查询来获取这些对象。答案:
SQL Server: How to list all CLR functions/procedures/objects for assembly
根据您使用的 SQL Server 版本和/或程序集需要是什么PERMISSION_SET,您可能需要处理安全性。程序集总是有可能已经签名并且在[master] DB 中有一个关联的非对称密钥。有几种方法可以做到这一点,可能需要更长的讨论时间,所以现在这里有一些资源:
TRUSTWORTHY
TRUSTWORTHY
[master]
UNSAFE ASSEMBLY权限TRUSTWORTHY
有关 SQL Server 2017 及更高版本的更多详细信息,请参阅我在 S.O. 上对以下问题的回答:
CLR Strict Security on SQL Server 2017
有关使用 SQLCLR 的更多信息,请访问:SQLCLR Info
【讨论】: