杀掉本地进程其实很简单,取得进程ID后,调用OpenProcess函数打开进程句柄,然后调用TerminateProcess函数就可以杀掉进程了。有些情况下并不能直接打开进程句柄,例如WINLOGON等系统进程,因为权限不够。这个时候我们就得先提升自己的进程的权限了。提升权限过程也不复杂,先调用GetCurrentProcess函数取得当前进程的句柄,然后调用OpenProcessToken打开当前进程的访问令牌,接着调用LookupPrivilegeValue函数取得你想提升的权限的值,最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加权限就可以了。一般有了SeDebugPrivilege特权后,就可以杀掉除Idle外的所有进程了。
*dF>_F OK!那如何杀掉远程进程呢?说起来有点复杂,但其实也不难。
DN/YHSYK <1>与远程系统建立IPC连接
a>)f=uS <2>在远程系统的系统目录admin$\system32中写入一个文件killsrv.exe
w:l"\Tm <3>调用函数OpenSCManager打开远程系统的Service Control Manager[SCM]
<or2 <4>调用函数CreateService在远程系统创建一个服务,服务指向的程序是在<2>中写入的程序killsrv.exe
nd(S3rct& <5>调用函数StartService启动刚才创建的服务,把想杀掉的进程的ID作为参数传递给它
.KC++\{HE <6>服务启动后,killsrv.exe运行,杀掉进程
@H<q"-J <7>清场
U3kyraj 嗯!这样看来,我们需要两个程序了。Killsrv.exe的源代码如下:
{|\.i /***********************************************************************
_wOt39e& Module:Killsrv.c
KF/-wZ"1s Date:2001/4/27
fQ98(+6 Author:ey4s
+O5hH8<&b Http://www.ey4s.org d"NLE'R ***********************************************************************/
{x7, #include
Nluoqoac #include
_rYkis^u #include "function.c"
|%v^W 3 #define ServiceName "PSKILL"
1sCR4L:+ >Se,;cB'/] SERVICE_STATUS_HANDLE ssh;
T)CP2U SERVICE_STATUS ss;
%UM
*79 /////////////////////////////////////////////////////////////////////////
_~pbqa,
void ServiceStopped(void)
2JFpZU"1 {
2-b6gc7 ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
&OBkevg ss.dwCurrentState=SERVICE_STOPPED;
Jo}eeJ;k ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
vFsLY ss.dwWin32ExitCode=NO_ERROR;
??T#QQ ss.dwCheckPoint=0;
MfQ!6zE ss.dwWaitHint=0;
L+QLLcS~EM SetServiceStatus(ssh,&ss);
y==CTY@ return;
Bj~+WwD)QR }
:L;a:xSpn= /////////////////////////////////////////////////////////////////////////
"\=U)CJ void ServicePaused(void)
H|D.6^ {
pmilrZmm] ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
2"5v[,$1H ss.dwCurrentState=SERVICE_PAUSED;
:Yks|VJ1 ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
_2nx^E(pd ss.dwWin32ExitCode=NO_ERROR;
Z/K{A` ss.dwCheckPoint=0;
n(|^SH4$b ss.dwWaitHint=0;
%IRi1EmN8 SetServiceStatus(ssh,&ss);
]:f%l
mEy return;
6&-(&(_ }
HmwT~ void ServiceRunning(void)
$kKjgQS( {
Y<rU#Z #T ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
Uwi7) ss.dwCurrentState=SERVICE_RUNNING;
]fD}
^s3G ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
8*fv' ss.dwWin32ExitCode=NO_ERROR;
HKr
Mim- ss.dwCheckPoint=0;
)Wox Mmz ss.dwWaitHint=0;
.6V}3q$-@ SetServiceStatus(ssh,&ss);
^I)N. 5 return;
_~
&iq1 }
<9%R\_@$H /////////////////////////////////////////////////////////////////////////
j)GtEP<n# void WINAPI servier_ctrl(DWORD Opcode)//服务控制程序
BSMwdr {
Yuc> fFA switch(Opcode)
)/EO&F {
'ah[(F<*@e case SERVICE_CONTROL_STOP://停止Service
x=jK:3BF ServiceStopped();
;'Nd~:-] break;
QwJyY{O` case SERVICE_CONTROL_INTERROGATE:
yA>nli= SetServiceStatus(ssh,&ss);
FE{FGMq break;
LDg?'y;2 }
/SrAW`;" return;
"Yca%: }
N"1B/u //////////////////////////////////////////////////////////////////////////////
+@:x!q|^ //杀进程成功设置服务状态为SERVICE_STOPPED
#u
+ v_ //失败设置服务状态为SERVICE_PAUSED
|&[EZ+[ //
AvHCO8h| void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv)
+'@Dz9:> {
l$'wD hN* ssh=RegisterServiceCtrlHandler(ServiceName,servier_ctrl);
EyLu O-5 if(!ssh)
V/;B3t~f {
\_U$"/$4VH ServicePaused();
Z:7fV5b( return;
p6WX9\qS( }
,=mS,r7 ServiceRunning();
Jq^T1_iqn Sleep(100);
orvp*F{7[H //注意,argv[0]为此程序名,argv[1]为pskill,参数需要递增1
Z`BK/:vo3H //argv[2]=target,argv[3]=user,argv[4]=pwd,argv[5]=pid
%!L9)(}" if(KillPS(atoi(lpszArgv[5])))
Ib0ZjX6 ServiceStopped();
I0RvnMw else
BRYHX.}h\A ServicePaused();
^KE%C;u return;
Rx|;=-8zg }
i2^>vYCsl /////////////////////////////////////////////////////////////////////////////
{vO9ptR; void main(DWORD dwArgc,LPTSTR *lpszArgv)
RAK-UN {
Zr,VR-kW+ SERVICE_TABLE_ENTRY ste[2];
vI)LB)Q ste[0].lpServiceName=ServiceName;
27<
Enq] ste[0].lpServiceProc=ServiceMain;
,'iE;o{Tu ste[1].lpServiceName=NULL;
gRT00 ste[1].lpServiceProc=NULL;
(2
a`XwR StartServiceCtrlDispatcher(ste);
:Xd<74Nu return;
.y,0[i V
N }
,i@:5X/t /////////////////////////////////////////////////////////////////////////////
aoa)BNs function.c中有两个函数,一个是提升权限的,一个是提供进程ID,杀进程的。代码如
F.v{-8GV 下:
L z1ME( /***********************************************************************
UOmY-\ &c Module:function.c
Q?/o%`N Date:2001/4/28
<1COZ) Author:ey4s
9RI-Lq` Http://www.ey4s.org HOh!Xcu ***********************************************************************/
5Zva: #include
.eP.& ////////////////////////////////////////////////////////////////////////////
g|Fn7]G BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
HgkC~' {
E`k@{*Hn& TOKEN_PRIVILEGES tp;
4X(H; LUID luid;
CC^'@~)? }Ys>(w if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
AZ}Xj>= {
'!a'ZjYyi printf("\nLookupPrivilegeValue error:%d", GetLastError() );
d$AWu{y return FALSE;
)D82N`c2\i }
M+9 gL3W tp.PrivilegeCount = 1;
#`X?=/q tp.Privileges[0].Luid = luid;
{s{j~M if (bEnablePrivilege)
w(TJ*::T tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
QW~1%` else
`%Al>u5 tp.Privileges[0].Attributes = 0;
Q'mM3pq4r // Enable the privilege or disable all privileges.
Clb@$, AdjustTokenPrivileges(
5RpjN: 3 hToken,
H&}pkrH~ FALSE,
ZEO,]$Yi7 &tp,
=k:,qft2 sizeof(TOKEN_PRIVILEGES),
,$+V (PTOKEN_PRIVILEGES) NULL,
a"g!e^ (PDWORD) NULL);
*%t^;&x? // Call GetLastError to determine whether the function succeeded.
M>8A\;" if (GetLastError() != ERROR_SUCCESS)
%\Mo-Ow!\ {
a,#j = printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
B[?CbU return FALSE;
Y,e B| }
Sw^u3 return TRUE;
~PahoRS }
Ziu]'# ////////////////////////////////////////////////////////////////////////////
nSAdCJ;4 BOOL KillPS(DWORD id)
wtV#l4 {
fCobzDy
HANDLE hProcess=NULL,hProcessToken=NULL;
~B(4qK1G BOOL IsKilled=FALSE,bRet=FALSE;
'xg
Lt( __try
-701j'q{ {
;Nj7qt }HePZ{PLM if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
+|89>}w4 {
P &e\)Z| printf("\nOpen Current Process Token failed:%d",GetLastError());
3+fp2 __leave;
I[##2 }
:s6o"VkW //printf("\nOpen Current Process Token ok!");
r[Hc>wBv if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
t; {F%9j{ {
Q=20IQp __leave;
z4]api(xZ }
jc f #6 printf("\nSetPrivilege ok!");
zb<6
Ov q,eVjtF if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
BV upDGh3 {
t9:0TBt-[ printf("\nOpen Process %d failed:%d",id,GetLastError());
.oUTqki __leave;
*zL}&RUKM }
<=0
u2~E //printf("\nOpen Process %d ok!",id);
`eCo~(Fy if(!TerminateProcess(hProcess,1))
K_ ~"} {
^ tg<K printf("\nTerminateProcess failed:%d",GetLastError());
wInh~p __leave;
RnI&8 }
xJ)n4) IsKilled=TRUE;
/j|G(vt5 }
.:QLk&a,:, __finally
aL&7 1^R, {
,1CIBFY if(hProcessToken!=NULL) CloseHandle(hProcessToken);
!XCm>]R if(hProcess!=NULL) CloseHandle(hProcess);
krvp&+uX }
I \[_9 return(IsKilled);
Z%/=|[9i }
}YNR"X9*)/ //////////////////////////////////////////////////////////////////////////////////////////////
aAMVsE{ OK!服务端的程序已经好了。接下来还需要一个客户端。如果通过在客户端运行的时候,把killsrv.exe COPY到远程系统上,那么就需要提供两个exe文件给用户,这样显得不是很专业,呵呵。不如我们就把killsrv.exe的二进制码作为buff保存在客户端吧,这样在运行的时候,我们直接把buff中的内容写过去,这样提供给用户一个exe文件就可以了。Pskill.c的源代码如下:
C-MjJ6D< /*********************************************************************************************
zvH8^1yzG ModulesKill.c
:Ab%g- Create:2001/4/28
2=`o_<P'" Modify:2001/6/23
04l!:Tp, Author:ey4s
*P2S6z2 Http://www.ey4s.org e`xdSi>E PsKill ==>Local and Remote process killer for windows 2k
B%76rEpvW; **************************************************************************/
D(RTVef #include "ps.h"
^y1j.M@q #define EXE "killsrv.exe"
(/j/>9iro #define ServiceName "PSKILL"
T
iiW p!mX H>B&|BO_[ #pragma comment(lib,"mpr.lib")
j; y#[| //////////////////////////////////////////////////////////////////////////
!F1N~6f //定义全局变量
UsQ+`\| SERVICE_STATUS ssStatus;
;J2z p*| SC_HANDLE hSCManager=NULL,hSCService=NULL;
5}]"OXQ BOOL bKilled=FALSE;
9"A`sGZ char szTarget[52]=;
=~H<Z LE+ //////////////////////////////////////////////////////////////////////////
kep/+J-u BOOL ConnIPC(char *,char *,char *);//建立IPC连接函数
?D*/*Gk{ BOOL InstallService(DWORD,LPTSTR *);//安装服务函数
/+;h)3PN6 BOOL WaitServiceStop();//等待服务停止函数
g8xQ|px BOOL RemoveService();//删除服务函数
uIZ -#q /////////////////////////////////////////////////////////////////////////
o`P%& int main(DWORD dwArgc,LPTSTR *lpszArgv)
\GZM&Zd {
Ksj -zR; BOOL bRet=FALSE,bFile=FALSE;
z'\_jaj^ char tmp[52]=,RemoteFilePath[128]=,
Slher0.Y szUser[52]=,szPass[52]=;
A}N?/{y)G HANDLE hFile=NULL;
SY^t} A7:/ DWORD i=0,dwIndex=0,dwWrite,dwSize=sizeof(exebuff);
7KL v6]b P5nO78 //杀本地进程
]?
g@jRs if(dwArgc==2)
ua]o6GlO {
_EMwm&! if(KillPS(atoi(lpszArgv[1])))
&6YIn|} printf("\nLoacl Process %s have beed killed!",lpszArgv[1]);
\uC15s< else
=&2Lb printf("\nLoacl Process %s can't be killed!ErrorCode:%d",
^,_w$H lpszArgv[1],GetLastError());
Md2>3- return 0;
C:C}5<fkx }
DB:+E|vSD //用户输入错误
/.M N else if(dwArgc!=5)
;1.,Sn+zO {
_Khc3Jo printf("\nPSKILL ==>Local and Remote Process Killer"
Z99>5\k "\nPower by ey4s"
U\;6mK)M^J "\nhttp://www.ey4s.org 2001/6/23"
()+<)hg}2 "\n\nUsage:%s <==Killed Local Process"
^,8)iV0j_ "\n %s <==Killed Remote Process\n",
3?7\T#= lpszArgv[0],lpszArgv[0]);
dEA6 return 1;
O6/f5 }
X{'q24\F //杀远程机器进程
pd7NF-KD strncpy(szTarget,lpszArgv[1],sizeof(szTarget)-1);
[uq$5u strncpy(szUser,lpszArgv[2],sizeof(szUser)-1);
?$^2Umt0 strncpy(szPass,lpszArgv[3],sizeof(szPass)-1);
(>GK\=:< `[)YEgs //将在目标机器上创建的exe文件的路径
%i-c0|,T4 sprintf(RemoteFilePath,"\\%s\admin$\system32\%s",szTarget,EXE);
b6F4>@gjg __try
^1aAjYFn {
ReI/]#Us //与目标建立IPC连接
Hp|_6hO 2 if(!ConnIPC(szTarget,szUser,szPass))
4 G-wd {
"a"]o printf("\nConnect to %s failed:%d",szTarget,GetLastError());
qI<mjB{3` return 1;
'BPp ]R#{ }
>wBJy4: printf("\nConnect to %s success!",szTarget);
V=V:SlS9| //在目标机器上创建exe文件
M&Uj^K1 3]UUG hFile=CreateFile(RemoteFilePath,GENERIC_ALL,FILE_SHARE_READ|FILE_SHARE_WRIT
RUT,Y4 b E,
FPI;Jx6W' NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
7C ,UDp| if(hFile==INVALID_HANDLE_VALUE)
.wu
xoq {
w1#gOwA,$ printf("\nCreate file %s failed:%d",RemoteFilePath,GetLastError());
}36QsH8 __leave;
;u(<h?%e }
M8Z2Pg\0 //写文件内容
"WK{ >T while(dwSize>dwIndex)
o=?C&f{ {
5HO9+i QxOjOKAG
if(!WriteFile(hFile,&exebuff[dwIndex],dwSize-dwIndex,&dwWrite,NULL))
rKf-+6Na {
yA(K=?sq printf("\nWrite file %s
kO{s^_qR^c failed:%d",RemoteFilePath,GetLastError());
/)(#{i* __leave;
;Tc`}2 }
^__Dd)( dwIndex+=dwWrite;
;R?I4}O#R8 }
%V{7DA&C //关闭文件句柄
uYil ?H{kH CloseHandle(hFile);
nwaxz>; bFile=TRUE;
]=";IN:SU //安装服务
GBFtr if(InstallService(dwArgc,lpszArgv))
D]~MC {
_DNHc* //等待服务结束
j;3[KLmuK% if(WaitServiceStop())
o1Q7Th {
fasgmi} //printf("\nService was stoped!");
Qx47l }
zs*L~_K else
(RZD'U/B {
,gOOiB
} //printf("\nService can't be stoped.Try to delete it.");
sWblFvHqrU }
HnCzbt@ Sleep(500);
xz{IH,?IG //删除服务
hQH nwr RemoveService();
c#]q^L\x }
)R
2. }
S'B|>!z@ __finally
/3:q#2'v {
P*Tx14xe4 //删除留下的文件
7C2&NyWJ if(bFile) DeleteFile(RemoteFilePath);
>Ll$p0W //如果文件句柄没有关闭,关闭之~
@wC5 g 4E if(hFile!=NULL) CloseHandle(hFile);
`8>Py~ //Close Service handle
g9WGkHF if(hSCService!=NULL) CloseServiceHandle(hSCService);
1,~SS //Close the Service Control Manager handle
QtqfG{ if(hSCManager!=NULL) CloseServiceHandle(hSCManager);
0,rTdjH7 //断开ipc连接
Cp]"1%M, wsprintf(tmp,"\\%s\ipc$",szTarget);
Bv.`R0e& WNetCancelConnection2(tmp,CONNECT_UPDATE_PROFILE,TRUE);
-7&Gi
+] if(bKilled)
D<X.\})Md printf("\nProcess %s on %s have been
D"ehWLj killed!\n",lpszArgv[4],lpszArgv[1]);
Xy &uZ else
V-r3-b printf("\nProcess %s on %s can't be
<u:WlaS killed!\n",lpszArgv[4],lpszArgv[1]);
M7+h(\H]2 }
&o97u4xi return 0;
,qrQ"r9 }
GSQ/NYK //////////////////////////////////////////////////////////////////////////
u% n*gcY BOOL ConnIPC(char *RemoteName,char *User,char *Pass)
b-*3 2Y% {
^ Dt#$Z NETRESOURCE nr;
lmSo8/%T char RN[50]="\\";
u=/CRjot ~~,rp) ) strcat(RN,RemoteName);
yxq}QSb \3 strcat(RN,"\ipc$");
`VL}.h STw#lU) %( nr.dwType=RESOURCETYPE_ANY;
(q7
Ry4- nr.lpLocalName=NULL;
\7
NpT}dj nr.lpRemoteName=RN;
U(;&(W"M
nr.lpProvider=NULL;
y&= ALx@ (V% `k'N7f if(WNetAddConnection2(&nr,Pass,User,FALSE)==NO_ERROR)
FSbHn{@ return TRUE;
NwR}yb6 else
Z@%HvB7 return FALSE;
9bq<GC'eX8 }
gOK\%&S] /////////////////////////////////////////////////////////////////////////
[e4]"v`N BOOL InstallService(DWORD dwArgc,LPTSTR *lpszArgv)
?
j
9|5* {
rJInj>|{= BOOL bRet=FALSE;
eBO@7F$ __try
*d',Vuv&[ {
d 'Axum@ //Open Service Control Manager on Local or Remote machine
u}|%@=xn hSCManager=OpenSCManager(szTarget,NULL,SC_MANAGER_ALL_ACCESS);
.ol'.t,S if(hSCManager==NULL)
T!}[yW {
{?}*1,I printf("\nOpen Service Control Manage failed:%d",GetLastError());
*8tI*Pus __leave;
cFF*Z=L_ }
9A7@
5F //printf("\nOpen Service Control Manage ok!");
"h7tnMS //Create Service
h<\_XJJ hSCService=CreateService(hSCManager,// handle to SCM database
@ Ehn(} ServiceName,// name of service to start
a`u
S[r> ServiceName,// display name
'iY*6<xS< SERVICE_ALL_ACCESS,// type of access to service
34R!x6W0 SERVICE_WIN32_OWN_PROCESS,// type of service
X*7\lf2 SERVICE_AUTO_START,// when to start service
@AYo-gf SERVICE_ERROR_IGNORE,// severity of service
)CS.F= failure
`K
>?ju" EXE,// name of binary file
oo$MWN8a>r NULL,// name of load ordering group
J!*/a'Cv NULL,// tag identifier
'XUKN/. NULL,// array of dependency names
7RvUH-S[ NULL,// account name
e%>b+Sv NULL);// account password
A[YpcG'9 //create service failed
l@hjP1o if(hSCService==NULL)
m G1IQ! {
@MK"X}3 //如果服务已经存在,那么则打开
;|cTHGxbE if(GetLastError()==ERROR_SERVICE_EXISTS)
rBN)a" {
G^1b>K //printf("\nService %s Already exists",ServiceName);
"uPy,<l //open service
`:G% hSCService = OpenService(hSCManager, ServiceName,
z>[tF5 SERVICE_ALL_ACCESS);
1lnU77; if(hSCService==NULL)
7gS1~Q4\V2 {
$8BE[u|H2 printf("\nOpen Service failed:%d",GetLastError());
U`x bPQ __leave;
Q\3 Z|% }
1Fi86 //printf("\nOpen Service %s ok!",ServiceName);
{+g[l5CR[ }
=)OC|?9C\ else
.6pOvGKb {
=[<m[.)i printf("\nCreateService failed:%d",GetLastError());
g+C!kaC) __leave;
S?0)1O }
:b,^J&~/)1 }
N|2y"5 //create service ok
i$KpDXP\ else
OlQ,Ce {
S|GWcSg //printf("\nCreate Service %s ok!",ServiceName);
'?yCq$& }
Ab1/.~^ FCc=e{ // 起动服务
-6Mm#sX if ( StartService(hSCService,dwArgc,lpszArgv))
i
NWC6y {
G 8Y+w //printf("\nStarting %s.", ServiceName);
)hj|{h7 Sleep(20);//时间最好不要超过100ms
GW2')}g while( QueryServiceStatus(hSCService, &ssStatus ) )
mEuHl> {
s2v(=
if ( ssStatus.dwCurrentState == SERVICE_START_PENDING)
yO>V/5` {
WnAd5#G printf(".");
7>
Pgc Sleep(20);
K$REZe }
)DUL)S else
y/@iT8$rp break;
!=*.$4 }
(a6?s{( if ( ssStatus.dwCurrentState != SERVICE_RUNNING )
m^{
xd2 printf("\n%s failed to run:%d",ServiceName,GetLastError());
)-/gLZsx }
cub<G!K else if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)
^`qPs/b {
em]xtya //printf("\nService %s already running.",ServiceName);
&4$oudn }
WO,xMfK else
r5/R5Ga^ {
u>Ki$xP1 printf("\nStart Service %s failed:%d",ServiceName,GetLastError());
ZZ)G5ji __leave;
9|S` ub' }
"L2 m-e6 bRet=TRUE;
;' e@t8i6 }//enf of try
czBi Dk4 __finally
xUYow {
#cwCocw return bRet;
Nl8 gK{ }
/CT(k1> return bRet;
ZcryAm:I }
$~'Tf>e /////////////////////////////////////////////////////////////////////////
?Cci:Lin BOOL WaitServiceStop(void)
<kD#SV%" {
y?N Nz0 BOOL bRet=FALSE;
LN!W(n( //printf("\nWait Service stoped");
/b.oEGqZX while(1)
Y&'8VdW {
N)43};e Sleep(100);
=V^@%YIn if(!QueryServiceStatus(hSCService, &ssStatus))
i|\{\d {
xKJ>gr"w# printf("\nQueryServiceStatus failed:%d",GetLastError());
@5}gsC break;
S@:B6](D$ }
U 0ZB^` if(ssStatus.dwCurrentState==SERVICE_STOPPED)
(clU$m+oXX {
Uk-HP\C"7 bKilled=TRUE;
\/Ij7nD`l% bRet=TRUE;
MMD<I6Iyv break;
zd`=Ih2Wx }
~/`X*n& if(ssStatus.dwCurrentState==SERVICE_PAUSED)
?B4#f!X {
SQKt}kDbM //停止服务
IG / $!*E bRet=ControlService(hSCService,SERVICE_CONTROL_STOP,NULL);
M<