以下通过一个案例来进行分析。
症状:有一程序,每天开机自动弹出广告,很烦人。经检查发现,该程序位于 C:\Program Files 目录下,每次自动创建新目录,目录名称是随机的;同时,产生一个进程,进程的名称也是随机的。
目的:现在想写一个批处理来解决一问题,只需结束进程即可,不得屏蔽程序,不能随意结束其他程序的进程。
问题:遇到困难,就是无法确定进程名称,导致无法结束进程。
要结束进程首先要知道你结束的是什么进程。用taskkill命令可以结束进程,但你要知道进程名称、进程窗口名称、PID、命令路径、内存使用等等参数信息。现在我们遇到的这个程序的进程是随机的,进程名称、窗口名称、PID、命令路径均不可知,内存使用也不好理解,那怎么办呢?
以前写过《一键清理非系统进程》,但在此处不能使用,因为“不能随意结束其他程序的进程”说明这是一台被监管的电脑。
批处理做实时监控是件吃力不讨好的事情,因为批处理缺乏一个嵌套在系统或其他程序的事件触发机制,如果不停地检测进程它就会占用完所有资源,虽然可用PING命令来增加间隔时间,但始终不如意。
下面我们主要讨论如何发现一个随机进程并结束该随机进程。
我们主要通过发现目录文件来发现随机进程,下面我们对该程序的行为进行分析,以便找出规律。
经检查发现:
第一、该程序生成的目录是随机的,由大小写字母和数字组成,而且一般都是七位。一般的程序目录很少使用数字的,相反,随机目录名里一般都含有数字,所以,我们可以使用 dir /b "%ProgramFiles%"|findstr "[0-9]" 来获得随机目录,成功率在80%以上。如果想更准确些,可以判断目录名称的位数,或者目录创建的日期等,但判断太多可能会导致效率下降。
第二、该程序生成的文件有一部分是随机的,有一部分是固定的。如果知道文件夹里有什么文件,用dir就能很容易找出来,因此,判断文件夹里的固定文件名就能初步判断出该目录就是我们所要找的目录了。
但是,这些固定文件名并非主程序,也没有出现在进程里,所以,我们把焦点对准那几个随机文件名上。
第三、随机文件名的构成是有规律的,它的长短、后缀名、大小等都有某些共同的特征,其中,有两个EXE程序,一个是AAAA123.EXE,另外一个是AAAA123bb.EXE,通过多次比较发现,差别只是在另外一个exe文件名多了一个bb字符,还有一个dll文件,文件名也是AAAA123。因此,存在三个共同文件名的目录就是我们要找的随机目录,再细一点,可以加入后缀名判断。
第二、第三点结合起来就能够判断该目录一定是我们要找的目录了。
- @echo off&setlocal enabledelayedexpansion
- cd /d %ProgramFiles%
- echo ——检测目录 . . .
- set num=0
- for /f "tokens=*" %%a in ('dir /b ^|findstr "[0-9]"') do (
- echo;找到目录【%ProgramFiles%\%%a】
- for /f "tokens=*" %%i in ('dir /b /a %%a') do (
- if /i "%%~ni"=="!var!" set /a num+=1&echo 找到程序:%%i&set str=%%i
- if /i %%i==log.dat set /a num+=1&echo 找到程序:log.dat
- if /i %%i==hello1.zip set /a num+=1&echo 找到程序:hello1.zip
- if /i %%i==hello6.zip set /a num+=1&echo 找到程序:hello6.zip
- set var=%%~ni
- )
- )
- if !num!==4 echo ——检测进程 . . . &taskkill /f /t /im !str!
- pause&exit
复制代码
对文件或字符进行判断的方法一般有:1)直接法,比如直接用DIR命令搜索;2)IF法,IF是等价命令判断;3)搜索法,DIR、FINDSTR、FIND等;4)连接法,&、&&、|、||等;5)FOR法,使用FOR的切分提取。
为什么不用findstr而用IF?因为findstr是外部程序,启动过程较慢,而IF是内部命令,判断的条件不多,运行效率有优势。
本处对多个文件判断使用了IF法,并用 set /a num+=1 来计数,如果满足四个IF条件判断则结束证明该进程就是我们要找的随机进程,可以taskkill。
如果担心错误结束了其他进程,可以加入对进程路径的判断来提高准确率,使用以下命令获得进程的路径:
- wmic process where name="!str!" get CommandLine,ExecutablePath
复制代码
但该命令效率比较差。
以上方法虽然比较粗糙,但是是可行的,成功率能达到90%,满足现实需要。在使用过程中加强检查,根据需要另行修改。
批处理处理进程,大家应当将思维建立在tasklist、taskkill、wmic process三组命令的基础上,并且要熟悉这三组命令的参数,灵活运用。
批处理处理文件,要学会研究文件的各种属性,通过文件名、路径名、后缀名、文件大小、日期、隐藏等等文件属性获得对文件的感官认识,通过文件的进程变化获得文件的行为认识。尽量寻找相同点和相异点,找到属于它们的一些特征规律,然后用判断法去进行判断,再进行细节上的处理。
在文件与命令之间建立一座桥梁,你才能使得批处理发挥作用。
通过以上案例,我们发现分析问题的关键就是,找出程序运行的规律,研究程序的行为特征。
我们应当清楚地认识到,批处理对其他程序的操作是一种外部的碰撞式的操作,批处理无法嵌入程序内部,无法控制程序的执行过程,除非程序提供了命令接口。比如,批处理无法命令进程窗口向左向右移动,无法改变程序的执行参数等等。原因在于,批处理对于外部程序的操作仅限于简单的几个命令中有限的几个参数。因此,我们考虑问题的时候,就得基于批处理命令本身来考虑,当无法通过命令直接处理问题的时候,那只有转变思维,通过巧妙的命令组合来处理了。找到命令和命令的参数,找到API,找到突破口,才能找到解决问题的钥匙。
批处理就是这样一种哲学,如果不能对此有深刻的认识和领悟,就会陷入批处理无用论、过时论的泥潭,从而痛苦于自己所学的知识。 |