调用MessageBoxA()的应用程序是否总是由ExitProcess()而不是正常的函数结尾终止?
我无法理解为什么“android:name="android.support.multidex.MultiDexApplication"
”程序在Windows 10 x64上执行MessageBox
指令后会挂起。
在GDB下调试程序,似乎Win32函数ret
是行为的原因,即在执行NtUserSetCursor
指令后没有任何反应。
ret 0x4
但是,如果我使用0x779c2440 in ?? ()
=> 0x779c2440: ff 25 18 12 a5 77 jmp DWORD PTR ds:0x77a51218
(gdb)
0x6c417000 in ?? ()
=> 0x6c417000: ea 09 70 41 6c 33 00 jmp 0x33:0x6c417009
(gdb)
0x7476262c in win32u!NtUserSetCursor () from C:\WINDOWS\SysWoW64\win32u.dll
=> 0x7476262c <win32u!NtUserSetCursor+12>: c2 04 00 ret 0x4
退出程序,则没有问题。
使用ExitProcess
功能的应用程序是否始终以MessageBoxA
终止?
程序:
ExitProcess
汇编和链接:
BITS 32
extern _MessageBoxA@16
section .data
_szTitle: db "This is a test", 0x00
_szMsg: db "Hello World!", 0x00
section .text
global _start
_start:
push ebp
mov ebp, esp
push 0x00
push _szTitle
push _szMsg
push 0x00
call _MessageBoxA@16
leave
ret
答案 0 :(得分:2)
申请在三种情况下终止:
大约1个案例 - 经常在自己的应用程序中创建工作线程的窗口。这非常依赖于你所做的和windows版本。所以即使你有单线程应用程序 - 你也不能确定你的进程中没有其他线程启动。在你的情况下,在MessageBoxA之后你回到了kernel32.dll代码(比如win 8.1中的BaseThreadInitThunk),它会调用ExitThread。但不是ExitProcess。所以你的申请很可能没有被终止。我们总是必须调用ExitProcess。如果我们使用c / c ++ crt - 当我们从main或WinMain返回时称为ExitProcess的运行时。你不使用crt - 所以必须通过自我直接调用ExitProcess
--------------编辑----------------------------- - 强>
我做了一些研究,赢了10(1607)。首先现在ntdll初始化阶段调用EtwEventRegister
(UserDiagnosticGuid
, UserDiagnosticProviderCallback);
内部此调用TpAllocWait
和2个工作线程(TppWorkerThread
)
创建。
所以每个,甚至是单线程设计的应用程序都开始了3个线程的最小值(2个工作线程在ZwWaitForWorkViaWorkerFactory
中等待WrQueue
KWAIT_REASON
)
现在LoadLibrary有时会创建工作线程。 LdrpMapAndSnapDependency -> LdrpQueueWork -> TpPostWork
(当我认为存在循环模块依赖时 - 就像user32 <-> gdi32
)。
当MessageBox退出时 - 在进程中加载ole32.dll并创建工作线程 - 这里调用stack:
结果,在MessageBox返回之后 - 我们有2个线程在进行 - 你的和woking线程,调用LdrpWorkCallback
然后在ZwWaitForWorkViaWorkerFactory
中等待1分钟后再退出
从_Start
- ExitThread
(但不是ExitProcess
)返回时被调用。但是进程没有终止 - 另一个线程就在这个过程中。
并且晚了~1分钟 - 当工作线程退出时 - 进程最终终止