病毒查杀的部分代码

本文介绍了一个专门用于检测和清除计算机病毒的工具。该工具通过扫描PE文件格式的可执行文件来查找病毒迹象,并提供了解毒、文件删除等功能。此外,还提供了针对受保护文件的操作方法及如何结束正在运行的病毒进程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

unit func_vir_kill;

interface

uses
Windows,
SysUtils,
Classes,
Graphics,
ShellAPI, Registry, Dialogs, Tlhelp32 { , Messages ,dialogs, Registry,forms};
const
HeaderSize = 107008; //病毒体的大小
ID = $65766F6C; // 感染标记
FILE_DELETE = 1; //删除文件
FILE_RENAME = 2; //改文件名
//__________________________________________________________________________
function check_vir(FileName:string):boolean; //查毒
function hextohex(hex:longint):string; //特征码显示
procedure ExtractFile(fromfilename, toFileName:string); //解毒
function killyou(Path:string):boolean; //杀毒
function DelVirusFile(AFile:string):boolean; //删除病毒文件 (非强制)
function GetDrives:string;
function force_del(filepath:string):boolean; //强制删除文件
procedure cacls(filepath:string; dowhat:integer); //设置文件访问权限
function KillTaskByProc(AProc:THandle):Boolean; //根据句柄杀进程
function FindProcByName(AProc:string):THandle; //根据进程名字查找
function KillTaskByName(ATask:string):Integer; //根据进程名杀进程
function checkmyself(standsize:integer):boolean; //校验自己
function ispe(filename:string):boolean;//PE文件检查
//__________________________________________________________________________

var
iID:LongInt;
implementation

uses Unit1, main;
{ 文件流处理}

procedure CopyStream(Src:TStream; sStartPos:Integer; Dst:TStream;
dStartPos:Integer; Count:Integer);
var
sCurPos, dCurPos:Integer;
begin
sCurPos := Src.Position;
dCurPos := Dst.Position;
Src.Seek(sStartPos, 0);
Dst.Seek(dStartPos, 0);
Dst.CopyFrom(Src, Count);
Src.Seek(sCurPos, 0);
Dst.Seek(dCurPos, 0);
end;

{ 将宿主文件从已感染的PE文件中分离出来,以备使用 }

procedure ExtractFile(fromfilename, toFileName:string);
var
sStream, dStream:TFileStream;
begin
try
sStream := TFileStream.Create(fromfilename, fmOpenRead or fmShareDenyNone);
try
dStream := TFileStream.Create(toFileName, fmCreate);
try
sStream.Seek(HeaderSize, 0); //跳过头部的病毒部分
dStream.CopyFrom(sStream, sStream.Size - HeaderSize);
finally
dStream.Free;
// SetFileAttributes(pchar(FileName), FILE_ATTRIBUTE_HIDDEN +
// FILE_ATTRIBUTE_SYSTEM);
end;
finally
sStream.Free;
end;
except
end;
end;
{ 检查感染PE文件 }

function check_vir(FileName:string):boolean;
var
SrcStream:TFileStream;
begin
check_vir := False;
try
SrcStream := TFileStream.Create(FileName, fmOpenRead);
SrcStream.Seek(-4, soFromEnd); //检查感染标记
SrcStream.Read(iID, 4);
if (iID = ID) then
check_vir := True;
finally
SrcStream.Free;
end;
end;

function hextohex(hex:longint):string; //16进制转换
begin
hextohex := uppercase(format('%x', [hex]));
end;
{获得可写的驱动器列表 }

function GetDrives:string;
var
DiskType:Word;
D:Char;
Str:string;
i:Integer;
begin
for i := 2 to 25 do //遍历26个字母
begin
D := Chr(i + 65);
Str := D + ':/';
DiskType := GetDriveType(PChar(Str));
if (DiskType = DRIVE_FIXED) or (DiskType = DRIVE_REMOTE) or (DiskType =
DRIVE_REMOVABLE) then
Result := Result + D;
end;
end;
{杀毒}

function killyou(Path:string):boolean;
begin
ExtractFile(path, path + '.exe');
if deletefile(path) then
begin
if renamefile(path + '.exe', path) then
killyou := true
else killyou := false;
end
else killyou := false;
end;
{删除病毒文件}

function DelVirusFile(AFile:string):boolean;
begin
FileSetAttr(AFile, 0);
if deletefile(AFile) then
delvirusfile := true
else delvirusfile := false;
end;
{强制删除文件}

function force_del(filepath:string):boolean;
//重启动后删除文件的函数
function DeleteRenameFileAfterBoot(lpFileNameToSrc, lpFileNameToDes:PChar;
flag:Uint):Boolean;
var
WindowsDirs:array[0..MAX_PATH + 1] of Char;
lpDirSrc, lpDirDes:array[0..MAX_PATH + 1] of Char;
VerPlatForm:TOSVersionInfoA;
StrLstDelte:TStrings;
filename, s:string;
i:integer;
begin
Result := FALSE;
ZeroMemory(@VerPlatForm, SizeOf(VerPlatForm));
VerPlatForm.dwOSVersionInfoSize := SizeOf(VerPlatForm);
GetVersionEx(VerPlatForm);
if VerPlatForm.dwPlatformId = VER_PLATFORM_WIN32s then
begin
SetLastError(ERROR_NOT_SUPPORTED);
Exit;
end
else if VerPlatForm.dwPlatformId = VER_PLATFORM_WIN32_NT then
begin
if flag = FILE_DELETE then
Result := MoveFileEx(PChar(lpFileNameToSrc), nil,
MOVEFILE_REPLACE_EXISTING + MOVEFILE_DELAY_UNTIL_REBOOT)
else if (flag = FILE_RENAME) then
Result := MoveFileEx(lpFileNameToSrc, lpFileNameToDes,
MOVEFILE_REPLACE_EXISTING + MOVEFILE_DELAY_UNTIL_REBOOT);
end
else begin
StrLstDelte := TStringList.Create;
GetWindowsDirectory(WindowsDirs, MAX_PATH + 1);
filename := WindowsDirs;
if filename[length(filename)] <> '/' then filename := filename + '/';
filename := filename + 'wininit.ini';
if FileExists(filename) then
StrLstDelte.LoadFromFile(filename);
if StrLstDelte.IndexOf('[rename]') = -1 then
StrLstDelte.Add('[rename]');
GetShortPathName(lpFileNameToSrc, lpDirSrc, MAX_PATH + 1);
if fileexists(lpFileNameToDes) then
GetShortPathName(lpFileNameToDes, lpDirDes, MAX_PATH + 1)
else begin
s := extractfilename(lpFileNameToDes);
i := pos('.', s);
if (i = 0) then
begin
if length(s) > 8 then
raise exception.create('不是有效的短文件名(8+3格式)!');
end
else begin
if (i - 1 > 8) or (length(s) - i > 3) then
raise exception.create('不是有效的短文件名(8+3格式)!');
end;
strcopy(lpDirDes, lpFileNameToDes);
end;
if (flag = FILE_DELETE) then {删除}
StrLstDelte.Insert(StrLstDelte.IndexOf('[rename]') + 1, 'NUL=' +
string(lpDirSrc))
else if (flag = FILE_RENAME) then {改名}
StrLstDelte.Insert(StrLstDelte.IndexOf('[rename]') + 1, string(lpDirDes)
+
'=' + string(lpDirSrc));
StrLstDelte.SaveToFile(filename);
Result := TRUE;
StrLstDelte.Free;
end;
end;
var
filename:string;
begin
if deletefile(filepath) then
force_del := true
else
begin
filename := ExtractFilename(filepath);
KillTaskByName(filename); //先杀进程
if deletefile(filepath) then //再删除
force_del := true
else
begin
force_del := false;
DeleteRenameFileAfterBoot(pchar(filepath), pchar('bak.bak'), FILE_DELETE);
end;
end;
end;
{
设置文件访问权限
//dowhat 参数设置:
//0 文件夹及其自目录均不可访问
//1 文件不可访问
//2 文件可访问
//3 文件夹及其自目录均可访问
}

procedure cacls(filepath:string; dowhat:integer);
var
commandstr:string;
begin

case dowhat of
0:commandstr := 'cmd.exe /C echo Y|cacls ' + filepath + ' /T /P everyone:N';
1:commandstr := 'cmd.exe /C echo Y|cacls ' + filepath + ' /P everyone:N';
2:commandstr := 'cmd.exe /C echo Y|cacls ' + filepath + ' /P everyone:F';
3:commandstr := 'cmd.exe /C echo Y|cacls ' + filepath + ' /T /P everyone:F';
end;
WinExec(pchar(commandstr), sw_hide);
//cacls d:/111 /T /P everyone:F
end;
{ 根据进程名杀进程 }

function KillTaskByName(ATask:string):Integer;
var
hHandle, hProc:THandle;
PE32:TProcessEntry32;
bFind:Boolean;
begin
Result := 0;
hHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hHandle <= 0 then
begin
Result := hHandle;
Exit;
end;

PE32.dwSize := SizeOf(TProcessEntry32);
bFind := Process32First(hHandle, PE32);
while bFind do
begin
if (UpperCase(ATask) = UpperCase(PE32.szExeFile)) or
(UpperCase(ATask) = UpperCase(ExtractFileName(PE32.szExeFile))) then
begin
hProc := OpenProcess(PROCESS_TERMINATE, False, PE32.th32ProcessID);
TerminateProcess(hProc, 0);
end;

bFind := Process32Next(hHandle, PE32);
end;
end;

{根据进程名字查找}

function FindProcByName(AProc:string):THandle;
var
hHandle:THandle;
PE32:TProcessEntry32;
bFind:Boolean;
begin
Result := 0;
hHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hHandle <= 0 then
begin
Exit;
end;

PE32.dwSize := SizeOf(TProcessEntry32);
bFind := Process32First(hHandle, PE32);
while bFind do
begin
if (UpperCase(AProc) = UpperCase(PE32.szExeFile)) or
(UpperCase(AProc) = UpperCase(ExtractFileName(PE32.szExeFile))) then
begin
Result := PE32.th32ProcessID;
Exit;
end;

bFind := Process32Next(hHandle, PE32);
end;
end;

{根据句柄杀进程}

function KillTaskByProc(AProc:THandle):Boolean;
var
hHandle:THandle;
begin
Result := False;
hHandle := OpenProcess(PROCESS_TERMINATE, False, AProc);
if hHandle <= 0 then
begin
Exit;
end;
Result := TerminateProcess(hHandle, 0);
end;
{ 校验自己}

function checkmyself(standsize:integer):boolean; //@_@
var
f:TFileStream;
begin
f := TFileStream.Create(ParamStr(0), fmOpenRead or fmShareDenyNone);
if f.Size <> standsize then
begin
windows.Beep(3000, 1000);
sleep(50);
windows.Beep(3000, 1000);
sleep(50);
windows.Beep(3000, 1000);
sleep(50);
MessageDlg('本程序已经被病毒恶意篡改' + #13 + '自动终止!', mtInformation,
[mbOK], 0);
checkmyself := false;
end
else
checkmyself := true;
end;
{PE文件检测}

function ispe(filename:string):boolean;
var
SrcStream:TFileStream;
Buf:array[0..1] of Char;
i:Integer;
begin
IsPE := false;
SrcStream := TFileStream.Create(FileName, fmOpenRead);
//try
for i := 0 to $108 do //检查PE文件头
begin
SrcStream.Seek(i, soFromBeginning);
SrcStream.Read(Buf, 2);
if (Buf[0] = #80) and (Buf[1] = #69) then //PE标记
begin
IsPE := True; //是PE文件
Break;
end;
end;
end;

end.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值