2010-07-08

SQL Server 2000 解碼 Stored Procedure

要救回以往加密過的 Stored Procedure 嗎?以下的是編排過的程序,只適用於 SQL Server 2000 環境。我改的地方不多,主要是變排整齊一點。Line.73.增加我要的程式碼 Drop 的部分。Line.132.增加了程式碼結尾的部分。Line.140.與原作者的前後順序調換了一下。這一行也修正了在某些狀況下、伺服器內的程序被異動了而無法回復,但該程序依舊可以執行。或是該程序的『參數』被抹去了、或是該程序一樣會被破壞。

if exists (select * 
             from dbo.sysobjects 
            where id = object_id(N'dbo.sp_decrypt') 
              and OBJECTPROPERTY(id, N'IsProcedure') = 1)
drop procedure dbo.sp_decrypt
GO

/************* 解密存储过程 **********
------------------------sql2000大于40000的-----------------
原作:j9988 号:J老师
*/
CREATE PROCEDURE dbo.sp_decrypt (@objectName varchar(50))
AS
begin

begin transaction --add by playyuer

  DECLARE @objectname1 varchar(100)
  DECLARE @sql1 nvarchar(4000),
          @sql2 nvarchar(4000),
          @sql3 nvarchar(4000),
          @sql4 nvarchar(4000),
          @sql5 nvarchar(4000),
          @sql6 nvarchar(4000),
          @sql7 nvarchar(4000),
          @sql8 nvarchar(4000),
          @sql9 nvarchar(4000),
          @sql10 nvarchar(4000)  
  DECLARE @OrigSpText1 nvarchar(4000),  
          @OrigSpText2 nvarchar(4000), 
          @OrigSpText3 nvarchar(4000), 
          @resultsp nvarchar(4000)
  DECLARE @i int, 
          @t bigint,
          @m int, 
          @n int, 
          @q int
  
  set @m=(SELECT max(colid) 
            FROM syscomments  
           WHERE id = object_id(@objectName))
  set @n=1
  
  --get encrypted data
  create table #temp(
         colid int,
         ctext varbinary(8000)
  )
  
  insert #temp 
  SELECT colid, ctext 
    FROM syscomments  
   WHERE id = object_id(@objectName)
  
  set @sql1 = 'ALTER PROCEDURE '+ @objectName +' WITH ENCRYPTION AS '
--set @sql1 = 'ALTER PROCEDURE '+ @objectName +' WITH ENCRYPTION AS '
  set @q = len(@sql1)
  set @sql1 = 
         @sql1 + REPLICATE('-', 4000-@q)
  select @sql2 = REPLICATE('-', 4000), 
         @sql3 = REPLICATE('-', 4000),
         @sql4 = REPLICATE('-', 4000),
         @sql5 = REPLICATE('-', 4000),
         @sql6 = REPLICATE('-', 4000),
         @sql7 = REPLICATE('-', 4000),
         @sql8 = REPLICATE('-', 4000),
         @sql9 = REPLICATE('-', 4000),
         @sql10 = REPLICATE('-',4000)

  exec(@sql1+@sql2+@sql3+@sql4+@sql5+@sql6+@sql7+@sql8+@sql9+@sql10)

  -- Add by Jasper.hsia
  print 'if exists (select * '
  print '             from dbo.sysobjects '
  print '            where id = object_id(N'''+@objectName+''') '
  print '              and OBJECTPROPERTY(id, N''IsProcedure'') = 1)'
  print 'drop procedure ' + @objectName
  print 'GO'
  print ''

  while @n<=@m
  begin
    SET @OrigSpText1 = (SELECT ctext 
                          FROM #temp  
                         WHERE colid=@n)
    SET @objectname1 = @objectname + '_t'
    SET @OrigSpText3 = (SELECT ctext 
                          FROM syscomments 
                         WHERE id = object_id(@objectName) 
                           and colid = @n)
    if @n = 1
    begin
      SET @OrigSpText2 = 
            'CREATE PROCEDURE '+ @objectName + ' WITH ENCRYPTION AS '--
      SET @q = 4000 - len(@OrigSpText2)
      SET @OrigSpText2 = @OrigSpText2 + REPLICATE('-',@q)
    end
    else
    begin
      SET @OrigSpText2 = REPLICATE('-', 4000)
    end

    --start counter
    SET @i=1
  
    --fill temporary variable
    SET @resultsp = replicate(N'A', (datalength(@OrigSpText1) / 2))
  
    --loop
    WHILE @i <= datalength(@OrigSpText1)/2
    BEGIN
      --reverse encryption (XOR original+bogus+bogus encrypted)
      SET @resultsp = 
            stuff(@resultsp, @i, 1, NCHAR(UNICODE(substring(@OrigSpText1, @i, 1)) ^
            (UNICODE(substring(@OrigSpText2, @i, 1)) ^ UNICODE(substring(@OrigSpText3, @i, 1)))))
      SET @i=@i+1
    END
  
    --drop original SP
    --EXECUTE ('drop PROCEDURE '+ @objectName)
    --remove encryption
    --preserve case
    SET @resultsp=REPLACE((@resultsp),'WITH ENCRYPTION', '')
    SET @resultsp=REPLACE((@resultsp),'With Encryption', '')
    SET @resultsp=REPLACE((@resultsp),'with encryption', '')

    --replace Stored procedure without enryption
    IF CHARINDEX('WITH ENCRYPTION',UPPER(@resultsp) )>0 
      SET @resultsp = REPLACE(UPPER(@resultsp),'WITH ENCRYPTION', '')

    -- Append 'GO' by Jasper.hsia
    print @resultsp + 'GO'

    --execute( @resultsp)
    set @n = @n+1
  end
  drop table #temp

  -- Change Below 2 Line Order by Jasper.hsia
  rollback transaction --add by playyuer
end

GO

/*
适合40000字符。
每次4000 print出来,自已贴。
切记:我见过的解过程都是对原过程进行破坏。破解前一定要备份!!!!
超过40000的,自已加SQL(我上面用SQL.SQL2--SQL10)
超长的可加SQL11--sql20........
*/

使用範例:
sp_decrypt 'dbo.AccFA2AccLaw'

WITH ENCRYPTION

沒有留言: