通过指定Shell Embedding/IEFrame类窗口的句柄获得浏览器(IE)对象

要从指定窗口返回浏览器对象需要解决这么两个问题:
1、得到浏览器对象接口
2、跨进程调用对象
这两个问题用VB实现起来都不是什么轻松的事情。因为涉及到接口编程,所以可能需要用到自定义的类型库,麻烦!跨进程调用COM对象需要进行列集(Marshal)和散集(Unmarshal),更是麻烦!麻烦!不过麻烦归麻烦,问题还是要一个一个解决的。

首先,我们来看看如何得到浏览器对象接口。在翻遍了msdn后,最后终于在一个角落里发现了秘诀。其大致是这样描述整个过程的:
1、 发送一个微软没有公布的消息WM_USER+7到指定窗口,获得一个IShellBrowser指针
2、 从这个指针用QueryInterface获得一个IServiceProvider接口
3、 从IServiceProvider接口的QueryService方法得到一个服务ID为SID_STopLevelBrowser的IServiceProvider接口
4、 最后从服务ID为SID_STopLevelBrowser的IServiceProvider接口调用QueryService方法得到IID_IWebBrowser2接口

以上这个过程用VC实现起来是非常快的,而用VB的话就头疼了。另外,这些方法需要在指定窗口所在的线程里运行才可以,否则,后果将不可预料……

而第二个问题涉及到COM对象的列集(Marshal)和散集(Unmarshal)。很明显,列集的工作肯定也要在目标窗口所在线程中完成,而散集的工作则要在本地程序里来做。

因此,综上所述,要解决上述问题,就必须要在目标窗口线程空间里插入代码。

代码插入有多种方法,我这次还是跟以往一样用的是直接代码写入,但跟以往有一点不同的是,这次的代码插入后要立即运行。我先想到了CreateRemoteThread,但是后来再想,用这个API创建的是一个新的线程,从这个线程访问另一个线程中的对象,同样需要进行列集和散集的操作,而这样实在太麻烦了。而后我想到了在窗体过程(WindowProc)上安装个钩子,然后马上个发送NULL消息来激活代码,但是,WindowProc是个使用比较频繁的过程,弄不好的话就会把对象窗口弄疯掉,而且,同样的,这样做麻烦阿~~最后,我想到了SetThreadContext,使用这个api我们就可以设定目标线程的eip,hoho,没错,就是他了~~

实现思路大致就是上面这样,接下来讲一个不使用类型库释放对象的小技巧:

'释放IStream对象
Private Function ReleaseStream(ByVal lpStream As Long) As Boolean
    Dim lpThis As Long
    Dim lpVTable As Long
   
    Dim oTmp As Collection
   
    If lpStream = 0 Then Exit Function
   
    Set oTmp = New Collection
   
    lpThis = ObjPtr(oTmp)
   
    CopyMemory lpVTable, ByVal lpThis, 4
   
    CopyMemory ByVal lpThis, ByVal lpStream, 4
    Set oTmp = Nothing
    CopyMemory ByVal lpThis, lpVTable, 4
   
    Set oTmp = Nothing
    ReleaseStream = True
End Function

在这个CVBWebBrowserHunter类里需要释放所建立的IStream对象,而如果只为这一个释放操作而建立一个类型库就太头大了。所以,我这里就“借用”了一下oTmp这个Collection对象的驱壳,将IStream对象替换进去。然后当我们调用Set oTmp=Nothing的时候,VB就会去调用oTmp对象(现在其实是IStream)的Release方法。这样,我们就实现了不用类型库而直接调用IStream对象的Release方法。

最后贴一下要远程执行代码:
  pushad
  pushfd

  mov ebp,esp
  sub esp,30h

  mov ebx,123456h;ebx=lpStart
  lea edi,[ebp-08h]
  push edi
  lea edi,[ebx+1Ch];edi=IID_IServiceProvider
  push edi
  mov eax,[ebx+64h];eax=psb
  mov ecx,[eax]
  push eax
  call [ecx];psb->QueryInterface(IID_IServiceProvider,(void**)&psp)
  cmp eax,0
  jl setokflag

  lea edi,[ebp-0Ch]
  push edi
  lea edi,[ebx+1Ch]
  push edi
  lea edi,[ebx+2Ch]
  push edi
  mov eax,[ebp-08h];eax=psp
  mov ecx,[eax]
  push eax
  call [ecx+0Ch];psp->QueryService(SID_STopLevelBrowser,IID_IServiceProvider,(void**)&psptb)
  cmp eax,0
  jl releasepsp

  lea edi,[ebp-10h]
  push edi
  lea edi,[ebx+4Ch]
  push edi
  lea edi,[ebx+3Ch]
  push edi
  mov eax,[ebp-08h];eax=psp
  mov ecx,[eax]
  push eax
  call [ecx+0Ch];psptb->QueryService(IID_IWebBrowserApp,IID_IWebBrowser2,(void**)&pwb);
  cmp eax,0
  jl releasepsptb

  push 0
  push 0
  push 0
  push [ebp-10h]
  lea edi,[ebx+4Ch]
  push edi
  lea edi,[ebp-14h]
  push edi
  call [ebx];CoGetMarshalSizeMax (&ulSize, IID_IWebBrowser2,pwb, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
  cmp eax,0
  jl setokflag

  lea edi,[ebp-14h]
  push edi
  push 2
  call [ebx+0Ch];GlobalAlloc (GMEM_MOVEABLE, (DWORD) ulSize);
  cmp eax,0
  je setokflag
  lea ecx,[ebp-18h]
  mov [ecx],eax;hGlobal=GlobalAlloc;

  lea edi,[ebp-1Ch]
  push edi
  push 1
  mov edi,[ebp-18h]
  push edi
  call [ebx+8h];CreateStreamOnHGlobal (hGlobal, TRUE, &pStream);
  cmp eax,0
  jge go1

  mov edi,[ebp-18h]
  push edi
  call [ebx+10h];GlobalFree (hGlobal);
  jmp releasepsptb

  go1:
  push 0
  push 0
  push 0
  push [ebp-10h]
  lea edi,[ebx+4Ch]
  push edi
  push [ebp-1Ch]
  call [ebx+4];CoMarshalInterface (pStream, IID_IWebBrowser2, pwb, MSHCTX_LOCAL, NULL, MSHLFLAGS_NORMAL);
  cmp eax,0
  jl releasestream;

  lea edi,[ebx+5Ch]
  lea esi,[ebp-14h]
  movsd;cbData=ulSize;

  mov edi,[ebp-18h]
  push edi
  call [ebx+14h]
  mov [ebx+60h],eax;lpData=GlobalLock (hGlobal);

  mov edi,[ebp-18h]
  push edi
  call [ebx+18h];GlobalUnlock (hGlobal);

  mov [ebx+68h],dword ptr 1
loop1:
  cmp dword ptr [ebx+68h],0
  jne loop1

releasepsptb:
  mov eax,[ebp-0Ch];eax=psptb
  mov ecx,[eax]
  push eax
  call [ecx+8];psptb->Release();
releasepsp:
  mov eax,[ebp-08h];eax=psp
  mov ecx,[eax]
  push eax
  call [ecx+8];psp->Release();
releasestream:
  mov eax,[ebp-1Ch]
  mov ecx,[eax]
  push eax
  call [ecx+8h];pStream->Release ();

setokflag:
  mov [ebx+68h],dword ptr 2
   
  mov esp,ebp
  popfd
  popad

  push 123456h;push reteip
  ret

【源码下载地址】:http://60.191.21.235:1122/vbwebbrowserhunter.rar

评论 6 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

supergreenbean

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值