天天看點

sql server 2005/2008 加密存儲過程解密參考2使用DAC(專用管理者連接配接)連接配接到資料庫

sql server 2005 以上存儲過程無法進行檢視和編輯,網上找了個解密存儲過程,代碼如下:

Create PROCEDURE [dbo].[sp_windbi$decrypt]
(@procedure sysname = NULL, @revfl int = 1)
AS
/**//*
王成輝翻譯整理,轉貼請注明出自微軟BI開拓者www.windbi.com
調用形式為:
exec dbo.sp__windbi$decrypt @procedure,0
如果第二個參數使用1的話,會給出該存儲過程的一些提示。
--版本4.0  修正存儲過程過長解密出來是空白的問題
*/
SET NOCOUNT ON
IF @revfl = 1
BEGIN
PRINT '警告:該存儲過程會删除并重建原始的存儲過程。'
PRINT ' 在運作該存儲過程之前確定你的資料庫有一個備份。'
PRINT ' 該存儲過程通常應該運作在産品環境的一個備份的非産品環境下。'
PRINT ' 為了運作這個存儲過程,将參數@refl的值更改為0。'
RETURN 0
END
DECLARE @intProcSpace bigint, @t bigint, @maxColID smallint,@procNameLength int
select @maxColID = max(subobjid) FROM
sys.sysobjvalues WHERE objid = object_id(@procedure)
--select @maxColID as 'Rows in sys.sysobjvalues'
select @procNameLength = datalength(@procedure) + 29
DECLARE @real_01 nvarchar(max)
DECLARE @fake_01 nvarchar(max)
DECLARE @fake_encrypt_01 nvarchar(max)
DECLARE @real_decrypt_01 nvarchar(max),@real_decrypt_01a nvarchar(max)
declare @objtype varchar(2),@ParentName nvarchar(max)
select @real_decrypt_01a = ''
--提取對象的類型如是存儲過程還是函數,如果是觸發器,還要得到其父對象的名稱
select @objtype=type,@parentname=object_name(parent_object_id)
from sys.objects where [object_id]=object_id(@procedure)
-- 從sys.sysobjvalues裡提出加密的imageval記錄
SET @real_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
object_id(@procedure) and valclass = 1 order by subobjid)

--建立一個臨時表
create table #output ( [ident] [int] IDENTITY (1, 1) NOT NULL ,
[real_decrypt] NVARCHAR(MAX) )
--開始一個事務,稍後復原
BEGIN TRAN
--更改原始的存儲過程,用短橫線替換
if @objtype='P'
  SET @fake_01='ALTER PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
else if @objtype='FN'
  SET @fake_01='ALTER FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'
else if @objtype='V'
  SET @fake_01='ALTER view '+ @procedure +' WITH ENCRYPTION AS select 1 as col
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
else if @objtype='TR'
  SET @fake_01='ALTER trigger '+ @procedure +' ON '[email protected]+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
EXECUTE (@fake_01)
--從sys.sysobjvalues裡提出加密的假的
SET @fake_encrypt_01=(SELECT top 1 imageval FROM sys.sysobjvalues WHERE objid =
object_id(@procedure) and valclass = 1 order by subobjid )
if @objtype='P'
  SET @fake_01='Create PROCEDURE '+ @procedure +' WITH ENCRYPTION AS select 1
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
else if @objtype='FN'
  SET @fake_01='CREATE FUNCTION '+ @procedure +'() RETURNS INT WITH ENCRYPTION AS BEGIN RETURN 1
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/ END'
else if @objtype='V'
  SET @fake_01='Create view '+ @procedure +' WITH ENCRYPTION AS select 1 as col
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
else if @objtype='TR'
  SET @fake_01='Create trigger '+ @procedure +' ON '[email protected]+'WITH ENCRYPTION AFTER INSERT AS RAISERROR (''N'',16,10)
  /**//*'+REPLICATE(cast('*'as nvarchar(max)), datalength(@real_01) /2 - @procNameLength)+'*/'
--開始計數
SET @intProcSpace=1
--使用字元填充臨時變量
SET @real_decrypt_01 = replicate(cast('A'as nvarchar(max)), (datalength(@real_01) /2 ))
--循環設定每一個變量,建立真正的變量
--每次一個位元組
SET @intProcSpace=1
--如有必要,周遊每個@real_xx變量并解密
WHILE @intProcSpace<=(datalength(@real_01)/2)
BEGIN
--真的和假的和加密的假的進行異或處理
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, 1)))))
SET @[email protected]+1
END


--通過sp_helptext邏輯向表#output裡插入變量
insert #output (real_decrypt) select @real_decrypt_01
--select real_decrypt AS '#output chek' from #output --測試
-- -------------------------------------
--開始從sp_helptext提取
-- -------------------------------------
declare @dbname sysname
,@BlankSpaceAdded int
,@BasePos int
,@CurrentPos int
,@TextLength int
,@LineId int
,@AddOnLen int
,@LFCR int --回車換行的長度
,@DefinedLength int
,@SyscomText nvarchar(max)
,@Line nvarchar(255)
Select @DefinedLength = 255
SELECT @BlankSpaceAdded = 0 --跟蹤行結束的空格。注意Len函數忽略了多餘的空格
CREATE TABLE #CommentText
(LineId int
,Text nvarchar(255) collate database_default)
--使用#output代替sys.sysobjvalues
DECLARE ms_crs_syscom CURSOR LOCAL
FOR SELECT real_decrypt from #output
ORDER BY ident
FOR READ ONLY
--擷取文本
SELECT @LFCR = 2
SELECT @LineId = 1
OPEN ms_crs_syscom
FETCH NEXT FROM ms_crs_syscom into @SyscomText
WHILE @@fetch_status >= 0
BEGIN
SELECT @BasePos = 1
SELECT @CurrentPos = 1
SELECT @TextLength = LEN(@SyscomText)
WHILE @CurrentPos != 0
BEGIN
--通過回車查找行的結束
SELECT @CurrentPos = CHARINDEX(char(13)+char(10), @SyscomText,
@BasePos)
--如果找到回車
IF @CurrentPos != 0
BEGIN
--如果@Lines的長度的新值比設定的大就插入@Lines目前的内容并繼續
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
@[email protected] + @LFCR) > @DefinedLength
BEGIN
SELECT @AddOnLen = @DefinedLength-(isnull(LEN(@Line),0) +
@BlankSpaceAdded)
INSERT #CommentText VALUES
( @LineId,
isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,
@BasePos, @AddOnLen), N''))
SELECT @Line = NULL, @LineId = @LineId + 1,
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded = 0
END
SELECT @Line = isnull(@Line, N'') +
isnull(SUBSTRING(@SyscomText, @BasePos, @[email protected] + @LFCR), N'')
SELECT @BasePos = @CurrentPos+2
INSERT #CommentText VALUES( @LineId, @Line )
SELECT @LineId = @LineId + 1
SELECT @Line = NULL
END
ELSE
--如果回車沒找到
BEGIN
IF @BasePos <= @TextLength
BEGIN
--如果@Lines長度的新值大于定義的長度
While (isnull(LEN(@Line),0) + @BlankSpaceAdded +
@[email protected]+1 ) > @DefinedLength
BEGIN
SELECT @AddOnLen = @DefinedLength -
(isnull(LEN(@Line),0) + @BlankSpaceAdded)
INSERT #CommentText VALUES
( @LineId,
isnull(@Line, N'') + isnull(SUBSTRING(@SyscomText,
@BasePos, @AddOnLen), N''))
SELECT @Line = NULL, @LineId = @LineId + 1,
@BasePos = @BasePos + @AddOnLen, @BlankSpaceAdded =
0
END
SELECT @Line = isnull(@Line, N'') +
isnull(SUBSTRING(@SyscomText, @BasePos, @[email protected]+1 ), N'')
if LEN(@Line) < @DefinedLength and charindex(' ',
@SyscomText, @TextLength+1 ) > 0
BEGIN
SELECT @Line = @Line + ' ', @BlankSpaceAdded = 1
END
END
END
END
FETCH NEXT FROM ms_crs_syscom into @SyscomText
END
IF @Line is NOT NULL
INSERT #CommentText VALUES( @LineId, @Line )
select Text from #CommentText order by LineId
CLOSE ms_crs_syscom
DEALLOCATE ms_crs_syscom
DROP TABLE #CommentText
-- -------------------------------------
--結束從sp_helptext提取
-- -------------------------------------
--删除用短橫線建立的存儲過程并重建原始的存儲過程
ROLLBACK TRAN
DROP TABLE #output
go
           

執行上面的存儲過程方法為:

exec sp_windbi$Decrypt '你要解密的存儲過程名',0

在執行上面的語句後出現錯誤:

對象名'sys.sysobjvalues'無效

主要原因是我們沒有用DAC模式登陸,下面是解決辦法:

    第一步:允許DAC模式

             (1)如果是在本地伺服器做DAC的話用:sqlcmd -A (A一定要大寫,要不然不好用哦) 用這個指令就可以很輕松的連接配接上,連接配接上以後在裡面寫語句就可以,語句寫玩了要運作GO這個指令。

             (2)如果要做遠端連接配接DAC的話需要用: sqlcmd -S 伺服器名 -U sa(一個是sysadmin角色的登陸帳戶就可以了)-P(密碼)-A就可以了

    啟用遠端DAC登入選項:

             操作步驟:'程式'->'Sql Server2005'->  '配置工具'-> 'Sql Server  外圍應用配置器'-> '功能的外圍應用配置器'-> 'DataBase Engine'->  'DAC' -> '啟用遠端DAC'

    這樣DAC模式就啟用成功了,接下來是使用DAC模式登陸。

    第二步:使用DAC模式登陸(關鍵就在這個地方)

             1,DAC隻支援一個視窗

             2,DAC隻支援查詢視窗, 不支援Object Explorer. 如果你想在SQL Server Management Studio中用DAC連, 你應該用個正常的連接配接, 然後用DAC打開查詢視窗.

    下面是操作步驟:

      1,先用有sysadmin角色的使用者登陸SQL Server Management Studio,随便sa就可以了;

      2,建立查詢,在彈出的連接配接對話框中,伺服器名稱改為 ADMIN:伺服器名稱;然後,選項->連接配接屬性->連接配接到資料庫 改為加密存儲過程所在的資料庫->連接配接即可.

      3,最後執行上面的存儲過程方法;

如何啟用遠端DAC連接配接?

隻有 SQL Server sysadmin 角色的成員可以使用 DAC 連接配接。預設情況下,隻能從伺服器上運作的用戶端建立連接配接。除非通過 sp_configure 使用 remote admin connections 選項進行配置,否則不允許使用網絡連接配接。

DAC 支援加密和 SQL Server 的其他安全性功能。DAC 隻允許将使用者上下文切換到其他管理使用者。

預設情況下,DAC 僅偵聽環回 IP 位址 (127.0.0.1) 端口 1434。

remote admin connections 設定的可能值如下:

0 - 指明僅允許本地連接配接使用 DAC

1 - 指明允許遠端連接配接使用 DAC 

--啟用遠端DAC連接配接

sp_configure 'remote admin connections', 1;

GO

RECONFIGURE;

GO

注意:配置遠端管理連接配接之後,會立即啟用 DAC 偵聽器而不必重新啟動 SQL Server,并且用戶端可以立即遠端連接配接到 DAC

參考2

使用DAC(專用管理者連接配接)連接配接到資料庫

1. [轉]使用DAC(專用管理者連接配接)連接配接到資料庫

    在“連接配接到資料庫引擎”對話框的“伺服器名稱”框中,鍵入 ADMIN:,并在其後繼續鍵入伺服器執行個體的名稱。例如,若要連接配接到名為 ACCT\PAYABLE 的伺服器執行個體,請鍵入 ADMIN:ACCT\PAYABLE。

注1: 無法連接配接到 ADMIN:WIN-SV3NUJLD0C5\MSSQLSERVER_NEW

注2:無法連接配接到 ADMIN:192.168.1.100

在與 SQL Server 建立連接配接時出現與網絡相關的或特定于執行個體的錯誤。未找到或無法通路伺服器。請驗證執行個體名稱是否正确并且 SQL Server 已配置為允許遠端連接配接。 (provider: SQL 網絡接口, error: 43 - 在擷取專用的管理者連接配接(DAC)端口時出錯。 確定正在運作 SQL 浏覽器,或檢查錯誤日志中是否有該端口号) (.Net SqlClient Data Provider)

------------------------------

有關幫助資訊,請單擊: http://go.microsoft.com/fwlink?ProdName=Microsoft+SQL+Server&EvtSrc=MSSQLServer&EvtID=-1&LinkId=20476

原因可能是:

The firewall on the server has refused the connection.

A specified SQL Server instance name is not valid.

The SQL Server Browser service (sqlbrowser) is not started.(打開Sql Server裡的 SQL Server Brower 資料庫浏覽服務)

不支援專用管理者連接配接。 (ObjectExplorer)

如何啟用遠端DAC連接配接?

隻有 SQL Server sysadmin 角色的成員可以使用 DAC 連接配接。預設情況下,隻能從伺服器上運作的用戶端建立連接配接。除非通過 sp_configure 使用 remote admin connections 選項進行配置,否則不允許使用網絡連接配接。

DAC 支援加密和 SQL Server 的其他安全性功能。DAC 隻允許将使用者上下文切換到其他管理使用者。

預設情況下,DAC 僅偵聽環回 IP 位址 (127.0.0.1) 端口 1434。

remote admin connections 設定的可能值如下:

0 - 指明僅允許本地連接配接使用 DAC

1 - 指明允許遠端連接配接使用 DAC 

--啟用遠端DAC連接配接

sp_configure 'remote admin connections', 1;

GO

RECONFIGURE;

GO

注意:配置遠端管理連接配接之後,會立即啟用 DAC 偵聽器而不必重新啟動 SQL Server,并且用戶端可以立即遠端連接配接到 DAC

繼續閱讀