飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 4527|回复: 6

[分享] 游戏是如何检测到有OD等调试工具的

[复制链接]
  • TA的每日心情
    开心
    2019-3-25 14:18
  • 签到天数: 881 天

    [LV.10]以坛为家III

    发表于 2016-1-29 23:33:55 | 显示全部楼层 |阅读模式
    本帖最后由 GeekCat 于 2016-1-29 23:39 编辑

    原文链接:http://www.cnblogs.com/huhu0013/archive/2011/03/31/2000716.html

    知其然,知其所以然,希望大家觉得有用,大家可以用在自己程序中查看自己的程序是否被调试..同时为了更好的了解一些游戏无法用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;


    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    昨天 06:37
  • 签到天数: 2490 天

    [LV.Master]伴坛终老

    发表于 2016-1-30 02:52:10 | 显示全部楼层
    很精彩的编程,楼主大才啊
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 09:27
  • 签到天数: 2091 天

    [LV.Master]伴坛终老

    发表于 2016-1-30 07:57:25 | 显示全部楼层
    谢谢楼主分享,学习新知识
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    昨天 09:11
  • 签到天数: 958 天

    [LV.10]以坛为家III

    发表于 2016-1-30 09:40:17 | 显示全部楼层
    哦。。很早就看过了
    PYG19周年生日快乐!
  • TA的每日心情

    2022-5-20 13:32
  • 签到天数: 235 天

    [LV.7]常住居民III

    发表于 2016-1-30 17:30:47 | 显示全部楼层
    不错,感谢分享
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2019-3-1 23:51
  • 签到天数: 559 天

    [LV.9]以坛为家II

    发表于 2016-1-30 20:30:35 | 显示全部楼层
    谢谢楼主分享,前排膜拜一下。
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-3-29 14:47
  • 签到天数: 175 天

    [LV.7]常住居民III

    发表于 2019-12-3 22:28:56 | 显示全部楼层
    谢谢楼主分享,学习新知识
    PYG19周年生日快乐!
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表