Posted on 2009-10-14 15:01
S.l.e!ep.¢% 閱讀(404)
評論(0) 編輯 收藏 引用 所屬分類:
Crack
1.程序窗口句柄檢測
原理:用FindWindow函數(shù)查找具有相同窗口類名和標(biāo)題的窗口,如果找到就說明有OD在運(yùn)行
//********************************************
//通過查找窗口類名來實(shí)現(xiàn)檢測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,'找到調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
else
??? MessageBox(Handle,'未找到調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
end;
2.用線程環(huán)境塊檢測
原理:用ring3級下的調(diào)試器對可執(zhí)行程序進(jìn)行調(diào)試時,調(diào)試器會把被調(diào)試的可執(zhí)行程序作為一個子線程進(jìn)行跟蹤.這時被調(diào)試的可執(zhí)行程序的PEB結(jié)構(gòu)偏移0x02處的BeingDebugged的值為1,如果可執(zhí)行程序未被調(diào)試,則值為0,所以可以利用這個值來檢測程序是否被ring3級下的調(diào)試器調(diào)試
//***************************************
//使用PEB結(jié)構(gòu)檢測OllyDBG
//***************************************
function AntiLoader():Boolean; //檢測調(diào)試器;
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,'發(fā)現(xiàn)調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
else
??? MessageBox(Handle,'未發(fā)現(xiàn)調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION);
end;
3.用API函數(shù)IsDebuggerPresent檢測
原理:操作系統(tǒng)將調(diào)試對象設(shè)置為在特殊環(huán)境中運(yùn)行,而kernel32.dll中的API函數(shù)IsDebuggerPresent的功能是用于判斷進(jìn)程是否處于調(diào)試環(huán)境中,這樣就可以利用這個API函數(shù)來查看進(jìn)程是否在調(diào)試器中執(zhí)行
//****************************************
//利用IsDebuggerPresent函數(shù)檢測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,'發(fā)現(xiàn)調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
else
??? MessageBox(Handle,'未發(fā)現(xiàn)提示器!','提示',MB_OK+MB_ICONINFORMATION);
end;
4.檢查程序的父進(jìn)程
原理:Windows操作系統(tǒng)下的GUI可執(zhí)行程序的父進(jìn)程都是explorer.exe(CUI可執(zhí)行程序的父進(jìn)程是CMD.exe,系統(tǒng)服務(wù)的父進(jìn)程是Service.exe,在實(shí)際使用的時候需要根據(jù)自己的程序類型來選擇父進(jìn)程實(shí)現(xiàn)反跟蹤),而正被調(diào)試器OD調(diào)試的程序的父進(jìn)程是調(diào)試器的執(zhí)行程序ollydbg.exe而不是別的.所以可以利用檢查父進(jìn)程是否為explorer.exe的方法來檢測OD.
//***************************************************
//檢查父進(jìn)程來檢測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
////得到所有進(jìn)程的列表快照
hSnap:=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if hSnap=INVALID_HANDLE_VALUE then
begin
??? Result:=False;
??? Exit;
end;
Process32.dwSize:=sizeof(PROCESSENTRY32);
//查找進(jìn)程
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
????????????????? //取得系統(tǒng)目錄
????????????????? GetWindowsDirectory(szBuffer,MAX_PATH);
????????????????? //合并系統(tǒng)目錄和\EXPLORER.EXE
????????????????? StrCat(szBuffer,ParentName);
????????????????? //轉(zhuǎn)換成大寫以后比較當(dāng)前調(diào)試程序的進(jìn)程是否為父進(jìn)程
????????????????? 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,'發(fā)現(xiàn)調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
else
??? MessageBox(Handle,'未發(fā)現(xiàn)調(diào)試器!','提示',MB_OK+MB_ICONINFORMATION)
end;
5.檢查STARTUPINFO結(jié)構(gòu)
原理:Windows操作系統(tǒng)中的explorer.exe創(chuàng)建進(jìn)程的時候會把STARTUPINFO結(jié)構(gòu)中的值設(shè)為0,而非explorer.exe創(chuàng)建進(jìn)程的時候會忽略這個結(jié)構(gòu)中的值,也就是結(jié)構(gòu)中的值不為0,所以可以利用這個來判斷OD是否在調(diào)試程序.
/************************************************
//通過檢測STARTUPINFO結(jié)構(gòu)來檢測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,'發(fā)現(xiàn)調(diào)試器!','提示',MB_OK)
else
??? MessageBox(Handle,'未發(fā)現(xiàn)調(diào)試器!','提示',MB_OK);