吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 11670|回复: 15
收起左侧

[分享] Anti-Debug检测int3断点源码

  [复制链接]
JoyChou 发表于 2013-4-23 19:54
本帖最后由 JoyChou 于 2013-5-9 13:10 编辑

今天看到zxcfvasd发了一篇关于int检测的CM文章
然后给大家分享下怎么实现的。

这里用VS写了一个内嵌的汇编代码
C代码:
[C++] 纯文本查看 复制代码
#include <windows.h>
  
BOOL DetectFuncBreakpoints();
  
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd )
{
  
    if (DetectFuncBreakpoints())
    {
        MessageBox(NULL, "检测到int3断点", "结果", MB_OK);
        return 0;
    }
    else
    {
        MessageBox(NULL, "没有检测到int3断点", "结果", MB_OK);
    }
  
    return 0;
}
  
BOOL DetectFuncBreakpoints()
{
    BOOL bFoundOD;
    bFoundOD=FALSE;
    DWORD dwAddr;
    dwAddr = (DWORD)GetProcAddress(LoadLibrary("user32.dll"),"MessageBoxA"); //将FARPROC类型转换成DWORD
    __asm
    {
            cld               ;检测代码开始
            mov     edi,dwAddr
            mov     ecx,100  ;100bytes
            mov     al,0CCH ;字母前面必须有0
            repne   scasb
            jnz     ODNotFound
            mov bFoundOD,1
ODNotFound:             
    }
    return bFoundOD;
}


再发一个win32汇编写的吧
[C++] 纯文本查看 复制代码
;检测时,BP MessageBoxA
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
            
            .const
szKernelDll  db        'user32.dll',0
szAPIMessbox db        'MessageBoxA',0
szCaption    db        '结果',0
szFound       db        '发现API断点',0
szNotFound   db        '未发现断点',0
            .code
start: 
           invoke   GetModuleHandle,addr szKernelDll
           invoke   GetProcAddress,eax,addr szAPIMessbox  ;API地址
                       
           cld               ;检测代码开始
           mov     edi,eax   ;API开始位置
           mov     ecx,100H  ;检测100字节
           mov     al, 55H 
           xor     al, 99H   ;55和99异或等于0xCC
           repne   scasb     
           cmp     ecx, 0h         
           jnz      debugger_found       
                                      
       invoke  MessageBox,NULL,addr szNotFound,addr szCaption,MB_OK
           jmp     exit
debugger_found: invoke  MessageBox,NULL,addr szFound,addr szCaption,MB_OK
          exit: invoke  ExitProcess,NULL
                end start


首先我们得知道一个问题,当用OD调试的时候,我们F2或者下bp断点的时候,即是下int3断点
OD载入分析:
比如我们在00401000 F2下断,此时应该00401000地址应该是CC 18204000
因为OD做了对int3的隐藏,我们看到的还是是68,而不是我们下断时的CC,当然这也是为了我们方便。

说这么多是为了理解00401021  |.  F2:AE         repne scas byte ptr es:[edi] 这句话
因为当[edi]等于我们下断的时,此时数据窗口并不等于CC。
这也是我调试的觉得有点困惑的地方,分享一下。

[C] 纯文本查看 复制代码
00401000 >/$  68 18204000   push APISoftB.00402018                   ; /pModule = "user32.dll"
00401005  |.  E8 5A000000   call <jmp.&KERNEL32.GetModuleHandleA>    ; \GetModuleHandleA
0040100A  |.  68 23204000   push APISoftB.00402023                   ; /ProcNameOrOrdinal = "MessageBoxA"
0040100F  |.  50            push eax                                 ; |hModule
00401010  |.  E8 55000000   call <jmp.&KERNEL32.GetProcAddress>      ; \GetProcAddress
00401015  |.  FC            cld
00401016  |.  8BF8          mov edi,eax
00401018  |.  B9 00010000   mov ecx,0x100
0040101D  |.  B0 55         mov al,0x55
0040101F  |.  34 99         xor al,0x99
00401021  |.  F2:AE         repne scas byte ptr es:[edi]
000401023  |.  83F9 00       cmp ecx,0x0                              ;  ecx不等于0表示检测到int3断点
00401026  |.  75 15         jnz short APISoftB.0040103D
00401028  |.  6A 00         push 0x0                                 ; /Style = MB_OK|MB_APPLMODAL
0040102A  |.  68 2F204000   push APISoftB.0040202F                   ; |Title = "结果"
0040102F  |.  68 40204000   push APISoftB.00402040                   ; |Text = "未发现断点"
00401034  |.  6A 00         push 0x0                                 ; |hOwner = NULL
00401036  |.  E8 1D000000   call <jmp.&USER32.MessageBoxA>           ; \MessageBoxA
0040103B  |.  EB 13         jmp short APISoftB.00401050
0040103D  |>  6A 00         push 0x0                                 ; /Style = MB_OK|MB_APPLMODAL
0040103F  |.  68 2F204000   push APISoftB.0040202F                   ; |Title = "结果"
00401044  |.  68 34204000   push APISoftB.00402034                   ; |Text = "发现API断点"
00401049  |.  6A 00         push 0x0                                 ; |hOwner = NULL
0040104B  |.  E8 08000000   call <jmp.&USER32.MessageBoxA>           ; \MessageBoxA
00401050  |>  6A 00         push 0x0                                 ; /ExitCode = 0
00401052  \.  E8 07000000   call <jmp.&KERNEL32.ExitProcess>         ; \ExitProcess


对代码段的int3检测
[C++] 纯文本查看 复制代码
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
    PIMAGE_DOS_HEADER pDosHeader;
    PIMAGE_NT_HEADERS32 pNtHeaders;
    PIMAGE_SECTION_HEADER pSectionHeader;
    DWORD dwBaseImage = (DWORD)GetModuleHandle(NULL); //获取当前进程的基址
   
   
    pDosHeader = (PIMAGE_DOS_HEADER)dwBaseImage;
    pNtHeaders = (PIMAGE_NT_HEADERS32)((DWORD)pDosHeader + pDosHeader->e_lfanew);
    pSectionHeader = (PIMAGE_SECTION_HEADER)((DWORD)pNtHeaders + sizeof(pNtHeaders->Signature) + sizeof(IMAGE_FILE_HEADER) + 
    (WORD)pNtHeaders->FileHeader.SizeOfOptionalHeader);
       
    DWORD dwAddr = pSectionHeader->VirtualAddress + dwBaseImage; //获取代码段在内存中的地址
    DWORD dwCodeSize = pSectionHeader->SizeOfRawData;    //获取代码段对齐后的大小
    BOOL bFound = FALSE;
   
    __asm
    {
            cld               ;检测代码开始
            mov     edi,dwAddr
            mov     ecx,10h ;检测0x10个字节测试,原则应该是dwCodeSize大小
            mov     al,0CCH ;字母前面必须有0
            repne   scasb
            jnz     NotFound
            mov bFound,1
NotFound:             
    }
    if (bFound)
    {
        MessageBoxA(NULL, "检测到断点", "结果", 0);
    } 
    else
    {
        MessageBoxA(NULL, "没有检测到断点", "结果", 0);
    }
    return 0;
   
}

最后说下原理:
先得到函数的地址,设置一个检测的字节长度(我这里设的0x100),然后就一直搜索0xCC,如果发现了就表示检测到了。反之亦然。
不过只能检测bp断点和F2(int3断点),硬件等断点是检测不到的,硬件断点可以用CONTEXT结构体里面的iDr0,iDr1,iDr2,iDr3成员检测,这里就不多说了。

跳过检测方法:
1、修改检测时的跳转
2、下 hr等强点的断点

网上很多关于int3检测的资料,所以大家想学习的善于利用好搜索功能能学到很多东西的。

免费评分

参与人数 3吾爱币 +1 热心值 +3 收起 理由
52pojie老高 + 1 + 1 感谢代码分享
Winmu + 1 谢谢@Thanks!
Chief + 1 欢迎分析讨论交流,[吾爱破解论坛]有你更精.

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

混小子 发表于 2013-4-23 19:59
感谢楼主分享代码。。。
real金龟子 发表于 2013-4-23 20:07
 楼主| JoyChou 发表于 2013-4-23 20:10
real金龟子 发表于 2013-4-23 20:07
前来膜拜。。。学习了!

金龟子大大辛苦了
leeyeah93 发表于 2013-4-23 20:11
感谢楼主分享
头像被屏蔽
bambooqj 发表于 2013-4-23 20:18
提示: 作者被禁止或删除 内容自动屏蔽
 楼主| JoyChou 发表于 2013-4-23 20:39
bambooqj 发表于 2013-4-23 20:18
前排膜拜技术贴。。。

只是混个脸熟
daiandy 发表于 2013-4-24 16:46
我有时候下硬件执行也被检测了
 楼主| JoyChou 发表于 2013-4-24 18:32
daiandy 发表于 2013-4-24 16:46
我有时候下硬件执行也被检测了

怎么会呢
sunflover 发表于 2013-4-26 10:55
前排支持围观,话说VMP处理一下关键位置,CC检测也相当了得。不知道硬件断点如何检测,求楼主爆料,我等菜鸟好学习
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-18 04:32

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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