sqlserver 属性 TextHeader 不可用于 StoredProcedure“[dbo].[x]”该对象可能没有此属性,也可能是访问权限不足而无法检索。 该文本已加密。

本文介绍了解决SQL Server中存储过程加密问题的方法。通过使用SQL Server的DAC功能登录数据库,并创建专门的解密存储过程,可以恢复加密的存储过程为非加密状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

打开sqlserver proc 存储过程错误:属性 TextHeader 不可用于 StoredProcedure“[dbo].[x]”。该对象可能没有此属性,也可能是访问权限不足而无法检索。  该文本已加密。 (Microsoft.SqlServer.Smo),提示如下图错误:

注:本文基于SQLserver 2008R2,其他版本没有测试过

解决方法:

1、使用原有数据库从新导出非加密脚本重新建立数据库(略过)

2、使用解密proc方式从新生成proc脚本

步骤整理:

1、使用sql dac功能登录数据库,首先要启用dac,否则会报错:不支持专用管理员连接

1
2
3
4
5
6
7
USE master;
GO
SP_CONFIGURE 'remote admin connections' ;
SP_CONFIGURE 'remote admin connections' , 1; --0 表示仅允许本地连接使用 DAC,1表示允许远程连接使用 DAC
GO
RECONFIGURE WITH OVERRIDE;
GO

选择新建连接->数据库引擎查询,然后输入admin:机器名登录即可。


连接中可能出现如下错误:

这说明已经连接过并成功,不能再次连接,也可以使用sql配置管理器重启sqlserver服务,从新来过

2、成功使用DAC功能登录后,如下图:


3、选择要解密操作的数据库

4、创建解密存储表

1
2
3
4
5
6
7
8
9
CREATE TABLE [dbo].[SQL_DECODE]
     (
       [ID] [ INT ] IDENTITY(1, 1)
                  NOT NULL ,
       [SQLTEXT] [NVARCHAR]( MAX ) NOT NULL ,
       CONSTRAINT [ID] PRIMARY KEY CLUSTERED ( [ID] ASC )
     )
ON  [ PRIMARY ]
GO
5、创建解密proc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
CREATE PROCEDURE [dbo].[DECODE_PROC]
     (
       @PROC_NAME SYSNAME = NULL
     )
AS
     SET NOCOUNT ON
 
     DECLARE @PROC_NAME_LEN INT    --存储过程名长度
     DECLARE @MAX_COL_ID SMALLINT    --最大列ID
     SELECT  @MAX_COL_ID = MAX (subobjid)
     FROM    sys.sysobjvalues
     WHERE   objid = OBJECT_ID(@PROC_NAME)
     GROUP BY imageval
 
     SELECT  @PROC_NAME_LEN = DATALENGTH(@PROC_NAME) + 29
     DECLARE @REAL_01 NVARCHAR( MAX )    --真实加密存储过程数据
     DECLARE @FACK_01 NVARCHAR( MAX )    --修改为假的存储过程,长度(40003 - 存在过程名长度),原理不明?
     DECLARE @FACK_ENCRYPT_01 NVARCHAR( MAX )    --伪加密存储过街程数据
     DECLARE @REAL_DECRYPT_01 NVARCHAR( MAX )    --最终解密后的数据,初始化为原始加密长度的一半的“A”,原理不明?
 
     SET @REAL_01 = ( SELECT imageval
                      FROM   sys.sysobjvalues
                      WHERE  objid = OBJECT_ID(@PROC_NAME)
                             AND valclass = 1
                             AND subobjid = 1
                    )
 
     DECLARE @REAL_DATA_LEN BIGINT
     SET @REAL_DATA_LEN = DATALENGTH(@REAL_01)
--PRINT @REAL_DATA_LEN
 
     DECLARE @FACK_LEN BIGINT
     SET @FACK_LEN = @REAL_DATA_LEN * 10    --改造:假的长度在原真实数据长度上放大10倍
 
--此处需将NVARCHAR显示转换成NVARCHAR(MAX),不然将只能产生4K长度
     SET @FACK_01 = 'ALTER PROCEDURE ' + @PROC_NAME + ' WITH ENCRYPTION AS '
         + REPLICATE( CONVERT (NVARCHAR( MAX ), '-' ), @FACK_LEN - @PROC_NAME_LEN)
--PRINT '@FACK_01 = ' + STR(LEN(@FACK_01))
     EXECUTE (@FACK_01)
     SET @FACK_ENCRYPT_01 = ( SELECT imageval
                              FROM   sys.sysobjvalues
                              WHERE  objid = OBJECT_ID(@PROC_NAME)
                                     AND valclass = 1
                                     AND subobjid = 1
                            )
 
     SET @FACK_01 = 'CREATE PROCEDURE ' + @PROC_NAME + ' WITH ENCRYPTION AS '
         + REPLICATE( CONVERT ( VARCHAR ( MAX ), '-' ), @FACK_LEN - @PROC_NAME_LEN)
     SET @REAL_DECRYPT_01 = REPLICATE( CONVERT (NVARCHAR( MAX ), N 'A' ),
                                      ( DATALENGTH(@REAL_01) / 2 ))
--PRINT 'LEN(@REAL_DECRYPT_01) = ' + STR(LEN(@REAL_DECRYPT_01))
 
 
--按位对 @REAL_01、 @FACK_01、 @REAL_DECRYPT_01 进行异或操作。
     DECLARE @INT_PROC_SPACE BIGINT
     SET @INT_PROC_SPACE = 1
     WHILE @INT_PROC_SPACE <= ( DATALENGTH(@REAL_01) / 2 )
         BEGIN
             SET @REAL_DECRYPT_01 = STUFF(@REAL_DECRYPT_01, @INT_PROC_SPACE, 1,
                                          NCHAR (UNICODE( SUBSTRING (@REAL_01,
                                                               @INT_PROC_SPACE,
                                                               1))
                                                ^ ( UNICODE( SUBSTRING (@FACK_01,
                                                               @INT_PROC_SPACE,
                                                               1))
                                                    ^ UNICODE( SUBSTRING (@FACK_ENCRYPT_01,
                                                               @INT_PROC_SPACE,
                                                               1)) )))
             SET @INT_PROC_SPACE = @INT_PROC_SPACE + 1
         END
 
--移除WITH ENCRYPTION
     SET @REAL_DECRYPT_01 = REPLACE (@REAL_DECRYPT_01, 'WITH ENCRYPTION' , '' )
     INSERT  INTO [SQL_DECODE]
     VALUES  ( @REAL_DECRYPT_01 )
 
--PRINT '@REAL_DECRYPT_01 = ' + @REAL_DECRYPT_01
--PRINT 'LEN(@REAL_DECRYPT_01) = ' + STR(LEN(@REAL_DECRYPT_01))
 
--删除原存储过程
     SET @FACK_01 = 'DROP PROCEDURE ' + @PROC_NAME
     EXEC (@FACK_01)
 
GO
6、执行解密proc

1
EXEC dbo.DECODE_PROC 'proc名称'

7、查询解密存储表,会发现已经存储了要解密的proc脚本

8、将脚本拷贝到查询窗口格式化后无误,执行创建即可,原加密proc被删除了已经,新的proc已经不带有加密锁标记了


参考整理:

SQLSERVER数据库管理员的专用连接DAC 

SQL2005解密已经被加密的存储过程

[SQL Server 2005/2008]专用管理员连接(DAC)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值