
基于窗口子类化的跨进程远程调用易语言源码使用场景一:调用线程绑定的API
有一批 Win32 API 是线程绑定的,只能在创建窗口 / 拥有资源的那个线程里调用。
例子
操作 需求 要求
DestroyWindow 销毁目标程序里的指定窗口 必须在创建该窗口的线程调用;跨线程 / 跨进程调用直接失败,本进程无替代方案
SetTimer / KillTimer 给目标窗口挂 / 摘定时器 定时器消息投递到窗口所属线程的消息队列,hwnd 须属于调用线程
GetMessage / PeekMessage / WaitMessage 取 / 探测目标窗口线程的消息 消息队列是线程私有的,只能在所属线程里操作
访问目标线程的 TLS / 线程局部状态 读取 / 修改目标线程的 TLS 数据 TLS 等线程私有状态,只有在该线程里才拿得到
补充一个常见的例子:精易Web浏览器的 API 也有线程亲和性,
必须在创建它的主线程(窗口线程)里调用,非主线程调用会失败。
使用场景二:COM 调用(STA 套间)
COM 的单线程套间(STA)要求:对象的方法必须在创建它的那个线程里调用。
而 GUI 程序的主窗口线程,通常就是 STA 套间线程。
例子
操作 需求 STA 套间要求
内嵌浏览器控件 IWebBrowser2::Navigate / ExecWB 控制目标程序里的网页:跳转 / 后退前进 / 执行脚本 必须在创建控件的窗口线程(STA 套间线程)调用;跨套间未 marshal 直接调用属未定义行为
就地激活 IOleObject::DoVerb / IOleInPlaceObject 激活目标程序里嵌入的 OLE 对象 与宿主窗口强绑定,须在窗口线程执行
Office / WPS 自动化 Application 方法 读写目标程序里打开的文档 对象为 STA,方法只能在创建它的线程调用
Shell 自动化对象 IShellWindows / IShellFolder 方法 cha询 / 操作资源管理器窗口 STA 对象,且接口指针是进程内地址,跨进程不能直接使用
目标程序自定义 COM 接口方法 调用目标程序内部功能 / 取数据 / 改状态 只存在于目标进程内,且为 STA,只能在它的套间线程调用
CoCreateInstance 激活对象 在目标进程里新建一个 COM 对象来用 对象归属调用线程的套间,之后须在同一套间线程内使用
? 在目标窗口线程上下文执行,可安全调用与窗口线程亲和的操作
? 纯 Shellcode
? x86 / x64 双架构,Unicode / ANSI 窗口自适应
? 支持任意个数参数
? 提供驻留式类,可反复调用,省去重复装钩子开销
需要注意的是,目标进程必须存在GUI窗口且消息循环没有阻塞,否则调用会一直等待或超时,另外还有 UIPI(用户界面特权隔离)和 Session 隔离问题,根据使用场景针对处理
使用示例
.版本 2
.局部变量 函数地址, 整数型
.局部变量 参数数组, 整数型, , “1”
.局部变量 调用情况, 整数型
.局部变量 返回值, 整数型
函数地址 = GetProcAddress (GetModuleHandleA (“user32.dll”), “IsWindow”)
参数数组[1] = 目标窗口句柄
返回值 = 远程调用_x86 (目标窗口句柄, , 函数地址, 参数数组, 3000, , 调用情况)


评论(0)