还有一点,调试器对我们的威胁很大,我们不会让Cracker们舒舒服服地使用SoftICE、TRW或OllyDbg来调试我们的程序。除了常用的MeItICE方法外,这里我给一个笔者写的方法:
{检查自己的进程的父进程是否为Explorer.exe,否则是被调试器加载了}
{不过注意,控制台程序的父进程在WinNT下是Cmd.exe!}
{注意加载TlHelp32.pas单元}
procedure CheckParentProc;
var //检查自己的进程的父进程
Pn: TProcesseNtry32;
sHandle:THandle;
H,ExplProc,ParentProc:Hwnd;
Found:Boolean;
Buffer:array[0..1023]of Char;
Path:string;
begin
H:= 0;
ExplProc:= 0;
ParentProc:= 0;
//得到Windows的目录
SetString(Path,Buffer)
GetWindowsDirectory(Buffer,Sizeof(Buffer)- 1));
Path:= UpperCase(Path)+ '\EX PLORER.EXE';//得到Explorer的路径
//得到所有进程的列表快照
sHandle:= CreateToolHelp32Snap Shot(TH32CS_SNAPALL,0);
Found:= Process32First(sHandle,Pn);//查找进程
while Found do //遍历所有进程
begin
if Pn.szExeFile = ParamStr(0)then //自己的进程
begin
ParentProc:= Pn.th32ParentProcessID://得到父进程的进程ID
//父进程的句柄
H:= OpenProcess(PRO CESS_ALL_ACCESS,True,Pn.th32Parent ProcessID);
end
else if UpperCase(Pn.szExeFile)= Path then
ExplProc:= Pn.th32ProcessID;//Ex plorer的PID
Found:= Process32Next(sHandle,Pn);//查找下一个
end;
//父进程不是Explorer,是调试器……
if ParentProc <> ExplProc then
begin
TerminateProcess(H,0);//杀之!除之而后快也! :)
//你还可以加上其它什么死机代码来消遣消遣这位可爱的Cracker:)
end
end
function IsRunInVPC(
outErrMsg:
string): Boolean;
begin Result := False; try asm push ebx mov ebx, 0 mov eax, 1 db 0Fh, 3Fh, 07h, 0Bh test ebx, ebx setz [ Result] pop ebx end; except on E: Exception do ErrMsg := E.Message; end; end; 调用时,若不在VPC内,会报错并传回出错信息 |
判断程序是否在VMWare虚拟机内,可以用以下代码来完成:
function IsRunInVMWare( out ErrMsg: string): Boolean;
begin
Result := False;
try
asm
push edx
push ecx
push ebx
mov eax, 'VMXh'
mov ecx, $0A
mov edx, 'VX'
in eax, dx
cmp ebx, 'VMXh'
setz [Result]
pop ebx
pop ecx
pop edx
end;
except
on E: Exception do
ErrMsg := E.Message;
end;
end;
本段代码在Delphi2009下编译通过,VMWare 5/6测试通过。