備注學(xué)院

          LuLu

            BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            5 隨筆 :: 50 文章 :: 16 評(píng)論 :: 0 Trackbacks

          微軟在1997年正式退出Browser Helper Object (BHO), 使程序員能夠更好的對(duì)IE進(jìn)行二次開發(fā)和操作. 在通過編寫B(tài)HO程序數(shù)月后, 我希望把我的一些經(jīng)驗(yàn)告訴才開始的同志, 避免走一些彎路.

          我本人是非常喜歡C++的. 因?yàn)镃++對(duì)內(nèi)存直接操作的方式可以節(jié)省非常多的內(nèi)存損耗, 也更快一些. 但是在開發(fā)BHO的時(shí)候, 我的確也認(rèn)識(shí)到, C#明顯要比C++強(qiáng)大很多. 例如C#提供的FOREACH 循環(huán)就可以避免FOR循環(huán)產(chǎn)生的溢出. 另外C#的類型轉(zhuǎn)換也明顯要強(qiáng)于C++. 畢竟BHO和C#都是出自微軟一家, 理所當(dāng)然, C#更適合BHO開發(fā)一些. 我的第一個(gè)BHO程序是用C++寫的. 對(duì)于COM的操作,讓我至少弄了幾天才搞清楚他們到底想干什么. 但是我的第一個(gè)C# BHO程序只用了幾分鐘就搭建好了鉤子. 如果你希望從事BHO開發(fā), 而且你才開始學(xué). 我想這片篇文章對(duì)您有點(diǎn)幫助.

          這篇文章本來是用英文寫成的. 因?yàn)楣ぷ鳝h(huán)境的原因, 中文已經(jīng)越來越生疏. 如果有錯(cuò)誤或者不太明顯的地方. 請(qǐng)參考英文原文

          http://www.horizonideas.com/writings/article.php?id=11

          下面竟讓我們開始.

          首先我們需要在C#中新建一個(gè)DLL工程. 因?yàn)锽HO是通過讓IE調(diào)用DLL來驅(qū)動(dòng)的. 我用的是V C# EXPRESS. 因?yàn)檫@已經(jīng)完全夠用了. V C# PROFESSIONAL 并不需要, 而且還很浪費(fèi)內(nèi)存.


           

          當(dāng)我們建立一個(gè)空工程以后, 隨便添加一個(gè)文件夾叫BHO, 然后添加一個(gè)文件.

          需要我們注意的是, 我們這個(gè)文件必須被命名為IObjectWithSite.cs因?yàn)檫@樣IE才知道這是一個(gè)BHO程序. 如果想知道更多關(guān)于IObjectWiteSite接口的內(nèi)容, 請(qǐng)查詢MSDN http://msdn2.microsoft.com/en-us/library/Aa768220.aspx

          在IObjectWithSite中必須有兩個(gè)方法GetSite和SetSite. 我們主要是對(duì)后者進(jìn)行調(diào)用.通過名字大家就可以猜到他們是干什么的.

          GetSite:  Gets the last site set with IObjectWithSite::SetSite. If there is no known site, the object returns a failure code.

          SetSite:  Provides the site's IUnknown pointer to the object.

          請(qǐng)把VS STUIDO 默認(rèn)的類名給去掉.因?yàn)镮ObjectWithSite并不是一個(gè)類, 而是一個(gè)接口.

           

          不要忘記添加 System.Runtime.InteropServices

          下面我們?cè)偬砑觿┮粋€(gè)叫BHO.CS的主文件.

          這個(gè)新建的類是基于 IObjectWithSite接口的. 正如同我前面講的. 你就是通過這個(gè)接口來調(diào)用IE.

           

          為了使用微軟的BHO庫(kù).我們必須添加下面兩個(gè)庫(kù): SHDocVw and MSHTML.他們一般都在 Windows\System32 下面

          SHDocVw is  Microsoft Shell Doc Object and Control Library

          MSHTML is:   All interfaces for accessing the Dynamic HTML (DHTML) Object Model are based on IDispatch and are the basis of access to the object model that is also used by scripts. http://msdn2.microsoft.com/en-us/library/bb498651.aspx

          光using SHDocVw" 是不夠的, 你需要添加

          Add SHDocVw 

          因?yàn)樯院笪覀冃枰玫組ESSAGEBOX, 所以這里我也添加了一個(gè)WINDOWS FORM庫(kù).

           

          下面添加兩個(gè)變量: WebBrowser and HTMLDocument. 就如同他們的名字. 一個(gè)是IE的變量, 另外一個(gè)是IE所訪問的HTML頁變量.

          下面在這個(gè)類中田間一個(gè)叫 OnDocumentComplete 的函數(shù). 取其他名字也行, 沒什么太大關(guān)系. 但是這里為了CODE的可用性,我們叫OnDocumentComplete. 這個(gè)函數(shù)實(shí)際上是和CDHTMLDIALOG下面的OnDocumentComplete所對(duì)應(yīng)的.

          CDHtmlDialog Class http://msdn2.microsoft.com/en-us/library/8bed8k60(VS.80).aspx .

          OnDocumentComplete的觸發(fā)是在一個(gè)HTML頁被LOAD完以后. 你也可以避免用Navigate() or OnBeforeNavigate(). 他們表示在發(fā)出訪問和訪問之前觸發(fā).

          Please refer to http://msdn2.microsoft.com/en-us/library/8k5z3ekh(VS.80).aspx to find out what you need exactly.

          在 IObjectWithSite.cs下,你需要支出IE的GUID, 這樣才方便注冊(cè)表的更改.

          另外你需要給自己的程序添加一個(gè)GUID. 這樣IE才能在注冊(cè)表中找到你的信息. 你可以使用System.Guid.NewGuid() method 來得到一個(gè)GUID. 這比C++得到GUID的方法要容易得多了.

           

          我們必須給 SetSite and GetSite 加上內(nèi)容. 在SETSITE中我們就需要加入一個(gè)EVENTHANDLER, 讓IE來觸發(fā)我們的OnDocumentComplete函數(shù).

          Add one more reference

          在BHO.CS下我們需要為我們的DLL添加register/unregister 函數(shù).

          編譯, 我們就有了我們的DLL.

          下面通過DOS下的 regasm /codebase "BHO HelloWorld.dll" 命令在注冊(cè)dll. 這里有一個(gè)問題了, 為什么?

          因?yàn)槲覀兺税盐覀兊闹黝愒O(shè)置成PUBLIC, 所以別人都不能調(diào)用到你的類. 自然注冊(cè)不了.

           

          然后就成功了.

          打開注冊(cè)表, 找到Browser Helper Object under LOCAL_MACHINE->SOFTWARE->MICROSOFT->WINDOWS->EXPLORER, 看看是不是有變化了?

           

          我們注冊(cè)完了, 下面就是來寫我們的住程序來控制IE了. 下面就是一個(gè)例子來抓去你正訪問的頁面上的所有INPUT 元素的NAME.

          在DOCUMENT中, 我們的所有元素都為IHTMLElement, 我們需要調(diào)用的是IHTMLInputElement. 所以我們通過GetElementByTagName的方法來查找所有的INPUT ELEMENT. 在找到以后還需要進(jìn)行類型轉(zhuǎn)換才能找到對(duì)應(yīng)的ATTRIBUTE. 否則IHTMLElement是不代有NAME ATTRIBUTE的. IHTMLElement提供的ATTRIBUTE都是所有元素都有的. 例如ID, 例如TITLE, 例如OnClick等. 有的元素有自己特有的ATTRIBUTE, 例如INPUT有OnFocus這就必須要轉(zhuǎn)換成IHTMLInputElement才能上使用. INPUT對(duì)應(yīng)的IHTMLInputElement, Select-> IHTMLSelectElement .......

          There you go, see?

          下面我們?cè)嚵硗庖粋€(gè)方法叫 BeforeNavigate() .它的觸發(fā)是在你開始下一個(gè)頁面之前. 也就是說例如你要提交一個(gè)表單, 頁面要變化了, 他就被觸發(fā).

          實(shí)際上MS提供了兩個(gè)類似的接口 BeforeNavigate and BeforeNavigate2(). 大家可以查MSDN看看有什么區(qū)別. 這里我們不多講了.

           

          同樣我們添加一個(gè)對(duì)應(yīng)的函數(shù)原形(點(diǎn)圖片, 看大圖).

          添加EVENTHANDLER

          我們下面要干的是截獲頁面上的密碼.

          See, how easily, you can get it.

          通過上面的過程. 我希望您對(duì)BHO有一個(gè)初步的了解. 如果想知道更多內(nèi)容, 請(qǐng)?jiān)L問MSDN. 里面有非常詳細(xì)的介紹. 這里也引出了一個(gè)話題. 我們可以看到, 幾乎用不了兩分鐘我們就可以截獲你填寫的任何內(nèi)容, 你覺得IE是安全的嗎? 即使他可以通過SSL來對(duì)進(jìn)出網(wǎng)卡的內(nèi)容加密, 但是在應(yīng)用層一樣是如此的薄弱. 另外大家如果用IE都會(huì)發(fā)覺泛濫成災(zāi)的ADD-ON, 這就是因?yàn)锽HO惹的禍.

          大家如果不想按照我上面的打,可以下我做好的模版.直接放到你的Visual Studio 2005\Templates\ProjectTemplates文件夾下. 當(dāng)開始一個(gè)新工程時(shí)候, 點(diǎn)下那個(gè)BHO HELLOWORLD就可以了. 所有上面的代碼都給你做好了.

          project template下載TEMPLATE

           

          posted on 2008-11-11 10:50 smildlzj 閱讀(1275) 評(píng)論(4)  編輯  收藏 所屬分類: C#

          評(píng)論

          # re: 兩分鐘用C#搭建IE BHO勾子, 竊取密碼 2009-08-04 17:51 1.1
          在 IObjectWithSite.cs下,你需要支出IE的GUID, 這樣才方便注冊(cè)表的更改.

          這句話是什么意思?不同版本的IE是不是GUID也不一樣?  回復(fù)  更多評(píng)論
            

          # re: 兩分鐘用C#搭建IE BHO勾子, 竊取密碼 2009-08-05 14:12 smildlzj
          @1.1
          GUID是唯一的,是標(biāo)識(shí)你的BHO.  回復(fù)  更多評(píng)論
            

          # re: 兩分鐘用C#搭建IE BHO勾子, 竊取密碼 2009-08-06 09:55 1.1
          您的意思是,IObjectWithSite.cs的GUID是任意取的?我在IE7下調(diào)試怎么都不成功,是這個(gè)GUID問題,還是IE7的安全設(shè)置問題呢?  回復(fù)  更多評(píng)論
            

          # re: 兩分鐘用C#搭建IE BHO勾子, 竊取密碼 2009-08-13 11:07 smildlzj
          @1.1
          好像VS可以生成GUID的.你說的問題.你得自己找一下答案.
          具體我也沒試過.  回復(fù)  更多評(píng)論
            

          主站蜘蛛池模板: 绥化市| 科技| 新田县| 彰化市| 龙江县| 临朐县| 泊头市| 深州市| 沧源| 彰化县| 宽甸| 玛沁县| 白河县| 黄梅县| 和田市| 华宁县| 海淀区| 宜都市| 龙海市| 汽车| 安福县| 高雄县| 金华市| 岳普湖县| 卓尼县| 民权县| 安塞县| 朝阳市| 渝中区| 巴楚县| 称多县| 乌拉特前旗| 丹寨县| 阿图什市| 当阳市| 兰西县| 沙湾县| 若尔盖县| 镇远县| 武穴市| 通州市|