回到頂部

sqlserver 屬性 TextHeader 不可用于 StoredProcedure“[dbo].[x]”該對象可能沒有此屬性,也可能是訪問權限不足而無法檢索。 該文本已加密。

時間:3年前   作者:龐順龍   瀏覽:4080   [站內原創,轉載請注明出處]

標簽: SQL Server  

打開sqlserver proc 存儲過程錯誤:屬性 TextHeader 不可用于 StoredProcedure“[dbo].[x]”。該對象可能沒有此屬性,也可能是訪問權限不足而無法檢索。  該文本已加密。 (Microsoft.SqlServer.Smo),提示如下圖錯誤:

注:本文基于SQLserver 2008R2,其他版本沒有測試過

解決方法:

1、使用原有數據庫從新導出非加密腳本重新建立數據庫(略過)

2、使用解密proc方式從新生成proc腳本

步驟整理:

1、使用sql dac功能登錄數據庫,首先要啟用dac,否則會報錯:不支持專用管理員連接

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、創建解密存儲表

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

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

EXEC dbo.DECODE_PROC 'proc名稱'

7、查詢解密存儲表,會發現已經存儲了要解密的proc腳本

8、將腳本拷貝到查詢窗口格式化后無誤,執行創建即可,原加密proc被刪除了已經,新的proc已經不帶有加密鎖標記了


參考整理:

SQLSERVER數據庫管理員的專用連接DAC 

SQL2005解密已經被加密的存儲過程

[SQL Server 2005/2008]專用管理員連接(DAC)

龐順龍最后編輯于:3年前

內容均為作者獨立觀點,不代表八零IT人立場,如涉及侵權,請及時告知。

評論努力加載中...
暫無評論
暫無評論

手機掃碼閱讀

熱門相關

加載中...
關于我們   聯系我們   申請友鏈   贊助記錄   站點地圖
? 2014 - 2017 www.1255315.live All Rights Reserved. 京ICP備14042174號-1
本站遵循 CC BY 4.0 協議,轉載請注明出處 。
辽宁十一选五走实图 上海天天彩选4官网 安徽11选5分布走势图 云南十一选五开奖 多乐彩稳赚技巧 陕西快乐10分中奖规则金额 新联电子股票 万科股票分析报告 贵州十一选五平台有哪些 快3开奖结果查询 北京时时彩平台总代理