-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathusb_vaccine.cmd
1547 lines (1476 loc) · 64.9 KB
/
usb_vaccine.cmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
@ECHO OFF
SETLOCAL EnableExtensions
IF CMDEXTVERSION==2 GOTO cmd_ext_ok
ENDLOCAL ;
echo Requires Windows 2000 or later.
GOTO EOF
exit 1;
REM Press Ctrl-C and answer Y to terminate.
COPY CON: NUL:
%0
:cmd_ext_ok
ENDLOCAL
SETLOCAL EnableExtensions EnableDelayedExpansion
REM ---------------------------------------------------------------------------
REM 'usb_vaccine.cmd' version 3 beta (2018-07-28)
REM Copyright (C) 2013-2018 Kang-Che Sung <explorer09 @ gmail.com>
REM This program is free software; you can redistribute it and/or
REM modify it under the terms of the GNU Lesser General Public
REM License as published by the Free Software Foundation; either
REM version 2.1 of the License, or (at your option) any later version.
REM This program is distributed in the hope that it will be useful,
REM but WITHOUT ANY WARRANTY; without even the implied warranty of
REM MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
REM Lesser General Public License for more details.
REM You should have received a copy of the GNU Lesser General Public
REM License along with this program. If not, see
REM <http://www.gnu.org/licenses/>.
REM ---------------------------------------------------------------------------
REM CONSTANTS
REM User's default options for commands. Reset.
SET COPYCMD=
SET DIRCMD=
REM Disable user override.
SET CD=
SET ERRORLEVEL=
SET HKLM_SFT=HKLM\SOFTWARE
SET HKLM_CLS=!HKLM_SFT!\Classes
SET HKLM_SFT_WOW=!HKLM_SFT!\Wow6432Node
SET "CMD_SUBKEY=Microsoft\Command Processor"
SET "INF_MAP_SUBKEY=Microsoft\Windows NT\CurrentVersion\IniFileMapping\autorun.inf"
SET "EXPLORER_SUBKEY=Microsoft\Windows\CurrentVersion\Explorer"
SET "ADVANCED_SUBKEY=!EXPLORER_SUBKEY!\Advanced"
SET "SHELL_ICON_SUBKEY=!EXPLORER_SUBKEY!\Shell Icons"
REM Files to keep. The whitelist.
SET KEEP_SYMLINK_FILES=
FOR %%i IN (
"vmlinux" "vmlinuz"
) DO (
SET KEEP_SYMLINK_FILES=!KEEP_SYMLINK_FILES! %%i
)
SET KEEP_HS_ATTRIB_FILES=
FOR %%i IN (
"ibmbio.com" "ibmdos.com" "IO.SYS" "IO.DOS" "WINBOOT.SYS" "JO.SYS" "MSDOS.SYS"
"MSDOS.DOS" "MSDOS.BAK" "MSDOS.W40" "MSDOS.---" "@oldbios.ui" "@oldbdos.ui"
"COMMAND.COM" "COMMAND.DOS" "AUTOEXEC.DOS" "CONFIG.DOS" "OS2BOOT" "OS2LDR"
"OS2LDR.MSG" "OS2KRNL" "OS2DUMP" "OS2VER" "OS2LOGO" "EA DATA. SF" "WP ROOT. SF"
"Nowhere\" "386SPART.PAR" "pagefile.sys" "swapfile.sys" "hiberfil.sys"
"SSPARTSS.ADD" "STACKER.BIN" "STACKER.INI" "STACVOL.DSK" "DBLSPACE.BIN"
"DRVSPACE.BIN" "DBLSPACE.INI" "DRVSPACE.INI" "DBLSPACE.000" "DRVSPACE.000"
"FAILSAFE.DRV\" "@DLWATCH.DAT" "Recycled\" "RECYCLER\" "$Recycle.Bin\"
"boot.ini" "Boot.BAK" "bootfont.bin" "bootsect.dos" "NTDETECT.COM" "ntldr"
"@oldboot.ui" "SUHDLOG.DAT" "SUHDLOG.---" "ldlinux.sys" "ldlinux.c32"
"arcldr.exe" "arcsetup.exe" "Boot\" "bootmgr" "BOOTNXT" "BOOTSECT.BAK"
"BOOTTGT" "BOOTLOG.TXT" "BOOTLOG.PRV" "DETLOG.TXT" "DETLOG.OLD" "NETLOG.TXT"
"SETUPLOG.TXT" "SETUPLOG.OLD" "system.1st" "UNINSTAL.INI" "WINLFN.INI"
"System Volume Information\" "cmdcons\" "cmldr" "Recovery\" "SECURITY.BIN"
"VIDEOROM.BIN" "EBD.SYS"
) DO (
SET KEEP_HS_ATTRIB_FILES=!KEEP_HS_ATTRIB_FILES! %%i
)
SET KEEP_H_ATTRIB_FILES=
FOR %%i IN (
"ibmbio.com" "ibmdos.com" "MSDOS.---" "logo.sys" "@command.ui" "autoexec.bat"
"@AUTOEXE.UI" "config.sys" "@CONFIG.UI" "OS2LDR" "OS2KRNL" "SENTRY\" "Boot.BAK"
"SUHDLOG.DAT" "SUHDLOG.---" "BOOTLOG.TXT" "BOOTLOG.PRV" "SETUPLOG.TXT"
"SETUPLOG.OLD" "ASD.LOG" "CLASSES.1ST" "system.1st" "W95UNDO.DAT" "W95UNDO.INI"
"WINUNDO.DAT" "WINUNDO.INI" "W98UNDO.DAT" "W98UNDO.INI" "W9XUNDO.DAT"
"W9XUNDO.INI" "$INPLACE.~TR\" "$WINDOWS.~Q\" "$Windows.~BT\" "$Windows.~WS\"
"_Restore\" "$WINRE_BACKUP_PARTITION.MARKER" "DOS00I.400" "DOS01L.400"
"ProgramData\" "MSOCache\"
) DO (
SET KEEP_H_ATTRIB_FILES=!KEEP_H_ATTRIB_FILES! %%i
)
SET KEEP_S_ATTRIB_FILES=
FOR %%i IN (
"PCTRACKR.DEL" "boot.ini" "BOOTSECT.BAK"
) DO (
SET KEEP_S_ATTRIB_FILES=!KEEP_S_ATTRIB_FILES! %%i
)
SET KEEP_EXECUTE_FILES=
FOR %%i IN (
"STACKER.EXE" "arcldr.exe" "arcsetup.exe"
) DO (
SET KEEP_EXECUTE_FILES=!KEEP_EXECUTE_FILES! %%i
)
REM ---------------------------------------------------------------------------
REM MAIN
SET g_reg_bak=
SET g_sids=
IF "!opt_move_subdir!"=="" SET opt_move_subdir=\MALWARE
REM Needed by restart routine. SHIFT will change %%*.
SET "args=%*"
:main_parse_options
SET "arg1=%~1"
IF "!arg1!"=="" GOTO main_sanity_test
IF "!arg1!"=="/?" SET opt_help=1
IF "!arg1!"=="-?" SET opt_help=1
IF "!arg1!"=="--help" SET opt_help=1
IF "!arg1:~0,5!"=="--no-" (
FOR %%i IN (restart reg_bak inf_mapping mkdir) DO (
IF "!arg1:-=_!"=="__no_%%i" SET "opt_%%i=SKIP"
)
)
IF "!arg1:~0,7!"=="--skip-" (
FOR %%i IN (
cmd_autorun mountpoints known_ext pif_ext scf_icon scrap_ext
symlink_ext
) DO (
IF "!arg1:-=_!"=="__skip_%%i" SET "opt_%%i=SKIP"
)
)
IF "!arg1:~0,12!"=="--all-users-" (
FOR %%i IN (cmd_autorun known_ext reassoc) DO (
IF "!arg1:-=_!"=="__all_users_%%i" SET "opt_%%i=ALL_USERS"
)
)
IF "!arg1:~0,6!"=="--fix-" (
FOR %%i IN (exe_ext shortcut_icon file_icon) DO (
IF "!arg1:-=_!"=="__fix_%%i" SET "opt_%%i=FIX"
)
)
IF "!arg1!"=="--always-exe-ext" SET "opt_exe_ext=ALWAYS"
IF "!arg1:~0,7!"=="--keep-" (
FOR %%i IN (
symlinks attrib shortcuts folder_exe autorun_inf desktop_ini
) DO (
IF "!arg1:-=_!"=="__keep_%%i" SET "opt_%%i=SKIP"
)
)
IF "!arg1:~0,13!"=="--move-subdir" (
IF "!arg1:~13,1!"=="=" (
REM User quotes the argument so that '=' is included.
SET opt_move_subdir=!arg1:~14!
) ELSE (
REM '=' becomes delimiter. Get the next argument.
SET "opt_move_subdir=%~2"
SHIFT /1
)
)
REM %%0 is needed by restart routine. Don't touch.
SHIFT /1
GOTO main_parse_options
:main_sanity_test
IF "!opt_help!"=="1" SET opt_restart=SKIP
IF "!opt_reg_bak!"=="SKIP" SET g_reg_bak=FAIL
REM Humbly quit when we get a Unix 'find' utility. We won't bother with
REM 'findstr' or (ported) 'grep'.
find . -prune >NUL: 2>NUL: && GOTO main_find_error
ECHO X | find "X" >NUL: 2>NUL: || GOTO main_find_error
IF "!opt_move_subdir!"=="" GOTO main_invalid_path
SET opt_move_subdir=!opt_move_subdir:^"=!
REM ^"
IF "!opt_move_subdir!"=="" GOTO main_invalid_path
SET opt_move_subdir=!opt_move_subdir:/=\!
IF /I "!opt_move_subdir!"=="NUL:" SET opt_move_subdir=NUL
REM Technically we can't check for every possibility of valid path without
REM actually 'mkdir' with it, but we may filter out common path attacks.
IF "!opt_move_subdir:~0,2!"=="\\" GOTO main_invalid_path
REM Windows 9x allows "\...\", "\....\" and so on for grandparent or any
REM ancestor directory. Thankfully it doesn't work anymore in NT.
SET "name=\!opt_move_subdir!\"
IF NOT "!name!"=="!name:*\..\=!" GOTO main_invalid_path
CALL :has_path_char ":*?<>|" && GOTO main_invalid_path
REM Check if "FOR /F" supports unquoted options and 'eol' being null.
REM Check this in a subshell because (a) it won't halt our script in case of
REM unsupported syntax, and (b) we need to disable Command Processor AutoRun.
SET g_cmdfor_unquoted_opts=0
SET "a=FOR /F tokens^=1-2^ delims^=^"
SET b="^ eol^= %%i IN (" ;""x") DO IF NOT "%%i.%%j"==" ;.x^" EXIT /B 1
REM ^"
!ComSpec! /q /d /e:on /c "!a!!b!" >NUL: 2>NUL: && SET g_cmdfor_unquoted_opts=1
REM Delayed expansion is not performed in FOR options field.
IF "!g_cmdfor_unquoted_opts!"=="1" (
SET "FOR_OPTS_FOR_DIR_B=/F delims^=^ eol^="
) ELSE (
SET FOR_OPTS_FOR_DIR_B=/F "eol=/ delims="
ECHO WARNING: This cmd.exe doesn't support unquoted "FOR /F" options string.>&2
)
SET g_is_wow64=0
IF DEFINED PROCESSOR_ARCHITEW6432 (
IF NOT "!opt_restart!"=="SKIP" GOTO main_restart_native
SET g_is_wow64=1
ECHO NOTICE: A WoW64 environment is detected. This script is supposed to be run in a>&2
ECHO native, 64-bit cmd.exe interpreter.>&2
)
reg query "HKCU" >NUL: 2>NUL: || (
REM Without 'reg', we cannot detect Command Processor AutoRun, so always
REM try restarting without it before going further.
IF NOT "!opt_restart!"=="SKIP" GOTO main_restart
ECHO.>&2
ECHO *** ERROR: Can't access Windows registry with reg.exe^^!>&2
ECHO.>&2
ECHO If you are using Windows 2000, please install Windows 2000 Support Tools. See>&2
ECHO ^<https://support.microsoft.com/kb/301423^> for details. You may download the>&2
ECHO Support Tools from ^<https://www.microsoft.com/download/details.aspx?id=18614^>>&2
IF "!opt_help!"=="1" GOTO main_help
ECHO.>&2
ECHO All registry tasks will be SKIPPED.>&2
GOTO main_all_drives
)
SET has_wow64=0
reg query "!HKLM_SFT_WOW!" >NUL: 2>NUL: && SET has_wow64=1
:main_cmd_autorun
REM The Command Processor AutoRun will execute every time we do command
REM substitution (via "FOR /F") and may pollute output of our every command.
SET has_cmd_autorun=0
FOR %%k IN (!HKLM_SFT_WOW! !HKLM_SFT! HKCU\Software) DO (
REM "reg query" outputs header lines even if key or value doesn't exist.
reg query "%%k\!CMD_SUBKEY!" /v "AutoRun" >NUL: 2>NUL: && (
IF NOT "!opt_restart!"=="SKIP" GOTO main_restart
SET has_cmd_autorun=1
REM Show user the AutoRun values along with error message below.
REM Key name included in "reg query" output.
IF "!g_is_wow64!!has_wow64!%%k"=="10!HKLM_SFT!" (
ECHO ^(The key below is a WoW64 redirected key. Its actual name is>&2
ECHO "!HKLM_SFT_WOW!\!CMD_SUBKEY!"^)>&2
)
IF NOT "!g_is_wow64!!has_wow64!%%k"=="11!HKLM_SFT!" (
reg query "%%k\!CMD_SUBKEY!" /v "AutoRun" >&2
)
)
)
IF "!has_cmd_autorun!"=="1" (
ECHO *** NOTICE: Your cmd.exe interpreter contains AutoRun commands, which have been>&2
ECHO run before this message is displayed and might be malicious.>&2
)
IF "!opt_help!"=="1" GOTO main_help
IF "!opt_cmd_autorun!"=="SKIP" GOTO main_inf_mapping
IF "!has_cmd_autorun!"=="1" (
IF NOT "!opt_cmd_autorun!"=="ALL_USERS" (
ECHO [cmd-autorun]
ECHO For security reasons, we will delete "AutoRun" registry values listed above.
ECHO ^(Affects machine and current user settings. Cannot be undone. To delete all
ECHO users' settings, please specify '--all-users-cmd-autorun' option.^)
CALL :continue_prompt || GOTO main_inf_mapping
)
FOR %%k IN (!HKLM_SFT_WOW! !HKLM_SFT! HKCU\Software) DO (
CALL :delete_reg_value "%%k" "!CMD_SUBKEY!" "AutoRun" "Command Processor /v AutoRun"
)
)
IF "!opt_cmd_autorun!"=="ALL_USERS" (
CALL :prepare_sids
FOR %%i IN (!g_sids!) DO (
ECHO SID %%~i
CALL :delete_reg_value "HKU\%%~i\Software" "!CMD_SUBKEY!" "AutoRun" "Command Processor /v AutoRun"
)
)
:main_inf_mapping
SET has_inf_mapping=1
reg query "!HKLM_SFT!\!INF_MAP_SUBKEY!" /ve 2>NUL: | find /I "@" >NUL: || (
SET has_inf_mapping=0
ECHO.>&2
ECHO *** NOTICE: Your computer is vulnerable to the AutoRun malware^^!>&2
)
ECHO.
ECHO This program can help you disable AutoRun, clean the autorun.inf files on your
ECHO disks, remove shortcuts and reveal hidden files. All of these undo the damage
ECHO that might be done by AutoRun malware.
ECHO This DOES NOT remove the malware itself and so is not a substitute for anti-
ECHO virus software. Please install anti-virus software to protect your computer.
ECHO If you are using Windows 2000, XP, Server 2003, Vista, or Server 2008, it is
ECHO strongly recommended that you install KB967715 and KB971029 updates from
ECHO Microsoft. These two updates correct bugs in AutoRun implementations ^(even
ECHO though we will disable AutoRun entirely^).
ECHO Please see ^<https://technet.microsoft.com/library/security/967940.aspx^>
REM Credit to Nick Brown for the solution to disable AutoRun. See:
REM http://archive.today/CpwOH
REM http://www.computerworld.com/article/2481506
REM Works with Windows 7 too, and I believe it's safer to disable ALL AutoRuns
REM in Windows 7 and above, rather than let go some devices.
REM Other references:
REM http://www.kb.cert.org/vuls/id/889747
REM https://www.us-cert.gov/ncas/alerts/TA09-020A
IF "!has_inf_mapping!"=="1" GOTO main_mountpoints
IF "!opt_inf_mapping!"=="SKIP" GOTO main_mountpoints
ECHO.
ECHO [inf-mapping]
ECHO When you insert a disc, or click the icon of a CD-ROM drive, Windows will
ECHO automatically run some programs ^(usually the setup^) by default. Originally
ECHO meant for convenience, this "AutoRun" design is easily exploited by malware,
ECHO which can run automatically without awareness of users.
ECHO We will disable AutoRun entirely, and stop Windows from parsing any autorun.inf
ECHO file. After AutoRun is disabled, if you wish to install or run software from a
ECHO disc, you will have to manually open the Setup.exe inside. This doesn't affect
ECHO the AutoPlay feature of music, video discs, or USB devices.
ECHO ^(This is a machine setting.^)
CALL :continue_prompt || GOTO main_mountpoints
CALL :backup_reg "!HKLM_SFT!" "!INF_MAP_SUBKEY!" /ve
reg add "!HKLM_SFT!\!INF_MAP_SUBKEY!" /ve /t REG_SZ /d "@SYS:DoesNotExist" /f >NUL:
IF ERRORLEVEL 1 (
CALL :show_reg_write_error "IniFileMapping\autorun.inf"
) ELSE (
CALL :delete_reg_key "!HKLM_SFT!" "DoesNotExist" "!HKLM_SFT!\DoesNotExist"
)
IF "!has_wow64!"=="1" (
CALL :backup_reg "!HKLM_SFT_WOW!" "!INF_MAP_SUBKEY!" /ve
reg add "!HKLM_SFT_WOW!\!INF_MAP_SUBKEY!" /ve /t REG_SZ /d "@SYS:DoesNotExist" /f >NUL:
IF ERRORLEVEL 1 (
CALL :show_reg_write_error "(WoW64) IniFileMapping\autorun.inf"
) ELSE (
CALL :delete_reg_key "!HKLM_SFT_WOW!" "DoesNotExist" "(WoW64) !HKLM_SFT!\DoesNotExist"
)
)
:main_mountpoints
IF "!opt_mountpoints!"=="SKIP" GOTO main_known_ext
REM "MountPoints" for Windows 2000, "MountPoints2" for Windows XP and later.
ECHO.
ECHO [mountpoints]
ECHO The "MountPoints" ^(or "MountPoints2"^) registry keys are the AutoRun cache used
ECHO by Windows Explorer shell. After AutoRun is disabled, clean the registry keys
ECHO in order to prevent AutoRun threats from previous devices.
ECHO ^(Affects all users' settings. Cannot be undone.^)
CALL :continue_prompt || GOTO main_known_ext
CALL :prepare_sids
FOR %%i IN (!g_sids!) DO (
ECHO SID %%~i
FOR %%k IN (MountPoints MountPoints2) DO (
CALL :clean_reg_key "HKU\%%~i\Software" "!EXPLORER_SUBKEY!\%%k" "Explorer\%%k"
)
)
:main_known_ext
IF "!opt_known_ext!"=="SKIP" GOTO main_exe_ext
REM The value shouldn't exist in HKLM and doesn't work there. Silently delete.
FOR %%k IN (!HKLM_SFT! !HKLM_SFT_WOW!) DO (
reg delete "%%k\!ADVANCED_SUBKEY!" /v "HideFileExt" /f >NUL: 2>NUL:
)
IF NOT "!opt_known_ext!"=="ALL_USERS" (
ECHO.
ECHO [known-ext]
ECHO Windows will hide extensions for known file types by default, but applications
ECHO may have custom icons. When the file extensions are hidden, malicious programs
ECHO may use icons to disguise themselves as regular files or folders, tricking
ECHO users into opening them.
ECHO We will disable "Hide extensions for known file types" in "Control Panel" -^>
ECHO "Folder Options", so that common file extensions ^(except shortcuts^) are always
ECHO shown. Users may recognize whether a file is executable ^(and suspicious^)
ECHO through the extensions. The following are executable file types:
ECHO .com ^(MS-DOS application^) .cmd ^(Windows NT command script^)
ECHO .exe ^(Application^) .scr ^(Screen saver^)
ECHO .bat ^(Batch file^)
ECHO ^(Affects current user setting. To change all users' settings, please specify
ECHO '--all-users-known-ext' option.^)
CALL :continue_prompt || GOTO main_exe_ext
)
REM "HideFileExt" is enabled (0x1) if value does not exist.
reg add "HKCU\Software\!ADVANCED_SUBKEY!" /v "HideFileExt" /t REG_DWORD /d 0 /f >NUL: || (
CALL :show_reg_write_error "Explorer\Advanced /v HideFileExt"
)
IF "!opt_known_ext!"=="ALL_USERS" (
CALL :prepare_sids
FOR %%i IN (!g_sids!) DO (
ECHO SID %%~i
reg add "HKU\%%~i\Software\!ADVANCED_SUBKEY!" /v "HideFileExt" /t REG_DWORD /d 0 /f >NUL: || (
CALL :show_reg_write_error "Explorer\Advanced /v HideFileExt"
)
)
)
:main_exe_ext
IF "!opt_exe_ext!"=="ALWAYS" (
FOR %%k IN (exefile scrfile) DO (
reg add "!HKLM_CLS!\%%k" /v "AlwaysShowExt" /t REG_SZ /f >NUL: || (
CALL :show_reg_write_error "HKCR\%%k /v AlwaysShowExt"
)
)
SET opt_exe_ext=FIX
)
IF NOT "!opt_exe_ext!"=="FIX" GOTO main_pif_ext
FOR %%e IN (com exe bat scr cmd) DO (
CALL :delete_reg_value "!HKLM_CLS!" "%%efile" "NeverShowExt" "HKCR\%%efile /v NeverShowExt"
)
SET list="com=comfile" "exe=exefile" "bat=batfile" "scr=scrfile" "cmd=cmdfile"
CALL :reassoc_file_types !list!
:main_pif_ext
SET "user_msg=the current user"
IF "!opt_reassoc!"=="ALL_USERS" SET "user_msg=ALL USERS"
IF "!opt_pif_ext!"=="SKIP" GOTO main_scf_icon
REM .pif files already have shortcut arrows; no need to suggest AlwaysShowExt.
reg query "!HKLM_CLS!\piffile" /v "NeverShowExt" >NUL: 2>NUL: || (
GOTO main_scf_icon
)
REM Thankfully cmd.exe handles .pif right. Only Windows Explorer has this flaw.
ECHO.
ECHO [pif-ext]
ECHO The .pif files are shortcuts to DOS programs. Windows Explorer will generate a
ECHO .pif file when user requests to create a shortcut to a .com executable.
ECHO However, there's a design flaw in Explorer's handling of this file type. If
ECHO someone renames an executable file to .pif extension, and users opens that .pif
ECHO file, code will be executed. This flaw is exploitable. ^(An executable program
ECHO renamed to a .pif file will show either a generic file icon or an MS-DOS icon
ECHO depending on Windows version.^)
ECHO We will delete the "NeverShowExt" registry value for this file type. Users will
ECHO see the .pif extension if they disable "Hide extensions for known file types".
ECHO This increases awareness.
ECHO ^(This is a machine setting. In addition, the associations for this file type
ECHO for !user_msg! will be reset, which cannot be undone.^)
CALL :continue_prompt || GOTO main_scf_icon
CALL :delete_reg_value "!HKLM_CLS!" "piffile" "NeverShowExt" "HKCR\piffile /v NeverShowExt"
CALL :reassoc_file_types "pif=piffile"
:main_scf_icon
IF "!opt_scf_icon!"=="SKIP" GOTO main_scrap_ext
reg query "!HKLM_CLS!\SHCmdFile" >NUL: 2>NUL: || GOTO main_scrap_ext
reg query "!HKLM_CLS!\SHCmdFile" /v "IsShortcut" >NUL: 2>NUL: && (
GOTO main_scrap_ext
)
ECHO.
ECHO [scf-icon]
ECHO The .scf files are directive files that run internal commands of the Windows
ECHO Explorer shell when opened by users. The most common example is "Show Desktop"
ECHO on Quick Launch bar, in Windows versions before Vista. ^(The "Show desktop"
ECHO icons in Vista or later are .lnk files.^) While the format itself doesn't allow
ECHO code, it may still surprise users when a shell command is run accidentally.
ECHO We will add a shortcut arrow icon for this file type, to increase awareness of
ECHO users.
ECHO ^(This is a machine setting. In addition, the associations for this file type
ECHO for !user_msg! will be reset, which cannot be undone.^)
CALL :continue_prompt || GOTO main_scrap_ext
reg add "!HKLM_CLS!\SHCmdFile" /v "IsShortcut" /t REG_SZ /f >NUL: || (
CALL :show_reg_write_error "HKCR\SHCmdFile /v IsShortcut"
)
CALL :reassoc_file_types "scf=SHCmdFile"
:main_scrap_ext
REM Thanks to PCHelp and others for discovering this security flaw. See:
REM http://www.pc-help.org/security/scrap.htm
REM Other references:
REM http://www.trojanhunter.com/papers/scrapfiles/
REM http://www.giac.org/paper/gsec/614/wrapping-malicious-code-windows-shell-scrap-objects/101444
REM WordPad, Office Word and Excel are all known to support scrap files.
IF "!opt_scrap_ext!"=="SKIP" GOTO main_symlink_ext
REM Scrap files already have static icon; no need to suggest AlwaysShowExt.
SET scrap_ext_keys=
FOR %%k IN (ShellScrap DocShortcut) DO (
reg query "!HKLM_CLS!\%%k" /v "NeverShowExt" >NUL: 2>NUL: && (
SET scrap_ext_keys=!scrap_ext_keys! %%k
)
)
IF "!scrap_ext_keys!"=="" GOTO main_symlink_ext
ECHO.
ECHO [scrap-ext]
ECHO The .shs and .shb files are generated when user drags text out of a document
ECHO editor ^(such as WordPad^) and are formats that save document scraps and
ECHO shortcuts respectively. The format allows embedding executable code which can
ECHO get executed when user opens a ^(specially crafted^) file of these types.
ECHO ^(Windows Vista and later have removed support of scrap files.^)
ECHO We will delete the "NeverShowExt" registry value for these file types. Users
ECHO will see the extensions for these if they disable ^"Hide extensions for known
ECHO file types^". This increases awareness.
ECHO ^(This is a machine setting. In addition, the associations for these file types
ECHO for !user_msg! will be reset, which cannot be undone.^)
CALL :continue_prompt || GOTO main_symlink_ext
FOR %%k IN (!scrap_ext_keys!) DO (
CALL :delete_reg_value "!HKLM_CLS!" "%%k" "NeverShowExt" "HKCR\%%k /v NeverShowExt"
)
CALL :reassoc_file_types "shs=ShellScrap" "shb=DocShortcut"
:main_symlink_ext
REM The ".symlink" association only applies to Windows 8.1 or later, or
REM Windows 7 SP1 with KB3009980 hotfix. This requires shell32.dll's support.
IF "!opt_symlink_ext!"=="SKIP" GOTO main_shortcut_icon
REM If symlinks are not "known" (i.e. there's no "HKCR\.symlink" entry), then
REM the extensions will be always shown. Don't bother then.
reg query "!HKLM_CLS!\.symlink" >NUL: 2>NUL: || GOTO main_shortcut_icon
reg query "!HKLM_CLS!\.symlink" /v "AlwaysShowExt" >NUL: 2>NUL: && (
reg query "!HKLM_CLS!\.symlink" /v "NeverShowExt" >NUL: 2>NUL: || (
GOTO main_shortcut_icon
)
)
ECHO.
ECHO [symlink-ext]
ECHO A symbolic link is a kind of special file in NTFS file system that link to
ECHO another file by its path and file name. It's similar to a shortcut, and can be
ECHO identified by a shortcut arrow on its icon. However, a symbolic link may be
ECHO named with any or no extension. Windows Explorer hides file symbolic links'
ECHO extensions ^(which does not identify itself as being a link, such as ".txt" or
ECHO ".exe"^) by default. Unlike hiding ".lnk" for shortcuts, hiding such extensions
ECHO makes no sense.
ECHO We will force file symbolic links to always show their extensions, regardless
ECHO of users' "Hide extensions for known file types" option.
ECHO ^(This is a machine setting. In addition, the associations for this file type
ECHO for !user_msg! will be reset, which cannot be undone.^)
CALL :continue_prompt || GOTO main_shortcut_icon
reg add "!HKLM_CLS!\.symlink" /v "AlwaysShowExt" /t REG_SZ /f >NUL: || (
CALL :show_reg_write_error "HKCR\.symlink /v AlwaysShowExt"
)
CALL :delete_reg_value "!HKLM_CLS!" ".symlink" "NeverShowExt" "HKCR\.symlink /v NeverShowExt"
CALL :reassoc_file_types "symlink=.symlink"
:main_shortcut_icon
IF NOT "!opt_shortcut_icon!"=="FIX" GOTO main_file_icon
FOR %%k IN (piffile lnkfile DocShortcut InternetShortcut) DO (
reg query "!HKLM_CLS!\%%k" >NUL: 2>NUL: && (
reg add "!HKLM_CLS!\%%k" /v "IsShortcut" /t REG_SZ /f >NUL: || (
CALL :show_reg_write_error "HKCR\%%k /v IsShortcut"
)
)
)
reg query "!HKLM_CLS!\Application.Reference" >NUL: 2>NUL: && (
reg add "!HKLM_CLS!\Application.Reference" /v "IsShortcut" /t REG_SZ /f >NUL: || (
CALL :show_reg_write_error "Application.Reference /v IsShortcut"
)
)
REM The data string "NULL" is in the original entry, in both Groove 2007 and
REM SharePoint Workspace 2010.
reg query "!HKLM_CLS!\GrooveLinkFile" >NUL: 2>NUL: && (
reg add "!HKLM_CLS!\GrooveLinkFile" /v "IsShortcut" /t REG_SZ /d "NULL" /f >NUL: || (
CALL :show_reg_write_error "HKCR\GrooveLinkFile /v IsShortcut"
)
)
CALL :delete_reg_value "!HKLM_SFT!" "!SHELL_ICON_SUBKEY!" "29" "Explorer\Shell Icons /v 29"
IF NOT "!opt_file_icon!"=="FIX" (
SET list="pif=piffile" "lnk=lnkfile" "shb=DocShortcut" "url=InternetShortcut"
SET list=!list! "appref-ms=Application.Reference" "glk=GrooveLinkFile"
CALL :reassoc_file_types !list!
)
:main_file_icon
IF NOT "!opt_file_icon!"=="FIX" GOTO main_all_drives
REM "DefaultIcon" for "Unknown" is configurable since Windows Vista.
SET key=Unknown\DefaultIcon
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
IF NOT "!ERRORLEVEL!"=="1" (
reg add "!HKLM_CLS!\!key!" /ve /t REG_EXPAND_SZ /d "%%SystemRoot%%\System32\shell32.dll,0" /f >NUL: || (
CALL :show_reg_write_error "HKCR\!key!"
)
)
SET key=comfile\DefaultIcon
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_EXPAND_SZ /d "%%SystemRoot%%\System32\shell32.dll,2" /f >NUL: || (
CALL :show_reg_write_error "HKCR\!key!"
)
SET key=comfile\shellex\IconHandler
CALL :delete_reg_key "!HKLM_CLS!" "!key!" "HKCR\!key!"
REM Two vulnerabilities exist in the .lnk and .pif IconHandler:
REM MS10-046 (CVE-2010-2568), MS15-020 (CVE-2015-0096)
REM Windows 2000 has no patch for either. XP has only patch for MS10-046.
REM Expect that user disables the IconHandler as the workaround.
FOR %%k IN (piffile lnkfile) DO (
CALL :delete_reg_key "!HKLM_CLS!" "%%k\DefaultIcon" "HKCR\%%k\DefaultIcon"
SET key=%%k\shellex\IconHandler
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_SZ /d "{00021401-0000-0000-C000-000000000046}" /f >NUL: || (
CALL :show_reg_write_error "HKCR\!key!"
)
)
REM Scrap file types. Guaranteed to work (and only) in Windows 2000 and XP.
FOR %%k IN (ShellScrap DocShortcut) DO (
reg query "!HKLM_CLS!\%%k" >NUL: 2>NUL: && (
CALL :backup_reg "!HKLM_CLS!" "%%k\DefaultIcon" /ve
reg add "!HKLM_CLS!\%%k\DefaultIcon" /ve /t REG_EXPAND_SZ /d "%%SystemRoot%%\System32\shscrap.dll,-100" /f >NUL: || (
CALL :show_reg_write_error "HKCR\%%k\DefaultIcon"
)
CALL :delete_reg_key "!HKLM_CLS!" "%%k\shellex\IconHandler" "%%k\shellex\IconHandler"
)
)
REM The "InternetShortcut" key has "DefaultIcon" subkey whose Default value
REM differs among IE versions.
reg query "!HKLM_CLS!\InternetShortcut" >NUL: 2>NUL: && (
SET key=InternetShortcut\shellex\IconHandler
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_SZ /d "{FBF23B40-E3F0-101B-8488-00AA003E56F8}" /f >NUL: || (
CALL :show_reg_write_error "InternetShortcut IconHandler"
)
)
reg query "!HKLM_CLS!\SHCmdFile" >NUL: 2>NUL: && (
CALL :delete_reg_key "!HKLM_CLS!" "SHCmdFile\DefaultIcon" "HKCR\SHCmdFile\DefaultIcon"
SET key=SHCmdFile\shellex\IconHandler
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_SZ /d "{57651662-CE3E-11D0-8D77-00C04FC99D61}" /f >NUL: || (
CALL :show_reg_write_error "HKCR\!key!"
)
)
reg query "!HKLM_CLS!\Application.Reference" >NUL: 2>NUL: && (
SET key=Application.Reference\DefaultIcon
CALL :delete_reg_key "!HKLM_CLS!" "!key!" "!key!"
SET key=Application.Reference\shellex\IconHandler
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_SZ /d "{E37E2028-CE1A-4f42-AF05-6CEABC4E5D75}" /f >NUL: || (
CALL :show_reg_write_error "Application.Reference IconHandler"
)
)
REM The "GrooveLinkFile" key has "DefaultIcon" value (data: "%1") and no
REM "DefaultIcon" subkey.
reg query "!HKLM_CLS!\GrooveLinkFile" >NUL: 2>NUL: && (
SET key=GrooveLinkFile\ShellEx\IconHandler
CALL :backup_reg "!HKLM_CLS!" "!key!" /ve
reg add "!HKLM_CLS!\!key!" /ve /t REG_SZ /d "{387E725D-DC16-4D76-B310-2C93ED4752A0}" /f >NUL: || (
CALL :show_reg_write_error "!key!"
)
)
REM We don't reset associations for .url files because user's favorite browser
REM may have its own settings.
SET list="com=comfile" "pif=piffile" "lnk=lnkfile" "shs=ShellScrap"
SET list=!list! "shb=DocShortcut" "scf=SHCmdFile"
SET list=!list! "appref-ms=Application.Reference" "glk=GrooveLinkFile"
CALL :reassoc_file_types !list!
:main_all_drives
ECHO.
ECHO Now we will process the root directories of all disk drives.
ECHO Please insert all storage devices that are affected by malware, including USB
ECHO flash drives, external hard drives, memory cards, PDAs, smartphones, or digital
ECHO cameras. If you have CD- or DVD-RW discs in your drives, it is recommended that
ECHO you eject them, lest burning actions be triggered accidentally.
IF /I "!opt_move_subdir!"=="NUL" (
ECHO Files that are found to be suspicious will be DELETED directly, if possible.
) ELSE (
ECHO Files that are found to be suspicious will be moved to a sub-directory named
ECHO "!opt_move_subdir!" inside the drive, if possible.
)
ECHO If you type 'skip' here, this program will end.
CALL :continue_prompt || GOTO main_end
REM Symlinks have to be handled first because we can't guarantee that user's
REM 'attrib' utility supports '/L' (don't follow symlinks).
IF NOT "!opt_symlinks!"=="SKIP" (
ECHO.
ECHO [symlinks] ^(1 of 7^)
ECHO In Windows Vista or later, the NTFS file system supports "symbolic links",
ECHO which are a kind of special files that function like shortcuts, and also have a
ECHO shortcut arrow icon. But symbolic links are a file system feature, and do not
ECHO need file name extensions. Some malware will create symbolic links that point
ECHO to a ^(malicious^) executable file, tricking users into opening them.
IF /I "!opt_move_subdir!"=="NUL" (
ECHO We will delete all symbolic links that reside in the root directories and point
ECHO to files ^(not directories^).
) ELSE (
ECHO We will move away all symbolic links that reside in the root directories and
ECHO point to files ^(not directories^).
ECHO NOTICE: Due to a technical limitation, symbolic links with "Hidden" or "System"
ECHO attribute will be DELETED instead.
)
CALL :continue_prompt || SET opt_symlinks=SKIP
)
REM [attrib] must be done before moving anything, or MOVE refuses to move
REM Hidden or System files.
IF NOT "!opt_attrib!"=="SKIP" (
ECHO.
ECHO [attrib] ^(2 of 7^)
ECHO With the "Hidden" or "System" attribute set on files, they will no longer be
ECHO visible by default in Windows Explorer or 'DIR' command. Some malware will hide
ECHO the files and generate executable files ^(or shortcuts to executables^) with the
ECHO same name, tricking users into opening them. ^(Few malware will actually delete
ECHO the files, otherwise the disk space freed through deletion can draw attention
ECHO of users or anti-virus software.^)
ECHO Except for real known operating system files, we will clear both "Hidden" and
ECHO "System" attributes of all files and folders in the root directories. This
ECHO restores files that are hidden by the malware ^(and might also reveal malware
ECHO files themselves^).
CALL :continue_prompt || SET opt_attrib=SKIP
)
IF NOT "!opt_shortcuts!"=="SKIP" (
ECHO.
ECHO [shortcuts] ^(3 of 7^)
IF /I "!opt_move_subdir!"=="NUL" (
ECHO We will delete shortcut files of the following types in the root directories:
ECHO .pif, .lnk, .shb, .url, .appref-ms and .glk.
) ELSE (
ECHO We will move away shortcut files of the following types in the root
ECHO directories: .pif, .lnk, .shb, .url, .appref-ms and .glk.
)
CALL :continue_prompt || SET opt_shortcuts=SKIP
)
IF NOT "!opt_folder_exe!"=="SKIP" (
REM COM format does not allow icons and Explorer won't show custom icons
REM for an NE or PE renamed to .com.
ECHO.
ECHO [folder-exe] ^(4 of 7^)
ECHO Some malware will hide the folders and generate executable files with the same
ECHO names, usually with also the folder icon, tricking users into opening them.
IF /I "!opt_move_subdir!"=="NUL" (
ECHO We will delete executable files that reside in the root directories and carry
ECHO the same name as an existing folder. File types that will be deleted are: .exe
ECHO and .scr.
) ELSE (
ECHO We will move away executable files that reside in the root directories and
ECHO carry the same name as an existing folder. File types that will be moved are:
ECHO .exe and .scr.
)
ECHO WARNING: This may affect legitimate applications. When in doubt, skip this.
CALL :continue_prompt || SET opt_folder_exe=SKIP
)
IF NOT "!opt_autorun_inf!"=="SKIP" (
ECHO.
ECHO [autorun-inf] ^(5 of 7^)
ECHO Some malware will create the autorun.inf file, so that malware itself may be
ECHO automatically run on computers that didn't have AutoRun disabled. Except for
ECHO optical drives, no other drives should ever contain a file named "autorun.inf".
IF /I "!opt_move_subdir!"=="NUL" (
ECHO We will delete them.
) ELSE (
ECHO We will move and rename them to "!opt_move_subdir!\_autorun.in0".
)
IF NOT "!opt_attrib!"=="SKIP" (
ECHO Also, for folders named "autorun.inf" in the root directories, we will retain
ECHO their "Hidden" or "System" attributes, if set, so the folders remain hidden.
ECHO If you choose to 'skip', they will be revealed instead.
)
CALL :continue_prompt || SET opt_autorun_inf=SKIP
)
REM We won't deal with Folder.htt, because technically it could be any name in
REM any location, as specified in Desktop.ini.
IF NOT "!opt_desktop_ini!"=="SKIP" (
ECHO.
ECHO [desktop-ini] ^(6 of 7^)
ECHO In Windows 98, 2000 or Me ^(or in 95 or NT 4.0 with IE4 installed^), there is a
ECHO "Customize this folder" feature that allows customizing the root folder of a
ECHO drive, creating or editing the folder's "Web View" template ^(usually named
ECHO "Folder.htt"^). The template allows embedding JavaScript or VBScript which will
ECHO be executed when a user "browses" the folder.
ECHO If you are using Windows 2000 or XP, it is recommended that you install the
ECHO latest service pack ^(at least 2000 SP3 or XP SP1^) to fix security risks caused
ECHO by custom templates. Vista and later versions are safe.
ECHO The "Desktop.ini" file specifies which template would be used for the folder.
ECHO However, it's not supposed to exist in the root directories. ^(Not every feature
ECHO of Desktop.ini works in root folders, and it was not part of design that custom
ECHO Web View template works there.^)
IF /I "!opt_move_subdir!"=="NUL" (
ECHO We will delete the "Desktop.ini" files in the root directories.
) ELSE (
ECHO We will move away and rename the "Desktop.ini" files from the root directories,
ECHO to "!opt_move_subdir!\_Desktop.in0".
)
IF NOT "!opt_attrib!"=="SKIP" (
ECHO Also, for folders named "Desktop.ini" in the root directories, we will retain
ECHO their "Hidden" or "System" attributes, if set, so the folders remain hidden.
ECHO If you choose to 'skip', they will be revealed instead.
)
CALL :continue_prompt || SET opt_desktop_ini=SKIP
)
IF "!opt_autorun_inf!.!opt_desktop_ini!"=="SKIP.SKIP" SET opt_mkdir=SKIP
IF NOT "!opt_mkdir!"=="SKIP" (
ECHO.
ECHO [mkdir] ^(7 of 7^)
ECHO With autorun.inf or Desktop.ini or both files removed, in order to prevent
ECHO malware from creating either of them again, we will create hidden directories
ECHO with same names. Users won't see them, but they may interfere with malware.
ECHO Unless the malware has the ability to delete them, the drive won't be infected
ECHO by AutoRun any more.
CALL :continue_prompt || SET opt_mkdir=SKIP
)
SET g_files_moved=0
REM In Windows NT versions before Vista, when accessing A:\ or B:\ without a
REM floppy inserted into the respective drive, a graphical (!) error dialog
REM "Windows - No Disk" will pop up, blocking script execution.
REM Only DIR command (in NT 4 or later) on A: or B: shows non-blocking and no-
REM pop-up behavior.
REM The text of this dialog is usually:
REM "There is no disk in the drive. Please insert a disk into drive A:."
REM "[>Cancel<] [&Try Again] [&Continue]"
REM But due to a bug in Windows XP, it may instead show:
REM "Exception Processing Message c0000013 Parameters <address> 4 <address>
REM <address>" (<address> varied among OS language releases)
REM Beware that it's a really bad idea to supress such error dialogs! Don't
REM follow what the Web suggests and set the "ErrorMode" value in
REM "HKLM\SYSTEM\CurrentControlSet\Control\Windows" to 2! It could make real
REM serious errors to go unnoticed in your system.
FOR %%d IN (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z) DO (
DIR /B %%d:\ >NUL: 2>NUL: && (
CD /D %%d:\
SET g_move_status=
ECHO.
ECHO Drive %%d:
IF NOT "!opt_attrib!"=="SKIP" CALL :clear_files_attrib
IF NOT "!opt_shortcuts!"=="SKIP" CALL :process_shortcuts
IF NOT "!opt_folder_exe!"=="SKIP" CALL :process_folder_exes
SET name=autorun.inf
IF NOT "!opt_autorun_inf!"=="SKIP" CALL :make_dummy_dir
SET name=Desktop.ini
IF NOT "!opt_desktop_ini!"=="SKIP" CALL :make_dummy_dir
IF NOT "!opt_symlinks!"=="SKIP" CALL :process_symlinks
IF "!g_move_status!"=="OK_EMPTY" (
DEL "!opt_move_subdir!\README.txt" >NUL:
RMDIR "!opt_move_subdir!"
)
)
)
ECHO.
IF "!g_files_moved!"=="0" (
ECHO All done. Press any key to close this program.
) ELSE (
ECHO All done. Please examine the "!opt_move_subdir!"
ECHO sub-directories, which all suspicious files are moved into.
ECHO Press any key to close this program.
)
PAUSE >NUL:
GOTO main_end
:main_help
ECHO.
ECHO --help show this help
ECHO --no-restart don't restart script ^(default will restart when
ECHO Command Processor AutoRun is detected^)
ECHO --no-reg-bak don't generate registry backup file "Vacc_reg.bak"
ECHO --skip-cmd-autorun don't delete Command Processor AutoRun registry
ECHO --all-users-cmd-autorun delete ALL USERS' cmd.exe AutoRun ^(default: no^)
ECHO --no-inf-mapping don't disable parsing of autorun.inf
ECHO --skip-mountpoints don't clean MountPoints registry keys ^(caches^)
ECHO --skip-known-ext don't show extensions for known file types
ECHO --all-users-known-ext ALL USERS show ext for known types ^(default: no^)
ECHO --fix-exe-ext delete NeverShowExt for executables ^(default: no^)
ECHO --always-exe-ext always show ext for .exe and .scr ^(default: no^)
ECHO --skip-pif-ext don't delete NeverShowExt for .pif files
ECHO --skip-scf-icon don't add shortcut arrow icons for .scf files
ECHO --skip-scrap-ext don't delete NeverShowExt for .shs and .shb
ECHO --skip-symlink-ext don't always show extensions for symbolic links
ECHO --fix-shortcut-icon restore shortcut arrow icons ^(default: no^)
ECHO --fix-file-icon restore icons for Unknown, com, pif, lnk, shs, shb,
ECHO url, scf, appref-ms and glk types ^(default: no^)
ECHO --all-users-reassoc when editing file associations, apply to ALL USERS
ECHO in addition to machine default and current user
ECHO The following procedures apply to root directories of all drives:
ECHO --move-subdir=SUBDIR sub-directory for each drive that suspicious files
ECHO will be moved to ^(default: "\MALWARE"^)
ECHO --keep-symlinks don't move or delete symbolic links
ECHO --keep-attrib keep all files' "Hidden" and "System" attributes
ECHO --keep-shortcuts don't move or delete shortcut files
ECHO --keep-folder-exe don't move/del executables with same name as folders
ECHO --keep-autorun-inf don't move or delete autorun.inf
ECHO --keep-desktop-ini don't move or delete Desktop.ini
ECHO --no-mkdir don't create placeholder directories
ECHO For security reasons, this script doesn't move suspicious files outside of
ECHO their drives. To delete the files instead, specify '--move-subdir=NUL'.
GOTO main_end
:main_end
ENDLOCAL
EXIT /B 0
:main_find_error
ECHO *** FATAL ERROR: Not a DOS/Windows 'find' command.>&2
ENDLOCAL
EXIT /B 1
:main_invalid_path
ECHO *** FATAL ERROR: Invalid path is specified in '--move-subdir' option.>&2
ENDLOCAL
EXIT /B 1
:main_restart_native
REM KB942589 hotfix brings Sysnative folder support to Windows 2003 SP1+ (IA64
REM and x64) and XP x64 but is never offered in Windows Update.
SET status=1
REM Even with file system redirection in WoW64, the "IF EXIST" construct and
REM 'attrib' command do not redirect and can be used to check the existence of
REM real file names on disk. (Better not run cmd.exe inside if we're unsure
REM that "Sysnative" is a redirected pseudo-directory.)
FOR %%I IN ("!WinDir!\Sysnative") DO (
REM "%%~aI" redirects.
CALL :has_ci_substr "%%~aI" "d" && (
CALL :has_ci_substr "%%~aI" "h" || (
IF NOT EXIST %%I (
%%I\cmd /d /c "%0 --no-restart !args!" && GOTO :main_end
SET status=!ERRORLEVEL!
)
)
)
)
ECHO *** A WoW64 environment is detected. This script is supposed to be run in a>&2
ECHO native, 64-bit cmd.exe interpreter.>&2
ECHO Please follow these steps:>&2
ECHO 1. Run "%%WinDir%%\explorer.exe" ^(The native, 64-bit Windows Explorer. Note that>&2
ECHO it is not explorer.exe in System32 or SysWOW64 directory.^)>&2
ECHO 2. In the new Explorer window, navigate to "%%WinDir%%\System32", and then find>&2
ECHO and right-click on the "cmd.exe".>&2
ECHO 3. Select "Run as administrator".>&2
ECHO 4. In the new Command Prompt window, run the following command:>&2
ECHO %0 !args!>&2
ECHO.
PAUSE
ENDLOCAL & EXIT /B %status%
:main_restart
cmd /d /c "%0 --no-restart !args!" && GOTO :main_end
SET status=!ERRORLEVEL!
ECHO *** Error occurred when restarting. Please rerun this script using the>&2
ECHO following command ^(note the '/d' and '--no-restart' options^):>&2
ECHO cmd /d /c ^"%0 --no-restart !args!^">&2
ECHO.
PAUSE
ENDLOCAL & EXIT /B %status%
REM ---------------------------------------------------------------------------
REM SUBROUTINES
REM Checks if string contains any of the substrings, ignoring case.
REM @param %1 String, which must be quoted
REM @param %2... Substrings, each must be quoted and not contain "!" or "="
REM @return 0 (true) if any of the substrings is found in string
:has_ci_substr
SET "str=%~1"
REM cmd.exe bug: "SET v=&ECHO.!v:s=r!x" outputs "s=rx" instead of "x".
REM Must return early lest the bug break the condtional below.
IF "%~1"=="" EXIT /B 1
SHIFT /1
REM Can't use FOR because it expands "*" and "?" that we don't want.
GOTO has_ci_substr_loop_
:has_ci_substr_loop_
IF "%~1"=="" EXIT /B 1
REM The first "*" in "!v:*s=r!" syntax is special (read "SET /?" page);
REM the rest is matched literally even if it contains "*".
REM Undocumented: String substitution is case insensitive.
REM Undocumented: On a multi-byte code page, string substitution operates
REM on characters, not bytes. E.g. !v:s=! won't match the character 0xE073.
IF NOT "!str!"=="!str:*%~1=!" EXIT /B 0
SHIFT /1
GOTO has_ci_substr_loop_
REM Checks if path or file name contains any character in the set.
REM @param %1 Quoted string containing set of characters to be checked.
REM @param name Unquoted file name
REM @return 0 (true) if names contain any of the characters in %1
:has_path_char
FOR /F "tokens=2 eol=/ delims=%~1" %%t IN ("x!name!x") DO (
REM It won't enter loop body if token 2 is empty, but for safety...
SETLOCAL DisableDelayedExpansion
IF NOT "%%t"=="" (
ENDLOCAL & EXIT /B 0
)
ENDLOCAL
)
EXIT /B 1
REM Prompts user to continue or skip.
REM @return 0 if user says to continue, or 1 if says to skip
:continue_prompt
REM Note: If the user answers empty string after a "SET /P", The variable
REM is kept the previous value and NOT set to the empty string.
SET reply=
SET /P reply="Press Enter to continue, or type 'skip' to skip this step: "
IF "!reply!"=="" EXIT /B 0
IF /I "!reply!"=="Y" EXIT /B 0
IF /I "!reply!"=="SKIP" EXIT /B 1
GOTO continue_prompt
REM Creates a file.
REM @param name Unquoted, valid file name
REM @return 0 if file is created
:create_file
REM There's no atomic "create file if not exist" command in Batch, so we
REM can't avoid a TOCTTOU attack completely.
REM "IF EXIST" doesn't detect the existence of file with Hidden attribute.
REM "%%~aI" outputs empty string for files with (hacked) Device attribute.
REM Neither of them are more reliable than MKDIR for checking file's
REM existence (or availability of the file name).
MKDIR "!name!" || EXIT /B 1
RMDIR "!name!" & TYPE NUL: >>"!name!"
IF NOT EXIST "!name!" EXIT /B 1
FOR %%I IN ("!name!") DO (
CALL :has_ci_substr "%%~aI" "d" && EXIT /B 1
)
EXIT /B 0
REM Creates and initializes "Vacc_reg.bak"
:init_reg_bak
REM This is not .reg format! So we don't allow user to specify file name.
SET name=Vacc_reg.bak
CALL :create_file || (
SET g_reg_bak=FAIL
ECHO.>&2
ECHO WARNING: Can't create registry backup file "Vacc_reg.bak" in the directory>&2