如何获取其它进程中窗口的窗口过程

开发环境: Windows XP + VC6+Platform SDK 或者 VS.NET 2003+

测试环境: Windows XP

曾经以为获取一个窗口的窗口过程很简单,不就是GetWindowLong一下吗,看spyxx获取的多么顺利。后来才发现原来不是这么简单。获取本进程内窗口的窗口过程确实很简单,直接调用GetWindowLong(hWnd,GWL_WNDPROC)就可以了(注意,根据窗口是否是Unicode的,你要判断是调用GetWindowLongA,还是GetWindowLongW,可以用IsWindowUnicode来判断), 但是GetWindowLong这个函数内部会检查调用进程和该窗口句柄是否属于同一进程,如果不是,就简单的返回0了。

既然这样,我们又不能去修改GetWindowLong,那就只有想办法让它认为我们和那个窗口是在一个进程里了。回想起Windows核心编程里讲过,通过创建远程线程的方式,可以在其它进程内创建一个新的线程,并且可以指定这个线程的线程函数。因为Windows的进程之间的地址相互之间是不可见的,所以我们不能指定本地的线程函数,而要在远程分配内存,把我们要做的事情以机器码的形式写进去。

(spyxx是怎么做的呢?它启动时安装了一个全局的钩子WH_GETMESSAGE,这样,几乎所有有消息循环的程序都会加载它的hook dll,从而可以在其它进程的地址空间里调用GetWindowLong,如果我们仅仅为了获取一下窗口过程装一个全局钩子,未免有点儿太浪费了:))

先来分析一下我们的线程函数都需要做什么。

首先,需要调用GetWindowLong获取这个窗口的窗口过程,然后要告诉我们。可以用PostMessage或者PostThreadMessage的方式通知我们的程序。具体如下所示:

//hWndTarget是我们要获取其窗口过程的窗口句柄, 假设 hWndTarget = 0x12345678
//dwThreadId是我们的线程Id          ,假设 dwThreadId = 0x5678
LONG wndProc = GetWindowLong(hWndTarget,GWL_WNDPROC);
PostThreadMessage(dwThreadId,WM_MYMESSAGE,(WPARAM)hWndTarget,(LPARAM)wndProc);

因为这个时候函数的参数我们都已经知道了,所以可以直接硬编码到程序里。先看一下GetWindowLongA的函数原型:

WINUSERAPI LONG WINAPI GetWindowLongA( HWND hWnd, int nIndex)

一共有两个参数,我们的 GetWindowLongA(hWnd,GWL_WNDPROC)函数调用的汇编代码大概就是这个样子(右边是响应的机器码):

//参数入栈的顺序是从右向左,所以先push nIndex,然后是push hWnd
push 0xFC //6A FC //GWL_WNDPROC的值是-4,写成16进制就是0xFC
push hWndTarget //58 78 56 34 12 //假设 hWndTarget = 0x12345678
call GetWindowLongA //E8 (GetWindowLongA-下一条指令的地址)

GetWindowLongA函数的返回值在eax寄存器里,我们的PostThreadMessageA函数里用wParam参数发送该窗口句柄,用lParam参数发送该窗口的窗口过程 ,所以push lParam 就是 push eax

时间: 2024-09-20 16:53:42

如何获取其它进程中窗口的窗口过程的相关文章

获取其他进程中ListBox和ComboBox的内容

说明:Window2000+Delphi6调试通过 //*) function GetListBoxText(mHandle: THandle; mStrings: TStrings): Boolean; var vItemCount: Integer; I: Integer; S: string; begin Result := False; if not Assigned(mStrings) then Exit; mStrings.BeginUpdate; try mStrings.Clea

如何遍历当前进程中的AppDomain

.Net Framework居然没有提供托管的接口来获取当前进程中的其它AppDomain!所以,我们只有借助承载接口(Hosting Interfaces)来完成这事了. 在MSCOREE.DLL中,.Net 1.0提供了一个ICorRuntimeHost接口,该接口中有EnumDomains和NextDomain方法,而幸运的是:MSCOREE.DLL中居然直接提供了一个Public的实现:CorRuntimeHostClass.所以,我们只需要新建一个CorRuntimeHostClass

如何获取某个进程的主窗口以及创建进程的程序名

在编写工具程序以及系统管理程序的时候.常常需要获取某个进程的主窗口以及创建此进程的程序名.获取主窗口的目的是向窗口发送各种消息.获取启动进程的程序名可以控制对进程的操作.但是有些进程往往有多个主窗口.你要的是哪一个主窗口呢?如果你用过Outlook程序,你就会发现它有多个主窗口,一个窗口列出收件箱和其它文件夹.如果你打开e-mail,便会有另外一个窗口显示信息.它们都是没有父窗口(或者说宿主窗口)的主窗口.运行一下Spy程序,你甚至会发现它们的窗口类名都相同:rctrl_renwnd32.资源管

《Android 应用案例开发大全(第二版)》——6.7节获取第三方程序中可调用的窗口

6.7 获取第三方程序中可调用的窗口 Android开发权威指南(第二版) 第X问1 源代码目录:src/ch06/InvokeSinaWeibo 现在很多程序中使用的功能并未包含在程序本身,都是通过各种插件方式获得的其他程序的资源.例如,经常会使用到的"分享"功能就是调用了系统中所有可以处理某类资源的窗口来实现的,如果这样的窗口多于一个,就会显示一个选择列表. 如果想利用其他程序中的资源,首先要了解程序对外的接口.但很多程序并没有公开相应的接口,在这种情况下,就需要通过该程序的APK

如何在win8系统中通过任务管理器窗口查看网络状态

  任务管理器窗口想必是大家都比较熟悉的一个功能了吧?很多时候,咱们需要结束进程,需要查看win7 64位旗舰版下载 iso电脑CPU占用情况的时候,咱们都需要调用出windows系统中的任务管理器窗口.那么对于这个任务管理器窗口的功能,大家了解的透彻了吗?其实,任务管理器窗口除了可以实现上述的操作之外,还可以对咱们windows系统中的网络状态进行查询,下面,小编就以win8系统为例,为大家详细的介绍一下,如何在任务管理器窗口中查看网络连接状况吧! 1.首先,咱们需要返回到win8系统的传统桌

JavaScript子窗口ModalDialog中操作父窗口对像_基础知识

在ModalDialog中操作父窗口对象 1.不能使用window.parent Window.parent是用来在frame中进行操作的,在对话框中不能用来操作父窗口对象 2.正确的做法 调用modaldialog时通过传参数的方式操作 例: 需求 父窗口页面为a.html 子窗口页面为b.html.a.html中有文本框id为test1,在打开的对话框中点击按钮,将a.html的文本框值改为"子窗口值". 实现 打开对话框时把test1作为参数传给子窗口,在子窗口中获取参数,将参数

在PowerScript脚本中访问数据窗口中的数据

访问|脚本|数据 在PowerScript脚本中访问数据窗口中的数据张健姿 01-6-22 下午 03:50:25 在4.0 以 前 的 版 本, 如 果 您 想 在PowerScript 脚 本 中 访 问数 据 窗 口 中 的 数 据, 方 法 只 有 一 种, 那 就 是 使 用SetItem 和GetItem 系 列 的 函 数, 指 定 您 所 要 访 问 的 某 一 行 列 的 值, 这 一 方 法的 局 限 性 在 于 您 一 次 只 能 访 问 到 一 个 数 值. 而 在5.0

win7中常用切换窗口的4种快捷键

平常在使用系统中,我们经常会通过一些快捷键来切换窗口,小编在这里给大家终结下,有哪些切换窗口的快捷键可以用.小编长用的只有4种,如果你有更多的话,欢迎补充. 1 Ait+Tab这个是大家都知道的切换的快捷方式,按照你使用的顺序切换. 2 Win+Tab效果更佳,有3D效果的切换.在不知道那个窗口是你想要的,用这个查找效果很好. 3 先按住Ctrl键,在你想要切换的程序上点下,然后再按Ait+Tab键切换.效果是比如你要在几个QQ窗口里面切换,这个效果很好.试用于你打开多个游戏而只想在这几个游戏窗

电脑中无法设置窗口的颜色如何解决

  电脑中无法设置窗口的颜色如何解决          1.按win+R打开运行,输入gpedit.msc并回车; 2.在组策略编辑器中依次展开"用户配置->管理模板->控制面板->个性化"; 3.在右侧右击"阻止更改窗口颜色和外观",选择"编辑"; 4.将"已启用"改为"未配置",点击确定即可. 如果电脑中无法设置窗口的颜色,可以参考上述介绍的解决电脑窗口颜色不能修改的方法.