吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1511|回复: 14
收起左侧

[C&C++ 原创] Dll劫持 -- 硬件断点的实现

  [复制链接]
wtujoxk 发表于 2024-7-25 17:53
本帖最后由 wtujoxk 于 2024-7-25 19:19 编辑

前言,这是菜鸟学习Dll劫持硬件断点的过程,参考了几篇文章

下面帖上我学习的完整类:HwBreakpoint.cpp
[C++] 纯文本查看 复制代码
#include "HwBreakpoint.h"

// 保存所有下断点的线程ID和相应寄存器
std::vector<HwBreakpoint> hwbrk;
void SetBits(DWORD_PTR& dw, int lowBit, int bits, int newValue)
{
        DWORD_PTR mask = (1 << bits) - 1;
        dw = (dw & ~(mask << lowBit)) | (newValue << lowBit);
}

// 设置硬件断点,在线程里调用
int RunHwBreakpoint(HANDLE HThread, HWBRK_TYPE Type, HWBRK_SIZE Size, ULONGLONG breakpoint)
{
        SuspendThread(HThread);
        CONTEXT context = { 0 };
        context.ContextFlags = CONTEXT_ALL;
        GetThreadContext(HThread, &context);
        // 找到一个空闲的调试寄存器
        int drIndex = -1, st = 0, le = 0;
        for (int i = 0; i < 4; ++i) {
                if ((context.Dr7 & (3 << (16 + i * 2))) == 0) {
                        drIndex = i;
                        break;
                }
        }
        if (drIndex == -1) return -1; // 没有空闲的调试寄存器

        //std::cout << "drIndex:" << drIndex << std::endl;
        if (drIndex == 0)context.Dr0 = breakpoint;
        if (drIndex == 1)context.Dr1 = breakpoint;
        if (drIndex == 2)context.Dr2 = breakpoint;
        if (drIndex == 3)context.Dr3 = breakpoint;

        if (Type == HWBRK_TYPE_CODE)       st = 0;
        if (Type == HWBRK_TYPE_READWRITE)  st = 3;
        if (Type == HWBRK_TYPE_WRITE)      st = 1;

        if (Size == HWBRK_SIZE_1)          le = 0;
        if (Size == HWBRK_SIZE_2)          le = 1;
        if (Size == HWBRK_SIZE_4)          le = 3;
        if (Size == HWBRK_SIZE_8)          le = 2;
        SetBits(context.Dr7, 16 + drIndex * 4, 2, st);  // 读取、写入、执行
        SetBits(context.Dr7, 18 + drIndex * 4, 2, le);  // 1、2、4、8字节
        SetBits(context.Dr7, drIndex * 2, 1, 1);        //
        SetThreadContext(HThread, &context);
        ResumeThread(HThread);
        HwBreakpoint* h = new HwBreakpoint();
        h->hwbpAddr = breakpoint;
        //h->threadId = GetThreadId(HThread);
        h->iReg = drIndex;
        hwbrk.push_back(*h);
        return 0;
}

DWORD WINAPI BPThreadProc(LPVOID lpParameter)
{
        HwBreakpoint* h = (HwBreakpoint*)lpParameter;
        if (!h)return false;

        if (h->threadId) {
                //方式一:对指定的线程下硬件断点
                HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, false, h->threadId);
                if (hThread)
                {
                        RunHwBreakpoint(hThread, h->Type, h->Size, h->hwbpAddr);  //下硬件断点
                        CloseHandle(hThread);
                        return TRUE;
                }
        }
        else
        {
                //方式二:对所有线程下硬件断点,加壳程序容易出错
                HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, GetCurrentProcessId());
                if (hSnap != INVALID_HANDLE_VALUE)
                {
                        THREADENTRY32 te;
                        te.dwSize = sizeof(THREADENTRY32);
                        if (Thread32First(hSnap, &te))
                        {
                                do
                                {    // 因为线程会挂起,排除自己的线程
                                        if (te.th32OwnerProcessID == GetCurrentProcessId() && te.th32ThreadID != GetCurrentThreadId())
                                        {
                                                //printf("当前进程: %d, 线程: %d, 优先级: %d\n", te.th32OwnerProcessID, te.th32ThreadID, te.tpBasePri);
                                                HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, false, te.th32ThreadID);
                                                if (hThread)
                                                {
                                                        RunHwBreakpoint(hThread, h->Type, h->Size, h->hwbpAddr);  //下硬件断点
                                                        CloseHandle(hThread);
                                                }
                                        }
                                } while (Thread32Next(hSnap, &te));
                        }
                }
                if (hSnap) CloseHandle(hSnap);
        }
        return true;
}

// 设置硬件断点
bool SetHwBreakpoint(int ThreadId, HWBRK_TYPE Type, HWBRK_SIZE Size, ULONGLONG breakpoint)
{
        HwBreakpoint* h = new HwBreakpoint();
        h->threadId = ThreadId;
        h->Type = Type;
        h->Size = Size;
        h->hwbpAddr = breakpoint;

        HANDLE handle = CreateThread(NULL, NULL, BPThreadProc, (LPVOID)h, NULL, NULL);
        if (handle)CloseHandle(handle);

        return true;
}

// 删除硬件断点 DelHwBreakpoint(ExceptionInfo->ContextRecord, 0x123456);
bool DelHwBreakpoint(PCONTEXT context, ULONGLONG breakpoint)
{
        if (hwbrk.empty()) return false;
        for (auto& h : hwbrk)
        {
                if (h.hwbpAddr == breakpoint)
                {
                        //std::cout << "dr7:" << breakpoint << std::endl;
                        int FlagBit = 0;
                        if (h.iReg == 0)
                        {
                                FlagBit = 0;
                                context->Dr0 = 0;
                        }
                        if (h.iReg == 1)
                        {
                                FlagBit = 2;
                                context->Dr1 = 0;
                        }
                        if (h.iReg == 2)
                        {
                                FlagBit = 4;
                                context->Dr2 = 0;
                        }
                        if (h.iReg == 3)
                        {
                                FlagBit = 6;
                                context->Dr3 = 0;
                        }
                        context->Dr7 &= ~(1 << FlagBit);
                        // 删除用过的元素
                        hwbrk.erase(std::find(hwbrk.begin(), hwbrk.end(), h));
                }
        }
        return true;
}


头文件:HwBreakpoint.h
[C++] 纯文本查看 复制代码
#include <windows.h>
#include <vector>
#include <TlHelp32.h>
#include <iostream>

enum HWBRK_TYPE
{
        HWBRK_TYPE_CODE,         // 执行
        HWBRK_TYPE_READWRITE,    // 读
        HWBRK_TYPE_WRITE,        // 写
};

enum HWBRK_SIZE
{
        HWBRK_SIZE_1,
        HWBRK_SIZE_2,
        HWBRK_SIZE_4,
        HWBRK_SIZE_8,
};

class HwBreakpoint
{
public:

        ULONGLONG hwbpAddr;    // 断点位置
        int threadId;          // 线程
        int iReg;              // 第几个寄存器
        HWBRK_TYPE Type;       // 读、写、执行
        HWBRK_SIZE Size;       // 字节
        HwBreakpoint()         // 初始化
        {
                hwbpAddr = 0;
                threadId = 0;
                iReg = 0;
                Type = HWBRK_TYPE_CODE;
                Size = HWBRK_SIZE_1;
        }

        bool operator ==(const HwBreakpoint& p)
        {
                return true;
        }
};

/************************************************************************
SetHwBreakpoint:   设置线程硬件断点
ThreadId:          线程ID,0为所有线程下断,否则指定线程下断
Type:              参考 enum HWBRK_TYPE
Size:              参考 enum HWBRK_SIZE
breakpoint:        断点位置
调用:SetHwBreakpoint(MainThreadId, HWBRK_TYPE_CODE, HWBRK_SIZE_1, bpAddr);
/************************************************************************/
bool SetHwBreakpoint(int ThreadId, HWBRK_TYPE Type, HWBRK_SIZE Size, ULONGLONG breakpoint);

/************************************************************************
DelHwBreakpoint:  删除硬件断点
context:          PCONTEXT指针:ExceptionInfo->ContextRecord
dwAddr:           断点地址:0x123456
调用:            DelHwBreakpoint(ExceptionInfo->ContextRecord, 0x123456);
/************************************************************************/
bool DelHwBreakpoint(PCONTEXT context, ULONGLONG dwAddr);


下断点调用:
[C++] 纯文本查看 复制代码
//下断点调用
SetHwBreakpoint(0, HWBRK_TYPE_CODE, HWBRK_SIZE_1, bp2);


清除硬件断点调用:
[C++] 纯文本查看 复制代码
AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)ExceptionHandler);

DWORD NTAPI ExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo)
{
        if ((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == bpAddr)
        {                
                DelHwBreakpoint(ExceptionInfo->ContextRecord, bpAddr);
                // 这里执行自己的逻辑

                return EXCEPTION_CONTINUE_EXECUTION;
        }

        return EXCEPTION_CONTINUE_SEARCH;
}


附件: HwBreakpoint.rar (2.39 KB, 下载次数: 59)

免费评分

参与人数 7威望 +1 吾爱币 +28 热心值 +7 收起 理由
1equal100 + 1 + 1 谢谢@Thanks!
苏紫方璇 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
a5436539 + 1 + 1 我很赞同!
xiaohui13 + 1 + 1 我很赞同!
朱朱你堕落了 + 3 + 1 支持一下大佬。
Bob5230 + 1 + 1 热心回复!
richard_ljd + 1 + 1 我很赞同!

查看全部评分

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

朱朱你堕落了 发表于 2024-7-25 21:35
wtujoxk 发表于 2024-7-25 21:30
看到你发的帖子去学习的硬件断点,你试试就知道了

硬件断点就是鸡肋,不稳定,而且麻烦复杂,失效或不起作用或出错都不好找原因。不再折腾了,我还是老老实实的用inline hook吧。
董督秀 发表于 2024-7-25 21:36
该代码能对付这个吗?

简易的反补丁 CrackMe 64 位
https://www.52pojie.cn/thread-1917353-1-1.html
(出处: 吾爱破解论坛)
daxia520 发表于 2024-7-25 19:19
虽然不知道有啥用,但是感觉以后会有用。给大佬点赞!!!!
yang97 发表于 2024-7-25 19:32
学习了,顶一下
justwz 发表于 2024-7-25 20:10
向大佬学习
朱朱你堕落了 发表于 2024-7-25 21:27
刚发贴时,大佬说有问题,现在的是已经修复好了?
 楼主| wtujoxk 发表于 2024-7-25 21:30
朱朱你堕落了 发表于 2024-7-25 21:27
刚发贴时,大佬说有问题,现在的是已经修复好了?

看到你发的帖子去学习的硬件断点,你试试就知道了

点评

硬件断点就是鸡肋,不稳定,而且麻烦复杂,失效或不起作用或出错都不好找原因。不再折腾了,我还是老老实实的用inline hook吧。  详情 回复 发表于 2024-7-25 21:35
 楼主| wtujoxk 发表于 2024-7-25 21:50
董督秀 发表于 2024-7-25 21:36
该代码能对付这个吗?

简易的反补丁 CrackMe 64 位

因为你这个是cm,但是写补丁要方案!调试程序不在行
CodeZPro 发表于 2024-7-25 22:06
学到了,希望以后用得上
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-24 11:48

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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