杀掉本地进程其实很简单,取得进程ID后,调用OpenProcess函数打开进程句柄,然后调用TerminateProcess函数就可以杀掉进程了。有些情况下并不能直接打开进程句柄,例如WINLOGON等系统进程,因为权限不够。这个时候我们就得先提升自己的进程的权限了。提升权限过程也不复杂,先调用GetCurrentProcess函数取得当前进程的句柄,然后调用OpenProcessToken打开当前进程的访问令牌,接着调用LookupPrivilegeValue函数取得你想提升的权限的值,最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加权限就可以了。一般有了SeDebugPrivilege特权后,就可以杀掉除Idle外的所有进程了。
0,.|-OZ OK!那如何杀掉远程进程呢?说起来有点复杂,但其实也不难。
a{rUk%x <1>与远程系统建立IPC连接
"sY}@Q7 <2>在远程系统的系统目录admin$\system32中写入一个文件killsrv.exe
y>gw@+ <3>调用函数OpenSCManager打开远程系统的Service Control Manager[SCM]
r{SDJa <4>调用函数CreateService在远程系统创建一个服务,服务指向的程序是在<2>中写入的程序killsrv.exe
87!m l <5>调用函数StartService启动刚才创建的服务,把想杀掉的进程的ID作为参数传递给它
,]]IJ;:w <6>服务启动后,killsrv.exe运行,杀掉进程
T*8K.yw2 <7>清场
8HIX$OX>2 嗯!这样看来,我们需要两个程序了。Killsrv.exe的源代码如下:
Ss\?SEq /***********************************************************************
&k-NDh3 Module:Killsrv.c
hH%fWB2( Date:2001/4/27
p1HbD`ST Author:ey4s
>dD$GD{ Http://www.ey4s.org n'JS- ***********************************************************************/
FS!)KxC/- #include
.j**>&7L #include
elpTak@ #include "function.c"
+Kg }R5+ #define ServiceName "PSKILL"
BD86t[${W e L}X(). SERVICE_STATUS_HANDLE ssh;
FCKyKn SERVICE_STATUS ss;
87eH~&<1 /////////////////////////////////////////////////////////////////////////
h/8p2Mrqi void ServiceStopped(void)
VhAJ1[k4! {
Ip)u6We>I ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
K~S*<? ss.dwCurrentState=SERVICE_STOPPED;
ucU7
@j ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
N`N?1!fM<} ss.dwWin32ExitCode=NO_ERROR;
CQrP%}`r ss.dwCheckPoint=0;
*W>, 98 ss.dwWaitHint=0;
-"H0Qafm SetServiceStatus(ssh,&ss);
19!;0fe= return;
"5sA&^_#_ }
T.-tV[2 /////////////////////////////////////////////////////////////////////////
zn_#}}e;G void ServicePaused(void)
9$C?)XKXB {
X')l04P@% ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
Ck"db30. ss.dwCurrentState=SERVICE_PAUSED;
u&UmI-} ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
R osU~OK ss.dwWin32ExitCode=NO_ERROR;
O/d]2<V ss.dwCheckPoint=0;
suGd &eP| ss.dwWaitHint=0;
T0)bnjm SetServiceStatus(ssh,&ss);
)EKWsGNe/ return;
hdSP#Y'- }
qfxEo76' void ServiceRunning(void)
L%QRWhB {
LXhR"PWZM\ ss.dwServiceType=SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS;
`ah|BV ss.dwCurrentState=SERVICE_RUNNING;
oGl<i ss.dwControlsAccepted=SERVICE_ACCEPT_STOP;
.c0u##/0 ss.dwWin32ExitCode=NO_ERROR;
6iF&!Fd>J ss.dwCheckPoint=0;
#Er"i ss.dwWaitHint=0;
(uhE'IQ{( SetServiceStatus(ssh,&ss);
<o*b6m% return;
6-J}ZfGj }
y'>JT/Q5 /////////////////////////////////////////////////////////////////////////
6%>'n? void WINAPI servier_ctrl(DWORD Opcode)//服务控制程序
6?C';1 {
dG]B-(WTC switch(Opcode)
tns8B {
V|}9bNF case SERVICE_CONTROL_STOP://停止Service
J2!
Q09 }5 ServiceStopped();
iXL^[/}&?M break;
-o{ x
;:4 case SERVICE_CONTROL_INTERROGATE:
) jvI Nb SetServiceStatus(ssh,&ss);
1,Mm+_)B break;
hiA\~}sl n }
UL>2gl4s/ return;
>w,jaQ }
M+HhTW;I= //////////////////////////////////////////////////////////////////////////////
XuHR //杀进程成功设置服务状态为SERVICE_STOPPED
Wi>m}^}9 //失败设置服务状态为SERVICE_PAUSED
%N`_g' r! //
6akI5\b void WINAPI ServiceMain(DWORD dwArgc,LPTSTR *lpszArgv)
$?]`2*i {
SBs! 52 ssh=RegisterServiceCtrlHandler(ServiceName,servier_ctrl);
4#]g852 if(!ssh)
M6^
\LtFt {
d,Oagx ServicePaused();
\@N~{72:k return;
%iEdU V\$ }
]7yxXg ServiceRunning();
3(,m(+J[S Sleep(100);
y,ub*-: //注意,argv[0]为此程序名,argv[1]为pskill,参数需要递增1
udBIEW,` //argv[2]=target,argv[3]=user,argv[4]=pwd,argv[5]=pid
N}ND()bf if(KillPS(atoi(lpszArgv[5])))
'g'RXC}D> ServiceStopped();
.s!0S-RkC else
jWi~Q o+ ServicePaused();
gTOx|bx return;
m6$&yKQ-=h }
"e8EA!Ipte /////////////////////////////////////////////////////////////////////////////
:D-D+x void main(DWORD dwArgc,LPTSTR *lpszArgv)
bDJ!Fc/ {
q1x[hv3
pP SERVICE_TABLE_ENTRY ste[2];
~9yKMUf ste[0].lpServiceName=ServiceName;
tgi%#8ZDpz ste[0].lpServiceProc=ServiceMain;
vR2);ywX ste[1].lpServiceName=NULL;
r=vY-p ste[1].lpServiceProc=NULL;
5$HG#2"Kb# StartServiceCtrlDispatcher(ste);
kD%MFT4 return;
y %61xA`# }
bu_@A^ys /////////////////////////////////////////////////////////////////////////////
^"54Q^SH function.c中有两个函数,一个是提升权限的,一个是提供进程ID,杀进程的。代码如
|uw48*t 下:
r^<,f[yH /***********************************************************************
V&vG.HAT Module:function.c
V\{@c%xW Date:2001/4/28
fR'!p: ~ Author:ey4s
bn8maYUZ Http://www.ey4s.org fHEIys,{ ***********************************************************************/
z5(5\j] #include
"c]9Q% ////////////////////////////////////////////////////////////////////////////
^v cnDi BOOL SetPrivilege(HANDLE hToken,LPCTSTR lpszPrivilege,BOOL bEnablePrivilege)
GA[D@Wy {
h-;> v. TOKEN_PRIVILEGES tp;
<jF&+[*iT LUID luid;
S Z/yijf izaqEz if(!LookupPrivilegeValue(NULL,lpszPrivilege,&luid))
3HYdb|y {
A%F8w'8( printf("\nLookupPrivilegeValue error:%d", GetLastError() );
,IqE<i!U return FALSE;
!&g_hmnIF }
,pdzi9@=t tp.PrivilegeCount = 1;
&y=OZ
!M tp.Privileges[0].Luid = luid;
`Ds=a`^b if (bEnablePrivilege)
mI4GBp tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
_|0# else
&dmIv[LU tp.Privileges[0].Attributes = 0;
:.]EM*p?GV // Enable the privilege or disable all privileges.
%7aJSuQN% AdjustTokenPrivileges(
*GBV[D[G, hToken,
r"h09suZBW FALSE,
Z$KyK.FUU &tp,
FZ+2{wIV^ sizeof(TOKEN_PRIVILEGES),
R8u8jG(4 (PTOKEN_PRIVILEGES) NULL,
aY(s
& (PDWORD) NULL);
]?D$n // Call GetLastError to determine whether the function succeeded.
SM
RKEPwp& if (GetLastError() != ERROR_SUCCESS)
)D6i {I0 {
V*Fy@ printf("AdjustTokenPrivileges failed: %u\n", GetLastError() );
5YNAb/!!F return FALSE;
0|tyKP|J }
QK0]9 return TRUE;
eZ]r"_? }
/*Q3=Dse] ////////////////////////////////////////////////////////////////////////////
X=)L$Kd7 BOOL KillPS(DWORD id)
A>upT' {
XE<5( HANDLE hProcess=NULL,hProcessToken=NULL;
P![ZO6`:W' BOOL IsKilled=FALSE,bRet=FALSE;
,e;,+w=~E __try
@S}j=k {
vnQFq f~a
7E;y if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ALL_ACCESS,&hProcessToken))
P[q>;Fx* {
%#v$d printf("\nOpen Current Process Token failed:%d",GetLastError());
1R~$m __leave;
6O6B8 }
nKr'cb //printf("\nOpen Current Process Token ok!");
.u#Hg'o P if(!SetPrivilege(hProcessToken,SE_DEBUG_NAME,TRUE))
wUr(i * {
(UjaL@G __leave;
$#s5y~z }
sGtxqnX:J printf("\nSetPrivilege ok!");
BV>9U5 /]Y#*r8jRi if((hProcess=OpenProcess(PROCESS_ALL_ACCESS,FALSE,id))==NULL)
~zac.:a8 {
i*mU<:t printf("\nOpen Process %d failed:%d",id,GetLastError());
kJf0..J[#< __leave;
8\'tfHL }
=lk'[P/p` //printf("\nOpen Process %d ok!",id);
$A{$$8P if(!TerminateProcess(hProcess,1))
f:~G) {
<|Lz#iV37 printf("\nTerminateProcess failed:%d",GetLastError());
[u K,.G __leave;
,"#nJC }
hf9i%,J IsKilled=TRUE;
.txtt?ZF2 }
6IT6EkiT __finally
K\xM%O? {
XBCHJj]k if(hProcessToken!=NULL) CloseHandle(hProcessToken);
T$2A2gb` if(hProcess!=NULL) CloseHandle(hProcess);
y< dBF[ }
~< UYJc return(IsKilled);
tg#jjXV\0p }
dazML|1ow //////////////////////////////////////////////////////////////////////////////////////////////
6 *S/frE OK!服务端的程序已经好了。接下来还需要一个客户端。如果通过在客户端运行的时候,把killsrv.exe COPY到远程系统上,那么就需要提供两个exe文件给用户,这样显得不是很专业,呵呵。不如我们就把killsrv.exe的二进制码作为buff保存在客户端吧,这样在运行的时候,我们直接把buff中的内容写过去,这样提供给用户一个exe文件就可以了。Pskill.c的源代码如下:
*#}=>, v /*********************************************************************************************
\{ QH^ ModulesKill.c
(EWGX |QA Create:2001/4/28
E`^D9:3:) Modify:2001/6/23
5ILKYUg, Author:ey4s
ll$mRC Http://www.ey4s.org t/O^7)% PsKill ==>Local and Remote process killer for windows 2k
?;P6#ByR **************************************************************************/
We}9'X} #include "ps.h"
T>|
hID #define EXE "killsrv.exe"
PP'5ANK #define ServiceName "PSKILL"
M=;csazN G5t7KI #pragma comment(lib,"mpr.lib")
gE@Pb //////////////////////////////////////////////////////////////////////////
dS 4/spNq //定义全局变量
FN!?o:|( SERVICE_STATUS ssStatus;
_('
@'r SC_HANDLE hSCManager=NULL,hSCService=NULL;
.@nfqv7{ BOOL bKilled=FALSE;
B\rY\ char szTarget[52]=;
PZV>A!7C8n //////////////////////////////////////////////////////////////////////////
<HRPloVKo BOOL ConnIPC(char *,char *,char *);//建立IPC连接函数
[Ca''JqrA BOOL InstallService(DWORD,LPTSTR *);//安装服务函数
I$+=Fb'N0 BOOL WaitServiceStop();//等待服务停止函数
O
]
!tK BOOL RemoveService();//删除服务函数
DU"Gz!X]Jd /////////////////////////////////////////////////////////////////////////
k&t.(r\ int main(DWORD dwArgc,LPTSTR *lpszArgv)
L9Zz-Dr s {
=GP L>a& BOOL bRet=FALSE,bFile=FALSE;
k CGb~+ char tmp[52]=,RemoteFilePath[128]=,
m ne)c[Qn szUser[52]=,szPass[52]=;
Z|a*"@5_ HANDLE hFile=NULL;
]SU)L5Dt; DWORD i=0,dwIndex=0,dwWrite,dwSize=sizeof(exebuff);
A#I&&qZ ^C^I //杀本地进程
_)Txg2?= if(dwArgc==2)
<$A/ (' {
g_l-@ if(KillPS(atoi(lpszArgv[1])))
_7:Bxx4B printf("\nLoacl Process %s have beed killed!",lpszArgv[1]);
=*ErN else
h~
_i::vg
printf("\nLoacl Process %s can't be killed!ErrorCode:%d",
!+@70|gFF lpszArgv[1],GetLastError());
g]z k` R5 return 0;
B!quj!A }
lW#2 ox //用户输入错误
Y9#dAI[Gce else if(dwArgc!=5)
{e2ZW] {
MNe/H\ printf("\nPSKILL ==>Local and Remote Process Killer"
RE4#a2 "\nPower by ey4s"
RF2I_4 "\nhttp://www.ey4s.org 2001/6/23"
F^Jz
"\n\nUsage:%s <==Killed Local Process"
k^K76m B "\n %s <==Killed Remote Process\n",
{*hFG:u lpszArgv[0],lpszArgv[0]);
g fAWN return 1;
@YaI5> ,/ }
pd: YR; //杀远程机器进程
lj&\F|-i strncpy(szTarget,lpszArgv[1],sizeof(szTarget)-1);
ol_\ " strncpy(szUser,lpszArgv[2],sizeof(szUser)-1);
!WlL RkwO strncpy(szPass,lpszArgv[3],sizeof(szPass)-1);
[vb#W!M&| &${| o@ //将在目标机器上创建的exe文件的路径
;t9_*)[ sprintf(RemoteFilePath,"\\%s\admin$\system32\%s",szTarget,EXE);
4NaT@68p __try
oaq,4FT {
&I'J4gk[ //与目标建立IPC连接
K9&Q@3V if(!ConnIPC(szTarget,szUser,szPass))
FPK=Tr:b {
VK*H1EH1 printf("\nConnect to %s failed:%d",szTarget,GetLastError());
V[WZ#u-p return 1;
Vtj*O'0 }
CHqi5Z/+ printf("\nConnect to %s success!",szTarget);
ak:f4dEd //在目标机器上创建exe文件
^5~x*=_ FYC]^D hFile=CreateFile(RemoteFilePath,GENERIC_ALL,FILE_SHARE_READ|FILE_SHARE_WRIT
q*4@d)_& E,
'Tqusr>lPY NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
p%bMfi*T if(hFile==INVALID_HANDLE_VALUE)
`]GL3cIh: {
%|JL=E}%| printf("\nCreate file %s failed:%d",RemoteFilePath,GetLastError());
V :5aq.o! __leave;
};9/J3]m }
*tpS6{4=#7 //写文件内容
A9ld9R while(dwSize>dwIndex)
4<1V {
"X?Zw$gRud v?3xWXX, if(!WriteFile(hFile,&exebuff[dwIndex],dwSize-dwIndex,&dwWrite,NULL))
h|'|n/F {
_M7|:* printf("\nWrite file %s
d<=!*#q;o failed:%d",RemoteFilePath,GetLastError());
GYf{~J __leave;
DU*qhW`X }
H[pvC=O= dwIndex+=dwWrite;
.@;5" }
d?YSVmG //关闭文件句柄
K9ih(fh) CloseHandle(hFile);
dQp>z%L) bFile=TRUE;
oIj/V|ByK //安装服务
-3d`e2^&} if(InstallService(dwArgc,lpszArgv))
ia
/#`#. {
QjpJIw //等待服务结束
_RzoXn{1e if(WaitServiceStop())
Imzh`SI, {
n3U|
d+ //printf("\nService was stoped!");
jc>B^mqx }
9$[MM*r else
xo
^|d3 {
4UW)XLu6T7 //printf("\nService can't be stoped.Try to delete it.");
6=Q6J }
!]mo.zDSW5 Sleep(500);
Q9p2.!/C1 //删除服务
<]oPr1 RemoveService();
$'!n4}$} }
a.O"I3{?h }
(<OmYnm __finally
Eoo[H2=^H {
q:jv9eL.O //删除留下的文件
lQ[JA[ if(bFile) DeleteFile(RemoteFilePath);
I)*J,hs1 //如果文件句柄没有关闭,关闭之~
=:R${F if(hFile!=NULL) CloseHandle(hFile);
6b` Jq>v //Close Service handle
qOyS8tA.H if(hSCService!=NULL) CloseServiceHandle(hSCService);
w*@9:+ //Close the Service Control Manager handle
I~"l9Jc!" if(hSCManager!=NULL) CloseServiceHandle(hSCManager);
1UrkDz?X //断开ipc连接
rfgsas{F wsprintf(tmp,"\\%s\ipc$",szTarget);
i6;rh-M?. WNetCancelConnection2(tmp,CONNECT_UPDATE_PROFILE,TRUE);
_q@lP| if(bKilled)
kwS[,Qy\ printf("\nProcess %s on %s have been
[CV0sYEA killed!\n",lpszArgv[4],lpszArgv[1]);
|D'!.$7% else
vu*{+YpH printf("\nProcess %s on %s can't be
7n;a_Z0s$ killed!\n",lpszArgv[4],lpszArgv[1]);
wc}x
[cS }
=''*'a-P return 0;
Y<@_d }
d|UH AX //////////////////////////////////////////////////////////////////////////
,gkWksl9 BOOL ConnIPC(char *RemoteName,char *User,char *Pass)
U&$I!80. {
h"2^`
)!u NETRESOURCE nr;
JiA1yt char RN[50]="\\";
\
sz ](X s1%2({wP strcat(RN,RemoteName);
l<"B[ strcat(RN,"\ipc$");
G[zy sxd !([ v=O# nr.dwType=RESOURCETYPE_ANY;
2Qp]r+! nr.lpLocalName=NULL;
m<MN.R7 nr.lpRemoteName=RN;
_\,4h2( nr.lpProvider=NULL;
4l/~::y 9(Kff nE^ if(WNetAddConnection2(&nr,Pass,User,FALSE)==NO_ERROR)
5':j=KQE_ return TRUE;
<P Vmr2Jp" else
q}g0-Da return FALSE;
VF7H0XR/k5 }
>Mm.MNU /////////////////////////////////////////////////////////////////////////
3] U/^f3 BOOL InstallService(DWORD dwArgc,LPTSTR *lpszArgv)
%uP/v\l {
TUp%Cx BOOL bRet=FALSE;
n2F*a __try
&(x>J:b {
N=8CVI //Open Service Control Manager on Local or Remote machine
p1z^i( hSCManager=OpenSCManager(szTarget,NULL,SC_MANAGER_ALL_ACCESS);
QX(t@VP if(hSCManager==NULL)
un,W{*s8* {
!E *IktAI printf("\nOpen Service Control Manage failed:%d",GetLastError());
oJ=u
pnBn- __leave;
%+
MYg^ }
|ew:}e: k< //printf("\nOpen Service Control Manage ok!");
% <%r //Create Service
,fm{
krE hSCService=CreateService(hSCManager,// handle to SCM database
:3}K$ ServiceName,// name of service to start
R*vfp?x ServiceName,// display name
>4T7DMy SERVICE_ALL_ACCESS,// type of access to service
=D 5!Xq'| SERVICE_WIN32_OWN_PROCESS,// type of service
Zk gj_ SERVICE_AUTO_START,// when to start service
].gC9@C:$i SERVICE_ERROR_IGNORE,// severity of service
pl 1CEoe failure
Lg6>\Z4 EXE,// name of binary file
vZSwX@0 NULL,// name of load ordering group
)YLZ"@ NULL,// tag identifier
_p+q)#.W NULL,// array of dependency names
*b1NVN$ NULL,// account name
B8V85R NULL);// account password
mj2sbRiSR= //create service failed
ck`$ ` if(hSCService==NULL)
q1%xk=8 {
Sa6YqOel@ //如果服务已经存在,那么则打开
"9H#pj - if(GetLastError()==ERROR_SERVICE_EXISTS)
JCITIjD7= {
J8`vk#5 //printf("\nService %s Already exists",ServiceName);
f%STkL) //open service
IS!]!s'EI hSCService = OpenService(hSCManager, ServiceName,
Lb2/ Te* SERVICE_ALL_ACCESS);
*>j4tA{b@v if(hSCService==NULL)
TrHUM4 {
@ v}M\$N? printf("\nOpen Service failed:%d",GetLastError());
T!5g:;~y > __leave;
j 2Jew }
^F/H?V/PX //printf("\nOpen Service %s ok!",ServiceName);
]G=^7O]`C! }
Fz_8m4 else
sJLJVSv8c {
m] IN-' printf("\nCreateService failed:%d",GetLastError());
xx%*85 < __leave;
gf|&u4D }
3],[6%w }
{E>(%vD //create service ok
;cWFh4_ else
p:|p? {
rAQ3x0 //printf("\nCreate Service %s ok!",ServiceName);
^eqq|(<K }
RXbZaje$ UrB{jS? // 起动服务
5CM]-qbf@ if ( StartService(hSCService,dwArgc,lpszArgv))
t*!Q9GC_ {
X]%n#\t,] //printf("\nStarting %s.", ServiceName);
}Q>??~mVl Sleep(20);//时间最好不要超过100ms
3ry0. while( QueryServiceStatus(hSCService, &ssStatus ) )
[UaM}-eR {
Pexg"328 if ( ssStatus.dwCurrentState == SERVICE_START_PENDING)
QEq>zuz5; {
Y3f2RdGl printf(".");
>K;C?gHo Sleep(20);
ljj}XJQ }
<F5x}i~(C else
0o&7l%Y/ break;
j&=!F3[ }
J.npv1F if ( ssStatus.dwCurrentState != SERVICE_RUNNING )
+t;j5\HS printf("\n%s failed to run:%d",ServiceName,GetLastError());
?-PW$p }
|Ns[{/ else if(GetLastError()==ERROR_SERVICE_ALREADY_RUNNING)
Qc"UTvq {
9xUAfU //printf("\nService %s already running.",ServiceName);
>PiEu->P, }
;(9q, ) else
{= l9{K`~ {
09rbu\h printf("\nStart Service %s failed:%d",ServiceName,GetLastError());
t[ ^68] __leave;
@{UtS2L }
9.$k^|~ bRet=TRUE;
XhJbBVS| }//enf of try
62%=%XD __finally
/=ro$@ {
`zOQ*Y& return bRet;
OX)[?1m8 }
@Vac!A??: return bRet;
skn];%[v\ }
o%=OBTh_ /////////////////////////////////////////////////////////////////////////
TW?A/GoXI BOOL WaitServiceStop(void)
Ny)!uqul* {
FQCz_z BOOL bRet=FALSE;
V@Fj!/ //printf("\nWait Service stoped");
2AI~Jm# while(1)
M2e_)f:
{
;?0k> Sleep(100);
%,G0)t if(!QueryServiceStatus(hSCService, &ssStatus))
V,)bw {
h48
jKL( printf("\nQueryServiceStatus failed:%d",GetLastError());
ey>V^Fj break;
G4eY}3F7,4 }
P mgTTI if(ssStatus.dwCurrentState==SERVICE_STOPPED)
sKI{AHJ?X {
\"@BZ.y bKilled=TRUE;
v9s/!<j bRet=TRUE;
n[pW^&7x break;
BiUbg6T.G }
@'{m-?* if(ssStatus.dwCurrentState==SERVICE_PAUSED)
q}mQm' {
U(cV#@Y //停止服务
A~Ov( bRet=ControlService(hSCService,SERVICE_CONTROL_STOP,NULL);
Ov=^}T4zl break;
"]C$"JR }
=tE7XC3X_ else
\d#|n u {
jN43vHm\Y9 //printf(".");
7Z+4F=2ff continue;
u*J,3o}
< }
1FiFP5 }
K7H`Yt return bRet;
(\<