.Net 反汇编调试教程
開篇之鄭重聲明
? ? 本系列文章的目的在于通過研究底層,來加強編程技術,涉及到類似于破解等等方面的細節,將不會列出。
第一章 IL匯編語言精要
第二章 .Net反匯編工具
一?reflector
程序集,是.NET時代的動態鏈接庫。Visual Studio內置的ILDASM成為最初挖掘程序集的上佳工具。但,Reflector能提供更多的程序集信息,而且免費。
在Visual studio中編譯源代碼(無論是VB還是C#)時,編譯器都會將高級源代碼翻譯成MSIL,即“微軟中間語言”,而不是特定的機器指令。具有更多安全性、版本控制、共享能力與其它相關元數據的中間語言(IL),是包在一個或多個DLL或可執行文件中的。
基于ILDASM檢查程序集中的IL有時很有用。
Reflector可以將.NET程序集中的中間語言反編譯成C#或者Visual Basic代碼。除了能將IL轉換為C#或Visual Basic以外,Reflector還能夠提供程序集中類及其成員的概要信息、提供查看程序集中IL的能力以及提供對第三方插件的支持。
? ? ? ? 默認情況下,Reflector會打開一組公共程序集(mscorlib、System、System.Data、System.Drawing等等)。每個打開的程序集都列在Reflector的主窗口中。單擊程序集旁邊的+圖標可以展開樹結構并展示程序集的命名空間。每個命名空間旁邊都有一個相關的+圖標,單擊這個圖標將顯示這個命名空間內的類。除此以外,還可以展開每個類,顯示類的成員:事件、字段、方法與屬性。想查看其它程序集(包括我們自己創建的程序集)的細節,你可以使用菜單命令“File→Open”。然后,瀏覽到想要查看的程序集。示例如下圖,
? ? 只要瀏覽到類級的成員,就可以通過Tools菜單中的Disassembler項(或在該項上單擊右鍵)反匯編此成員。這將打開第二個窗格,以C#、Visual Basic、Delphi或者IL顯示反匯編后的內容。
? ??目前市場上的.NET混淆產品有:PreEmptive Solution的Dotfuscator、WiseOwl的Dmeanor以及Remotesoft的.NET Obfuscator等。
? ??? ? Reflector還可以顯示類與其成員的調用與被調用圖、提供單鍵訪問Google或MSDN搜索的能力并提供了允許第三方開發人員為Reflector創建插件的框架。
要查看調用或被調用圖,只需要在樹視圖中選擇一個成員,訪問Tools菜單,選擇Call Graph或Callee Graph選項即可。Call Graph會列出所選項所調用的成員,而Callee Graph列出調用所選項的成員。
通過使用插件,Reflector的功能可以得到進一步擴展。目前有能顯示程序集依賴圖、自動加載當前運行中的程序集、輸出整個程序集的反匯編內容以及在Visual Studio中作為Reflector的宿主等的插件。
存在一個Reflector.VisualStudio插件。有了這個插件,就可以讓Reflector集成在Visual Studio環境中,進而取代以前那個有些“拙漏”的對象瀏覽器。有人試過,似乎無大用。
第三章 VS調試
二 斷點
? ? 為源行、程序集指令和調用堆棧函數設置斷點。 指定條件、命中次數和執行位置。 打印跟蹤點。 保存并導出斷點。
? ? 創建可在需要時中斷的斷點
? ? 標準斷點是開發人員的工具箱中最重要的調試技術之一,它會在每次命中源文件位置時中斷調試器執行。 Visual Studio 可幫助您超出標準斷點,以便創建對執行斷點的時間和位置的細化控制。
? ? 您可設置當您的程序返回調用堆棧上的函數時暫停執行的運行時斷點,并避免長序列的“跳出”命令。
? ? 如果您懷疑在一定數量的迭代后代碼中的循環開始產生錯誤行為,則可以設置斷點,以在指定的命中數傳入相關的代碼行后停止執行,而不是強制重復按 F5(“調試”、“繼續”)以達到迭代級別。
? ? 通過使用代碼表達式,您可以指定斷點中斷的具體條件。
? ? 您可使用“斷點”窗口來管理大量斷點的狀態和行為。 如果您已小心構造斷點序列以診斷常見的或特別復雜的問題,則可以使用“斷點”窗口導入和導出命令來保存或共享這些斷點。
? ? 避免當正在調試混合模式(本機和托管)代碼時在系統組件上設置斷點。 在混合模式調試期間,如果在系統組件上設置斷點,則會導致公共語言運行時中斷并使調試器停止響應。
?
? ? 在“調用堆棧”窗口中的函數返回處設置斷點
? ? 可通過在“調用堆棧”窗口中設置斷點來中斷調用函數返回到的指令或行處的執行。 調試器必須處于中斷模式。
? ? 打開“調用堆棧”窗口(快捷鍵:Ctrl + Alt + C),并選擇要中斷的調用函數。
? ? 在上下文菜單中選擇“斷點”、“插入斷點”,或者僅使用快捷鍵:F9。
? ? 斷點符號出現在函數調用名稱旁的左邊距中。
? ? 如果打開“斷點”窗口(快捷鍵:Ctrl+Alt+B),則該斷點顯示為一個地址斷點,此地址斷點具有一個與函數中下一個可執行指令相對應的內存位置。 調試器在指令處中斷執行。
? ??
? ? 若要在執行代碼期間直觀地跟蹤斷點,請參閱在 Visual Studio 中調試時映射調用堆棧上的方法。
? ??
? ? 在“反匯編”窗口中的程序集指令處設置斷點
? ? 若要在程序集指令處設置斷點,必須使調試器處于中斷模式下。
? ? 打開“反匯編”窗口(快捷鍵:Ctrl + Alt + D)。
? ? 執行下列操作之一:
? ? 在窗口的滾動條槽中雙擊您想中斷的行。
? ? - 或 -
? ? 選擇該行并選擇 F9。
? ? 在源行、程序集指令或調用堆棧函數處設置斷點
? ? 在源窗口、“調用堆棧”窗口或“反匯編”窗口中,打開斷點的上下文菜單并選擇屬性。
? ? 在“斷點”窗口中,選擇斷點行并打開上下文菜單。 也可在條件列中直接設置一些條件。
? ? 當斷點被命中次數、表達式計算、執行位置或數據更改中斷時進行指定
? ? 指定斷點執行的命中次數 ? 使用代碼表達式指定斷點條件 ? 指定斷點執行的設備、進程或線程 ? 設置數據更改斷點(僅限本機 C++)
? ? 指定斷點執行的命中次數
? ? “命中次數”跟蹤斷點的命中次數。 您設置值和條件,以使滿足以下條件之一時執行斷點:命中次數等于值、等于指定值的倍數或大于或等于值。 指定命中次數和條件:
? ? 打開“命中次數斷點”對話框。
? ? 在源窗口、“反匯編”窗口或“調用堆棧”窗口中,選擇包含斷點的行,然后選擇上下文菜單上的“斷點”、“命中次數”。
? ? - 或 -
? ? 在“斷點”窗口中,選擇一個斷點行,然后選擇上下文菜單上的“命中次數”。
? ? 選擇條件并輸入命中次數。
? ? 命中次數條件有助于在一定數量的迭代中中斷循環。 如果您要對斷點的命中次數進行計數,也可指定非常大的數量,但不要中斷執行。
? ? 僅為調試會話保留指定的命中次數。 在調試會話結束時,命中次數將重置為零。
?
? ? 當斷點被命中次數、表達式計算、執行位置或數據更改中斷時進行指定
? ? 使用代碼表達式指定斷點條件
? ? 斷點條件是一個到達斷點時調試器將計算的表達式。 如果滿足條件,調試器將中斷執行。
? ? 條件可以是調試器能夠識別的任何有效表達式。 例如,在一個銀行業務程序中,您可以設置 balance < 0 等斷點條件。?
? ? 指定斷點條件
? ? 打開該斷點的上下文菜單,然后選擇“條件”。
? ? 在“斷點條件”對話框中,在“條件”框中輸入有效表達式。
? ? 如果想要在滿足表達式時中斷,請選擇“為 true”;如果想要在表達式的值已更改時中斷,請選擇“已更改”。
? ? 直到第一次到達該斷點后,調試器才會計算該表達式。 對于本機代碼,如果選擇“已更改”,則調試器不會將條件的第一次計算當作一次更改,所以第一次計算時不會命中斷點。 對于托管代碼,如果選擇“已更改”,則選擇“已更改”之后的第一次計算時便會命中斷點。
? ? 如果在設置斷點條件時使用了無效語法,將立即出現警告消息。 如果在指定斷點條件時使用的語法有效但語義無效,則在第一次命中斷點將出現警告消息。 在這兩種情況下,當命中無效斷點時,調試器都會中斷執行。 只有當條件有效并且條件的計算結果為 false 時,才會跳過斷點。
?
? ? 當斷點被命中次數、表達式計算、執行位置或數據更改中斷時進行指定
? ? 指定斷點執行的設備、進程或線程
? ? 打開該斷點的上下文菜單,然后選擇“篩選器”。
第四章 靜態分析
? ? 一段關于窗口根據判斷是否注冊而選擇顯示“Licensed to XXXX”還是未注冊的示例代碼。
? .method private instance void ?xb4fe74a3788695e0(object x897f7d97ff45d640,?
? ? ? ? ? ?class [mscorlib]System.EventArgs x92a51111cd18ca81) cil managed?
? {?
? ? // Code size ? ? ? 122 (0x7a)?
? ? .maxstack ?7?
? ? .locals init (class CodeLib.xf9b7e3b2c792f083 V_0)?
? ? IL_0000: ?newobj ? ? instance void CodeLib.xf9b7e3b2c792f083::.ctor()?
? ? IL_0005: ?stloc.0?
? ? IL_0006: ?ldsfld ? ? bool CodeLib.x83a1ac2c48984168::x6ae105ff7a55905e //注意這句?
? ? IL_000b: ?brfalse.s ?IL_0017 ?//然后這里跳轉?
? ? IL_000d: ?ldloc.0?
? ? IL_000e: ?callvirt ? instance class [System.Windows.Forms]System.Windows.Forms.Label CodeLib.xf9b7e3b2c792f083::get_x6bc866479ed84b6d()?
? ? IL_0013: ?br.s ? ? ? IL_0043?
? ? IL_0015: ?br.s ? ? ? IL_0072?
? ? IL_0017: ?ldloc.0?
? ? IL_0018: ?callvirt ? instance class [System.Windows.Forms]System.Windows.Forms.Label CodeLib.xf9b7e3b2c792f083::get_x6bc866479ed84b6d()?
? ? IL_001d: ?ldstr ? ? ?bytearray (AF 06 CD 0D CF 14 78 1B A7 22 B7 29 B6 30 B5 37 ? // ......x..".).0.7?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? BC 3E BA 45 A8 4C B2 53 A2 5A 9E 61 58 68 ) ? ? ? // .>.E.L.S.Z.aXh?
? ? IL_0022: ?ldc.i4 ? ? 0x5c4c0661?
? ? //解碼后的信息?
? ? //Not Registered!?
? ? IL_0027: ?call ? ? ? string xed3d7768b7546353.x7846ebd83ad1c299::_bc22ed13a5229081(string,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?int32)?
? ? IL_002c: ?call ? ? ? string [mscorlib]System.String::Intern(string)?
? ? IL_0031: ?callvirt ? instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)?
? ? IL_0036: ?ldloc.0?
? ? IL_0037: ?callvirt ? instance class [System.Windows.Forms]System.Windows.Forms.Label CodeLib.xf9b7e3b2c792f083::get_x6bc866479ed84b6d()?
? ? IL_003c: ?call ? ? ? valuetype [System.Drawing]System.Drawing.Color [System.Drawing]System.Drawing.Color::get_Red()?
? ? IL_0041: ?br.s ? ? ? IL_006d?
? ? IL_0043: ?ldstr ? ? ?"Licensed to "?
? ? IL_0048: ?ldsfld ? ? string CodeLib.x83a1ac2c48984168::xa07a59ecbea7b301?
? ? IL_004d: ?ldstr ? ? ?"Settings"?
? ? IL_0052: ?ldstr ? ? ?"User"?
? ? IL_0057: ?ldstr ? ? ?""?
? ? IL_005c: ?call ? ? ? string [Microsoft.VisualBasic]Microsoft.VisualBasic.Interaction::GetSetting(string,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?string,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?string,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?string)?
? ? IL_0061: ?call ? ? ? string [mscorlib]System.String::Concat(string,?
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? string)?
? ? IL_0066: ?callvirt ? instance void [System.Windows.Forms]System.Windows.Forms.Control::set_Text(string)?
? ? IL_006b: ?br.s ? ? ? IL_0015?
……?
總結
以上是生活随笔為你收集整理的.Net 反汇编调试教程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows命令行工具实验
- 下一篇: GIS程序功能演示