13 Security Lab

[스크랩] BHO - Browser helper object 브라우저 헬퍼 오브젝트 본문

Computer Science/Projects

[스크랩] BHO - Browser helper object 브라우저 헬퍼 오브젝트

Maj0r Tom 2013. 4. 19. 00:07

브라우저 헬퍼 오브젝트

인터넷 익스플로러(버전 4.0 이상) 에서는 브라우저 헬퍼 오브젝트(Browser Helper Object)라는 DLL 컴포넌트를 통해 제3의 개발자가 인터넷 익스플로러에 자신이 원하는 기능을 추가시킬 수 있는 길을 열어놓고 있다.
 인터넷 익스플로러는 자신이 새로 기동될 때마다 브라우저 헬퍼 오브젝트로 등록된 COM 객체를 생성하고 그로부터 특정 인터페이스를 얻고 그 인터페이스의 어떤 멤버함수를 호출하게 된다. 이는 곧 제3의 개발자가 개발한 DLL 컴포넌트를 인터넷 익스플로러 프로세스의 주소 공간 속으로 접근시키는 길을 열어놓은 것이다.

브라우저 헬퍼 오브젝트는 단 하나의 인터페이스, 바로 IObjectWithSite 인터페이스를 제공하기만 하면 되는 매우 간단한 DLL 컴포넌트이다. 그러나 IObjectWithSite 인터페이스를 제공하는 모든 DLL 컴포넌트가 전부 다 브라우저 헬퍼 오브젝트냐 하면 그건 아니다.
 하지만 어떤 DLL 컴포넌트가 IObjectWithSite 인터페이스를 제공한다면 일단 브라우저 헬퍼 오브젝트가 될 조건 중 한 개를 만족시키고 있는 것이다.

브라우저 헬퍼 오브젝트가 되기 위한 또 다른 조건은 DLL 컴포넌트의 CLSID를 인터넷 익스플로러가 미리 정해놓은 어떤 레지스트리 키 밑에 등록시키는 것이다. IObjectWithSite 인터페이스를 제공하는 DLL 컴포넌트가 브라우저 헬퍼 오브젝트로 동작하기를 원한다면 레지스트리의 다음 키 밑에 자신의 CLSID를 등록시켜야 할 것이다.

l 레지스트리 경로 브라우저 헬퍼 오브젝트 등록위치
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Browser Helper Objects

ocidl.idl 파일에는 IObjectWithSite 인터페이스에 대한 정의를 볼 수 있다.
Interface IObjectWithSite : IUnknown
{
typedef IObjectWithSite *LPOBJECTWITHSITE;
HRESULT SetSite(
[in] IUnknown *pUnkSite
);
HRESULT GetSite(
[in] REFIID riid,
[out, iid_is(riid)] void **ppvSite
);
}


SDK 문서를 열고 SetSite 함수의 설명을 찾아보면 사이트의 IUnknown 포인터를 객체에게 제공하는 함수 라고 나온다. 이 말이 무슨 말인가 하면 사이트는 객체를 생성한 놈인데 여기서는 인터넷 익스플로러가 되고 객체는 말 그대로 객체, 즉 브라우저 헬퍼 오브젝트가 된다
 인터넷 익스플로러가 SetSite 함수를 호출함으로써 브라우저 헬퍼 오브젝트에게 자신의 IUnknown 포인터를 전달한다는 말이다. IUnknown 포인터를 전달받은 브라우저 헬퍼 오브젝트는 이것을 잘 보관하고 있다가 나중에 유효 적절하게 사용할 수 있다
 객체가 사이트로부터 IUnknown 포인터를 받은 다음에는 반드시 AddRef 함수를 호출해서 참조카운트를 증가시켜 주어야 한다.

만약 SetSite 함수가 2회 이상 불릴 경우 객체가 이미 사이트의 IUnknown 포인터를 보관하고 있다면 가지고 있던 IUnknown Release 함수를 호출한 다음 새로운 IUnknown AddRef 함수를 호출하고 그 포인터를 보유하고 있으면 된다.

GetSite 함수는 객체가 보유하고 있는 가장 최신의 IUnknown 포인터를 제공하는 함수이다. 객체는 SetSite 함수가 호출됨으로써 사이트의 IUnknown 포인터를 보유하게 되고, GetSite 함수가 호출됨으로써 보유하고 있던 사이트 IUnknown 포인터를 제공할 수 있게 된다. 만약 객체가 사이트의 IUnknown 포인터를 가지고 있지 않다면 실패코드를 리턴해 줄 수 있다.

이상은 SDK 문서에서 제시하는 구현 가이드 라인이다. IObjectWithSite 인터페이스를 구현할 때 우리는 이 가이드 라인을 지켜가면서 우리가 원하는 다른 기능을 추가시킬 수 있다.

인터넷 익스플로러뿐만 아니라 윈도우 탐색기는 자신이 새로 기동될 때마다 레지스트리의 Browser Helper Objects 키를 검색해서 그 밑에 등록된 CLSID를 가지고 CoCreateInstance() 를 호출하여 브라우저 헬퍼 오브젝트를 생성하게 된다.

그런 다음에는 QueryInterface() 를 호출해서 IObjectWithSite 인터페이스를 요구하고
이를 얻으면 IObjectWithSite 인터페이스의 SetSite() 를 호출한다. 이때 SetSite()의 매개변수로 사이트가 되는 인터넷 익스플로러(혹은 윈도우 탐색기) IUnknown 포인터가 전달된다.

브라우저 헬퍼 오브젝트는 사이트가 전해준 IUnknown 포인터를 통해서 사이트, 즉 인터넷 익스플로러(혹은 윈도우 탐색기)의 다른 모든 인터페이스들을 얻을 수 있다. 인터넷 익스플로러는 내부적으로 WebBrowser 라고 불리는 ActiveX 컨트롤을 포함하고 있다. 브라우저 헬퍼 오브젝트는 전달받은 IUnknown 포인터를 통해 WebBrowser 컨트롤의 모든 인터페이스를 얻을 수 있다.

WebBrowser 컨트롤이 제공하는 인터페이스 중 가장 대표적인 인터페이스로는 IWebBrowser2가 있다. IWebBrowser2 인터페이스는 인터넷 익스플로러의 메뉴와 버튼을 통해 제공되는 기능들(예를 들면 앞으로, 뒤로, 중지, 새로고침, 이동 등)을 똑같이 수행할 수 있도록 다양한 함수들을 제공한다.


출처: http://debugjung.tistory.com/13
출처: Visual C++.Net Programming Bible(삼양출판사)

Comments