反调试技术,Delphi版

1.程序窗口句柄检测

原理:用FindWindow函数查找具有相同窗口类名和标题的窗口,如果找到就说明有OD在运行

//********************************************

//通过查找窗口类名来实现检测OllyDBG

//********************************************

function AntiLoader():Boolean;

const

OllyName='OLLYDBG';

var

Hwnd:Thandle;

begin

Hwnd:=FindWindow(OllyName,nil);

if Hwnd<>0 then

Result:=True

else

Result:=False;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

if AntiLoader then

MessageBox(Handle,'找到调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未找到调试器!','提示',MB_OK+MB_ICONINFORMATION)

end;

2.用线程环境块检测

原理:用ring3级下的调试器对可执行程序进行调试时,调试器会把被调试的可执行程序作为一个子线程进行跟踪.这时被调试的可执行程序的PEB结构偏移0x02处的BeingDebugged的值为1,如果可执行程序未被调试,则值为0,所以可以利用这个值来检测程序是否被ring3级下的调试器调试

//***************************************

//使用PEB结构检测OllyDBG

//***************************************

function AntiLoader():Boolean; //检测调试器;

var

YInt,NInt:Integer;

begin

asm

mov eax,fs:[$30]

//获取PEB偏移2h处BeingDebugged的值

movzx eax,byte ptr[eax+$2]

or al,al

jz @No

jnz @Yes

@No:

mov NInt,1

@Yes:

Mov YInt,1

end;

if YInt=1 then

Result:=True;

if NInt=1 then

Result:=False;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK+MB_ICONINFORMATION);

end;

3.用API函数IsDebuggerPresent检测

原理:操作系统将调试对象设置为在特殊环境中运行,而kernel32.dll中的API函数IsDebuggerPresent的功能是用于判断进程是否处于调试环境中,这样就可以利用这个API函数来查看进程是否在调试器中执行

//****************************************

//利用IsDebuggerPresent函数检测OllyDBG

//****************************************

function AntiLoader():Boolean;

var

isDebuggerPresent: function:Boolean;

Addr: THandle;

begin

Addr := LoadLibrary('kernel32.dll');

isDebuggerPresent := GetProcAddress(Addr, 'IsDebuggerPresent');

if isDebuggerPresent then

Result:=True

else

Result:=False;

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现提示器!','提示',MB_OK+MB_ICONINFORMATION);

end;

4.检查程序的父进程

原理:Windows操作系统下的GUI可执行程序的父进程都是explorer.exe(CUI可执行程序的父进程是CMD.exe,系统服务的父进程是Service.exe,在实际使用的时候需要根据自己的程序类型来选择父进程实现反跟踪),而正被调试器OD调试的程序的父进程是调试器的执行程序ollydbg.exe而不是别的.所以可以利用检查父进程是否为explorer.exe的方法来检测OD.

//***************************************************

//检查父进程来检测OllyDBG

//***************************************************

function AntiLoader():Boolean;

const

ParentName='/EXPLORER.EXE';

var

hSnap,hProcess:THandle;

szBuffer:array[0..MAX_PATH] of char;

FileName:array[0..MAX_PATH] of char;

Process32:PROCESSENTRY32;

LoopFlag:BOOL;

begin

////得到所有进程的列表快照

hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);

if hSnap=INVALID_HANDLE_VALUE then

begin

Result:=False;

Exit;

end;

Process32.dwSize:=sizeof(PROCESSENTRY32);

//查找进程

LoopFlag:=Process32First(hSnap,Process32);

if LoopFlag=False then

begin

CloseHandle(hSnap);

Result:=False;

Exit;

end;

while Integer(LoopFlag)<>0 do

begin

if Process32.th32ProcessID=GetCurrentProcessId() then

begin

hProcess:=OpenProcess(PROCESS_ALL_ACCESS,FALSE,Process32.th32ParentProcessID);

if hProcess<>0 then

begin

if GetModuleFileNameEx(hProcess,0,FileName,MAX_PATH)<>0 then

begin

//取得系统目录

GetWindowsDirectory(szBuffer,MAX_PATH);

//合并系统目录和/EXPLORER.EXE

StrCat(szBuffer,ParentName);

//转换成大写以后比较当前调试程序的进程是否为父进程

if UpperCase(String(FileName))<>UpperCase(String(szBuffer)) then

Result:=True

else

Result:=False;

end;

end

else

Result:=False;

end;

LoopFlag:=Process32Next(hSnap,Process32);

end;

CloseHandle(hSnap);

end;

procedure TForm1.FormCreate(Sender: TObject);

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK+MB_ICONINFORMATION)

end;

5.检查STARTUPINFO结构

原理:Windows操作系统中的explorer.exe创建进程的时候会把STARTUPINFO结构中的值设为0,而非explorer.exe创建进程的时候会忽略这个结构中的值,也就是结构中的值不为0,所以可以利用这个来判断OD是否在调试程序.

/************************************************

//通过检测STARTUPINFO结构来检测OllyDbg

//************************************************

function AntiLoader():Boolean;

var

Info:STARTUPINFO;

begin

GetStartupInfo(Info);

if (Info.dwX<>0) or (Info.dwY<>0) or (Info.dwXCountChars<>0) or (Info.dwYCountChars<>0) or

(Info.dwFillAttribute<>0) or (Info.dwXSize<>0) or (Info.dwYSize<>0) then

Result:=True

else

Result:=False;

end;

procedure TMainFrm.FormCreate(Sender: TObject);

begin

if AntiLoader then

MessageBox(Handle,'发现调试器!','提示',MB_OK)

else

MessageBox(Handle,'未发现调试器!','提示',MB_OK);

http://blog.csdn.net/jiangxinyu/article/details/5348468