反调试方法---0xCC检测--检验API断点实现反调试

反调试

0xCC检测

软件断点的原理:调试器在对应设置断点的位置上修改该地址的字节为0xCC。若是关键位置检测到该指令,可以判断进程处于调试状态。

0xCC既可以是INT 3指令,也可以是其他指令的操作数。

API断点

API断点一般下在API的首地址处或函数返回地址处。检查这些易被下端的地址首字节是否为0xCC就可以判断程序是否正在被调试

检验代码(以MessageBoxA函数为例):

#include <Windows.h>
#include<iostream>
using namespace std;
int main() {
	FARPROC addr = GetProcAddress(LoadLibrary(L"user32.dll"), "MessageBoxA");
	byte byteaddr = *(byte*)addr;
	MessageBoxA(NULL, "context", "title", MB_OK);

	if (byteaddr == 0xCC)
	{
		printf("检测到调试");
	}
	else {
		printf("无调试");
	}
	return 0;
}

检验方式(x32dbg中):加载文件–>查看符号–>点击原程序所在的模块–>在调用函数窗口搜索MessageBoxA函数–>下断点。之后进行调试。会输出“检测到调试”

出现的问题:验证MessageBoxW函数时,所用代码:

int main() {
	PBYTE byteaddr = (PBYTE)MessageBoxW;
	MessageBoxW(NULL, L"context", 0, MB_OK);
	if (*byteaddr == 0xCC)
	{
		printf("检测到调试");
	}
	else {
		printf("无调试");
	}
	return 0;
}

在OD里调试时,关键汇编语句:

003C1054 | 803E CC                  | cmp byte ptr ds:[esi],CC  
003C1057 | B9 18213C00              | mov ecx,project1.3C2118 
003C105C | B8 28213C00              | mov eax,project1.3C2128  
003C1061 | 0F44C1                   | cmove eax,ecx       
003C1064 | 50                       | push eax                
003C1065 | E8 A6FFFFFF              | call <project1._printf> 

其中,cmove语句的用法:

;如果eax和ebx相等,则会将edx复制到ecx
cmp eax,abx
cmove ecx,edx

;相当于:
cmp eax,ebx
jne skip
	mov ecx,edx
skip:

出问题的点:给MessageBoxW函数下断之后进行调试,调试到下面这个语句(即与0xCC比较)的时候,byte ptr ds:[esi]=8B,并不等于0xCC。按理说 值不等于0xCC,应该返回“未检查到调试”,但是继续调试,打印出来的内容还是检测到调试。

也就是过程上出了问题,但是结果还是正确的。==稍微有点难以接受=。(希望找到解决办法的同学可以指点一二

003C1054 | 803E CC                  | cmp byte ptr ds:[esi],CC  ;[esi] = 8B

把断点去掉,调试,输出的内容是“无调试”。

反反调试:

在需要下断点的API函数的中间部位下断点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值