首页
社区
课程
招聘
[讨论]问一下,ExitProcess哪里不安全了?
发表于: 2009-3-12 23:47 12600

[讨论]问一下,ExitProcess哪里不安全了?

2009-3-12 23:47
12600
我承认,ExitThread的确是不安全,多线程环境下肯定会泄露资源

不过ExitProcess和TerminateProcess应该都是安全的吧

最多就是类的析构函数不会被调用,还有C/C++ run time的TLS等问题

不过一旦Process完全结束后,系统会保证所有的资源都被回收

难道就在这Process结束的零点几秒,资源会被泄露?不安全就是指这个?

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 635
活跃值: (101)
能力值: ( LV12,RANK:420 )
在线值:
发帖
回帖
粉丝
2
可能崩溃。。
2009-3-13 00:04
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
程序主线程在退出之前,crt会进行一系列的清理操作,其中就有调用atexit/onexit设置过的回调函数。如果是ExitProcess的话,这些操作可能都不会被执行,所谓的不安全就是指这个吧。
当然,如果程序的安全只能用这个来保证的话,那肯定是架构出了问题。

vc8带的crt代码里面可以看的比较清楚:



static void __cdecl doexit (
int code,
int quick,
int retcaller
)
{
#ifdef _DEBUG
static int fExit = 0;
#endif /* _DEBUG */

#ifdef CRTDLL
if (!retcaller && check_managed_app())
{
/*
Only if the EXE is managed then we call CorExitProcess.
Native cleanup is done in .cctor of the EXE
If the Exe is Native then native clean up should be done
before calling (Cor)ExitProcess.
*/
__crtCorExitProcess(code);
}
#endif /* CRTDLL */

_lockexit(); /* assure only 1 thread in exit path */
__TRY

if (_C_Exit_Done != TRUE) {
_C_Termination_Done = TRUE;

/* save callable exit flag (for use by terminators) */
_exitflag = (char) retcaller; /* 0 = term, !0 = callable exit */

if (!quick) {

/*
* do _onexit/atexit() terminators
* (if there are any)
*
* These terminators MUST be executed in reverse order (LIFO)!
*
* NOTE:
* This code assumes that __onexitbegin points
* to the first valid onexit() entry and that
* __onexitend points past the last valid entry.
* If __onexitbegin == __onexitend, the table
* is empty and there are no routines to call.
*/

_PVFV * onexitbegin = (_PVFV *)_decode_pointer(__onexitbegin);
_PVFV * onexitend = (_PVFV *)_decode_pointer(__onexitend);

if (onexitbegin) {
while ( --onexitend >= onexitbegin )
/*
* if current table entry is non-NULL,
* call thru it.
*/
if ( *onexitend != NULL && *onexitend != _encoded_null())
(*(_PVFV)_decode_pointer(*onexitend))();
}
#ifndef CRTDLL
/*
* do pre-terminators
*/
_initterm(__xp_a, __xp_z);
#endif /* CRTDLL */
}

#ifndef CRTDLL
/*
* do terminators
*/
_initterm(__xt_a, __xt_z);
#endif /* CRTDLL */

#ifdef _DEBUG
/* Dump all memory leaks */
if (!fExit && _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) & _CRTDBG_LEAK_CHECK_DF)
{
fExit = 1;
#ifndef CRTDLL
__freeCrtMemory();
_CrtDumpMemoryLeaks();
#endif /* CRTDLL */
}
#endif /* _DEBUG */

}
/* return to OS or to caller */

__FINALLY
if (retcaller)
_unlockexit(); /* unlock the exit code path */
__END_TRY_FINALLY
if (retcaller)
return;


_C_Exit_Done = TRUE;

_unlockexit(); /* unlock the exit code path */

__crtExitProcess(code);
}


最后crt还是会调用ExitProcess来结束的。
2009-3-13 01:03
0
雪    币: 63
活跃值: (17)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
4
CRT退出肯定要调用exitprocess嘛
2009-3-13 09:32
0
雪    币: 93
活跃值: (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
关注,我貌似好像记得Jeffrey曾说过,无论程序是怎么被结束的,windows系统会帮助清理的嘛。
2009-3-13 09:50
0
雪    币: 108
活跃值: (141)
能力值: ( LV9,RANK:490 )
在线值:
发帖
回帖
粉丝
6
这个所谓的不安全,应该是你没有机会清理环境,可能造成信息丢失之类的。比如你做了一块缓冲区,在工作线程里面往磁盘写。但是直接ExitProcess的时候如果还没写完,你的数据就丢失了
2009-3-13 11:20
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
7
用exit(0)就好啦~
2009-3-13 11:57
0
雪    币: 203
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
理解了

virtual memory或heap中的数据应该不会丢失,毕竟Process没了

你这个例子中,可能会对磁盘上的数据造成影响,比如bt下载到一半,强行退出,可能原来下载的数据就有问题

其他情况下,也有可能造成崩溃等
2009-3-13 12:12
0
雪    币: 203
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
exit本身应该不能释放局部对象,比如类的析构函数不会被调用
2009-3-13 12:19
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
10

没错,但是它还是有一些善后工作的,不会导致崩溃
2009-3-13 12:56
0
雪    币: 203
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
多线程下,应该也有可能崩溃吧

其实只要还有其他的thread在运行,哪怕这时是主线程return,同样存在崩溃的可能吧(当然现实中不可能有这样的程序)
2009-3-13 13:09
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
既然要执行ExitProcess,那肯定是有非执行不可的理由,不退出可能会导致更严重的错误发生。

如果连资源都没掌握好就贸然ExitProcess,这个可不是一个合格的程序员该做的事情。
2009-3-13 14:22
0
雪    币: 203
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
比如迅雷、bitcomet等软件,你下载到一半,然后强行退出,怎么实现的?

不可能软件帮你老老实实的把下载任务停止然后再退出吧,这样的话弹出警告窗口有什么意义?

另外也不可能去hook ExitProcess来释放资源吧
2009-3-13 16:08
0
雪    币: 193
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
你说的强行退出是什么意思?
如果是点迅雷菜单里面的“退出”,他肯定会首先关闭网络连接,关闭打开的文件,然后正常结束程序,程序员能做到的也只有这些了。

如果是用户在任务管理器里面任意的去强行关闭进程,那跟程序员没有任何关系,当然大多数的 程序还是要考虑到这些情况,在下次启动以后,尽量多的恢复当前环境信息。
2009-3-13 16:36
0
游客
登录 | 注册 方可回帖
返回
//