zoukankan      html  css  js  c++  java
  • SQL2005解密已经被加密的存储过程

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

    第一步:打开DAC连接功能

    第二步:在MASTER数据库创建一个解密存储过程

      1 USE master
      2 GO
      3 CREATE PROCEDURE [dbo].[sp__windbi$decrypt]
      4 (
      5   @procedure SYSNAME = NULL ,
      6   @revfl INT = 1
      7 )
      8 AS /**//*
      9 王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
     10 调用形式为:
     11 exec dbo.sp__windbi$decrypt @procedure,0
     12 如果第二个参数使用1的话,会给出该存储过程的一些提示。
     13 --版本4.0  修正存储过程过长解密出来是空白的问题
     14 */
     15 SET NOCOUNT ON
     16 IF @revfl = 1 
     17     BEGIN
     18         PRINT '警告:该存储过程会删除并重建原始的存储过程。'
     19         PRINT ' 在运行该存储过程之前确保你的数据库有一个备份。'
     20         PRINT ' 该存储过程通常应该运行在产品环境的一个备份的非产品环境下。'
     21         PRINT ' 为了运行这个存储过程,将参数@refl的值更改为0。'
     22         RETURN 0
     23     END
     24 DECLARE @intProcSpace BIGINT ,
     25     @t BIGINT ,
     26     @maxColID SMALLINT ,
     27     @procNameLength INT
     28 SELECT  @maxColID = MAX(subobjid)
     29 FROM    sys.sysobjvalues
     30 WHERE   objid = OBJECT_ID(@procedure)
     31 --select @maxColID as 'Rows in sys.sysobjvalues'
     32 SELECT  @procNameLength = DATALENGTH(@procedure) + 29
     33 DECLARE @real_01 NVARCHAR(MAX)
     34 DECLARE @fake_01 NVARCHAR(MAX)
     35 DECLARE @fake_encrypt_01 NVARCHAR(MAX)
     36 DECLARE @real_decrypt_01 NVARCHAR(MAX) ,
     37     @real_decrypt_01a NVARCHAR(MAX)
     38 DECLARE @objtype VARCHAR(2) ,
     39     @ParentName NVARCHAR(MAX)
     40 SELECT  @real_decrypt_01a = ''
     41 --提取对象的类型如是存储过程还是函数,如果是触发器,还要得到其父对象的名称
     42 SELECT  @objtype = type, @parentname = OBJECT_NAME(parent_object_id)
     43 FROM    sys.objects
     44 WHERE   [object_id] = OBJECT_ID(@procedure)
     45 -- 从sys.sysobjvalues里提出加密的imageval记录
     46 SET @real_01 = ( SELECT TOP 1
     47                         imageval
     48                  FROM   sys.sysobjvalues
     49                  WHERE  objid = OBJECT_ID(@procedure) AND valclass = 1
     50                  ORDER BY subobjid
     51                )
     52 --创建一个临时表
     53 CREATE TABLE #output
     54 (
     55   [ident] [int] IDENTITY(1, 1)
     56                 NOT NULL ,
     57   [real_decrypt] NVARCHAR(MAX)
     58 )
     59 ------------------------------------------------------------
     60 
     61 --开始一个事务,稍后回滚
     62 BEGIN TRAN
     63 
     64 --更改原始的存储过程,用短横线替换
     65 IF @objtype = 'P' 
     66     SET @fake_01 = 'ALTER PROCEDURE ' + @procedure + ' WITH ENCRYPTION AS select 1
     67   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
     68                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
     69 ELSE 
     70     IF @objtype = 'FN' 
     71         SET @fake_01 = 'ALTER FUNCTION ' + @procedure + '() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
     72   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
     73                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/ END'
     74     ELSE 
     75         IF @objtype = 'V' 
     76             SET @fake_01 = 'ALTER view ' + @procedure + ' WITH ENCRYPTION AS select 1 as col
     77   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
     78                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
     79         ELSE 
     80             IF @objtype = 'TR' 
     81                 SET @fake_01 = 'ALTER trigger ' + @procedure + ' ON ' + @parentname + 'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
     82   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
     83                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
     84 EXECUTE (@fake_01)
     85 --从sys.sysobjvalues里提出加密的假的
     86 SET @fake_encrypt_01 = ( SELECT TOP 1
     87                                 imageval
     88                          FROM   sys.sysobjvalues
     89                          WHERE  objid = OBJECT_ID(@procedure) AND valclass = 1
     90                          ORDER BY subobjid
     91                        )
     92 IF @objtype = 'P' 
     93     SET @fake_01 = 'Create PROCEDURE ' + @procedure + ' WITH ENCRYPTION AS select 1
     94   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
     95                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
     96 ELSE 
     97     IF @objtype = 'FN' 
     98         SET @fake_01 = 'CREATE FUNCTION ' + @procedure + '() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
     99   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
    100                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/ END'
    101     ELSE 
    102         IF @objtype = 'V' 
    103             SET @fake_01 = 'Create view ' + @procedure + ' WITH ENCRYPTION AS select 1 as col
    104   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
    105                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
    106         ELSE 
    107             IF @objtype = 'TR' 
    108                 SET @fake_01 = 'Create trigger ' + @procedure + ' ON ' + @parentname + 'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
    109   /**//*' + REPLICATE(CAST('*' AS NVARCHAR(MAX)),
    110                       DATALENGTH(@real_01) / 2 - @procNameLength) + '*/'
    111 --开始计数
    112 SET @intProcSpace = 1
    113 --使用字符填充临时变量
    114 SET @real_decrypt_01 = REPLICATE(CAST('A' AS NVARCHAR(MAX)),
    115                                  ( DATALENGTH(@real_01) / 2 ))
    116 --循环设置每一个变量,创建真正的变量
    117 --每次一个字节
    118 SET @intProcSpace = 1
    119 --如有必要,遍历每个@real_xx变量并解密
    120 WHILE @intProcSpace <= ( DATALENGTH(@real_01) / 2 ) 
    121     BEGIN
    122 --真的和假的和加密的假的进行异或处理
    123         SET @real_decrypt_01 = STUFF(@real_decrypt_01, @intProcSpace, 1,
    124                                      NCHAR(UNICODE(SUBSTRING(@real_01,
    125                                                              @intProcSpace, 1)) ^ ( UNICODE(SUBSTRING(@fake_01,
    126                                                               @intProcSpace, 1)) ^ UNICODE(SUBSTRING(@fake_encrypt_01,
    127                                                               @intProcSpace, 1)) )))
    128         SET @intProcSpace = @intProcSpace + 1
    129     END
    130 --通过sp_helptext逻辑向表#output里插入变量
    131 INSERT  #output ( real_decrypt )
    132         SELECT  @real_decrypt_01
    133 --select real_decrypt AS '#output chek' from #output --测试
    134 -- -------------------------------------
    135 --开始从sp_helptext提取
    136 -- -------------------------------------
    137 DECLARE @dbname SYSNAME ,
    138     @BlankSpaceAdded INT ,
    139     @BasePos INT ,
    140     @CurrentPos INT ,
    141     @TextLength INT ,
    142     @LineId INT ,
    143     @AddOnLen INT ,
    144     @LFCR INT --回车换行的长度
    145     ,
    146     @DefinedLength INT ,
    147     @SyscomText NVARCHAR(MAX) ,
    148     @Line NVARCHAR(255)
    149 SELECT  @DefinedLength = 255
    150 SELECT  @BlankSpaceAdded = 0 --跟踪行结束的空格。注意Len函数忽略了多余的空格
    151 CREATE TABLE #CommentText
    152 (
    153   LineId INT ,
    154   Text NVARCHAR(255) COLLATE database_default
    155 )
    156 --使用#output代替sys.sysobjvalues
    157 DECLARE ms_crs_syscom CURSOR LOCAL
    158 FOR
    159 SELECT  real_decrypt
    160 FROM    #output
    161 ORDER BY ident FOR READ ONLY
    162 --获取文本
    163 SELECT  @LFCR = 2
    164 SELECT  @LineId = 1
    165 OPEN ms_crs_syscom
    166 FETCH NEXT FROM ms_crs_syscom INTO @SyscomText
    167 
    168 WHILE @@fetch_status >= 0 
    169     BEGIN
    170         SELECT  @BasePos = 1
    171         SELECT  @CurrentPos = 1
    172         SELECT  @TextLength = LEN(@SyscomText)
    173         WHILE @CurrentPos != 0 
    174             BEGIN
    175         --通过回车查找行的结束
    176                 SELECT  @CurrentPos = CHARINDEX(CHAR(13) + CHAR(10),
    177                                                 @SyscomText, @BasePos)
    178         --如果找到回车
    179                 IF @CurrentPos != 0 
    180                     BEGIN
    181                 --如果@Lines的长度的新值比设置的大就插入@Lines目前的内容并继续
    182                         WHILE ( ISNULL(LEN(@Line), 0) + @BlankSpaceAdded + @CurrentPos - @BasePos + @LFCR ) > @DefinedLength 
    183                             BEGIN
    184                                 SELECT  @AddOnLen = @DefinedLength - ( ISNULL(LEN(@Line),
    185                                                               0) + @BlankSpaceAdded )
    186                                 INSERT  #CommentText
    187                                 VALUES  ( @LineId,
    188                                           ISNULL(@Line, N'') + ISNULL(SUBSTRING(@SyscomText,
    189                                                               @BasePos,
    190                                                               @AddOnLen), N'') )
    191                                 SELECT  @Line = NULL, @LineId = @LineId + 1,
    192                                         @BasePos = @BasePos + @AddOnLen,
    193                                         @BlankSpaceAdded = 0
    194                             END
    195                         SELECT  @Line = ISNULL(@Line, N'') + ISNULL(SUBSTRING(@SyscomText,
    196                                                               @BasePos,
    197                                                               @CurrentPos - @BasePos + @LFCR),
    198                                                               N'')
    199                         SELECT  @BasePos = @CurrentPos + 2
    200                         INSERT  #CommentText
    201                         VALUES  ( @LineId, @Line )
    202                         SELECT  @LineId = @LineId + 1
    203                         SELECT  @Line = NULL
    204                     END
    205                 ELSE
    206 --如果回车没找到
    207                     BEGIN
    208                         IF @BasePos <= @TextLength 
    209                             BEGIN
    210                         --如果@Lines长度的新值大于定义的长度
    211                                 WHILE ( ISNULL(LEN(@Line), 0) + @BlankSpaceAdded + @TextLength - @BasePos + 1 ) > @DefinedLength 
    212                                     BEGIN
    213                                         SELECT  @AddOnLen = @DefinedLength - ( ISNULL(LEN(@Line),
    214                                                               0) + @BlankSpaceAdded )
    215                                         INSERT  #CommentText
    216                                         VALUES  ( @LineId,
    217                                                   ISNULL(@Line, N'') + ISNULL(SUBSTRING(@SyscomText,
    218                                                               @BasePos,
    219                                                               @AddOnLen), N'') )
    220                                         SELECT  @Line = NULL,
    221                                                 @LineId = @LineId + 1,
    222                                                 @BasePos = @BasePos + @AddOnLen,
    223                                                 @BlankSpaceAdded = 0
    224                                     END
    225                                 SELECT  @Line = ISNULL(@Line, N'') + ISNULL(SUBSTRING(@SyscomText,
    226                                                               @BasePos,
    227                                                               @TextLength - @BasePos + 1),
    228                                                               N'')
    229                                 IF LEN(@Line) < @DefinedLength AND CHARINDEX(' ',
    230                                                               @SyscomText,
    231                                                               @TextLength + 1) > 0 
    232                                     BEGIN
    233                                         SELECT  @Line = @Line + ' ',
    234                                                 @BlankSpaceAdded = 1
    235                                     END
    236                             END
    237                     END
    238             END
    239         FETCH NEXT FROM ms_crs_syscom INTO @SyscomText
    240     END
    241     
    242     
    243 IF @Line IS NOT NULL 
    244     INSERT  #CommentText
    245     VALUES  ( @LineId, @Line )
    246 SELECT  Text
    247 FROM    #CommentText
    248 ORDER BY LineId
    249 CLOSE ms_crs_syscom
    250 DEALLOCATE ms_crs_syscom
    251 DROP TABLE #CommentText
    
    252 -- -------------------------------------
    253 --结束从sp_helptext提取
    254 -- -------------------------------------
    255 --删除用短横线创建的存储过程并重建原始的存储过程
    256 ROLLBACK TRAN
    257 DROP TABLE #output
    258 GO

    第三步:在新建查询的时候选择DAC连接

    不明白的可以看一下这篇文章:SQLSERVER数据库管理员的专用连接DAC

    第四步:执行之前点击一下“以文本格式显示结果”按钮

    我这里被加密的存储过程存放在pratice数据库

    1 USE PRATICE
    2 GO
    3 EXEC master.dbo.sp__windbi$decrypt 'dbo.creat_test_Encryption', 0

    第五步:执行刚才创建的存储过程,代入被加密的存储过程的名字然后执行查询

    可以看到creat_test_Encryption这个存储过程里面的内容还是比较少的

    只有一句select top 100 * from dbo.test13


    为什麽需要使用DAC连接???

    因为如果不用DAC连接是访问不了系统表的,执行的时候会报错

    1 消息 208,级别 16,状态 1,过程 sp__windbi$decrypt,第 262 对象名 'sys.sysobjvalues' 无效。

    网上说就算存储过程里的内容非常长也能解密出来,不会出现空白或者横线的情况

    至于是不是,大家可以测试一下

    如有不对的地方,欢迎大家拍砖o(∩_∩)o

  • 相关阅读:
    Java之Map遍历方式性能分析:ketSet与entrySet
    Java之null保留字
    Java之&0xff用法解析以及原码、反码、补码相关知识
    Android之使用apt编写编译时注解
    Android之ViewPager.PageTransformer
    Android Studio利用javac导出Api文档
    06_Java多线程、线程间通信
    05_Java异常(Exception)
    04_Java面向对象特征之继承与多态
    03_Java面向对象特征: 封装性
  • 原文地址:https://www.cnblogs.com/lyhabc/p/3384906.html
Copyright © 2011-2022 走看看