zoukankan      html  css  js  c++  java
  • SQL存储过程解密

    转载:

    首先要建立一张表和一个存储过程:

    SQL_DECODE表:
    复制代码
    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
    复制代码
    DECODE_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
    复制代码

    然后使用DAC登录数据库:admin:计算机名称,需要在数据库所在的电脑登录,不能使用客户端远程操作这些步骤。

    如果不成功,可以先windows身份登录,新建查询,然后更改链接使用admin:计算机名称登录。

    然后执行存储过程:

    exec dbo.DECODE_PROC '存储过程名'

    如果执行成功,SQL_DECODE表会增加一条记录:

    复制里面的内容出来就解密后的存储过程了。

    vinson

     

  • 相关阅读:
    PHP面试题(二)
    机房的带外管理---远程管理你的开发测试机
    《Qt编程的艺术》——8.2.1 在Designer中使用View类
    一步一步学android之事件篇——单击事件
    OC类方法和实例方法 及常用的for/in方法
    终止imp/exp和expdp/impdp进程运行的方法
    java MessageFormat 应用 和 疑惑
    菜鸟成长日记之新手备忘录-IOS开发第一个项目总结
    视频监控之VSCloud版本计划
    ural 1136. Parliament
  • 原文地址:https://www.cnblogs.com/lairui1232000/p/9185948.html
Copyright © 2011-2022 走看看