介紹好用工具:CAT.NET (靜態程式碼安全檢測工具)

市場上已經有許多類似的靜態程式碼分析軟體商業軟體,在這一期的 iThome 雜誌(第 405 期)就有介紹好幾套程式碼安全檢測軟體,像我就親自領教過阿碼科技CodeSecure™ 以及 FortifySource Code Analyzer 的威力,誤判是難免,但專業度倒是沒話說,對軟體品質與安全性絕對可大幅提昇。雖然這類商業軟體都所費不貲,微軟為了拯救龐大的開發人員,也不落人後推出了一套 Microsoft Code Analysis Tool .NET (CAT.NET) 工具。

目前 CAT.NET 工具還處於 CTP 階段,而且也發展一段時間了,在之前的 CTP 版有許多問題,常常在 Visual Studio 中執行到一半就會掛掉,所以一直不敢推薦,但最近出的 v1.1.1.9 就穩定非常多了,建議各位大內高手可以放手一試。

Microsoft Code Analysis Tool .NET (CAT.NET) 是一套還算不錯的 .NET 靜態程式碼安全檢測工具 (有比沒有好),分析方式似乎跟 FortifySource Code Analyzer 分析方式有點像,他可以直接分析二位元的 .NET 組件,並可協助找出在組件中潛在的安全性漏洞,例如:Cross-Site Scripting (XSS), SQL Injection, XPath Injection, File Canonicalization, … 等知名且常見的漏洞,目前僅支援 8 條規則而已,但規則都是以 XML 定義,很容易擴充 (如果你看的懂得話)。

使用 CAT.NET 有 2 種方式:

1. 直接從 Visual Studio 中開啟 CAT.NET Code Analysis 工具 ( 包括 VS2005 與 VS2008 )

先用 Visual Studio 開啟開發中的專案,然後從選單 Tools –> CAT.NET Code Analysis 開啟工具視窗

先用 Visual Studio 開啟開發中的專案,然後從選單 Tools –> CAT.NET Code Analysis 開啟工具視窗

也不用多說些什麼,體驗威力時“Play”鍵熊熊給他按下去就對了:

CAT.NET Code Analysis

若要進行進階設定,可以按下如下圖那一排工具列,可以讓你挑選要套用哪些規則、要掃瞄專案中哪些組件、…等等。

CAT.NET Code Analysis - Settings

掃瞄時間依據專案大小而定,通常都會掃瞄一段時間,Visual Studio 感覺會像當掉了一樣「白白的一片」,總之要有點耐性。若 Visual Studio 執行到一半掛掉,那是 CTP 的關係,沒有人會負責的。

如果專案太大,且每次 Visual Studio 都會掛掉的話,建議用第二種方式進行檢測。

2. 直接在「命令提示字元」下執行掃瞄工具

先進入組件所在目錄,然後執行如下的指令:

C:\WebSite\bin>"c:\Program Files\Microsoft\CAT.NET\CATNetCmd.exe" /file:WebSite.dll
Microsoft (R) Code Analysis Tool for .NET (CAT.NET) Version 1.1.1.9
Copyright (C) Microsoft Corporation.  All rights reserved.

Running in 32-bit mode

2009/7/2 下午 04:16:23:Info : Starting analysis [1 modules]
2009/7/2 下午 04:16:23:Info : Analyzing module WebSite...
2009/7/2 下午 04:16:35:Info : 2 Exception Information issues found.
2009/7/2 下午 04:16:37:Info : Analysis completed.

如上範例,你可以發現有兩個 Issue 被找到,而且是跟 “Exception Information”有關。

執行完之後,會在同目錄下看到兩個新增的檔案:

其中 MicrosoftACECodeAnalysisReport.xml 是完整的分析報告,以 XML 方式儲存。另一個是 report.html 是給人看的,裡面有問題描述、出現問題的程式行號、以及建議的解決之道。

其中 MicrosoftACECodeAnalysisReport.xml 是完整的分析報告,以 XML 方式儲存。另一個是 report.html 是給人看的,裡面有問題描述、出現問題的程式行號以及建議的解決之道。

Code Analysis Report

除了以上兩種方式外,事實上還可以跟 FxCop 與 MSBuild Task 結合,讓開發流程中導入 CAT.NET 成為標準化流程中的一環,建議可參考以下文章:Running CAT.NET as a Custom MSBuild Task

我個人是很期待正式版的推出 (也許是 V2.0 才會出正式版),不過我想應該還要等一段時間,畢竟資安工具是馬虎不得的,即便如此也並不代表這套工具不能用,事實上從微軟部落格得知,微軟內部也是用這套來掃瞄他們開發的軟體,所以建議各位可以一試。

相關連結

  

此文章由 will 發表於 2009/7/2 下午 04:46:01

永久連結 | 評論 (2) | 此文章的RSSRSS comment feed |

分類: .Net | 介紹好用工具 | Security

標籤: ,

收藏:

如何啟用 FileZilla Server 的 FTPS 功能 ( FTP over SSL )

之前找了一套支援 SFTP (FTP over SSH) 的 FTP Server 就是為了解決 Port 不夠用的問題,直到最近才發現我們常用的 FileZilla Server 原來就有支援 FTPS ( FTP over SSL ) 功能,雖然使用 FTPS 無法省 Port,但至少對資料傳輸的安全性來說絕對是大幅提昇。

要啟用 FileZilla Server 的 FTPS 功能可參照以下步驟:

1. 先啟用 SSL/TLS 支援,然後建立一個測試用憑證

FileZilla Server: 先啟用 SSL/TLS 支援,然後建立一個測試用憑證

2. 輸入一些基本資料,如果這台 FTP 是自己用的,就不用講究這麼多啦,隨便填一填,最後要指定儲存憑證的檔名與路徑,再按下 Generate certificate 即可。這裡建立的憑證預設有效期限只有一年而已,若要建立較長時間的憑證可以利用 Windows Server 內建的憑證管理工具建立憑證。

輸入一些基本資料,如果這台 FTP 是自己用的,就不用講究這麼多啦,隨便填一填,最後要指定儲存憑證的檔名與路徑,再按下 Generate certificate 即可。

3. 接著他會自動幫你填入自建的憑證路徑,直接按下 OK 即可設定完成。

image

最後在設定 FileZilla Client 的「站台管理員」中設定連線時,記得要選對「伺服器種類」,要選取「FTPS - 透過隱含式 TLS/SSL 的 FTP」才會利用 FTPS 連線喔。

image

第一次連線時,由於憑證是自建的,沒有信任關係,所以才會出現「未知的憑證」警告畫面,你可以勾選「總是信是未來連線的憑證」即可跳過這個警告。

第一次連線時,由於憑證是自建的,沒有信任關係,所以才會出現「未知的憑證」警告畫面,你可以勾選「總是信是未來連線的憑證」即可跳過這個警告。

底下你可以看到連線時的狀態,預設 FTPS 的 Port 為 990,由於 SSL/TLS 在 TCP 連線時要先進行 Handshake 驗證憑證,所以當 TCP 連線建立後會先驗證憑證,通過後才會開始進行 FTP 指令,也代表著利用 FTP 傳輸檔案的安全性將大大提升。

你可以看到連線時的狀態,預設 FTPS 的 Port 為 990,由於 SSL/TLS 在 TCP 連線時要先進行 Handshake 驗證憑證,所以當 TCP 連線建立後會先驗證憑證,通過後才會開始進行 FTP 指令,也代表著利用 FTP 傳輸檔案的安全性將大大提升。

2009-07-02 更新

使用 FTPS 一樣需要區分 Command Channel 與 Data Channel,所以一樣會用到不只一個 Port,所以防火牆一樣需要設定正確才能通。

相關連結

  

此文章由 will 發表於 2009/7/1 下午 01:30:49

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: 介紹好用工具 | 系統管理

標籤: , , ,

收藏:

ASP.NET 若需用非預設帳號執行,必須妥善設定相關權限

在 IIS 中,應用程式集區使用的身份識別為 Network Service,而 ASP.NET 應用程式預設的執行權限也是這個身份,當我們需要以非預設的權限執行 ASP.NET 時通常有兩種作法:1) 修改 應用程式集區的身份識別、2) 設定 web.config 中的 <identity> 參數。

針對第一種狀況,除了要參考我另一篇【IIS應用程式集區自訂身份識別後如何讓 ASP.NET 正常執行】文章之外,在該文章「備註二」,可以替換成以下指令:

cd C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727
aspnet_regiis -ga User1

在 aspnet_regiis /? 所輸出的說明是

-ga <user>     針對 ASP.NET 所使用的 IIS Metabase 和其他目錄,授與指定的使用者或群組存取權限。

也就是說,只要利用 aspnet_regiis.exe 就可以幫我們設定完所有該設定的權限,不需要額外手動調整。

而第二種狀況,就是修改 web.config 中的 <identity> 參數,如下範例:

<identity impersonate="true" userName="User1" password="MyPassW0rd"/>

若要透過這種方式運作 ASP.NET 一樣會遇到許多權限不足的情況,建議也是透過 aspnet_regiis 幫你設定相關權限即可。

相關連結

  

此文章由 will 發表於 2009/6/29 下午 11:47:23

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: ASP.NET | IIS

標籤: , , , , ,

收藏:

如何利用 .NET 檢查某「路徑字串」是檔案或目錄

這好像不是什麼有意義的題目,雖然我知道有 File.ExistsDirectory.Exists 可用,只是我昨天心血來潮想找找 .NET Framework 中是否有檢查某「路徑字串」是「檔案」或「目錄」的方法(Method),一開始先猜想 Path 類別是否有相關的 Method,但找不到。

如果你今天得到一個「路徑字串」,光從字串中是無法判定這是檔案或目錄的,「檔案」通常都有副檔名,但也可以沒有;而「目錄」通常都沒有副檔名,但也可以有。所以無論如何都需要有個判斷方法。

既然找不到簡單的方法,就必須用傳統的方法判斷,如下範例:

if (File.Exists(strPath))
{
    // 有效的檔案
}
else if (Directory.Exists(strPath))
{
    // 有效的目錄
}
else
{
    // 無效的路徑(檔案或目錄不存在)或沒有讀取權限。
}

我們在判斷路徑字串時,大多時候得到的路徑字串都是檔案居多,所以應該先判斷「是否為檔案」,然後再判斷「是否為目錄」,當兩者條件都不成立時,就代表該路徑不存在,或該路徑沒有讀取權限。

至於對檔案或目錄的操作,可以多參考以下類別的 MSDN 文件說明:

  

此文章由 will 發表於 2009/6/28 下午 03:19:49

永久連結 | 評論 (2) | 此文章的RSSRSS comment feed |

分類: C# | .Net

標籤: , , ,

收藏:

當 System.DirectoryServices 發生「驗證機制不明」的錯誤

今天又遇到一個奇特的狀況,之前一個已經跑了將近三年且運作正常的系統,由於該系統必須連接本機的 ADAM 進行身份驗證,卻突然間開始出現【驗證機制不明】的錯誤,讓我丈二金剛摸不著頭緒。

中文錯誤訊息如下

System.Runtime.InteropServices.COMException: 驗證機制不明。

英文錯誤訊息如下

System.Runtime.InteropServices.COMException: The authentication mechanism is unknown.

由於程式在進行任何 AD 節點(Node)操作時都必須先透過 Binding 的程序,並傳入帳號密碼登入驗證:

DirectoryEntry dnNode = new DirectoryEntry(BasePath + mCurrentDN, Username, Password);

而我傳入的帳號密碼一直都沒有加上 Domain\ 的部分,例如:

string Username = "LoginUser";

結果,解決這個問題的方法只要加上本機電腦的名稱即可:

string Username = "COMPUTERNAME\LoginUser";

相關連結

  

此文章由 will 發表於 2009/6/27 下午 06:43:25

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: .Net | Tips

標籤: , , ,

收藏:

在 .NET 中撰寫 String.Contains 方法時容易犯的錯誤

.NET Framework 中的 String.Contains 方法從 .NET 2.0 時就開始出現,但你可能從未想過這個問題,這個簡單的 String.Contains 方法到底有什麼該注意的地方呢。先考各位一段簡單的程式碼,並先仔細想想如果以下程式碼執行完後,變數 b 的值應該是 True 或 False 呢?

string s1 = "The quick brown fox jumps over the lazy dog";
string s2 = "";
bool b;
b = s1.Contains(s2);

不蠻各位,連我在寫類似這段程式時,大多從心裡直覺的認為答案是 False,直到上週才發現一個幾個月前完成的專案竟然開始出現一些不合理的結果,原本不應該出現的資料全部都出現了。

我會想說,s1 有一堆字串,而 s2 卻是空字串,當判斷 s1 是否包含「空字串」時,怎麼可能會是 True 呢?

我也好奇的問了多位有在寫 .NET 的朋友,不少都是 .NET 撰寫多年且實力不差的開發人員,大家都一致的回答 False

我都說成這樣了,還有人認為答案是 False 嗎?除了我親自跑程式驗證過答案是 True 外,也轉貼 MSDN 上關於 String.Contains 方法的說明,如下圖示:

.NET Framework 類別庫 - String.Contains 方法

這樣的結果著實讓我匪夷所思,像這種簡單到爆的方法(Method)誰會真的認真到仔細的看這種 Method 的 MSDN 文件,而這種違反直覺判斷的程式行為實在是需要「經驗」,遇到了才知道,即便是如此簡單的字串用法。

※ 2009-06-26 補充說明

我多列出幾個跟 String 類別有關的字串比對 Method,供各位參考:

Console.WriteLine("123".Contains(""));    // True
Console.WriteLine("123".StartsWith(""));  // True
Console.WriteLine("123".EndsWith(""));    // True
Console.WriteLine("123".IndexOf(""));     // 0
Console.WriteLine("123".LastIndexOf("")); // 2

總之「空字串」代表的不是「字串」,而擁有一個特殊的意義,你可以想像著每一個字串開頭結尾都會包括一個「空字串」,這個「空字串」本身不佔空間,但卻存在這樣一個虛擬字元,緊緊黏在第一個字元最後一個字元上。

我不知道這樣說明會不會對某些人來說太複雜,但我自己是這樣想像的,可以幫助我記憶這個現象,這樣想以後寫程式的時候就比較不會出錯了。

相關連結

  

此文章由 will 發表於 2009/6/25 下午 08:17:25

永久連結 | 評論 (10) | 此文章的RSSRSS comment feed |

分類: .Net

標籤: ,

收藏:

如何在批次檔(Batch)中實現 sleep 命令讓任務暫停執行 n 秒

在批次檔(*.bat)中內建並沒有 SLEEP 命令,當你在執行批次任務時若需要暫停執行幾秒鐘,就需要一些小技巧來實現了,以下分享幾個我之前用過的技巧:

1. 利用 PING 指令幫忙停 5 秒

   每壹台電腦都有 PING 執行檔,這個最好用啦!

@ping 127.0.0.1 -n 5 -w 1000 > nul

2. 利用 CHOICE 指令

   CHOICE 命令在 Windows XP 中找不到,但在 Windows Server 2003 或 Vista 都有內建。

@CHOICE /C YN /N /T 5 /D y > nul

3. 安裝 Windows Server 2003 Resource Kit Tools 即可獲得 sleep.exe 工具

   預設安裝路徑在 C:\Program Files\Windows Resource Kits\Tools 目錄下會有個 sleep.exe 執行檔

sleep 5

相關連結

  

此文章由 will 發表於 2009/6/24 下午 11:46:26

永久連結 | 評論 (1) | 此文章的RSSRSS comment feed |

分類: Tips | 系統管理

標籤: , , ,

收藏:

PowerShell 執行非 .NET 程式在輸出資料時要注意編碼問題

我今天發現 PowerShell 有個非常需要小心運用的地方,就是在執行非 .NET 應用程式時,當利用 Out-File 或 pipe 運算子 ( > ) 輸出至文字檔時很容易會有編碼錯亂的問題,如果一不小心設定,你輸出的所有文字全部都會變成亂碼,而且是無法復原的亂碼!

我今天利用 PowerShell 執行 mysqldump 指令將 MySQL 資料庫匯出成檔案,執行的指令如下:

&mysqldump -u $strUserName "-p$strUserPassword" $strDBName > "$strDBName-$Today.sql"

看起來是多麼的理所當然阿,但魔鬼總在細節裡

首先,當你執行 mysqldump 指令時,所預設輸出字集是 UTF-8 編碼,你自然也會很理所當然的認為輸出的 "$strDBName-$Today.sql" 檔案也是 UTF-8 編碼,而且結果也不例外,輸出的檔案用 Notepad++ 開啟後的確也是 UTF-8 編碼。

在 DOS 模式下執行 mysqldump 指令匯出資料的時候中文正常的,而且是 UTF-8 編碼

在 DOS 模式下執行 mysqldump 指令,再匯出資料的時候中文是正常的,而且是 UTF-8 編碼

但是在 PowerShell 模式下執行 mysqldump 指令匯出資料的時候中文卻是亂碼,但文件還是 UTF-8 編碼!

在 PowerShell 模式下執行 mysqldump 指令匯出資料的時候中文卻是亂碼,但文件還是 UTF-8 編碼!

如果開啟 mysqldump 匯出的資料檔,在編輯器第一頁可能看不到任何中文字,所以你也許會誤以為檔案匯出成功,而放心的度假去了。

由於 PowerShell 核心就是 .NET 執行環境,當你執行非 .NET 應用程式時,PowerShell 卻會以系統預設字集當成所有文字派送管道(pipeline),所以就算 mysqldump 輸出的文字編碼是 UTF-8,PowerShell 依然會將他認為是 Big5 (繁體作業系統下的預設編碼),但是 PowerShell 雖然是以 Big5 作為 mysqldump 的輸入編碼,但透過大於符號 ( > ) 輸出的檔案卻是以 UTF-16 編碼 ( 因為 PowerShell 就等於 .NET,所有 .NET 的文字處理預設用 UTF-16 進行編碼 )。

為了驗證上述觀念,我利用 Jeffery Lee 所開發的 中文編碼解析 Ver 1.31 版 分析被弄成亂碼的文字:

利用 Jeffery Lee 所開發的 中文編碼解析 Ver 1.31 版 分析被弄成亂碼的文字 

你可以看到,原本的 [平裝] 透過 mysqldump 輸出時的確是 UTF-8 編碼,但是 PowerShell 卻以 Big5 碼進行處理,我試著用內碼輸入法依序輸入 E5 B9 B3 E8 A3 9D 等十六進制位元,所得到的文字正好就是變亂碼的 [撟唾?]。其中 E5 B9 正是 Big5 編碼的 [],B3 E8 正是 Big5 編碼的 [],而最後的 A3 9D 並不是有效的 Big5 文字,所以才會出現問號 ( ? )。

我試著用內碼輸入法依序輸入 E5 B9 B3 E8 A3 9D 等十六進制位元

這就是典型的文字編碼錯亂事件,而且由於這種文字錯亂的現象是先從 UTF-8 轉成 Big5 編碼,此時已經有些編碼轉不過去了,所以變成問號,也就是說原本的 A3 9D 這兩個位元(byte)只會變成一個問號位元 ( 3F ),文字已經不完整了。之後再從一個不完整的 Big5 字元再轉成 UTF-16 編碼,這時的文字已經殘破不堪,而且幾乎無法逆轉。

這種問題我遇到不止一次了,老外寫軟體總是不仔細考慮非英語系使用者的困難,而且像這種問題微軟根本不應該再允許發生,透過程式比對非 .NET 應用程式的輸出是不是 UTF-8 應該很容易阿,為什麼不多做一點檢查呢?!

若要解決 mysqldump 輸出文字混亂的情況,可以指定輸出的字集為 Big5 就能輸出正常的編碼,例如:

&mysqldump -u $strUserName "-p$strUserPassword" --default-character-set=big5 $strDBName > 
    "$strDBName-$Today.sql"

不過,也只有 DML (資料操作語言) 的部分才會正常 [資料部分],原本在 DDL (資料定義語言) 的部分 [結構部分] 依然會輸出 UTF-8 編碼,所以輸出後的結果依然會出問題。在此建議的作法是套用 mysqldump 的 -r 選項,直接在 mysqldump 執行時直接指定輸出檔名與路徑,例如:

&mysqldump -u $strUserName "-p$strUserPassword" -r "$strDBName-$Today.sql" $strDBName

最後給PowerShell使用者的由衷建議

當執行非 .NET 應用程式時,不要用 PowerShell 執行文字資料匯流排(pipe)功能,否則你會欲哭無淚

給微軟開發 PowerShell 團隊的建議

別再害我的資料毀損了,PowerShell 又不是什麼需要超高效能的運算能力,不就是一些腳本嘛,多花點 CPU 時間判斷我原本程式輸出的文字編碼吧,總比把客戶的資料搞亂掉的好些。(希望有人可以幫我回報)

  

此文章由 will 發表於 2009/6/23 下午 08:28:41

永久連結 | 評論 (0) | 此文章的RSSRSS comment feed |

分類: .Net | 系統管理 | MySQL

標籤: , ,

收藏:

如何利用 .NET 對 byte[] 進行 Reguar Expression 比對

記得以前在寫 Perl 或 PHP 時都可以直接用內建的 Regular Expression 功能直接比對二進位的字串內容,但到了 .NET 就不知道怎麼做了,因為當你使用 System.Text.RegularExpressions 命名空間所接受的輸入參數只有 String 型別,並不接受 byte[] 位元陣列。

你可能會問,怎麼會有這種需求呢?採用 Regular Expression 不就是為了要做字串樣式比對嗎,為什麼有必要用來比對二進位的資料呢?

例如在 Perl 中,沒有十分明確的型別(Type)觀念,所有變數都是動態轉型的,所以當我們從檔案讀入所有內容時,不管是文字檔二進位檔都可以儲存在變數中,所以當我們要用 Regular Expression 比對出檔案內容中所有的 UTF-8 字串,就可以用以下 Regular Expression 取法獲得:

$field =~
  m/\A(
     [\x09\x0A\x0D\x20-\x7E]            # ASCII
   | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
   |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
   | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
   |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
   |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
   | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
   |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
  )*\z/x;

這是一種多麼直覺的用法阿!你可以比對出任意檔案的內容,直接用二進位比對文字編碼,用以判斷該檔案採用哪一種編碼(Encoding),不過到了 .NET 就沒那麼直覺了。

事實上,.NET 也可以這樣寫,你可以從逸出字元文件得知在 .NET 中也有支援符合使用十六進位表示的 ASCII 字元比對 ( 例如: 0x20 ),所以上述 Perl 語法的 Regular Expression 也可以完整搬到 .NET 上,若用 C# 語法表示範例如下:

Regex rx = new Regex(@"[\x09\x0A\x0D\x20-\x7E]            # ASCII
                     | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
                     |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
                     | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
                     |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
                     |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
                     | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
                     |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
                    ", RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline);

不過,當你要將一個 未知編碼(Unknown Encoding) 的檔案讀入比對時,卻會立即發生問題,例如:

string data = File.ReadAllText(@"C:\test.txt");

當在嘗試使用 File.ReadAllText 方法且不指定編碼的情況下,預設會先判斷檔案內容的 BOM (byte order marks) 字元用以決定檔案的編碼,如果沒有 BOM 字元就會預設以本機的預設編碼 (繁體系統就是 Big5 編碼) 讀入。

對於所有編碼,在 .NET Framework 內部的字串都是 UTF-16 字串,所以只要檔案內容被強迫指定編碼後,所有原本檔案中的 byte order 在讀入 .NET 記憶體中之後就會被打亂,所以你就無法透過 .NET 內建的 Regular Expression 比對原本檔案中二進位字元的 byte 範圍。

所以如果需要將讀入的資料維持原狀,也且可以透過 .NET 的 Regular Expression 進行位元比對,就必須要利用下列程式碼進行讀入,讓檔案中「每一個位元」都轉換成一個 UTF-16 的字元(Char)。由於每一個位元(Byte)的範圍都固定從 U+0000 to U+ffff,所以我們可以利用這個特色將每一個 byte 都轉換成 Char 字元,先儲存到 List<Char> 中,最後再轉換成字串(String)。

byte[] _bytes = File.ReadAllBytes(@"C:\test.txt");
List<char> _cList = new List<char>();
foreach (byte b in _bytes)
{
    _cList.Add((char)b);
}
string data = new string(_cList.ToArray());

成功將檔案內容轉成一連串的 Char 字元並轉成 String 後,就可以利用上述的 rx 物件進行比對了,如下範例:

foreach (Match mx in rx.Matches(data))
{
    byte[] bb = new byte[mx.Value.Length];
    Console.Write("Length: {0} ", mx.Value.Length);
    Console.Write("Bytes: ");
    for (int i = 0; i < mx.Value.Length; i++)
    {
        bb[i] = (byte)mx.Value[i];
        Console.Write("{1}(0x{2:X}) ", i, bb[i], bb[i]);
    }
    string a = Encoding.UTF8.GetString(bb);
    Console.WriteLine("\tChar: [{1}]", mx.Value.Length, a);
}

透過這個方式就可以利用 .NET 直接對任意檔案進行二進位位元的 Regular Expression 比對,這看起來似乎是很罕見的使用方式,但卻很適合用來判斷來源檔案的文字編碼(Encoding),如果要拿來比對二進位檔案的病毒特徵碼我想應該也是有可能的。

我一直很想找到這種比對方式的唯一目的就是因為 .NET 在讀入文字檔或讀入 Stream 資料時 (例如透過WebClient 類別下載網頁),時常因為在讀入資料前不知道來源資料的編碼(Encoding),而導致資料下載後全部變成亂碼。

我之前為了找這個方法找了好幾年,每次找到一半就放棄,且每次都要用很長的程式碼與一堆 if 判斷式達成這個目的,直到今天才找到這個完美的方法。

相關連結

  

此文章由 will 發表於 2009/6/22 下午 03:04:23

永久連結 | 評論 (4) | 此文章的RSSRSS comment feed |

分類: .Net | C# | Tips

標籤: , , , , , ,

收藏:

介紹 jQuery Tools 與 jQuery UI 這兩套好用的 jQuery 套件

我想家喻戶曉的 jQuery UI 套件應該不用特別介紹了,但我最近又看到一套不錯的 jQuery Tools 套件,相較於知名且多功能的 jQuery UI 套件,jQuery Tools 提供一種額外的選擇,他只提供幾種網站上最常用的功能,包括 Tabs、Tooltips、Expose、Overlay、Scrollable、Flashembed 等,其中的 Flashembed 就可以取代我們之前常用的 swfobject 套件,他還支援 SIFR 功能喔。光聽我說還不夠,最好立即看看線上展示,你就知道有哪些酷炫實用的效果了。

jQuery TOOLS - The missing UI library for the Web

整個套件在透過 gzip 壓縮過僅 5.8KB 除了下載快,JavaScript 的執行速度也號稱相當快,而且還提供 CDN (Content Delivery Network) 下載連結如下:

<script src="http://cdn.jquerytools.org/1.0.2/jquery.tools.min.js"></script>

當然在載入 jQuery Tools 還是必須先載入 jQuery 的,目前的 1.0.2 版相容於 jQuery 1.3.2 版。若要透過 Google 的 CDN 網路下載 jQuery 可以參考我這篇文章的說明,或直接用以下語法載入 jQuery:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>

即便 jQuery Tools 也是另一個佛心級的開放原始碼產品(免費),但有趣的是我還看到網路上有人直接拿 jQuery Tools vs jQuery UI 做評比,而且還引發不小的爭論,連 jQuery Tools 的作者也參與討論,也連帶的促進 jQuery Tools 的進步,讓 jQuery Tools 與 jQuery Plugins 架構的相容性更高,相信日後會有越來越好用的新功能出現,值得關注。

相關連結

  

此文章由 will 發表於 2009/6/21 上午 12:41:13

永久連結 | 評論 (1) | 此文章的RSSRSS comment feed |

分類: JavaScript | Web

標籤: , ,

收藏: