调用MessageBoxA()的应用程序是否应该始终由ExitProcess()终止而不是正常函数的结尾? [英] Should an application calling MessageBoxA() always terminate by ExitProcess() instead of normal function epilogue?

查看:70
本文介绍了调用MessageBoxA()的应用程序是否应该始终由ExitProcess()终止而不是正常函数的结尾?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我很难理解为什么在Windows 10 x64上执行 ret 指令后,下面的" MessageBox "-程序为何挂起.

在GDB下调试程序,似乎Win32函数 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)来自C:\ WINDOWS \ SysWoW64 \ win32u.dll的win32u!NtUserSetCursor()中的0x7476262c=>0x7476262c< win32u!NtUserSetCursor + 12> ;: c2 04 00 ret 0x4 

但是,如果我使用 ExitProcess 退出程序,就没有问题.

使用 MessageBoxA 函数的应用程序是否应始终通过 ExitProcess 终止?

程序:

  BITS 32外部_MessageBoxA @ 16.data节_szTitle:db这是一个测试",0x00_szMsg:db"Hello World!",0x00.text部分全局_start_开始:推ebpmov ebp,esp推0x00推_szTitle推_szMsg推0x00致电_MessageBoxA @ 16离开退回 

组装并链接:

  C:\ Users \ nlykkei \ Desktop> nasm -f win32 test.asmC:\ Users \ nlykkei \ Desktop> ld -o test.exe test.obj"C:\ dev \ lib \ User32.Lib" --entry _start 

解决方案

应用在三种情况下终止:

  1. 所有线程结束
  2. 应用程序调用ExitProcess
  3. 有人打电话给TerminateProcess

大约1种情况-通常是由您的应用中自行创建的工作线程构成的窗口.这很大程度上取决于您的工作和Windows版本.因此,即使您具有单线程应用程序,也无法确保进程中没有其他线程启动.在您的情况下,在MessageBoxA之后,您返回了kernel32.dll代码(例如win 8.1中的BaseThreadInitThunk),并调用ExitThread.但没有ExitProcess.因此很有可能您的应用程序没有终止.我们总是必须调用ExitProcess.如果使用c/c ++ crt-从main或WinMain返回时,运行时称为ExitProcess.您不使用crt,因此必须直接通过自己直接调用ExitProcess

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

我对胜利10(1607)进行了一些研究.首先,现在ntdll在初始化阶段调用 EtwEventRegister (因此,每个甚至是单线程设计的应用程序都开始以最少的3个线程开始(2个工作线程在 ZwWaitForWorkViaWorkerFactory 中通过 WrQueue KWAIT_REASON 等待)

现在LoadLibrary有时还会创建辅助线程. LdrpMapAndSnapDependency->LdrpQueueWork->TpPostWork (当我想存在循环模块依赖项时,例如 user32<-> gdi32 ).

也在MessageBox退出时-在进程中加载​​了ole32.dll并创建了工作线程-此处调用堆栈:

因此,在MessageBox返回之后-我们有2个线程正在处理-您的唤醒线程,该线程名为 LdrpWorkCallback ,然后在 ZwWaitForWorkViaWorkerFactory 中等待近1分钟,然后退出

_Start - ExitThread (但不是 ExitProcess )返回时返回

的结果.但进程未终止-该进程中存在另一个线程.大约晚1分钟-当工作线程退出时-进程最终终止

Should an application calling MessageBoxA() always terminate by ExitProcess() instead of normal function epilogue?

I've trouble understanding why the "MessageBox"-program below hangs after executing the ret instruction on Windows 10 x64.

Debugging the program under GDB, it seems like the Win32 function NtUserSetCursor is the reason for the behavior, i.e., after executing the ret 0x4 instruction nothing happens.

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

However, if I exit the program using the ExitProcess there are no problems.

Should an application using the MessageBoxA function always terminate by ExitProcess?

Program:

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

Assembled and linked:

C:\Users\nlykkei\Desktop>nasm -f win32 test.asm

C:\Users\nlykkei\Desktop>ld -o test.exe test.obj "C:\dev\lib\User32.Lib" --entry _start

解决方案

application terminated in three cases:

  1. all thread ended
  2. application call ExitProcess
  3. somebody call TerminateProcess

about 1 case - frequently windows by self created worked threads in your app. this is very depended from what you doing and windows version. so even if you have single thread application - you can not be sure that no other thread started in your process. in your case after MessageBoxA you returned to kernel32.dll code (say BaseThreadInitThunk in win 8.1) wich call ExitThread. but not ExitProcess. so very possible your application not terminated. we always must call ExitProcess. if we use c/c++ crt - runtime called ExitProcess when we return from main or WinMain. you not use crt - so must by self direct call ExitProcess

-------------- EDIT -------------------------------

i do some research om win 10 (1607). at first now ntdll in initialize phase call EtwEventRegister(UserDiagnosticGuid , UserDiagnosticProviderCallback);

internally this call TpAllocWait and 2 worked thread (TppWorkerThread) created.
so every, even single-thread designed application started how minimum with 3 threads (2 worked threads wait in ZwWaitForWorkViaWorkerFactory with WrQueue KWAIT_REASON)

also now LoadLibrary sometimes create worker threads. LdrpMapAndSnapDependency -> LdrpQueueWork -> TpPostWork(when exist cyclic module dependencies i guess - like user32 <-> gdi32 ).

also when MessageBox exited - ole32.dll loaded in process and working thread is created - here call stack:

as result, after MessageBox returned - we have 2 thread in process - your and woking thread, which called LdrpWorkCallback and then wait near 1 minute in ZwWaitForWorkViaWorkerFactory before exit

as result when return from _Start -ExitThread (but not ExitProcess) was called. but process not terminated - another thread live in this process. and ~ 1 min late - when worked thread is exit - process finally terminated

这篇关于调用MessageBoxA()的应用程序是否应该始终由ExitProcess()终止而不是正常函数的结尾?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆