SQL存储过程解密

Posted vinsonLu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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表会增加一条记录:

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

以上是关于SQL存储过程解密的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server存储过程文本加密与解密过程详解 2019版可用

sql server 存储过程解密

sql server里面的内容加密了,用啥方法可以解密?

Java调用SQL Server的存储过程详解(转)

sql 这些代码片段将演示如何逐步使用PolyBase。你应该有一个blob存储和存储秘密方便

MSSQL 存储过程加密解密