杀掉本地进程其实很简单,取得进程ID后,调用OpenProcess函数打开进程句柄,然后调用TerminateProcess函数就可以杀掉进程了。有些情况下并不能直接打开进程句柄,例如WINLOGON等系统进程,因为权限不够。这个时候我们就得先提升自己的进程的权限了。提升权限过程也不复杂,先调用GetCurrentProcess函数取得当前进程的句柄,然后调用OpenProcessToken打开当前进程的访问令牌,接着调用LookupPrivilegeValue函数取得你想提升的权限的值,最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加权限就可以了。一般有了SeDebugPrivilege特权后,就可以杀掉除Idle外的所有进程了。
>?XbU} OK!那如何杀掉远程进程呢?说起来有点复杂,但其实也不难。
Wb=Jj 9; <1>与远程系统建立IPC连接
z<C[nR$N <2>在远程系统的系统目录admin$\system32中写入一个文件killsrv.exe
]H 2R <3>调用函数OpenSCManager打开远程系统的Service Control Manager[SCM]
=xEk7'W6k <4>调用函数CreateService在远程系统创建一个服务,服务指向的程序是在<2>中写入的程序killsrv.exe
cV$lobqO <5>调用函数StartService启动刚才创建的服务,把想杀掉的进程的ID作为参数传递给它
&>}.RX]t <6>服务启动后,killsrv.exe运行,杀掉进程
;cSGlE | <7>清场
:B#EqeI 嗯!这样看来,我们需要两个程序了。Killsrv.exe的源代码如下:
y~#\#w{ /***********************************************************************
ZW ye>] Module:Killsrv.c
t/:w1rw Date:2001/4/27
O4+F^+qN Author:ey4s
Rlg#z4m Http://www.ey4s.org P!+v:'P5f ***********************************************************************/
okBE|g #include
gn5% F5W #include
=Q?f96T #include "function.c"
|1V2tx #define ServiceName "PSKILL"
oXc/#{NC j8HOc( SERVICE_STATUS_HANDLE ssh;
[%.18FWI SERVICE_STATUS ss;
nlfPg-78B+ /////////////////////////////////////////////////////////////////////////
4UCwT1 void ServiceStopped(void)
nTZ> |R) {
DA <ynBQ ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
n85r^W ss.dwCurrentState=SERVICE_STOPPED;
RebTg1vGu ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
Z*bC#s? ss.dwWin32ExitCode=NO_ERROR;
me. /o(!? ss.dwCheckPoint=0;
2,AaP*, ss.dwWaitHint=0;
sMi{"`37 SetServiceStatus(ssh,&ss);
$v&C@l \ return;
ce5nG0@# }
oa0X5}D /////////////////////////////////////////////////////////////////////////
,RK3eQ void ServicePaused(void)
?vu|o'$T, {
ltEF:{mLe# ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
{'IFWD. 5 ss.dwCurrentState=SERVICE_PAUSED;
{% F`%_{" ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
VN|G5* ss.dwWin32ExitCode=NO_ERROR;
Pf8u/?/ ss.dwCheckPoint=0;
}'`xu9< ss.dwWaitHint=0;
:HZ;Po SetServiceStatus(ssh,&ss);
_'c+fG
\ return;
%8Yyj{^!( }
V<-htV void ServiceRunning(void)
*-z4 <LAa {
94z8B;+H] ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
^gm>!-Gx ss.dwCurrentState=SERVICE_RUNNING;
A7'b Nd6f9 ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
5^F]tRz- ss.dwWin32ExitCode=NO_ERROR;
uu3M{*} ss.dwCheckPoint=0;
i`~~+6`J ss.dwWaitHint=0;
,Oi^ySn SetServiceStatus(ssh,&ss);
$xcv > return;
!QTPWA }
jM\ %$_/ /////////////////////////////////////////////////////////////////////////
DyX0xx^ void WINAPI servier_ctrl(DWORD Opcode)//服务控制程序
@KJV1t` {
?>)yKa# U switch(Opcode)
L1MrrC {
lM&UFEl-\ case SERVICE_CONTROL_STOP://停止Service
;Vo mFp L ServiceStopped();
=, TS MV break;
`e*61k5 case SERVICE_CONTROL_INTERROGATE:
b Fn(w:1Q SetServiceStatus(ssh,&ss);
a 2E t,WA% break;
JjDS"hK# }
Gt'/D>FE0 return;
poY8
)2 }
qL>v&Rd< //////////////////////////////////////////////////////////////////////////////
'fl(N2t //杀进程成功设置服务状态为SERVICE_STOPPED
RO$*G
jQd //失败设置服务状态为SERVICE_PAUSED
! OfO:L7- //
paYz[Xq void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv)
^?sSx!:bZ {
vrO%XvXW ssh=RegisterServiceCtrlHandler(ServiceName,servier_ctrl);
]Da4.s*mW if(!ssh)
~ a>S#S {
dgY5ccP ServicePaused();
Wbd_aR
( return;
"s;ci~$ }
9@etg4#] ServiceRunning();
Cg*kN"8q Sleep(100);
H` Lu"EK //注意,argv[0]为此程序名,argv[1]为pskill,参数需要递增1
>.@MR<H#5 //argv[2]=target,argv[3]=user,argv[4]=pwd,argv[5]=pid
* 2%oZXF if(KillPS(atoi(lpszArgv[5])))
[U']kt ServiceStopped();
bQpoXs0w; else
qu!<lW~c ServicePaused();
*cQz[S@F return;
7H?!RYrx }
_0*=u$~R /////////////////////////////////////////////////////////////////////////////
@aUZ#,(< void main(DWORD dwArgc,LPTSTR *lpszArgv)
'yeh7oR {
aLHrl6" SERVICE_TABLE_ENTRY ste[2];
oo'iwq-\ ste[0].lpServiceName=ServiceName;
YZ{;%&rB ste[0].lpServiceProc=ServiceMain;
d>~`j8,B ste[1].lpServiceName=NULL;
e~*S4dKR ste[1].lpServiceProc=NULL;
S}O5l}E StartServiceCtrlDispatcher(ste);
U#$:\fT return;
P8u"T!G }
?qIGQ/af& /////////////////////////////////////////////////////////////////////////////
^:U;rHY function.c中有两个函数,一个是提升权限的,一个是提供进程ID,杀进程的。代码如
g.=!3e&z% 下:
s1v{~xP /***********************************************************************
%27G 2^1 Module:function.c
| 4%v"U Date:2001/4/28
>LCjtm\ Author:ey4s
LsnXS9_ Http://www.ey4s.org zM)M_L ***********************************************************************/
I>!|3ElT #include
.$OjUlzr-H ////////////////////////////////////////////////////////////////////////////
hOV_Oqe4? BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
1k`|[l^
{
<%(f9j TOKEN_PRIVILEGES tp;
7%X+O8 LUID luid;
fA;x{0CAMX 83X/"2-K if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
75PS^5T, {
oX2r?.j#M printf("\nLookupPrivilegeValue error:%d", GetLastError() );
KM E XT$p return FALSE;
gMCy$+? }
&9k"9 tp.PrivilegeCount = 1;
i /C'0 tp.Privileges[0].Luid = luid;
})q]gMj if (bEnablePrivilege)
B piEAwh tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
S[ i$e else
3!1&DII4 tp.Privileges[0].Attributes = 0;
xvHOY: // Enable the privilege or disable all privileges.
"_Zh5
g AdjustTokenPrivileges(
5,Qy/t}K hToken,
p~ mN2x ] FALSE,
>&g2 IvDS &tp,
0;'j!`l9 sizeof(TOKEN_PRIVILEGES),
hgNY[, (PTOKEN_PRIVILEGES) NULL,
;A`IYRzt (PDWORD) NULL);
A<]&JbIt // Call GetLastError to determine whether the function succeeded.
,Z >JvTnH if (GetLastError() != ERROR_SUCCESS)
OrzM
hQaf {
L/c4"f|.*v printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
3KR2TcT#{ return FALSE;
|:{g?4Mi }
m<~>&mWr return TRUE;
9$8X>T^ }
L,tZh0 ////////////////////////////////////////////////////////////////////////////
]U#JsMS BOOL KillPS(DWORD id)
6_x}.bkIx= {
p^}L HANDLE hProcess=NULL,hProcessToken=NULL;
^"PfDTyA BOOL IsKilled=FALSE,bRet=FALSE;
g6HphRJ5s __try
T,A!5V>cX {
5R&x{jf$ |)~Ex 9%ev if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
wbn^R' {
7cy+Nz printf("\nOpen Current Process Token failed:%d",GetLastError());
;B,nzx(L __leave;
6oPUYn- }
`4se7{'UK` //printf("\nOpen Current Process Token ok!");
8Ix-i if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
$b&BH'*'~ {
`"i^'VL, __leave;
EolE?g@l8 }
uv?8V@x2 printf("\nSetPrivilege ok!");
x;<oaT$X
<|ka{=T if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
I3V{"Nx6 {
v/QEu^C printf("\nOpen Process %d failed:%d",id,GetLastError());
dw@TbJ __leave;
[P (rY }
-9hp+0 < //printf("\nOpen Process %d ok!",id);
oNh68ON:c if(!TerminateProcess(hProcess,1))
7uWJ6Wk {
oFX"F0rx printf("\nTerminateProcess failed:%d",GetLastError());
7[(Lrx.pM __leave;
_Ac/i r[,: }
WK/b=p|#o IsKilled=TRUE;
7*R{u*/e }
v)wY __finally
&\CJg'D:m {
TsoCW]h if(hProcessToken!=NULL) CloseHandle(hProcessToken);
[i2A{(x if(hProcess!=NULL) CloseHandle(hProcess);
V,99N'o~x }
;P0,60 return(IsKilled);
yaCd4KP }
l"2^S6vU //////////////////////////////////////////////////////////////////////////////////////////////
EOMuqP) OK!服务端的程序已经好了。接下来还需要一个客户端。如果通过在客户端运行的时候,把killsrv.exe COPY到远程系统上,那么就需要提供两个exe文件给用户,这样显得不是很专业,呵呵。不如我们就把killsrv.exe的二进制码作为buff保存在客户端吧,这样在运行的时候,我们直接把buff中的内容写过去,这样提供给用户一个exe文件就可以了。Pskill.c的源代码如下:
O7Y
P_<,# /*********************************************************************************************
PT
0Qzg ModulesKill.c
F5:2TEA Create:2001/4/28
T)$6H}[c Modify:2001/6/23
Z1XUYe62 Author:ey4s
R !:eYoQ Http://www.ey4s.org OqAh4qa,$ PsKill ==>Local and Remote process killer for windows 2k
m70`{-O **************************************************************************/
s{x*~M$vt #include "ps.h"
cij]&$;Q #define EXE "killsrv.exe"
K|P9uHD #define ServiceName "PSKILL"
xMO[3D&D 1R^XWAb #pragma comment(lib,"mpr.lib")
nsM>% +o //////////////////////////////////////////////////////////////////////////
ze#rYN vo/ //定义全局变量
IN]`lJ SERVICE_STATUS ssStatus;
A &X SC_HANDLE hSCManager=NULL,hSCService=NULL;
%OezaNOtm BOOL bKilled=FALSE;
duZ|mT8Q== char szTarget[52]=;
'qD'PLV //////////////////////////////////////////////////////////////////////////
wR5\^[GN BOOL ConnIPC(char *,char *,char *);//建立IPC连接函数
.b!OZ BOOL InstallService(DWORD,LPTSTR *);//安装服务函数
`2
%eDFZ BOOL WaitServiceStop();//等待服务停止函数
ox i
a} BOOL RemoveService();//删除服务函数
gNMKGf\Y /////////////////////////////////////////////////////////////////////////
s0X/1Cq int main(DWORD dwArgc,LPTSTR *lpszArgv)
HM(bR"E {
MbT
ONt?~v BOOL bRet=FALSE,bFile=FALSE;
TsFV
;Sl3 char tmp[52]=,RemoteFilePath[128]=,
kx;xO>dC szUser[52]=,szPass[52]=;
L@d]R MNv HANDLE hFile=NULL;
:V5!C$QV DWORD i=0,dwIndex=0,dwWrite,dwSize=sizeof(exebuff);
wI1M0@}PV K#m\qitb //杀本地进程
iMOPD}`IX if(dwArgc==2)
bn<I#ZH2 {
!9ceCnwbNN if(KillPS(atoi(lpszArgv[1])))
IL8'{<lM printf("\nLoacl Process %s have beed killed!",lpszArgv[1]);
i"2J5LLv else
@M1yBN printf("\nLoacl Process %s can't be killed!ErrorCode:%d",
&Cx yP_ lpszArgv[1],GetLastError());
2Q`PUXj return 0;
14@q $}sf }
DRKc&F6Qy //用户输入错误
8S[<[CH else if(dwArgc!=5)
/Gh
x2B {
l\A}lC0?J printf("\nPSKILL ==>Local and Remote Process Killer"
)n[`Z# "\nPower by ey4s"
;Wfv+]n9 "\nhttp://www.ey4s.org 2001/6/23"
l"~h1xk~ "\n\nUsage:%s <==Killed Local Process"
}QApeZd+q "\n %s <==Killed Remote Process\n",
!"o1ve`{ lpszArgv[0],lpszArgv[0]);
h^[ppc{Z return 1;
.5Z,SGBf }
}R(0[0NQe- //杀远程机器进程
0s+rd& strncpy(szTarget,lpszArgv[1],sizeof(szTarget)-1);
8`rAE_n`% strncpy(szUser,lpszArgv[2],sizeof(szUser)-1);
)M|O;~q strncpy(szPass,lpszArgv[3],sizeof(szPass)-1);
^Xt]wl*]+ H;b'"./ //将在目标机器上创建的exe文件的路径
P}.yEta sprintf(RemoteFilePath,"\\%s\admin$\system32\%s",szTarget,EXE);
]6i_d __try
Wj {
E:dT_x<Y //与目标建立IPC连接
#Kb)>gzT if(!ConnIPC(szTarget,szUser,szPass))
I2Or&
_ {
$fj"* printf("\nConnect to %s failed:%d",szTarget,GetLastError());
Hjo:;s return 1;
RJ`/qXL }
^~YmLI4 printf("\nConnect to %s success!",szTarget);
7y)|^4X2 //在目标机器上创建exe文件
tswG"1R iC5JU&l hFile=CreateFile(RemoteFilePath,GENERIC_ALL,FILE_SHARE_READ|FILE_SHARE_WRIT
t<EX#_i, E,
HPd+Bd NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
n)wpxR if(hFile==INVALID_HANDLE_VALUE)
%;"B;~ {
=vqE=:X6 printf("\nCreate file %s failed:%d",RemoteFilePath,GetLastError());
Y+PvL|`O __leave;
oN1wrf}Sh }
CB{k;H //写文件内容
:'^dy%&UB while(dwSize>dwIndex)
+2k|g2 {
D .oS8' 7Hr4yh[j& if(!WriteFile(hFile,&exebuff[dwIndex],dwSize-dwIndex,&dwWrite,NULL))
Um0<I) {
[y&h_w. printf("\nWrite file %s
pFv[z':&Q failed:%d",RemoteFilePath,GetLastError());
>/OXC+=^4 __leave;
_
/28Cw }
K&"Pm9
dwIndex+=dwWrite;
);/5#b@<Y }
RGPU~L //关闭文件句柄
e&a[k CloseHandle(hFile);
>a anLLO bFile=TRUE;
Spr:K, //安装服务
exrt|A]_[ if(InstallService(dwArgc,lpszArgv))
)1tnZ=& {
;6&=]I //等待服务结束
Y$`hudJ& if(WaitServiceStop())
dO4U9{+ {
c_8 mQ //printf("\nService was stoped!");
;HLMU36q }
<J_,9&\J else
77=y!SDP {
C6=;(=?C //printf("\nService can't be stoped.Try to delete it.");
'm p{O }
.5Z@5g` Sleep(500);
?\p%Mx? //删除服务
/o06h y RemoveService();
tU~H@' }
<0,ah4C }
'y@ 2,9v __finally
m*Lv,yw %a {
`))J8j" //删除留下的文件
KlX |PQ if(bFile) DeleteFile(RemoteFilePath);
bEXHB //如果文件句柄没有关闭,关闭之~
I>4Tbwy.- if(hFile!=NULL) CloseHandle(hFile);
F+m4 //Close Service handle
]zR;%p if(hSCService!=NULL) CloseServiceHandle(hSCService);
qu~"C, //Close the Service Control Manager handle
T[$hYe8%^ if(hSCManager!=NULL) CloseServiceHandle(hSCManager);
H/la'f#o% //断开ipc连接
*$Wx*Jo wsprintf(tmp,"\\%s\ipc$",szTarget);
q
]R @:a/ WNetCancelConnection2(tmp,CONNECT_UPDATE_PROFILE,TRUE);
hu*>B if(bKilled)
`GN5QLg#}0 printf("\nProcess %s on %s have been
AYQh=$)( killed!\n",lpszArgv[4],lpszArgv[1]);
y8WXp_\ else
ujp,D#xHP printf("\nProcess %s on %s can't be
`q{'_\gVt( killed!\n",lpszArgv[4],lpszArgv[1]);
Cq;K,B9 }
f+88R=-u6S return 0;
.$s|T }
nF
y7gA| //////////////////////////////////////////////////////////////////////////
xbH!:R; BOOL ConnIPC(char *RemoteName,char *User,char *Pass)
-N!soJ< {
mt6uW+t/ NETRESOURCE nr;
wTuRo
J char RN[50]="\\";
bFdg'_ d~bH!P strcat(RN,RemoteName);
mbG^fy' strcat(RN,"\ipc$");
WF.$gBH" 8_,wOkk_B nr.dwType=RESOURCETYPE_ANY;
exMPw;8 nr.lpLocalName=NULL;
y42T.oK8c nr.lpRemoteName=RN;
o6yZ@R nr.lpProvider=NULL;
O09g b[ `[u>NEb if(WNetAddConnection2(&nr,Pass,User,FALSE)==NO_ERROR)
Q_h+r!b return TRUE;
D@1^:'$V else
H.G^!0j; return FALSE;
ia.B@u1/ }
[&}<!:9' /////////////////////////////////////////////////////////////////////////
;%.k}R%O@ BOOL InstallService(DWORD dwArgc,LPTSTR *lpszArgv)
6!PX!
UkF {
bIl0rx[` BOOL bRet=FALSE;
]]QCJf@p __try
{_N(S]Z {
4)Wzj4qW //Open Service Control Manager on Local or Remote machine
0+`*8G) hSCManager=OpenSCManager(szTarget,NULL,SC_MANAGER_ALL_ACCESS);
!F s)"? if(hSCManager==NULL)
91Sb=9 {
<u%e* printf("\nOpen Service Control Manage failed:%d",GetLastError());
[B;Ek\ 5W __leave;
-hV KPIb }
*ww(5 t //printf("\nOpen Service Control Manage ok!");
FrM~6A_ //Create Service
cx%9UK*c hSCService=CreateService(hSCManager,// handle to SCM database
-r0\ ServiceName,// name of service to start
iYs?B0*JWK ServiceName,// display name
:h dh$}y SERVICE_ALL_ACCESS,// type of access to service
%lW:8ckL SERVICE_WIN32_OWN_PROCESS,// type of service
>N"PLSY1 SERVICE_AUTO_START,// when to start service
MBrVh6z> SERVICE_ERROR_IGNORE,// severity of service
F&j|Y>m failure
p"
W0$t. EXE,// name of binary file
^7<m lr NULL,// name of load ordering group
&y wY?ox NULL,// tag identifier
e~[z]GLO% NULL,// array of dependency names
d33Nx)No NULL,// account name
(w NULL);// account password
,colGth54 //create service failed
dllf~:b if(hSCService==NULL)
fszeJS}Dw {
&=O1Qg=K //如果服务已经存在,那么则打开
AS^$1i: if(GetLastError()==ERROR_SERVICE_EXISTS)
/3%xQK>% {
mK/P4]9g //printf("\nService %s Already exists",ServiceName);
&jd<rs5} //open service
e[o
;l
hSCService = OpenService(hSCManager, ServiceName,
,+evP=(cX SERVICE_ALL_ACCESS);
TTak[e&j3 if(hSCService==NULL)
3Ya6yz {
'UCx^- printf("\nOpen Service failed:%d",GetLastError());
Gf.o{ __leave;
#u(,#(P'# }
AdW7 vn //printf("\nOpen Service %s ok!",ServiceName);
X.5LB!I) }
p arG else
eV}Tx;1|} {
nECf2>Yp v printf("\nCreateService failed:%d",GetLastError());
N2Hb19/k __leave;
\`# 0,pLr }
HBGA
lZ }
Upen/1 bA //create service ok
6MQ:C'8T&= else
QP0X8%+p {
HaUo+,= //printf("\nCreate Service %s ok!",ServiceName);
nOzTHg8 }
=x]dP. glIIJ5d|, // 起动服务
IcA~f@ if ( StartService(hSCService,dwArgc,lpszArgv))
eZ$1|Sj]j {
{-qTU6 //printf("\nStarting %s.", ServiceName);
k=
1+mG Sleep(20);//时间最好不要超过100ms
xGk4KcxKs while( QueryServiceStatus(hSCService, &ssStatus ) )
H43D=N& {
,6pH *b$ if ( ssStatus.dwCurrentState == SERVICE_START_PENDING)
N'.+ezZ;h {
|:BYOxAYZ8 printf(".");
j"8N)la Sleep(20);
1"PE@!] }
)C6 7qY[P else
9F!&y- break;
~[6|VpGc: }
!qv;F?2
<g if ( ssStatus.dwCurrentState != SERVICE_RUNNING )
k] YGD printf("\n%s failed to run:%d",ServiceName,GetLastError());
W}3vY] }
feHAZ.8rp+ else if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)
*&MkkI# {
LRs;>O //printf("\nService %s already running.",ServiceName);
d69VgLg }
L@GD$F=<0 else
^2@~AD`&h {
(Ad!hyE( printf("\nStart Service %s failed:%d",ServiceName,GetLastError());
o|C{ s __leave;
Okc*)crw }
IBsn>*ja< bRet=TRUE;
)CQ}LbX Zy }//enf of try
3Re\ T __finally
Ev#aMK {
. %7A7a return bRet;
4f,x@:Jw }
PCjY,O return bRet;
n3,wwymQ }
"KwKO8f /////////////////////////////////////////////////////////////////////////
NE"fyX` BOOL WaitServiceStop(void)
A>yIH)b {
T667&@ BOOL bRet=FALSE;
L\DaZ(Y //printf("\nWait Service stoped");
gp2)35 while(1)
{*Pp^r {
![%,pip2/& Sleep(100);
b"9,DQB=i if(!QueryServiceStatus(hSCService, &ssStatus))
N4-J !r@#~ {
,iUx'U printf("\nQueryServiceStatus failed:%d",GetLastError());
4pv:u:Z break;
#m>mYp8E.5 }
q5PYc.E([ if(ssStatus.dwCurrentState==SERVICE_STOPPED)
3}Qh`+Yj] {
cw{[B%vw bKilled=TRUE;
Y1IlH8+0 bRet=TRUE;
|&vuK9q break;
o5R40[" }
U)8]pUI+/P if(ssStatus.dwCurrentState==SERVICE_PAUSED)
O1,[7F.4g {
37Y]sJrs$ //停止服务
|e>-v bRet=ControlService(hSCService,SERVICE_CONTROL_STOP,NULL);
pM3BBF% break;
6Tnzg`0I }
]9Hy
"#Fz else
Ea?.HRxl {
Ags`%( //printf(".");
<&iBR continue;
(z7#KJ1+Aw }
Xg,BK0O }
ibyA~YUN/ return bRet;
4fswx@l }
Pa<