首先要建立一張表和一個存儲過程:
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表會增加一條記錄:
復制里面的內容出來就解密后的存儲過程了。