国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

解剖SQLSERVER 第十五篇 SQLSERVER存儲過程的源文本存放在哪里?(譯)

2024-07-21 02:48:56
字體:
來源:轉載
供稿:網友
解剖SQLSERVER 第十五篇 SQLSERVER存儲過程的源文本存放在哪里?(譯)解剖SQLSERVER 第十五篇 SQLSERVER存儲過程的源文本存放在哪里?(譯)

http://imPRove.dk/where-does-sql-server-store-the-source-for-stored-procedures/

目前我正在擴展OrcaMDF Studio的功能 不單只支持系統表,DMVs 和用戶表 而且也要支持存儲過程。那很容易,我們只需要查詢sys.procedures --或者查詢sys.sysschobjs,

因為當SQLSERVER沒有在運行的時候我們是不能查詢sys.procedures 的

然而,我不想只是列出存儲過程名稱,我也需要顯示存儲過程里面的源代碼。這帶來了新的任務--檢索源代碼。源代碼存儲在哪里?

我在Google上找不到任何有用的資料,所以我們只能依靠自己觀察了!

我已經創建了一個新的空數據庫 這個數據庫有一個3MB的數據文件。在這個數據庫里面,我已經創建了一個單獨的存儲過程就像這樣:

SET ANSI_NULLS ONGOSET QUOTED_IDENTIFIER ONGO-- =============================================-- Author:        -- Create date: -- Description:    -- =============================================CREATE PROCEDURE XYZ    ASBEGIN    -- SET NOCOUNT ON added to prevent extra result sets from    -- interfering with SELECT statements.    SET NOCOUNT ON;    -- Insert statements for procedure here    SELECT 'AABBCC' AS OutputEND

現在,當我select * from sys.procedures的時候,我們可以看到存儲過程的object ID 是2105058535

select * from sys.procedures

到目前為止一切順利。然后我們可以檢索存儲過程的定義 使用查詢sys.sql_modules 視圖返回nvarchar(MAX)類型的定義文本

select * from sys.sql_modules where object_id = 2105058535

上面就是XYZ存儲過程的源代碼!等下,我可以從sys.sysschobjs表里獲取存儲過程的object ID,我不需要訪問sys.sql_modules ,sys.sql_modules 只是一個視圖而不是系統表。我們看一下sys.sql_modules 視圖是如何獲取定義的:

select object_definition(object_id('sys.sql_modules'))
SELECT    object_id = o.id,    definition = Object_definition(o.id),    uses_ansi_nulls = Sysconv(bit, o.status & 0x40000), -- OBJMOD_ANSINULLS    uses_quoted_identifier = sysconv(bit, o.status & 0x80000),   -- OBJMOD_QUOTEDIDENT    is_schema_bound = sysconv(bit, o.status & 0x20000),    -- OBJMOD_SCHEMABOUND    uses_database_collation = sysconv(bit, o.status & 0x100000),  -- OBJMOD_USESDBCOLL    is_recompiled = sysconv(bit, o.status & 0x400000),     -- OBJMOD_NOCACHE    null_on_null_input = sysconv(bit, o.status & 0x200000),   -- OBJMOD_NULLONNULL    execute_as_principal_id = x.indepidFROM    sys.sysschobjs oLEFT JOIN    sys.syssingleobjrefs x ON x.depid = o.id AND x.class = 22 AND x.depsubid = 0 -- SRC_OBJEXECASOWNERWHERE    o.pclass <> 100 AND    (        (o.type = 'TR' AND has_access('TR', o.id, o.pid, o.nsclass) = 1) OR        (type IN ('P','V','FN','IF','TF','RF','IS') AND has_access('CO', o.id) = 1) OR        (type IN ('R','D') AND o.pid = 0)    )

大家如果使用sqlprompt的話也可以直接顯示定義而不需要執行object_definition函數

可以看到sys.sql_modules 視圖也是使用系統函數object_definition 來獲取代碼不幸的是,下面的代碼無法工作

select object_definition(object_id('object_definition'))

我碰巧記得有一個廢棄的視圖可以代替sys.sql_modules,sys.syscomments 視圖我們看一下獲取到的代碼

select object_definition(object_id('sys.syscomments'))
SELECT    o.id AS id,      convert(smallint, case when o.type in ('P', 'RF') then 1 else 0 end) AS number,      s.colid,    s.status,      convert(varbinary(8000), s.text) AS ctext,      convert(smallint, 2 + 4 * (s.status & 1)) AS texttype,      convert(smallint, 0) AS language,      sysconv(bit, s.status & 1) AS encrypted,      sysconv(bit, 0) AS compressed,      s.text  FROM    sys.sysschobjs oCROSS APPLY    OpenRowset(TABLE SQLSRC, o.id, 0) s  WHERE    o.nsclass = 0 AND    o.pclass = 1 AND    o.type IN ('C','D','P','R','V','X','FN','IF','TF','RF','IS','TR') AND    has_access('CO', o.id) = 1  UNION ALL  SELECT    c.object_id AS id,      convert(smallint, c.column_id) AS number,      s.colid,    s.status,      convert(varbinary(8000), s.text) AS ctext,      convert(smallint, 2 + 4 * (s.status & 1)) AS texttype,      convert(smallint, 0) AS language,      sysconv(bit, s.status & 1) AS encrypted,      sysconv(bit, 0) AS compressed,      s.text  FROM    sys.computed_columns cCROSS APPLY    OpenRowset(TABLE SQLSRC, c.object_id, c.column_id) s  UNION ALL  SELECT    p.object_id AS id,      convert(smallint, p.procedure_number) AS number,      s.colid,    s.status,      convert(varbinary(8000), s.text) AS ctext,      convert(smallint, 2 + 4 * (s.status & 1)) AS texttype,      convert(smallint, 0) AS language,      sysconv(bit, s.status & 1) AS encrypted,      sysconv(bit, 0) AS compressed,      s.text  FROM    sys.numbered_procedures pCROSS APPLY    OpenRowset(TABLE SQLSRC, p.object_id, p.procedure_number) s  UNION ALL  SELECT    o.id AS id,      convert(smallint, case when o.type in ('P', 'RF') then 1 else 0 end) AS number,      s.colid,    s.status,      convert(varbinary(8000), s.text) AS ctext,      convert(smallint, 2) AS texttype,      convert(smallint, 0) AS language,      sysconv(bit, 0) AS encrypted,      sysconv(bit, 0) AS compressed,      s.text  FROM    sys.sysobjrdb oCROSS APPLY    OpenRowset(TABLE SQLSRC, o.id, 0) s  WHERE    db_id() = 1 AND     o.type IN ('P','V','X','FN','IF','TF')

很令人失望,他不使用object_definition, 而是使用另一個內部函數格式是OpenRowset(TABLE SQLSRC, o.id, 0)。我不會輕易放棄 --我對 OpenRowset(TABLE RSCPROP)函數進行逆向

讓我們使用不同的方法去解決這個問題。在SQLSERVER里面任何東西的存儲都使用8KB頁面的固定格式。當存儲過程不是加密的,他們一定以明文存儲在數據庫的某個地方--只是我們不知道在哪個地方。

我們分離數據庫并使用hex編輯器進行破解(我推薦使用HxD這個hex編輯器)

HxD hex編輯器下載:

http://files.cnblogs.com/lyhabc/HxDhex%E7%BC%96%E8%BE%91%E5%99%A8.rar

我們為了要找到存儲過程的位置,我在存儲過程里故意使用“SELECT ‘AABBCC’ 這個字符串以便于我們能夠容易的找到存儲過程的所在位置:

我們找到了:

好了,我們現在代碼是存儲在數據庫里面。數據存儲在偏移位置為0x00101AF0 的數據文件里。十進制值是01055472。我們知道數據頁面是8KB,我們可以計算代碼所在的頁面編號

01055472 / 8192 = 128

現在我們知道代碼存儲在頁面號128頁上 --我們重新附加數據庫,使用DBCC PAGE看一下頁面內容:

--只顯示數據頁面頭DBCC TRACEON (3604)GODBCC PAGE(Test2, 1, 128, 0)GO

注意,對于DBCC PAGE 命令我使用了頁面樣式0作為執行。在這里我只想查看數據頁面頭--那里會有一些有趣的東西

正如所料,這是一個正常的數據頁面,m_type 字段顯示的值為1(type id為1表示這是數據庫內部的數據頁面)更有趣的是,我們可以看到頁面屬于object ID 60!我們看一下object ID 60是什么對象:

select * from sys.sysobjects where id = 60

讓我們看看sys.sysobjvalues的內容。注意,當你查詢sys.sysobjvalues視圖的時候,需要使用DAC連接,可以看到他實際上是一個內部的系統表:

select * from sys.sysobjvalues

這里顯示的很多內容我們都不需要關心,不過我們需要嘗試過濾出我們的存儲過程object ID為2105058535的信息:

select * from sys.sysobjvalues where objid = 2105058535

我想知道imageval 列包含了什么內容,如果我沒有記錯 0x2D2D 在ASCII里面應該是“-”這提醒了我 XYZ這個存儲過程剛開始的時候 ,我們嘗試將這列的值轉換為我們可讀的形式

select convert(varchar(max), imageval) from sys.sysobjvalues where objid = 2105058535

親愛的讀者,這就是XYZ存儲過程的源代碼,他存儲在sys.sysobjvalues系統表中。作為最后一個例子,下面是不依靠object_definition()函數和sys.sql_modules視圖從而檢索出用戶存儲過程的源代碼列表

select    p.name,    cast(v.imageval as varchar(MAX))from    sys.procedures pinner join    sys.sysobjvalues v on p.object_id = v.objid

第十五篇完


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 临洮县| 成都市| 江孜县| 临沭县| 平顺县| 会同县| 都匀市| 宜城市| 宁远县| 台北县| 兴业县| 武平县| 岳池县| 耿马| 安丘市| 桐庐县| 格尔木市| 鄢陵县| 海淀区| 固原市| 宿州市| 南陵县| 邢台市| 桓仁| 伊宁县| 株洲县| 鹤山市| 滨海县| 汉中市| 南丰县| 丹东市| 凯里市| 高雄市| 吴川市| 金昌市| 永德县| 鲁甸县| 淅川县| 宜兰县| 乌苏市| 清丰县|