一般地,在WINDOWS系统下,防止一个软件运行多次的方法大体有:
1)标志法:软件启动后,置一个已经启动的标志,常用的标志方式是写注册表或文件,软件启动时,首先是检测这个标志,如果有,直接退出,但这有一个致命的弱点,如果软件异常退出,标志没有清除的话,这个软件就无法再运行了,所以,如果采用这种方法,必然要考虑的是标志的真伪,即使标志存在,也要检测一下是否是真正的存在还是只是个僵尸,对付这种标志的方法相对简单,将其标志删除或让其认为是僵尸就可以了。
2)进程枚举法:启动前,先扫描系统进程表,好的设计不但要检查进程的名字,一般还要读取进程的关键信息,比如可执行文件的头,特定数据段等等,甚至会对代码作摘要(比如MD5)计算,如果这些特征符合,不管进程的名字和路径是什么,都可以认为该软件已经被启动了。这种方法能否奏效,比的就是进程枚举和进程隐藏在技术上谁更高一筹。
3)设备独占法:软件启动时,会以独占的方式方式打开并锁定某一个设备,比如串口,后续的打开均会失败,从而防止多次启动,对付这样的锁定,有一定的难度,如果锁定的是软件完成全功能必须的设备,基本上就失去了多次启动的意义。对TCP/UDP端口的占用,也可以归到这个类中,如果采用的是TCP/UDP的端口,可以以地址共享或修改其端口号应对。
4)命名管道和命名信号灯法:软件启动时,创建一个命名管道或信号灯,如果创建的结果是初次,就继续运行,否则就退出。这类比较难找,一般是先通过其IMPORT的表,找到类似CreateSemaphore的引用的地方,找到对应的名称,想办法做手脚。
5)DLL共享数据计数器法:在某个软件专署DLL上,设置一个共享数据段,定义一个计数器,凡是加载该DLL的进程都会导致这个计数器变化,从而根据其数值确定是否是多次启动,如果DLL防护的好,是需要花很多精力对付的。
SUN游戏不允许多开,现在其使用的方法是第4种,运行时创建一个叫SUN_GAME的信号灯,如果成功,并且返回的错误不是已经存在,就认为是初次启动,否则就退出,由于其代码加了还算先进的壳,要想多次启动SUN,最省心的方法就是直接操作内存了,有2个手段:
1)修改内存代码:在壳解压后,执行到CreateSemaphore点之前,将该段代码去掉。
2)修改信号灯的名称:比如,第一次启动名字不变,启动第二个时,将名字改为SUN_GAMF,依次类推。由于改名也必须在CreateSemaphore前进行,所以存在一个成功率问题,如果慢了,启动会失败,但慢的概率很小,低于10%,相对于改代码,要安全快捷一些.