调用MessageBoxA()的应用程序是否总是由ExitProcess()而不是正常的函数结尾终止?

时间:2016-11-03 18:30:58

标签: windows debugging winapi assembly x86

  

调用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

1 个答案:

答案 0 :(得分:2)

申请在三种情况下终止:

  1. 所有主题已结束
  2. 应用程序调用ExitProcess
  3. 有人打电话给TerminateProcess
  4. 大约1个案例 - 经常在自己的应用程序中创建工作线程的窗口。这非常依赖于你所做的和windows版本。所以即使你有单线程应用程序 - 你也不能确定你的进程中没有其他线程启动。在你的情况下,在MessageBoxA之后你回到了kernel32.dll代码(比如win 8.1中的BaseThreadInitThunk),它会调用ExitThread。但不是ExitProcess。所以你的申请很可能没有被终止。我们总是必须调用ExitProcess。如果我们使用c / c ++ crt - 当我们从main或WinMain返回时称为ExitProcess的运行时。你不使用crt - 所以必须通过自我直接调用ExitProcess

    --------------编辑----------------------------- -

    我做了一些研究,赢了10(1607)。首先现在ntdll初始化阶段调用EtwEventRegisterUserDiagnosticGuid , UserDiagnosticProviderCallback);

    内部此调用TpAllocWait和2个工作线程(TppWorkerThread) 创建。
    enter image description here 所以每个,甚至是单线程设计的应用程序都开始了3个线程的最小值(2个工作线程在ZwWaitForWorkViaWorkerFactory中等待WrQueue KWAIT_REASON

    现在LoadLibrary有时会创建工作线程。 LdrpMapAndSnapDependency -> LdrpQueueWork -> TpPostWork(当我认为存在循环模块依赖时 - 就像user32 <-> gdi32)。

    当MessageBox退出时 - 在进程中加载​​ole32.dll并创建工作线程 - 这里调用stack:

    enter image description here

    结果,在MessageBox返回之后 - 我们有2个线程在进行 - 你的和woking线程,调用LdrpWorkCallback然后在ZwWaitForWorkViaWorkerFactory中等待1分钟后再退出

    enter image description here

    _Start - ExitThread(但不是ExitProcess)返回时被调用。但是进程没有终止 - 另一个线程就在这个过程中。 并且晚了~1分钟 - 当工作线程退出时 - 进程最终终止