e核心自帶flash方案要比webkit複雜
Ie的flash插件是個ocx,也是com元件。
Windows Com元件的加載過程如下:
1、 通過元件的DllRegisterServer注冊com元件,會在系統資料庫生成com元件的路徑,guid,progid,threadtype等等
2、 Client通過guid查找到系統資料庫中com元件的位址,loadlibrary加載這個元件,調用com元件的DllGetClassObject接口,此接口傳回工廠類IClassFactory接口指針
3、 client通過IClassFactory接口,調用其createInstance接口或者QueryInterface接口可以擷取到真正的com應用接口
采用com庫函數CoCreateInstance,CoGetClassObject或者CoGetClassObjecFromUrl直接實作了上述過程
第一階段:
由于ie核心的封閉性,是以ie核心自帶flash方案一開始就确定了hookCoCreateInstance,CoGetClassObject、CoGetClassObjecFromUrl,修改ie核心加載flash元件的過程,讓ie核心加載我們自帶的flash元件
通過調試,發現ie核心是通過CoGetClassObject來加載flash ocx的,不調用CoCreateInstance,是以我們隻hook了CoGetClassObject、CoGetClassObjecFromUrl。在hook CoGetClassObject,讓ie核心加載了我們的flash ocx,按道理是可以在浏覽器上正常顯示flash插件了,但是事物的發展通常都是螺旋性的,雖然浏覽器拿到了flash的IClassFactory,但是還是沒顯示成功
第二階段:
無奈之下隻能分析其他浏覽器,

在windbg中輸入
bp ole32!CoGetClassObject
bp Kernel32!LoadLibraryEx
該浏覽器也hook了CoGetClassObject函數,通過ida分析和windbg動态調試,該浏覽器的方案是和我們一緻的,但是他可以,為什麼我們不可以呢
通過processexplorer觀察發現,該浏覽器程序内包含了兩個flash的ocx,通常一個程序加載同一個dll在程序空間隻會有一個,但是為什麼該浏覽器有兩個呢,通過仔細發現,這裡面有個dll是mapping的data,這個可以通過LoadLibraryEx,最後一個參數傳遞LOAD_LIBRARY_AS_DATAFILE或者LOAD_LIBRARY_AS_IMAGE_RESOURCE來實作,這樣就把dll或者exe通過資源的方式mapping到程序空間,段的屬性也是變成”隻讀”而不是”執行”
通過這個發現,得到了新的思路,就是要把我們的flash也要再加載一次,通過data的方式,于是通過windbg在該浏覽器的LoadLibraryEx,CreateFileMapping等處設定斷點,想通過這些函數的輸入參數來發現點什麼,但是結果沒發現該浏覽器直接LoadLibraryEx(LOAD_LIBRARY_AS_DATAFILE)或者CreateFileMapping
第三階段:
CreateFileMapping,在做檔案映射mapping的時候,他的第一個參數是HANDLE hFile,,如果要用到handle,必定要先CreateFile。于是在我們的浏覽器内hook了CreateFile,發現flash插件果然會來調用createfile來加載flash ocx的資源,這時候我們如果修改這個路徑,讓他調用我們自帶的flash ocx,這樣是可以了,我們浏覽器可以通過我們自帶的flash播放了。但是createfile調用比較頻繁,hook這個函數在性能上不劃算
再想想com的原理,com要找到自己的dll肯定要去系統資料庫找,在看下vc下調試的堆棧,在調用createfile前,flash會先調用oleaut32的接口
通過研究HRESULT LoadRegTypeLib(
REFGUID rguid,
unsigned short wVerMajor,
unsigned short wVerMinor,
LCID lcid,
ITypeLib FAR* FAR *pptlib
);
HRESULT LoadTypeLib(
const OLECHAR FAR *szFile,
ITypeLib FAR* FAR *pptlib
);
The function LoadRegTypeLib defers to LoadTypeLib to load the file.
我們得出了結論flash内部會調用LoadRegTypeLib,這個函數會去系統資料庫通過guid找到flash的ocx路徑,然後通過LoadTypeLib去加載這個ocx
是以我們hook了LoadRegTypeLib,在此函數内,調用LoadTypeLib來加載我們自帶的flash插件。由于LoadRegTypeLib調用很少,是以性能比hookcreatefile好
最後發現該浏覽器也hook了這個函數,由于之前不知道這個函數是什麼用的,是以走了些彎路。看來對com還不夠深入,歡迎兄弟們一起切磋讨論