十字星

  • 首页
  • 技术
  • 随笔
  • 瞎折腾
  • 平面设计
  • 文集
  • 留言
  • 其他
    • API测试
  1. 首页
  2. 技术
  3. 正文

SQL2008对加密的存储过程解密

2021-11-11 1393点热度 0人点赞 0条评论

本文环境为 Microsoft SQL Server 2008 R2

在创建存储时,在 as  前加WITH ENCRYPTION语句,创建出的存储如下图所示,会在对象资源管理器中显示带锁图标,并且右键菜单中的修改被置灰无法查看存储的具体内容,这时如果没有保存源文件,如何修改这个存储呢?接下来我们就来讲讲SQL2008存储过程解密.

存储过程的解密

解密用到的一个核心存储sp_DecryptObject,这个存储会贴在文末

1.首先打开Microsoft SQL Server Management Studio正常登陆到服务器,执行存储sp_DecryptObject,会在master库存创建了一个名为sp_DecryptObject的存储过程。

2.使用该存储过程解密,需要创建数据库引擎查询,操作见图

3.会打开登陆窗口,在服务器前加admin:,其他和正常登陆保持一致

4.上一步连接后会打开下图所示的一个查询窗口

5.输入命令exec sp_DecryptObject pda_bat_bill_inf,执行后发现结果不全,只有一部分

6.原因是解密存储的默认内容长度是4000

7,修改一下解密调用,把第二个参数传入,由于不知道有多长,所以先增大一倍,输入8000看看执行结果,发现还是没有显示全

8.把第二个参数加大20倍,输入80000,这次执行结果全部显示出来了

9.刷新一下[对象资源管理器→存储过程]节点,发现存储pda_bat_bill_inf前面锁图标已经消失且右键菜单中修改可用

10.解密存储sp_DecryptObject内容如下

Use master
Go
if object_ID('[sp_DecryptObject]') is not null
    Drop Procedure [sp_DecryptObject]
Go
create procedure sp_DecryptObject 
(
    @Object sysname,    --要解密的对象名:函数,存储过程,视图或触发器
    @MaxLength int=4000 --评估内容的长度
)
as
set nocount on
/* 1. 解密 */ 
if not exists(select 1 from sys.objects a where a.object_id=object_id(@Object) And a.type in('P','V','TR','FN','IF','TF'))
begin
    --SQL Server 2008
    raiserror 50001 N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。' 

    --SQL Server 2012
    --throw 50001, N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。',1   
    return
end
 
if exists(select 1 from sys.sql_modules a where a.object_id=object_id(@Object) and a.definition is not null)
begin
    --SQL Server 2008
    raiserror 50001 N'对象没有加密!' 

    --SQL Server 2012
    --throw 50001, N'无效的对象!要解密的对象必须是函数,存储过程,视图或触发器。',1 
    return
end
 
declare  @sql nvarchar(max)                --解密出来的SQL语句
        ,@imageval nvarchar(max)        --加密字符串
        ,@tmpStr nvarchar(max)            --临时SQL语句
        ,@tmpStr_imageval nvarchar(max) --临时SQL语句(加密后)
        ,@type char(2)                    --对象类型('P','V','TR','FN','IF','TF')
        ,@objectID int                    --对象ID
        ,@i int                            --While循环使用
        ,@Oject1 nvarchar(1000)
 
set @objectID=object_id(@Object)
set @type=(select a.type from sys.objects a where a.object_id=@objectID)
 
declare @Space4000 nchar(4000)
set @Space4000=replicate('-',4000)
 
/*
@tmpStr 会构造下面的SQL语句
-------------------------------------------------------------------------------
alter trigger Tr_Name on Table_Name with encryption for update as return /**/
alter proc Proc_Name with encryption  as select 1 as col /**/
alter view View_Name with encryption as select 1 as col /**/
alter function Fn_Name() returns int with encryption as begin return(0) end/**/
*/
set @Oject1=quotename(object_schema_name(@objectID))+'.'+quotename(@Object)
set @tmpStr=
        case     
            when @type ='P ' then N'Alter Procedure '+@Oject1+' with encryption as select 1 as column1 '
            when @type ='V ' then N'Alter View '+@Oject1+' with encryption as select 1 as column1 '
            when @type ='FN' then N'Alter Function '+@Oject1+'() returns int with encryption as begin return(0) end '
            when @type ='IF' then N'Alter Function '+@Oject1+'() returns table with encryption as return(Select a.name from sys.types a) '
            when @type ='TF' then N'Alter Function '+@Oject1+'() returns @t table(name nvarchar(50)) with encryption as begin return end '
            else 'Alter Trigger '+@Oject1+'on '+quotename(object_schema_name(@objectID))+'.'+(select Top(1) quotename(object_name(parent_id)) from sys.triggers a where a.object_id=@objectID)+' with encryption for update as return ' 
        end        
 
    
set @tmpStr=@tmpStr+'/*'+@Space4000
set @i=0
while @i < (ceiling(@MaxLength*1.0/4000)-1)
begin
    set @tmpStr=@tmpStr+ @Space4000
    Set @i=@i+1
end
set @tmpStr=@tmpStr+'*/'
 
------------
set @imageval =(select top(1) a.imageval from sys.sysobjvalues a where a.objid=@objectID and a.valclass=1)
 
begin tran
exec(@tmpStr)
set @tmpStr_imageval =(select top(1) a.imageval from sys.sysobjvalues a where a.objid=@objectID and a.valclass=1)
 
rollback tran
 
-------------
set @tmpStr=stuff(@tmpStr,1,5,'create')
set @sql=''
set @i=1
while @i<= (datalength(@imageval)/2)
begin
    set @sql=@sql+isnull(nchar(unicode(substring(@tmpStr,@i,1)) ^ unicode(substring(@tmpStr_imageval,@i,1))^unicode(substring(@imageval,@i,1)) ),'')
    Set @i+=1
end
 
/* 2. 列印 */ 
declare @patindex int    
while @sql>''
begin
    
    set @patindex=patindex('%'+char(13)+char(10)+'%',@sql)
    if @patindex >0
    begin
        print substring(@sql,1,@patindex-1)
        set @sql=stuff(@sql,1,@patindex+1,'')
    end    
    else 
    begin
        set @patindex=patindex('%'+char(13)+'%',@sql)
        if @patindex >0
        begin
            print substring(@sql,1,@patindex-1)
            set @sql=stuff(@sql,1,@patindex,'')
        end
        else
        begin
            set @patindex=patindex('%'+char(10)+'%',@sql)
            if @patindex >0
            begin
                print substring(@sql,1,@patindex-1)
                set @sql=stuff(@sql,1,@patindex,'')
            end        
            else
            begin
                print @sql
                set @sql=''
            end    
        end        
    end        
end
Go
exec sp_ms_marksystemobject 'sp_DecryptObject' --标识为系统对象
go

 

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: SQL Server
最后更新:2021-11-11

cxw

技术宅,最喜瞎折腾.

点赞
< 上一篇
下一篇 >

文章评论

取消回复

最新 热点 随机
最新 热点 随机
git迁移项目中的某个目录到新项目 winform判断设计模式还是运行时模式 C# 中的where T : class, new() 到底是什么意思? 解决安装.NET失败并提示“无法建立到信任根颁发机构的证书链” 关闭.net4.0的http访问默认代理 删除名称最后带空格的文件夹
宝贝语录2 Kms命令激活Windows系统 OA和ERP的区别 WinForm中在窗体的Load事件中使用Focus()设置焦点却始终不生效解决方法 Visual Studio Code(VSCode)中查看php数组的全部元素 XP系统屏幕保护返回到欢迎屏幕的方法
标签聚合
MySQL IT PHP CentOS C# Linux WordPress Excel WinForm W10
最近评论
alex 发布于 4 年前(01月22日) 博主,请问把代码贴到博客里可以复制是怎么实现的

COPYRIGHT © 2021 十字星. ALL RIGHTS RESERVED

THEME KRATOS MADE BY VTROIS

京ICP备2020032489号-2