|
作者: Winmillion [winmillion] 论坛用户 | 登录 |
知其然,知其所以然,希望大家觉得有用,大家可以用在自己程序中查看自己的程序是否被调试..同时为了更好的了解一些游戏无法用OD调试的原因 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); end; |
地主 发表时间: 09-03-09 21:14 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号