首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

.NET 加殼軟體 CLISecure 調試筆記(一):CLR 內核虛方法定位追蹤

     編輯:關於.NET

共兩篇,首篇與殼本身關係不大,聚焦 CLR 內核中介面虛方法定位機制;次篇詳細調試 CLISecure 保護原理。部落格原名「CLR 內核調試隨記」,屬隨手筆記,可能有疏漏錯誤,歡迎指正。急躁者請直接看第二篇。

調試殼:CLISecure,下載 secureteam.net,最新 3.0,調試版本 2.5,可能有差異。

CLR 內核隨記 (1) - 虛方法定位追蹤

追蹤 CLR 中介面虛方法定位,純屬好玩。某殼 Hook JIT 代碼中涉及此機制,頗有意思(殼作者似深諳 CLR 內部結構,推測微軟部分開源給他們)。

代碼片段分析

.text:10002A4C mov eax, [ebp+ICorJitInfo]
.text:10002A4F mov ecx, [eax+4]
; ecx 指向 CEEJitInfo::'vbtable'{for `ICorJitInfo'}
; 第一雙字指向 .text:79E97B14 dd offset [thunk]:CEEInfo::getHelperName...

記憶體中 vbtable 結構

79E97C14  FC FF FF FF 34 00 00 00 3C 00 00 00 44 00 00 00
79E97C24  4C 00 00 00 54 00 00 00 5C 00 00 00 64 00 00 00
79E97C34  6C 00 00 00 74 00 00 00 80 00 00 00 FC FF FF FF

編譯期確定(CLR 部分 C++ 實作)。FC FF FF FF 可能為 vtable 起始標記(結尾再見一次)。兩標記間雙字數暗示 10 個方法(SSCLI 代碼稍多,暫不深究)。

定位 getMethodName 過程

.text:10002A52 mov edx, [ecx+4]
.text:10002A55 mov eax, [ebp+ICorJitInfo]
...
.text:10002A61 lea eax, [ecx+eax+4]
.text:10002A65 mov ecx, [ebp+ICorJitInfo]
.text:10002A68 mov edx, [ecx+edx+4]

執行 lea eax 後,eax 指向記憶體:

0013EA18  78 7B E9 79 00 00 00 00 4C 7B E9 79 00 00 00 00
0013EA28  A8 7A E9 79 00 00 00 00 84 7A E9 79 00 00 00 00

[eax] = 0x79E97B78 指向:

.text:79E97B78 const CEEJitInfo::'vftable'{for `ICorMethodInfo'} dd offset [thunk]:CEEInfo::getMethodName...

即 ICorJitInfo vtable 含 getMethodName。但 SSCLI 代碼中 ICorJitInfo 無此方法。考慮繼承鏈:

class ICorJitInfo : public virtual ICorDynamicInfo
class ICorDynamicInfo : public virtual ICorStaticInfo
class ICorStaticInfo : public virtual ICorMethodInfo, public virtual ICorModuleInfo, ...

ICorStaticInfo 首繼承 ICorMethodInfo,其中定義:

class ICorMethodInfo {
  virtual const char* __stdcall getMethodName(CORINFO_METHOD_HANDLE ftn, const char** moduleName) = 0;
  virtual unsigned __stdcall getMethodHash(CORINFO_METHOD_HANDLE ftn) = 0;
}

虛方法定位完成。實為 C++ 編譯器記憶體佈局與運行期動態填充機制,與 CLR 核心關係不大。

CLR 內建 vtable 列舉

.text:79E977EC  mov [esi+4],  offset CEEJitInfo::'vbtable'{for `CEEInfo'}
.text:79E977F3  mov [esi+10h], offset CEEJitInfo::'vbtable'{for `ICorJitInfo'}
.text:79E977FA  mov [esi+88h], offset CEEInfo::'vbtable'{for `ICorStaticInfo'}
.text:79E97804  mov [esi+94h], offset CEEJitInfo::'vbtable'{for `ICorDynamicInfo'}
.text:79E9780E  mov [esi+44h], offset ICorStaticInfo::'vftable'{for `ICorMethodInfo'}
.text:79E97815  mov [esi+4Ch], offset ICorModuleInfo::'vftable'
.text:79E9781C  mov [esi+54h], offset ICorCompileInfo::'vftable'{for `ICorClassInfo'}
.text:79E97823  mov [esi+5Ch], offset ICorJitInfo::'vftable'{for `ICorFieldInfo'}
.text:79E9782A  mov [esi+64h], offset ICorDebugInfo::'vftable'
.text:79E97831  mov [esi+6Ch], offset ICorCompileInfo::'vftable'{for `ICorArgInfo'}
.text:79E97838  mov [esi+74h], offset CHashTableAndData::'vftable'

回到開頭 ICorJitInfo 表中第一值 0x34 定位至 getMethodName,第二值 0x3C 指向何方法?請自行追蹤。

下次將追蹤標記「for internal use」的 CLR 內部機制。環境:XP SP2 + .NET Framework 2.0 簡體中文版。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved