俄罗斯贵宾会 10

但直接双击”test.iqy”是没有问题的

By admin in 操作系统 on 2019年11月14日

1. 问题

当在console中调用API
ShellExecuteEx展开”test.iqy”文件时,开采excel会hang住,console退出后excel才会响应,但一贯双击”test.iqy”是未曾难题的,风趣的是其大器晚成情景独有在xp爆发,在win7上从未有过那几个难题。

 

2. 重现步骤

再次出现蒙受:XP sp3 / Office 2005(别的office版本应该也得以,未有测试卡塔尔国

1> 解压iqy_test.zip

2> 运行http_server.py(需先安装python卡塔尔国

3> 执行”shell_execute.exe test.iqy”

shell_execute.exe的主要code:

bool shell_execute_file(wstring file_path)
{
    SHELLEXECUTEINFOW shell_exec_info = { 0 };
    shell_exec_info.cbSize = sizeof(SHELLEXECUTEINFOW);
    shell_exec_info.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI;
    shell_exec_info.hwnd = NULL;
    shell_exec_info.lpVerb = NULL;
    shell_exec_info.lpFile = file_path.c_str();
    shell_exec_info.lpParameters = NULL;
    shell_exec_info.lpDirectory = NULL;
    shell_exec_info.nShow = SW_SHOW;
    shell_exec_info.hInstApp = NULL;
    bool ret = ShellExecuteExW(&shell_exec_info);
    printf("process handle is %pn", shell_exec_info.hProcess);

    return ret;
}

但直接双击”test.iqy”是没有问题的。 

3. 原因剖析

但直接双击”test.iqy”是没有问题的。3.1 excel hang在哪里?

3.1.1 用windbg附加到excel上,输入如下命令查看主线程hang住的地点

俄罗斯贵宾会 1

能够看出Excel
hang在NtUserMessageCall()中,经过查询知,SendMessage()内部正是调用NtUserMessageCall()来发送新闻的。

翻看参数知excel调用NtUserMessageCall()相仿如下:

NtUserMessageCall(HWND_BROADCAST, WM_DDE_INITIATE)

表达excel给持有顶层窗口发送三个WM_DDE_INITIATE音信,不过有窗口未有response

通过能够嫌疑是由于console进度在和excel用DDE音信通信时,console未有响应excel发送的DDE音讯,引致excel
hang住

 

3.2 为了验证3.1.1的揣摸,用API Monitor一下ShellExecuteEx

3.2.1
依据微软的文档可以预知,发送DDE音信除了WM_DDE_INITIATE和WM_DDE_ACK之外用的都以PostMessage

在API Monitor中找出一下PostMessage的调用,果然搜到一条

俄罗斯贵宾会 2

俄罗斯贵宾会,call stack显示实乃ShellExecuteEx所调用

俄罗斯贵宾会 3

消息1000为WM_DDE_EXECUTE,Post窗口句柄为0x00310172。

小心到下三个API GetWindowThreadProcessId ( 0x00310172 , 0x0012fb70
),适逢其会是拿到那几个窗口的pid和tid,查看下参数窗口:

其后生可畏窗口所属的经过PID =
0xc54,刚巧是excel的历程,表达ShellExecuteEx确实发送了DDE音信给excel,何况可执发送的消息的thread正是主线程

俄罗斯贵宾会 4

听闻DDE的新闻参数,可以见到wParam正是殡葬音讯的窗口,其句柄为2425190 =
0x250166,反向查询知那是ShellExecuteEx成立的”WorkerW”窗口

俄罗斯贵宾会 5

俄罗斯贵宾会 6

 

3.2.2 为了验证3.2.1的定论,在PostMessageW上下断点追踪一下

俄罗斯贵宾会 7

翻看一下buff的地址:

俄罗斯贵宾会 8

恰巧就是开发test.iqy的一声令下,表达ShellExecuteEx就是先成立了excel的进度,然后发送test.iqy的文书命令给excel展开。

 

3.3 总结

1> ShellExecuteEx展开test.iqy的时先成立excel进度

2> 然后创建三个”WorkerW”的窗口用于DDE通讯

3> Post WM_DDE_EXECUTE给excel,告知展开test.iqy的指令

4> ShellExecuteEx实行实现,但并不destroy “WorkerW”窗口

5>
excel收到WM_DDE_EXECUTE音讯后会广播WM_DDE_INITIATE音讯,”WorkerW”窗口所在的console进度由于没有概念音信处理函数,ShellExecuteEx定义的”WorkerW”窗口音信管理函数得不到CPU推行机缘,导致不会response该音讯,从而招致excel
hang住

恍如,大家能够创设叁个带窗口的主次,运维后将其挂起,当时,固然直接双击张开test.iqy也会hang住。

 

4. 怎么双击打开excel不会hang住

因为双击张开实际是用explorer.exe张开,而explorer.exe是有窗口的,能够健康的抽取管理WM_DDE_INITIATE消息

 

5. 为什么win7上不会有那般的标题

5.1 在API Monitor中看下PostMessageW

俄罗斯贵宾会 9

瞩目到win7下PostMessageW是用的线程2调用的,搜一下线程创造API
CreateThread

俄罗斯贵宾会 10

可以知道是ShellExecuteEx内部创设的线程,所以win7上ShellExecuteEx创立了二个线程特意用来管理和excel的DDE音信通讯,这样就能够符合规律的接受管理excel发过来的WM_DDE_INITIATE消息了

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2020 俄罗斯贵宾会 版权所有