CC断点检测

前言

以前看过CC断点的检测原理.
今天做脱壳练习时, 居然看到cm中有一个fnMessageBox函数中进行了CC断点检测.

记录

cm中的实际函数

00FAF476 <fnMessageBoxEx>      55              push    ebp
00FAF477                       8BEC            mov     ebp, esp
00FAF479                       51              push    ecx
00FAF47A                       53              push    ebx
00FAF47B                       56              push    esi
00FAF47C                       57              push    edi
00FAF47D                       60              pushad
00FAF47E                       8B15 7420FE00   mov     edx, dword ptr [FE2074]     ; kernel32.7C8092CA
00FAF484                       83C2 64         add     edx, 64
00FAF487                       FFD2            call    edx                         ; getTickCount, but not used result
00FAF489                       8B15 3020FE00   mov     edx, dword ptr [FE2030]     ; USER32.77D50786
00FAF48F                       83C2 64         add     edx, 64                     ; MessageBox
00FAF492                       B9 05000000     mov     ecx, 5
00FAF497                       803A CC         cmp     byte ptr [edx], 0CC
00FAF49A                       74 10           je      short <L_END>               ; find CC breakpoint
00FAF49C                     ^ E2 F9           loopd   short 00FAF497              ; check cc breakpoint 5 times
00FAF49E <L_CALL_ORG_FN>       FF75 14         push    dword ptr [ebp+14]
00FAF4A1                       FF75 10         push    dword ptr [ebp+10]
00FAF4A4                       FF75 0C         push    dword ptr [ebp+C]
00FAF4A7                       FF75 08         push    dword ptr [ebp+8]
00FAF4AA                       FFD2            call    edx                         ; call org MessageBox
00FAF4AC <L_END>               8945 FC         mov     dword ptr [ebp-4], eax      ; [ebp - 4] is local value iRc
00FAF4AF                       61              popad
00FAF4B0                       8B45 FC         mov     eax, dword ptr [ebp-4]
00FAF4B3                       5F              pop     edi
00FAF4B4                       5E              pop     esi
00FAF4B5                       5B              pop     ebx
00FAF4B6                       C9              leave
00FAF4B7                       C2 1000         retn    10

还原的CC断点检测

// CheckCcBp.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <CONIO.H>

int __stdcall MessageBoxA_ByAntiDebug( IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);
typedef int (__stdcall * PFN_MessageBoxA)( IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType);

#define API_INDEX_MessageBox 0
#define KEY_dwAryOrgApiAddr 0x64
DWORD g_dwAryOrgApiAddr[1] = {0};

int main(int argc, char* argv[])
{
    HMODULE hDll = NULL;
    PFN_MessageBoxA pfnMessageBox = NULL;

    // 先保存原始api地址, 这里模拟一下, 不要求和cm中相同
    hDll = LoadLibraryA("user32.dll");
    g_dwAryOrgApiAddr[API_INDEX_MessageBox] = (DWORD)GetProcAddress(hDll, "MessageBoxA") - KEY_dwAryOrgApiAddr;

    // MessageBoxA入口被下了CC断点时, 就不执行原始函数
    MessageBoxA_ByAntiDebug(NULL, NULL, NULL, NULL);

    system("pause");
    return 0;
}

int __stdcall MessageBoxA_ByAntiDebug( IN HWND hWnd, IN LPCSTR lpText, IN LPCSTR lpCaption, IN UINT uType)
{
    int iRc = 0;
    DWORD dwFunAddr = g_dwAryOrgApiAddr[API_INDEX_MessageBox] + KEY_dwAryOrgApiAddr; 
    if (0xcc != *(BYTE*)(dwFunAddr)) {
        iRc = ((PFN_MessageBoxA)dwFunAddr)(hWnd, lpText, lpCaption, uType);
    }

    return iRc;
}

/** cm's cc breeakpoint check
00FAF476 <fnMessageBoxEx>      55              push    ebp
00FAF477                       8BEC            mov     ebp, esp
00FAF479                       51              push    ecx
00FAF47A                       53              push    ebx
00FAF47B                       56              push    esi
00FAF47C                       57              push    edi
00FAF47D                       60              pushad
00FAF47E                       8B15 7420FE00   mov     edx, dword ptr [FE2074]     ; kernel32.7C8092CA
00FAF484                       83C2 64         add     edx, 64
00FAF487                       FFD2            call    edx                         ; getTickCount, but not used result
00FAF489                       8B15 3020FE00   mov     edx, dword ptr [FE2030]     ; USER32.77D50786
00FAF48F                       83C2 64         add     edx, 64                     ; MessageBox
00FAF492                       B9 05000000     mov     ecx, 5
00FAF497                       803A CC         cmp     byte ptr [edx], 0CC
00FAF49A                       74 10           je      short <L_END>               ; find CC breakpoint
00FAF49C                     ^ E2 F9           loopd   short 00FAF497              ; check cc breakpoint 5 times
00FAF49E <L_CALL_ORG_FN>       FF75 14         push    dword ptr [ebp+14]
00FAF4A1                       FF75 10         push    dword ptr [ebp+10]
00FAF4A4                       FF75 0C         push    dword ptr [ebp+C]
00FAF4A7                       FF75 08         push    dword ptr [ebp+8]
00FAF4AA                       FFD2            call    edx                         ; call org MessageBox
00FAF4AC <L_END>               8945 FC         mov     dword ptr [ebp-4], eax      ; [ebp - 4] is local value iRc
00FAF4AF                       61              popad
00FAF4B0                       8B45 FC         mov     eax, dword ptr [ebp-4]
00FAF4B3                       5F              pop     edi
00FAF4B4                       5E              pop     esi
00FAF4B5                       5B              pop     ebx
00FAF4B6                       C9              leave
00FAF4B7                       C2 1000         retn    10
*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值