破解SQL Server加密的存储过程的方法(含 sql 2000与sql 2005版)
2011-02-09 09:18
639 查看
转载自:/article/5866745.html
/article/4602275.html
SQLServer2005里使用with
encryption选项创建的存储过程仍然和sqlserver2000里一样,都是使用XOR进行了的加密。和2000不一样的是,在2005的系统表syscomments里已经查不到加密过的密文了。要查密文必须使用DAC(专用管理员连接)连接到数据库后,在系统表sys.sysobjvalues查询,该表的列imageval存储了相应的密文。具体可以使用下面的查询:
SELECT
imagevalFROMsys.sysobjvaluesWHEREobjid=object_id(@procedure)AND
valclass=1ANDsubobjid=1
案例2:有接手别人工作,而对于业务存储过程中使用加密了内容的,维护难受啊,GOOGLE搜索,终于不负有心人.Sql2000
的。
CREATEPROCEDUREusp_decrypt(@objectnamevarchar(50))
AS
begin
setnocounton
--CSDN:j9988copyright:2004.07.15
--V3.2
--破解字节不受限制,适用于SQLSERVER2000存储过程,函数,视图,触发器
--修正上一版"视图触发器"不能正确解密错误
--发现有错,请E_MAIL:CSDNj9988@tom.com
begintran
declare@objectname1varchar(100),@orgvarbinvarbinary(8000)
declare@sql1nvarchar(4000),@sql2varchar(8000),@sql3nvarchar(4000),@sql4nvarchar(4000)
DECLARE@OrigSpText1nvarchar(4000),@OrigSpText2nvarchar(4000),@OrigSpText3nvarchar(4000),@resultspnvarchar(4000)
declare@iint,@statusint,@typevarchar(10),@parentidint
declare@colidint,@nint,@qint,@jint,@kint,@encryptedint,@numberint
select@type=xtype,@parentid=parent_objfromsysobjectswhereid=object_id(@objectname)
createtable#temp(numberint,colidint,ctextvarbinary(8000),encryptedint,statusint)
insert#tempSELECTnumber,colid,ctext,encrypted,statusFROMsyscommentsWHEREid=object_id(@objectname)
select@number=max(number)from#temp
set@k=0
while@k<=@number
begin
ifexists(select1fromsyscommentswhereid=object_id(@objectname)andnumber=@k)
begin
if@type='P'
set@sql1=(casewhen@number>1then'ALTERPROCEDURE'+@objectname+';'+rtrim(@k)+'WITHENCRYPTIONAS'
else'ALTERPROCEDURE'+@objectname+'WITHENCRYPTIONAS'
end)
if@type='TR'
begin
declare@parent_objvarchar(255),@tr_parent_xtypevarchar(10)
select@parent_obj=parent_objfromsysobjectswhereid=object_id(@objectname)
select@tr_parent_xtype=xtypefromsysobjectswhereid=@parent_obj
if@tr_parent_xtype='V'
begin
set@sql1='ALTERTRIGGER'+@objectname+'ON'+OBJECT_NAME(@parentid)+'WITHENCRYPTIONINSTERDOFINSERTASPRINT1'
end
else
begin
set@sql1='ALTERTRIGGER'+@objectname+'ON'+OBJECT_NAME(@parentid)+'WITHENCRYPTIONFORINSERTASPRINT1'
end
end
if@type='FN'or@type='TF'or@type='IF'
set@sql1=(case@typewhen'TF'then
'ALTERFUNCTION'+@objectname+'(@achar(1))returns@btable(avarchar(10))withencryptionasbegininsert@bselect@areturnend'
when'FN'then
'ALTERFUNCTION'+@objectname+'(@achar(1))returnschar(1)withencryptionasbeginreturn@aend'
when'IF'then
'ALTERFUNCTION'+@objectname+'(@achar(1))returnstablewithencryptionasreturnselect@aasa'
end)
if@type='V'
set@sql1='ALTERVIEW'+@objectname+'WITHENCRYPTIONASSELECT1asf'
set@q=len(@sql1)
set@sql1=@sql1+REPLICATE('-',4000-@q)
select@sql2=REPLICATE('-',8000)
set@sql3='exec(@sql1'
select@colid=max(colid)from#tempwherenumber=@k
set@n=1
while@n<=CEILING(1.0*(@colid-1)/2)andlen(@sql3)<=3996
begin
set@sql3=@sql3+'+@'
set@n=@n+1
end
set@sql3=@sql3+')'
execsp_executesql@sql3,N'@sql1nvarchar(4000),@varchar(8000)',@sql1=@sql1,@=@sql2
end
set@k=@k+1
end
set@k=0
while@k<=@number
begin
ifexists(select1fromsyscommentswhereid=object_id(@objectname)andnumber=@k)
begin
select@colid=max(colid)from#tempwherenumber=@k
set@n=1
while@n<=@colid
begin
select@OrigSpText1=ctext,@encrypted=encrypted,@status=statusFROM#tempWHEREcolid=@nandnumber=@k
SET@OrigSpText3=(SELECTctextFROMsyscommentsWHEREid=object_id(@objectname)andcolid=@nandnumber=@k)
if@n=1
begin
if@type='P'
SET@OrigSpText2=(casewhen@number>1then'CREATEPROCEDURE'+@objectname+';'+rtrim(@k)+'WITHENCRYPTIONAS'
else'CREATEPROCEDURE'+@objectname+'WITHENCRYPTIONAS'
end)
if@type='FN'or@type='TF'or@type='IF'
SET@OrigSpText2=(case@typewhen'TF'then
'CREATEFUNCTION'+@objectname+'(@achar(1))returns@btable(avarchar(10))withencryptionasbegininsert@bselect@areturnend'
when'FN'then
'CREATEFUNCTION'+@objectname+'(@achar(1))returnschar(1)withencryptionasbeginreturn@aend'
when'IF'then
'CREATEFUNCTION'+@objectname+'(@achar(1))returnstablewithencryptionasreturnselect@aasa'
end)
if@type='TR'
begin
if@tr_parent_xtype='V'
begin
set@OrigSpText2='CREATETRIGGER'+@objectname+'ON'+OBJECT_NAME(@parentid)+'WITHENCRYPTIONINSTEADOFINSERTASPRINT1'
end
else
begin
set@OrigSpText2='CREATETRIGGER'+@objectname+'ON'+OBJECT_NAME(@parentid)+'WITHENCRYPTIONFORINSERTASPRINT1'
end
end
if@type='V'
set@OrigSpText2='CREATEVIEW'+@objectname+'WITHENCRYPTIONASSELECT1asf'
set@q=4000-len(@OrigSpText2)
set@OrigSpText2=@OrigSpText2+REPLICATE('-',@q)
end
else
begin
SET@OrigSpText2=REPLICATE('-',4000)
end
SET@i=1
SET@resultsp=replicate(N'A',(datalength(@OrigSpText1)/2))
WHILE@i<=datalength(@OrigSpText1)/2
BEGIN
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
set@orgvarbin=cast(@OrigSpText1asvarbinary(8000))
set@resultsp=(casewhen@encrypted=1
then@resultsp
elseconvert(nvarchar(4000),casewhen@status&2=2thenuncompress(@orgvarbin)else@orgvarbinend)
end)
print@resultsp
set@n=@n+1
end
end
set@k=@k+1
end
droptable#temp
rollbacktran
end
再有一个
Sql2005
版的
SQLServer2005里使用with
encryption选项创建的存储过程仍然和sqlserver2000里一样,都是使用XOR进行了的加密。和2000不一样的是,在2005的系统表syscomments里已经查不到加密过的密文了。要查密文必须使用DAC(专用管理员连接)连接到数据库后,在系统表sys.sysobjvalues查询,该表的列imageval存储了相应的密文。具体可以使用下面的查询:
SELECT
imagevalFROMsys.sysobjvaluesWHEREobjid=object_id(@procedure)AND
valclass=1ANDsubobjid=
1
DAC连接,在数据库引擎查询时,服务器名称前添加admin:
例:服务器名pc001则应使用admin:pc001
createPROCEDURE[dbo].[usp_decrypt]
(@proceduresysname=NULL,@revflint=1)
AS
/**//*
王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com
目前这个存储过程只能解密存储过程,至于解密函数、触发器、视图的存储过程本网站会进一步关注,调用形式为:
execdbo.usp_decryptprocedure,0
如果第二个参数使用1的话,会给出该存储过程的一些提示。
--版本3.0修正存储过程过长引起的问题
*/
SETNOCOUNTON
IF@revfl=1
BEGIN
PRINT'警告:该存储过程会删除并重建原始的存储过程。'
PRINT'在运行该存储过程之前确保你的数据库有一个备份。'
PRINT'该存储过程通常应该运行在产品环境的一个备份的非产品环境下。'
PRINT'为了运行这个存储过程,将参数@refl的值更改为0。'
RETURN0
END
DECLARE@intProcSpacebigint,@tbigint,@maxColIDsmallint,@procNameLengthint
select@maxColID=max(subobjid)FROM
sys.sysobjvaluesWHEREobjid=object_id(@procedure)
--select@maxColIDas'Rowsinsys.sysobjvalues'
select@procNameLength=datalength(@procedure)+29
DECLARE@real_01nvarchar(max)
DECLARE@fake_01nvarchar(max)
DECLARE@fake_encrypt_01nvarchar(max)
DECLARE@real_decrypt_01nvarchar(max),@real_decrypt_01anvarchar(max)
declare@objtypevarchar(2),@ParentNamenvarchar(max)
select@real_decrypt_01a=''
--提取对象的类型如是存储过程还是函数,如果是触发器,还要得到其父对象的名称
select@objtype=type,@parentname=object_name(parent_object_id)
fromsys.objectswhere[object_id]=object_id(@procedure)
--从sys.sysobjvalues里提出加密的imageval记录
SET@real_01=(SELECTtop1imagevalFROMsys.sysobjvaluesWHEREobjid=
object_id(@procedure)andvalclass=1orderbysubobjid)
--创建一个临时表
createtable#output([ident][int]IDENTITY(1,1)NOTNULL,
[real_decrypt]NVARCHAR(MAX))
--开始一个事务,稍后回滚
BEGINTRAN
--更改原始的存储过程,用短横线替换
if@objtype='P'
SET@fake_01='ALTERPROCEDURE'+@procedure+'WITHENCRYPTIONAS
'+REPLICATE(cast('-'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)
elseif@objtype='FN'
SET@fake_01='ALTERFUNCTION'+@procedure+'()RETURNSINTWITHENCRYPTIONASBEGINRETURN1
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/END'
elseif@objtype='V'
SET@fake_01='ALTERview'+@procedure+'WITHENCRYPTIONASselect1ascol
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/'
elseif@objtype='TR'
SET@fake_01='ALTERtrigger'+@procedure+'ON'+@parentname+'WITHENCRYPTIONAFTERINSERTASRAISERROR(''N'',16,10)
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/'
EXECUTE(@fake_01)
--从sys.sysobjvalues里提出加密的假的
SET@fake_encrypt_01=(SELECTtop1imagevalFROMsys.sysobjvaluesWHEREobjid=
object_id(@procedure)andvalclass=1orderbysubobjid)
if@objtype='P'
SET@fake_01='CreatePROCEDURE'+@procedure+'WITHENCRYPTIONAS
'+REPLICATE(cast('-'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)
elseif@objtype='FN'
SET@fake_01='CREATEFUNCTION'+@procedure+'()RETURNSINTWITHENCRYPTIONASBEGINRETURN1
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/END'
elseif@objtype='V'
SET@fake_01='Createview'+@procedure+'WITHENCRYPTIONASselect1ascol
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/'
elseif@objtype='TR'
SET@fake_01='Createtrigger'+@procedure+'ON'+@parentname+'WITHENCRYPTIONAFTERINSERTASRAISERROR(''N'',16,10)
/*'+REPLICATE(cast('*'asnvarchar(max)),datalength(@real_01)/2-@procNameLength)+'*/'
--开始计数
SET@intProcSpace=1
--使用字符填充临时变量
SET@real_decrypt_01=replicate(cast('A'asnvarchar(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@intProcSpace=@intProcSpace+1
END
--通过sp_helptext逻辑向表#output里插入变量
insert#output(real_decrypt)select@real_decrypt_01
--selectreal_decryptAS'#outputchek'from#output--测试
---------------------------------------
--开始从sp_helptext提取
---------------------------------------
declare@dbnamesysname
,@BlankSpaceAddedint
,@BasePosint
,@CurrentPosint
,@TextLengthint
,@LineIdint
,@AddOnLenint
,@LFCRint--回车换行的长度
,@DefinedLengthint
,@SyscomTextnvarchar(max)
,@Linenvarchar(255)
Select@DefinedLength=255
SELECT@BlankSpaceAdded=0--跟踪行结束的空格。注意Len函数忽略了多余的空格
CREATETABLE#CommentText
(LineIdint
,Textnvarchar(255)collatedatabase_default)
--使用#output代替sys.sysobjvalues
DECLAREms_crs_syscomCURSORLOCAL
FORSELECTreal_decryptfrom#output
ORDERBYident
FORREADONLY
--获取文本
SELECT@LFCR=2
SELECT@LineId=1
OPENms_crs_syscom
FETCHNEXTFROMms_crs_syscominto@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+
@CurrentPos-@BasePos+@LFCR)>@DefinedLength
BEGIN
SELECT@AddOnLen=@DefinedLength-(isnull(LEN(@Line),0)+
@BlankSpaceAdded)
INSERT#CommentTextVALUES
(@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,@CurrentPos-@BasePos+@LFCR),N'')
SELECT@BasePos=@CurrentPos+2
INSERT#CommentTextVALUES(@LineId,@Line)
SELECT@LineId=@LineId+1
SELECT@Line=NULL
END
ELSE
--如果回车没找到
BEGIN
IF@BasePos<=@TextLength
BEGIN
--如果@Lines长度的新值大于定义的长度
While(isnull(LEN(@Line),0)+@BlankSpaceAdded+
@TextLength-@BasePos+1)>@DefinedLength
BEGIN
SELECT@AddOnLen=@DefinedLength-
(isnull(LEN(@Line),0)+@BlankSpaceAdded)
INSERT#CommentTextVALUES
(@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,@TextLength-@BasePos+1),N'')
ifLEN(@Line)<@DefinedLengthandcharindex('',
@SyscomText,@TextLength+1)>0
BEGIN
SELECT@Line=@Line+'',@BlankSpaceAdded=1
END
END
END
END
FETCHNEXTFROMms_crs_syscominto@SyscomText
END
IF@LineisNOTNULL
INSERT#CommentTextVALUES(@LineId,@Line)
selectTextfrom#CommentTextorderbyLineId
CLOSEms_crs_syscom
DEALLOCATEms_crs_syscom
DROPTABLE#CommentText
---------------------------------------
--结束从sp_helptext提取
---------------------------------------
--删除用短横线创建的存储过程并重建原始的存储过程
ROLLBACKTRAN
DROPTABLE#output
已经打包好的文件
在这里
引用网摘:
解密
SQL2005
存储过程要使用
DAC
模式连接到
SQL2005
数据库处理
转载自:
如果你在网上找到破解SQL2005加密的存储过程,运行时提示不成功,那么你可要使用DAC模式连接到SQL2005数据库来处理,方法如下:
1、打开SQLServerManagementStudio
2、登录框
按“取消”
3、工具栏上的第一个图标:数据库引擎查询
4、服务器名称前加“ADMIN:”,如:ADMIN:hostname/sql2005
5、选择“Windows身份验证”,或输入sa和密码,登录。
已打开SQLServerManagementStudio
并连接,忽略1、2步。
如果出现:provider:SQL网络接口,error:43-在获取专用的管理员连接(DAC)端口时出错。确保正在运行SQL
浏览器,或检查错误日志中是否有该端口号的错误
原因可能是:
Thefirewallontheserverhasrefusedtheconnection.
AspecifiedSQLServerinstancenameisnotvalid.
TheSQLServerBrowserservice(sqlbrowser)isnot
started.(打开SqlServer里的SQLServerBrower数据库浏览服务)
需要执行:
sp_configure'remoteadminconnections',
1
GO
RECONFIGURE
这样一般都可以连接成功的
SQLServer2005中如何知道某个存储过程是否已加密?
转载自:
最近在写一个小软件,需要知道当前那些存储过程已经被加密,如果被加密,则调用解密过程,将其解密,还原明文保存。基于sql
server2005解密已加密的存储过程,网上有成熟的代码可供参考,但如何通过sql语句的方式知道当前数据库中的存储过程是否已加密呢??
最初我就认为加密与不加密的存储过程肯定是一个标记位,存放在某个系统表中,但这个系统表在那里?我却不知道,曾通过google或msdn去查找,但没有找到相关资料,甚至准备写邮件咨询邹建等大侠....
突然想到,原来经常利用sp_helptext查看某个未加密过程的明文,那如果用sp_helptext查看已加密的过程,会有什么反映呢。结果很明确,系统提示:对象***文件已加密!
呵呵,既然sp_helptext知道这个过程已经加密,那我查看一下sp_helptext源码不就可以知道,它是如何判断出该过程是否已加密的吗?
于是,输入:execsp_helptext
sp_helptext ,屏幕上果然输出sp_helptext的明文,从sp_helptext中我们很容易找到这行code:
selecttextfromsyscommentswhereid=@objidandencrypted=0............
这段代码意思很明确,查询输出未加密的过程,那么我所需要的就是:
select*fromsyscommentswhereencrypted=1
好了,说到这里,我想各位已经很清楚知道如何解决本文开头所提出的问题!祝各位好运!
===================================================================
示例
加密:
createprocedurep_test
withencryption
as
select*fromtest
解密:
use[test]
execsp_decrypt'p_test'
相关文章推荐
- 【转载】破解SQL Server加密的存储过程的方法(含 sql 2000与sql 2005版)
- 破解SQL Server加密的存储过程的方法(含 sql 2000与sql 2005版)
- 破解SQL Server加密的存储过程的方法(含 sql 2000与sql 2005版)
- 破解sql server 2005加密的存储过程的方法
- sql server中破解加密的存储过程 视图 等object的方法
- 无意中发现的sql server 存储过程加密破解方法
- 无意中发现的sql server 存储过程加密破解方法
- 在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
- SQL Server 2005与sql 2000之间的数据转换方法
- [转]SQL Server中获得EXEC后面的sql语句或者存储过程的返回值的方法
- sql server 2005分页存储过程和sql server 2000分页存储过程
- 怎样对SQL Server 2005加密的存储过程进行解密
- [转]SQL Server中获得EXEC后面的sql语句或者存储过程的返回值的方法
- sql server 2005/2008 加密存储过程解密
- SQL Server 2005系列教学_SQL 存储过程
- 在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
- 在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
- 在存储过程中编写正确的事务处理代码(SQL Server 2000 & 2005)
- sql server 批量修改数据表和存储过程的所有者(2000)或架构(2005)
- 解密SQL SERVER 2005加密存储过程,视图、函数