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

通过进程ID获取最顶层窗口句柄 代码很简单,需要注意的是:最顶层的窗口,需要具备没有父窗口,我这里根据需要加上了判断WS_VISIBLE属性。HWND hGetProcessWnd(DWORD dwProcessId){       HWND hRetWnd = NULL;       HWND hDesktopWnd = GetDesktopWindow();       DWORD dwEnumProcessID;       HWND hChildWnd = GetTopWindow(NULL);       while(hChil 阅读详情
 如何获取其它进程中窗口的窗口过程
helloworld 发表于:2008-9-29 14:52:00   阅读数:9


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

作者:耿海增

下载源代码

开发环境: 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

再来看看PostThreadMessageA的函数原型:

WINUSERAPI BOOL WINAPI PostThreadMessageA( DWORD idThread, UINT Msg, WPARAM wParam, LPARAM lParam)

PostThreadMessageA函数调用的汇编代码如下:

//Msg是我们自定义的消息,假设 Msg = 0x1234
push lParam                 //push eax        //50  
push wParam                //push hWndTarget  //58 78 56 34 12            //假设 hWndTarget = 0x12345678
push Msg                                     //58 34 12 00 00            //假设 Msg = 0x1234
push dwThreadId                              //58 78 56 00 00            //假设 dwThreadId = 0x5678
call PostThreadMessageA                      //E8 (PostThreadMessageA-下一条指令的地址)

解释一下call PostThreadMessageA指令:

  第一个机器码是E8,后边跟的不是PostThreadMessageA这个函数的地址,而是从当前指令的下一条指令的地址到那个函数的距离。例如,当前指令的地址是 0x2d0028,call指令长度为5个字节 ,那么下一条指令的地址就是0x2d0028 + 5 = 0x2d0033,假如 PostThreadMessageA函数的起始地址是0x77d3ebb0,那么我们call后边的数就是 0x77d3ebb0 - 0x2d0033 = 77A6EB7D,那么 call PostThreadMessageA的实际的机器码就是 E8 7D EB A6 77

0x002d0012 push eax                //50              1 byte
0x002d0013 push hWndTarget         //58 78 56 34 12    5 bytes
0x002d0018 push Msg                //58 34 12 00 00    5 bytes
0x002d0023 push dwThreadId         //58 78 56 00 00    5 bytes
0x002d0028 call PostThreadMessageA //E8 7D EB A6 77    5 bytes
0x002d0033 ret                     //C3              1 bytes
0x002d0034 xxxx

有了以上的准备工作,下边就可以正式进行工作了。假如给定了要获取 hWndTarget 窗口的窗口过程

  1. 调用 GetWindowThreadProcessId ,得到该窗口所属进程的Id,存放在 dwProcess中;
  2. 调用 OpenProcess,打开该进程(如果打开失败,可能是权限不够,需要调用AdjustTokenPrivileges提升一下当前进程的权限),得到一个该进程的句柄,存放在hProcess中 ;
  3. 调用 IsWindowUnicode,判断下一步应该调用 GetWindowLongA 还是 GetWindowLongW函数;
  4. 调用 VirtualAllocEx,在目标进程中分配一些内存,供我们写入线程函数使用。函数返回的就是分配的内存的起始地址,就是我们的线程函数的起始地址,假设叫fnStartAddr;根据我们上边分析的结果,需要33个字节,另外,线程函数最后要有一个 ret指令,占用一个字节,共需34个字节;
  5. 把以上分析的结果写入一个临时的缓冲区里;
  6. 调用 WriteProcessMemory,把刚才的结果写入远程进程 fnStartAddr的地址处 ;
  7. 调用 CreateRemoteThread,指定线程函数地址为 fnStartAddr;
  8. 进行一个小的消息循环,等待我们的返回结果;
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
        if(msg.message == uMsgSendBack)
        {
            procRet = msg.lParam;
            break;
        }
    }
    
  9. 进行一些善后工作,关闭打开的线程句柄、进程句柄,释放分配的远程内存;

具体细节请参考示例代码。

linux下根据进程pid获取对应的window id的方法 有时候我们需要在一个图形化进程中抓取另外一个进程的窗口以嵌入到当前进程的界面里。比如,在QT开发中,在当前的进程界面里启动另外一个进程并将其窗口嵌入到当前进程的界面内。下面的代码示例了如何根据进程的id获取其对应的UI窗口ID(基于x11框架)。 阅读详情

相关推荐

易语言获取进程句柄及其实战应用

进程句柄是操作系统用于标识进程资源的一种数据结构,它为进程提供了一种访问控制和管理的手段。在Windows系统中,进程句柄是核心概念之一,它与进程标识符(PID)不同,句柄更多用于操作系统层面的资源分配和管理。理解进程句柄的概念是深入学习Windows系统编程、调试和优化应用程序的基础。进程句柄是一个抽象的概念,它实质上是一个指向进程内部资源的指针。在Windows中,几乎所有的资源,如文件、线程、进程、窗口等,都可以通过句柄来进行操作。

weixin_42389113的博客 1827

nIndex总结

DeclareFunctionGetWindowLongLib"user32"Alias"GetWindowLongA"(ByValhwndAsLong,ByValnIndexAsLong)AsLong 在网上找了些API的相关函数说明,上面只给出常量的表示方法,没教如何去设置常量 参数类型及说明 hwndLong,欲为其获取信息的窗口的句柄 nIndex...

吕世良 628

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

俺收藏的好东西。可以获得别的窗口的消息。

跨进程获取其他应用程序窗体内容

以下三次测试分别用三种方式获取其他应用程序窗体上的内容. 具体是本人工作中遇到一个问题,即在wince手持终端系统上,获取其他应用程序界面上的窗体里的内容,由于我对wince不是很熟,所以先在Win7下想试试可行性,所以有了第一种方式, ////////////////////////////////////////////////第一种方式//////////////////...

abcd18515636230的博客 919

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

VC++6.0编写程序,供参考学习代码注入程序的开发

进程之间的通信,获取其他窗口指针

VS2008编写的! 进程的通信! 一个对话框发,一个收!

进程相关(进程Id获取主窗口)

1.知道进程handle 获取进程名称。 PROCESS_INFORMATION* processInfo =(PROCESS_INFORMATION*)pid();   HANDLE hProcess =processInfo->hProcess;   char buffer[255];   ZeroMemory(buffer,255*sizeof(char));   GetModule...

weixin_34380948的博客 304

睿尔曼超轻量仿人机械臂--PLC控制

PLC通过以太网与机械臂创建socket连接,PLC发送JSON协议控制机械臂进行物料抓取。

weixin_61488836的博客 2463

通过进程ID获得主窗口句柄

通过进程ID获得该进程主窗口的句柄     一个进程可以拥有很多主窗口,也可以不拥有主窗口,所以这样的函数是不存在的,所幸的是,相反的函数是有的。所以我们可以调用EnumWindows来判断所有的窗口是否属于这个进程。typedef struct tagWNDINFO...{DWORD dwProcessId;HWND hWnd;} WNDINFO, *LPWNDINFO;BOOL CALLB

liwei8703的专栏 1万+

17【Protues单片机仿真】基于51单片机的太阳能智能谷物翻晒机器人

基于51单片机,避障,低于50CM报警,LED灯亮起,自动翻晒用光敏电阻,光照强度大,电机转动,相当于翻晒粮食,远程控制用按键代替,按下去电机就转动,相当于翻晒粮食,然后光照强度和超声波的距离都在LCD1602显示屏显示出来。

weixin_70360261的博客 1447

飞常准小程序接口逆向分析:如何破解航班查询的签名机制

本文深度解析了飞常准小程序航班查询接口的安全机制,重点剖析了其基于MD5和参数排序的签名算法。通过逆向分析核心代码,详细阐述了签名生成流程,并提供了Python实现的签名生成器与调试技巧,为开发者理解与模拟此类接口调用提供了实战指南。

zz67890的博客 530

c语言获取qq文本框,C语言通过HOOK获取QQ游戏登录密码

//通过HOOK获取QQ游戏登录密码不得不先说一下API函数SendMessage:使用SendMessage向编辑框窗口发送WM_GETTEST消息,可以轻易获取到编辑框的内容(就算这个窗口不属于同一进程)。但是有一个特例,那就是当编辑框窗口具有ES_PASSWORD风格(即密码输入框)且不输入同一进程时,使用上面的方法就失效了。通俗的说,就是当你要使用SendMessage读取的密码框不属于同...

weixin_32279911的博客 503

SDN:使用Postman控制ODL查看和下发流表

所谓,其实可被视作是SDN对网络设备的数据转发功能的一种抽象。在传统网络设备中,交换机和路由器的数据转发需要依赖设备中保存的二层MAC地址转发表或者三层的IP地址路由表,SDN交换机中使用的流表也是如此,不过在它的表项中整合了网络中各个层次的网络配置信息,从而在进行数据转发时可以使用更丰富的规则。其流表中的每个表项结果如下图所示:OpenFlow1.3流表的每个表项由6部分组成:1、匹配域:匹配域即OpenFlow1.0流表中的包头域,用于对交换机接收到的数据包的包头内容进行匹配。Ehter Des。

lyhaoyuhangyuan的博客 2534

遍历查找某个进程拥有的所有窗口

#include #include #include #include #define WINDOW_TEXT_LENGTH 256 BOOL CALLBACK EnumChildWindowCallBack(HWND hWnd, LPARAM lParam) { DWOR

sha_jinhao的专栏 1万+

mongoDB 数据莫名其妙的没了

问题 之前没有接触过mongoDB,然后接手一个项目使用的是MongoDB,我就跟着网上的教程搭建一个MongoDB的服务,并运行起来。 一开始没有啥问题,成功的把服务与MongoDB都启动以来,运行也没有问题。但是过了几天,我再次打开时发现,以前的数据神奇的消失了。我还在想,是有什么定时清除的么,还是什么原因导致崩了然后数据就被清理了。 查找原因 第一次遇到我没有在意,重启了一下MongoDB,...

技术熊的博客小窝 1万+

DFT实战:如何用Synopsys工具搞定多时钟域Scan Chain设计(附避坑指南)

本文详细解析了使用Synopsys DFT Compiler工具链实现多时钟域Scan Chain设计的全流程,包括时钟混合策略、跨时钟域平衡技巧和实战脚本剖析。通过量产验证的工程实践方案,帮助DFT工程师有效解决复杂SoC设计中的Scan Chain挑战,提升测试效率和质量。

mm9012的博客 1031

根据窗口ID获取进程PID

功能:获取窗口所在进程的PID 知识点: 1、得到默认的display指针:XOpenDisplay 2、通过字串取对应的AtomID:XInternAtom 3、获取窗的某一属性:XGetWindowProperty                知识补充:        display: 由键盘,鼠标和一个或多个屏幕组成的一个工作站 screen:一个display可以有多个s

arccosxy的专栏 4226

黑猫带你学eMMC协议第1篇:全网最全emmc协议中文详讲,这份学习框架图,你值得拥有!!!(持续更新中...)

黑猫带你学eMMC协议第7篇:全网最全emmc写保护详解(write protect) 黑猫带你学eMMC协议第8篇:emmc可靠写详解(Write Reliability) 黑猫带你学eMMC协议第9篇:emmc的分区配置(partitioning) 黑猫带你学eMMC协议第10篇:eMMC命令队列详解(CMDQ) 黑猫带你学eMMC协议第11篇:eMMC擦除详解(erase/trim/discard/sanitize/secure erase/secure trim…) 黑猫带你学eMMC协议第12篇:

黑猫奥利奥的博客 2万+

Windows 创建窗口(模块、模块句柄、实例、进程)

注册一个窗口代码: 首先要获取该窗口的“上级”,即属于哪一个模块。 1. 这里获取的是 模块句柄,也是实例,不是进程ID。窗口的上级并不是进程,而是模块。 2. 一个进程由很多模块组成,比如执行文件 xx.exe模块,但光这一个模块不够,还需要 user32.dll模块等等,这些很多模块共同组成一个进程,而程序的主逻辑代码存储在 xx.exe模块中。 3. 所以,我们获取的是这个 xx.exe句...

OneTrianee的博客 744

第18章:Ingestion Pipeline 数据摄取流水线

本文介绍了LlamaIndex的IngestionPipeline如何解决合同文档处理中的四大核心问题:不可重复、无追溯、无容错和无法缓存。通过标准化数据处理流程,将手工操作升级为工厂流水线模式,实现数据的可复用、可追踪和高效处理。文章详细阐述了Pipeline的设计原理,包括Transformation的串行编排、缓存机制(基于输入和Transformation的哈希值)以及数据血缘追踪(通过Node的metadata记录处理过程)。

davidwang456的专栏 62

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

易语言通过进程名称获取进程ID

通过系统映像的名称来获取进程的PID,有了PID就可以通过(进程_ID取窗口句柄) 获取窗口句柄,有了句柄就可以大漠后台绑定窗口,所以最终目的还是通过进程名称来获取进程所在窗口的句柄,用来窗口的绑定操作。 用到的API 1、CreateToolhelp32Snapshot(创建进程快照) 2、Process32First(取第一个进程) 3、Process32Next(取下一个进程) 4、CloseHandle(关闭一个内核对象) 511遇见易语言模块API教程 自定义数据类型 进程信息列表.

511遇见 1万+

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

得到指定进程所有窗口。显示 影藏 置顶。

这里使用一个外挂程序测试,因为外挂程序没有做功能限制的处理 只是做了 窗口影藏。 全局变量 HWND hwnd[100]={0};int number=0;DWORD Tpid=0; 局部变量 char username[1028]; 先找到进程ID 1 HWND SelectPor() 2 { 3 bool isYes=false; 4 string ...

weixin_30484739的博客 379

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

进程ID,进程hmodule ,hwnd的获取

<br />进程ID<br /> <br /> <br />下面这个方式是枚举进程ID <br />typedef LONG    NTSTATUS;<br />typedef ULONG   ACCESS_MASK;<br />typedef ULONG    KPRIORITY ;<br />typedef DWORD    ACCESS_MASK ;<br />typedef struct _VM_COUNTERS {<br /> ULONG PeakVirtualSize;<br /> ULONG

361

Windows黑客基础(2):获取其他进程的HANDLE

在windows下,不管是进程还是句柄或者文件,他们都可以抽象为一个HANDLE,如果有接触过linux编程的都知道,linux下一切皆文件,对进程,文件,socket的操作都是通过int来标识的,windows下的HANDLE概念也跟linux下的int概念差不多,都可以归结为类似与ID的数据类型,只是表示形式不一样,我们对于所有对象的操作都需要通过这个标识来传递 当然在WINDOW...

639
上一篇: 自制进程管理器
下一篇: Webbrowser控件 怎么样禁用ActiveX
skyremember
博客等级 码龄20年 204粉丝 484原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值