共兩篇,第一篇和殼本身的過程關係不大,主要是涉及了虛方法的內容,第二篇則詳細調試了CLISecure的保護原理。在我的blog上名為CLR核心調試隨記,因為是隨記,所以文章中可能有不全面甚至錯誤的地方。找到錯誤的朋友請與偶聯絡。性急的兄弟請直接看第二篇。
本文章所調試殼為CLISecure,下載地址為http://www.secureteam.net/,最新版本為3.0,而我所調試的版本為2.5,所以可能與最新的殼有所不同。
CLR核心隨記(1)
把平時看到的一些東西記下來,沒準以後用的上。
本文利用調試跟蹤CLR中介面virtual方法的定位。為什麼呢?好玩兒而已。
這是在某殼掛鈎JIT的代碼,有些東西還是很有意思(總是覺得這些殼作者知道很多CLR的內部結構,估計微軟對他們部分開源了):
.text:10002A4C mov eax, [ebp+ICorJitInfo]
.text:10002A4F mov ecx, [eax+4]
//此時ecx==.text:79E97C14 const CEEJitInfo::`vbtable’{for `ICorJitInfo’},第一個雙字是什嗎?第一個雙字指向
.text:79E97B14 dd offset [thunk]:CEEInfo::getHelperName`vtordisp{4294967292,52}’ (CorInfoHelpFunc)
到這裡,來看看CEEJitInfo::’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++寫成,也就是C++中的vtable在編譯時間確定,mscorwks.dll中的代碼如下:
.text:79E97C14 const CEEJitInfo::`vbtable’{for `ICorJitInfo’} dd 0FFFFFFFCh, 34h, 3Ch, 44h, 4Ch, 54h, 5Ch, 64h, 6Ch
.text:79E97C14 dd 74h, 80h
FCFFFFFF是what?誰知道,也許是一個vtable的開始標誌,因為在第三行最後又見到一個同樣的雙字。計算兩個FCFFFFFF之間的雙字值,可以先猜測這個vtable含有10個方法。不過sscli中對應的代碼卻多出了一兩個方法,這裡暫且不管,下面主要看怎麼定位這些vtable的。
.text:10002A52 mov edx, [ecx+4]
.text:10002A55 mov eax, [ebp+ICorJitInfo]
.text:10002A58 mov ecx, [eax+4]
.text:10002A5B mov eax, [ecx+4]
.text:10002A5E mov ecx, [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
總覺得後面那句mov edx,[ecx+edx+4]重複了,直接mov edx,[eax]不就可以了嗎?這時[eax]的值是79E97B78指向什嗎?它指向了下面一個方法:
.text:79E97B78 const CEEJitInfo::`vftable’{for `ICorMethodInfo’} dd offset [thunk]:CEEInfo::getMethodName`vtordisp{4294967292,52}’ (CORINFO_METHOD_STRUCT_ *,char const * *)