断点检测学习

突然看到了一种反调试的手段,检测api函数的首字节是否为0xcc,即int 3类型的断点,来反调试,尝试一下

#include<stdio.h>
#include<stdlib.h>
void fun(int a) {
	a++;
	a--;
	a += 5;
	a -= 5;
	return;
}
int main() {
	void (*ptr)(int) = NULL;
	ptr = fun;
	int i =0; 
	char *arr=(char*)(ptr);
	for (i = 0; i < 99; i++) {
		printf("0x%2x\t", arr[i]);
	}
	return 0;
}

最开始的时候就遇到了一个问题,我用的virtual studio ,但是这是c++编译的,导致最后的函数指针不是指向的fun函数,这里可以很清楚的看到。

额,不太清楚编译的原理,那我用纯c,直接用devc++,里面有自带的gcc编译器

然后就和我预想的一样了,fun就是那个函数指针,在fun里多打一点断点(有个问题,为什么fun函数编译出来会有个nop,不是很懂)

执行结果上面就有预期的0xCC了,可见,ida确实是用的int 3断点

这种方法很简单,也很容易绕过,我们来看一下硬件断点,硬件断点基于DRx寄存器,换句话说,可以通过检测DRx寄存器来检测硬件断点

可以通过SetThreadContext直接设置指定线程的调试寄存器

DRx寄存器可以直接操作,但是需要设置特权级CPL等于0,这里采用比较简单的方法,直接用GetThreadContext获取当前线程的上下文

我一共下了3个硬件断点,执行结果如下

可见,确实用DRx寄存器来设置了硬件断点,而该程序正常执行情况(没有断点)如下

#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>
const char *strr = (const char*)"hello touful";
int main()
{   
    printf("enter\n");
    //获取当前线程的句柄
    HANDLE hThread = GetCurrentThread();

    //创建一个CONTEXT结构体
    CONTEXT threadContext;
    threadContext.ContextFlags = CONTEXT_ALL;

    //获取当前线程的运行上下文
    if (!GetThreadContext(hThread, &threadContext))
    {
        printf("GetThreadContext failed\n");
        return 0;
    }
    printf("DRO = 0x%x\n", threadContext.Dr0);
    printf("DR1 = 0x%x\n", threadContext.Dr1);
    printf("DR2 = 0x%x\n", threadContext.Dr2);
    printf("DR3 = 0x%x\n", threadContext.Dr3);
    printf("exit\n");
    return 0;
}


这里顺便贴出CONTEXT结构体的定义

typedef struct DECLSPEC_NOINITALL _CONTEXT {

    //
    // The flags values within this flag control the contents of
    // a CONTEXT record.
    //
    // If the context record is used as an input parameter, then
    // for each portion of the context record controlled by a flag
    // whose value is set, it is assumed that that portion of the
    // context record contains valid context. If the context record
    // is being used to modify a threads context, then only that
    // portion of the threads context will be modified.
    //
    // If the context record is used as an IN OUT parameter to capture
    // the context of a thread, then only those portions of the thread's
    // context corresponding to set flags will be returned.
    //
    // The context record is never used as an OUT only parameter.
    //

    DWORD ContextFlags;

    //
    // This section is specified/returned if CONTEXT_DEBUG_REGISTERS is
    // set in ContextFlags.  Note that CONTEXT_DEBUG_REGISTERS is NOT
    // included in CONTEXT_FULL.
    //

    DWORD   Dr0;
    DWORD   Dr1;
    DWORD   Dr2;
    DWORD   Dr3;
    DWORD   Dr6;
    DWORD   Dr7;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_FLOATING_POINT.
    //

    FLOATING_SAVE_AREA FloatSave;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_SEGMENTS.
    //

    DWORD   SegGs;
    DWORD   SegFs;
    DWORD   SegEs;
    DWORD   SegDs;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_INTEGER.
    //

    DWORD   Edi;
    DWORD   Esi;
    DWORD   Ebx;
    DWORD   Edx;
    DWORD   Ecx;
    DWORD   Eax;

    //
    // This section is specified/returned if the
    // ContextFlags word contians the flag CONTEXT_CONTROL.
    //

    DWORD   Ebp;
    DWORD   Eip;
    DWORD   SegCs;              // MUST BE SANITIZED
    DWORD   EFlags;             // MUST BE SANITIZED
    DWORD   Esp;
    DWORD   SegSs;

    //
    // This section is specified/returned if the ContextFlags word
    // contains the flag CONTEXT_EXTENDED_REGISTERS.
    // The format and contexts are processor specific
    //

    BYTE    ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];

} CONTEXT;

对于内存断点,是以页的方式添加的,设置页的权限位就行了,最常用的两种断点实现了最常用的检测方式

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值