sql存储过程的解决方法

 数据库     |      2020-02-27 01:33

1、并未删除原存款和储蓄重新建立,仅仅在决定台做了二个输出,拷贝出来非常不便于。2、对于长度大点的加密数据会解密退步。带着那多个难题来改变此存储进度。先做希图工作,首先供给知道DAC这么个东西, 指的是数据库教程专项使用管理员连接,为大班提供的一种特殊的确诊连接。知道了后得先开采它,以SQL2009为例:右击对象浏览器,找到Facets,点击,如图:找到Sruface Area Configuration,接收RemoteDacEnabled,设为True:然后举办DAC登陆,CMD方式下敲如下命令,不晓得原理的能够自动钻研:sqlcmd -A -S 192.168.1.101 -U sa -P 123456限令提醒行下张开需管理的数据库:USE TESTGO希图稳当,复制寻找获得的贮存进程,生成解密存款和储蓄程,然后大家希图四个加密后的仓库储存进度,当中三个长短十分的大,验证得出结论,短小的存款和储蓄进度便捷即解密成功,并出口,但长度异常的大的却解密失利。接下来看看其何等解密的:先看那句select @maxColID = max(subobjid卡塔尔国,@intEncrypted = imageval FROM sys.sysobjvalues WHERE objid = object_id(@procedure卡塔尔指的是加密后的数额贮存在sys.sysobjvalues表中,其内容寄放于imageval字段。知道了加密后的数据,就得举办解密,它定义了4个第一字段:DECLARE @real_01 nvarchar(max)DECLARE @fake_01 nvarchar(max)DECLARE @fake_encrypt_01 nvarchar(max)DECLARE @real_decrypt_01 nvarchar(maxState of Qatar分别指的原有加密数据内容、原始加密存款和储蓄过程的CREATE语句、自身组织的假的蕴藏进度加密后的数量、末精通密后的贮存进度。其方法是按位将@real_01、@fake_encrypt_01、@real_decrypt_01举行异或运算,此处为啥这么管理,原理不明!!!WHILE @intProcSpace=(datalength(@real_01)/2)BEGIN --xor real fake fake encrypted SET @real_decrypt_01 = stuff(@real_decrypt_01, @intProcSpace, 1, NCHAR(UNICODE(substring(@real_01, @intProcSpace, 1)) ^ (UNICODE(substring(@fake_01, @intProcSpace, 1)) ^UNICODE(substring(@fake_encrypt_01, @intProcSpace, 1State of Qatar卡塔尔国卡塔尔(قطر‎State of Qatar卡塔尔 SET @intProcSpace=@intProcSpace+1END实际上到此甘休,加密后的蕴藏进程已解密出来了。其下部还应该有第一次全国代表大会段语句未有留心切磋,但好些个是选择sp_helptext将内容输出,方法比较繁索,而且没有完成大家要的成效,大家将换一种艺术开展输出。基本上就这么轻易,除了原理不清楚外,基本桐月实现供给,接下去要解决起来建议的三个难题。首先是长度难题,为啥长度第一次全国代表大会就解密失利,来看看@real_decrypt_01的定义并打开领头化@real_decrypt_01的语句:DECLARE @real_decrypt_01 nvarchar(max)SET @real_decrypt_01 = replicate(N'A', (datalength(@real_01State of Qatar /2 State of QatarState of Qatar乍一看没什么难点,但我们使用LEN(@real_decrypt_01卡塔尔输出看看,最大出口长度为4000,可能难点就涌出NVARCHAHighlander的长短上了,理论上NVARCHA福睿斯(MAX卡塔尔(قطر‎支持2G的分寸。为啥会冒出这种意况未有色金属切磋所究过,但有人给出了化解方法,举办显示调换:SET @real_decrypt_01 = replicate(CONVERT(NVARCHAR(MAX), N'A'), (datalength(@real_01卡塔尔 /2 卡塔尔(قطر‎State of Qatar此外的几还应该有几处也是该原因,改进后张开重复运维,难点化解,长度比较大的蕴藏进程也解密成功。第多少个问题消除了,怎么着能方便的输出呢,试验了删消脂新建立,但未成功,那么就用最简便的格局吧,利用xp_cmdshell将内容输出到文本。先创建三个物理表,用于存款和储蓄解密后的数目:

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

然后创建贰个囤积进程,遍历全数加密过的积累进程,调用解密存款和储蓄进度实行解密,解密后输出:

CREATE PROCEDURE [dbo].[DECODE_DATABASE]ASSET NOCOUNT ONBEGIN DECLARE @PROC_NAME VARCHAR(256) SET @PROC_NAME = '' DECLARE @ROWS INT DECLARE @TEMP TABLE( NAME VARCHAR(256) ) INSERT INTO @TEMP SELECT NAME FROM sysobjects WHERE TYPE = 'P' AND NAME NOT IN ( 'DECODE_DATABASE', 'DECODE_PROC' ) SET @ROWS = @@ROWCOUNT WHILE @ROWS  0 BEGIN SELECT @PROC_NAME = NAME FROM ( SELECT ROW_NUMBER() OVER (ORDER by NAME) AS ROW, NAME FROM @TEMP ) T WHERE ROW = @ROWS EXEC [DECODE_PROC] @PROC_NAME PRINT @PROC_NAME SET @ROWS = @ROWS - 1 END RETURN EXEC master..xp_cmdshell 'bcp SELECT [SQLTEXT] FROM TEST.dbo.[SQL_DECODE] queryout C:decode.txt -c -T -S PC2011043012JUJ'ENDGO

最后是改变后的储存进程:

CREATE PROCEDURE [dbo].[DECODE_PROC]( @PROC_NAME SYSNAME = NULL)ASSET NOCOUNT ONDECLARE @PROC_NAME_LEN INT --存储过程名长度DECLARE @MAX_COL_ID SMALLINT --最大列IDSELECT @MAX_COL_ID = MAX(subobjid) FROM sys.sysobjvalues WHERE objid = OBJECT_ID(@PROC_NAME) GROUP BY imagevalSELECT @PROC_NAME_LEN = DATALENGTH(@PROC_NAME) + 29DECLARE @REAL_01 NVARCHAR(MAX) --真实加密存储过程数据DECLARE @FACK_01 NVARCHAR(MAX) --修改为假的存储过程,长度,原理不明?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 BIGINTSET @REAL_DATA_LEN = DATALENGTH(@REAL_01)--PRINT @REAL_DATA_LENDECLARE @FACK_LEN BIGINTSET @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 BIGINTSET @INT_PROC_SPACE = 1WHILE @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 + 1END--移除WITH ENCRYPTIONSET @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_NAMEEXEC(@FACK_01)GO

从那之后,解密全经过大功告成,命令行格局下运营:EXEC [DECODE_DATABASE]GO在C盘根目录下,解密后的积存进程文本生成成功。运营前别忘记展开xp_cmdshell使用权限,同开辟DAC雷同:可能命令行形式下敲如下命令:sp_configure 'show advanced options',1reconfiguregosp_configure 'xp_cmdshell',1reconfigurego

上一篇:一年的第一日等等,常用日期函数 下一篇:没有了