批处理
什么是批处理
在前面的文章中学习过Dos命令,单一的Dos命令能实现特定的功能,但功能较为单一;一行一行在命令行中输入Dos命令效率又不够高,因而产生一种方式,将这些Dos命令组织起来,并按照指令的顺序成批进行处理。这就是批处理,又被叫做脚本。
在Windows中,批处理是将Dos命令按照顺序组织起来成批执行;在Linux中也有一种形式,将bash命令组织起来成批执行,这种经过组织后的文件被称作Shell脚本。
如何创建批处理
新建一个文本文件,将后缀改为.bat形式保存,就得到了一个批处理文件,然后用记事本编辑即可。但是有些情况下,我们无法修改文件的后缀,此时需要做一个修改。打开Windows资源管理器 -> 工具 -> 文件夹选项 -> 查看,在高级设置中,有一个选项,隐藏已知文件类型的扩展名,将该扩展名的勾选去除,便可以修改文件后缀了。(注:本篇中的实验均基于Windows2003/WindowsXp,别的版本代码会有所改动)
接下来,我们可以应用前一篇学到的Dos命令,写一个批处理文件,用来打印一些语句,编辑完,双击即可运行批处理文件。
运行的结果看着很不友好,下面我们将学习更多的指令来对代码进行优化。
关闭回显与空行
批处理虽然的对代码成批进行处理,但真正执行时也只是一条条的指令进行执行。回顾刚刚的代码,命令行在执行时,将Dos命令一条条打印出来,再执行,这样视觉上很不美观,考虑不显示执行的语句,可以采用以下命令:
1 | @echo off |
在批处理的开头,输入该指令,执行时就不会显示执行的指令了。此外,批处理在处理的过程中,是不会处理文件中的空行的,遇到会直接跳过,执行下一条Dos指令,这样难道就没法在批处理中打印空行了吗?同样,针对这一点Windows也提供了一条命令 :
1 | echo. |
该指令将会打印一行空行,可以理解为python中的print()或C++中cout << endl;的作用。
另一个指令是在前文中出现过的
1 | pause |
该指令的作用,就是停留在命令行界面,这样我们可以看到指令执行时的效果,否则一下就执行结束了;该指令与C/C++中的getchar()作用是一样的。
有了新学习的指令后,我们对刚刚的批处理作简单的修改:
这样看上去就清晰多了。
变量与取值
批处理可以实现很多功能,自然需要一些基础功能的指令组合才能完成。这里介绍一个可以设置变量的指令,set指令。默认情况下,set指令可以设置一个变量的值,例如:
该语句的意思是,使用set指令设置一个名为a的变量值为6,接着用echo语句打印它,可以发现,这里我们用了%a%的形式,这就是Dos命令中格式化的方式,可以类比python中的.format或者C语言中的%d。
设置变量可以做到了,那是否可以从缓冲区获取输入参数的值呢?答案是肯定的。仅需将set指令增加一个参数/p,就可以做到类似C++中的cin>>或C中scanf()功能的效果:
图中,name获取到的不是值,而是显示在命令行中的语句,接下来用户输入的值,才会赋给变量name。接下再打印name的值。有了/p参数,我们便可以从命令行中获取参数,增加程序的交互性。
条件分支
任何一门语言中,都会有条件分支,根据不同的条件,执行不同的代码。Windows也提供了相应的Dos命令,if和goto。这两个命令相互间配合,就可以做到类似switch语句实现的条件跳转。下面来看一下定义:
1 | 1. 命令:goto |
有了这几条指令后,我们可以写一个小的批处理测试一下:
该批处理,实现很简单的功能,根据按下的数字为1还是2,打印相应的语句。
批处理小实验
在对批处理和大部分常用命令有所了解后,来进行一个练习,再做练习之前,需要再掌握一个指令:
1 | 1. 命令:net user |
该指令用于修改用户密码,在练习中会用到。
这里练习编写一个批处理文件,能够实现一个简单的菜单功能,功能包括修改用户密码,定时关机以及退出。
我这里参照Beglage_buglige的代码,实现了一份类似功能的,执行效果如下:
难度不大,可以先自己尝试,这里附上代码
1 | @echo off |
病毒
这里提到的病毒,不能算真正的病毒,可以认为是一些整人的手段或把戏。因为这些病毒是基于Dos命令,进行磁盘文件的修改等操作,如果同样有过Dos命令经验的人,就很容易识破这样的把戏。真正的病毒大多要涉及到操作系统底层的修改,更偏向二进制方面。
无限CMD
首先来看简单的无限CMD的实现,仅仅需要3行指令即可实现:
1 | :Inf |
效果如下:
这里补充说明一下start命令。
1 | 1. 命令:start/start cmd |
虽然无限CMD很好实现,但是有所警惕的人一般不会点开,这时我们就需要给这个代码做一点伪装。
伪装杀毒软件
这里先来看代码,然后再分析这个代码做了什么:
先来看第一部分:
1 | @echo off |
这里首先是关闭命令的显示,切换到C盘,创建一个文件夹a。
然后使用echo指令,在文件夹a中创建批处理文件virus.bat,并将无限打开cmd的指令写入。
接着将该批处理文件复制到当前用户的 ”启动“ 文件夹下,这个文件夹有啥用呢?这是Windows开机自启动的文件夹,当电脑开机后,Windows会自动执行该文件夹下的程序,当我们把无限cmd批处理放到该目录下时,每当电脑启动时,就会进入这样的死循环,这样的恶作剧会让用户很是头疼。但每个平台下的路径是不一样的,用户名也不一样,如何写出一个通用的指令呢?这时需要用到一个系统变量%UserProfile%,前面讲到了,用Set设置的变量可以通过%*%的形式获取到它的值,这个变量就是系统变量,Windows中定义了很多系统变量(可以参考此篇),%UserProfile%就是其中之一,它对应的值则是”C:\User\用户名”, 可以看到,我这里UserProfile对应的就是 “C:\Documents and Settings\Administrator” ,所以我们可以把
dos1
copy C:\a\virus.bat "C:\Documents and Settings\Administrator\「开始」菜单\程序\启动\" >nul
改成
dos1
copy C:\a\virus.bat "%USERPROFILE%\「开始」菜单\程序\启动\" >nul
这样就可以在WindowsXP/Windows2003的系统上完成功能的实现了,当然对于别的版本的Windows路径可能会有所不同,需要做相应修改。
然后我们来看剩下的部分:
1 | echo ====== 垃圾清理中,请不要关闭窗口====== |
- 这部分,主要是打印出一个界面,在Dos中看到一个界面,让人误以为是个杀毒软件,然后按照你的步骤执行
- 值得注意的是那条ping语句,输出通过>nul丢掉了,但是依旧会执行,”-n“ 这个参数用来设置发包的数量,这条ping语句的作用就是,给人一种有程序正在执行的感觉(发包越多,等待时间越长),让人误以为正在进行电脑垃圾清理。
- 最后是一条重启电脑指令,这样,等到重启后,电脑就会因为开机自动打开无限CMD的脚本,最终至死机
执行时,表现如下:
可以看到,生成的virus.bat会被写入到 “启动” 文件夹的位置,并且提示是否需要重启,若重启,则开机后便会后上面的无限CMD结果一样。
杀死桌面
桌面也是可以被杀死的,桌面存在的原因是为了能够让电脑使用起来更加方面,从而打造的GUI界面。但是桌面也只是一个进程(explorer.exe),在开机时该进程会启动而已。所以我们只需要关掉这个进程,就可以杀死桌面,下面介绍一条指令:
1 | 1. 命令:taskkill |
执行时状态如下:
那桌面被杀死了,该如何使用呢?这是只需要将explorer.exe进程重新启起来就行,该程序通常位于 “c:\windows” 目录下,可以使用指令:
1 | start C:\windows\explorer.exe |
重启桌面进程,效果如下:
蓝屏
这里涉及到一个调试工具ntsd,该调试工具主要位于WindowsXP/2003版本中,可以用来强制结束进程。刚刚的taskkill不也可以结束进程吗?为什么需要ntsd?来看一个例子:
taskkill并不能结束所有进程,所以这时候就需要ntsd。这里出现的winlogon.exe又是什么进程呢?winlogon.exe是一个系统核心进程,用于管理用户登录和退出。强行关闭则会引起蓝屏。下面简要说明下ntsd的语法:
1 | 1. 命令:ntsd |
可以尝试在WindowsXP/2003中执行如下指令:
1 | ntsd -c q -pn winlogon.exe |
结果显而易见,蓝屏并重启。
参考链接:
- https://www.bilibili.com/video/BV1i7411G7vm?p=14 (千峰网络开源课程p14~p15)
- https://blog.csdn.net/weixin_43252204/article/details/105389619 (Beglage_buglige关于本篇内容的学习笔记)
- https://blog.csdn.net/evilcry2012/article/details/79447194 (CSDN博客-系统变量与路径的对应关系)