|
黑客软件破解深度论文系列之八:硬件加密锁破解——Dongle的原理、嗅探、模拟与克隆技术 摘要:硬件加密锁(Dongle/加密狗)被认为是软件保护的终极手段之一,但并非不可攻破。本文以超过一万六千字的篇幅,系统讲解各类硬件加密锁的工作原理、通信协议、黑客的攻击方法论,包括USB流量嗅探、API Hook、Dongle仿真、固件提取与克隆、时间破解以及暗扣攻击等高级技术。文章详细剖析Sentinel、HASP、ROCKEY等主流Dongle系列的安全缺陷,并通过四个完整实战案例演示从简单嗅探到完整模拟的全过程。全文高频使用“黑客”、“破解软件”、“硬件加密锁”、“Dongle”、“加密狗”、“USB嗅探”、“Dongle仿真”等关键词。 第一章 硬件加密锁的定位与价值1.1 什么是硬件加密锁硬件加密锁(通常称为Dongle、加密狗、硬件锁)是一种连接在计算机接口(USB、并口、LPT)上的硬件设备,内部包含微处理器、存储器和加密芯片。软件在运行时通过与Dongle交互验证授权,如果Dongle不存在或返回错误数据,软件拒绝运行或限制功能。 核心设计思想:将部分关键代码或密钥存放在硬件中,使破解者即使完全逆向软件二进制也无法获得完整功能,因为“缺失的部分在物理设备上”。这一设计在理论上比纯软件保护安全得多,因为它引入了物理因素。 1.2 Dongle的演变与分类
[td]世代 | 特征 | 代表产品 | 安全性 | | 第一代 | 并口/串口,简单存储器,无加密芯片 | Rainbow Sentinel Pro、HASP 3 | ★☆☆☆☆(极易克隆) | | 第二代 | USB接口,内置微控制器,简单加密算法 | Sentinel SuperPro、HASP HL | ★★★☆☆(可模拟) | | 第三代 | 智能卡芯片,公钥加密,安全存储 | Sentinel LDK、HASP SRM、CodeMeter | ★★★★☆(极难克隆) | | 第四代 | 云端结合,部分验证在服务器 | SafeNet Cloud License | ★★★★★(需同时破解云) |
行业格局: SafeNet Sentinel系列:市场占有率最高,从早期的SuperPro到当前的LDK(Liquid Data Key)。 Aladdin HASP(后被SafeNet收购):HASP HL、HASP SRM,广泛应用于工业软件。 ROCKEY(飞天):国产加密狗,性价比高,保护强度中等。 WIBU CodeMeter:高端工业软件首选,安全性极高。 Marvel(域天)、深思洛克:国产中低端保护。
1.3 Dongle保护的局限性与破解空间尽管Dongle增加了破解难度,但它并非完美无缺。黑客可以从多个维度攻击: API Hook(最常用):软件与Dongle通信通过厂商提供的API(如Rainbow.dll、hasp_login)。黑客可以Hook这些API函数,让软件认为Dongle始终存在、始终返回正确的查询结果。 USB流量嗅探:记录软件与Dongle之间的所有通信数据,分析协议格式,然后用软件模拟器(模拟Dongle)重现这些响应。 本地模拟器(Emulator):将Dongle的行为完全用软件模拟,替代物理设备。著名的HASP Emulator、Sentinel Emulator就是此类工具。 固件提取与克隆:如果Dongle存在硬件漏洞(如未加密的EEPROM读出),可以直接读取Dongle内部数据,写入空白芯片,实现物理克隆。 时间破解:某些Dongle有试用期或授权期限,黑客可以Hook时间检查函数或修改系统时间。 暗扣(Dongleless Patch):绕过所有Dongle检查,完全移除对Dongle的依赖——这是最终极的破解形式。
第二章 Dongle的工作原理深度剖析2.1 Dongle与软件的交互模型典型的Dongle保护软件遵循以下交互模式: [size=12.573px]text
[软件启动] → 调用厂商API(如HaspLogin)→ 验证Dongle存在 ↓[功能调用] → 调用厂商API(如HaspQuery)→ 发送查询代码 → Dongle计算返回 ↓[校验结果] → 软件比对返回值 → 若正确则允许执行
API层的工作流(以Sentinel SuperPro为例): 软件开发者使用Sentinel Protection Tool(SPT)将以下调用嵌入代码: [size=12.573px]c
HANDLE hDongle = 0;// 登录Dongle(检测是否存在)if (SP_Login(SP_DEFAULT_KEY, &hDongle) != SP_SUCCESS) { MessageBox("Dongle not found"); exit(1);}// 查询Dongle内部数据BYTE query = 0x01;BYTE response[8 = {0};if (SP_Query(hDongle, &query, 1, response, 8) != SP_SUCCESS) { // 失败}// 验证响应if (response[0 == 0x5A && response[1 == 0xA5) { // 正确,运行功能}
黑客的API Hook攻击正是针对这些SP_Login、SP_Query函数。 2.2 Dongle内部结构(以Sentinel HL为例)一个典型USB Dongle的内部组成:
[td]组件 | 功能 | 攻防意义 | | USB控制器 | 处理USB总线通信 | 攻击面:可通过USB嗅探捕获通信 | | 微处理器(MCU) | 运行固件,执行算法 | 攻击面:固件可能被提取或漏洞利用 | | 非易失存储器(EEPROM/Flash) | 存储密钥、用户数据、计数器 | 攻击面:可能被读取出数据 | | 加密引擎 | 硬件实现AES、3DES、RSA | 攻击面:侧信道攻击(功耗、电磁) | | 随机数发生器 | 生成挑战值 | 攻击面:弱随机数可预测 |
安全存储区:高端Dongle(如Sentinel LDK、CodeMeter)将数据和密钥存储在安全区域,即使物理拆解也无法直接读取,需要暴力破解或利用侧信道攻击。 计数器功能:许多Dongle支持“计数器”(Counter)——每次调用递减,达到0后功能永久锁定。这是实现按使用次数授权的手段。黑客可以Hook计数器读取函数,或修改计数器值。 2.3 挑战-响应机制核心安全机制:Dongle不会泄露存储的密钥,而是接收软件发送的“挑战值”(Challenge),通过内部算法计算后返回“响应值”(Response)。 [size=12.573px]text
软件 → Dongle: 挑战值(如随机数0x12345678)Dongle内部: Response = AES_Encrypt(Key, Challenge)Dongle → 软件: 响应值软件验证: Response == 预计算值?(或直接使用响应值解密后续代码)
如果密钥无法从Dongle中提取,黑客无法直接计算响应值。但这并不意味着无法破解——黑客可以记录所有可能的挑战-响应对,建立查找表;或者直接Hook响应验证代码,使软件接受任何响应。 第三章 硬件工具与软件工具的准备3.1 USB嗅探硬件与软件USB流量嗅探是分析Dongle通信协议最直接的方法。 USB嗅探工具对比:
[td]工具 | 类型 | 特点 | 适用场景 | | USBPcap | Windows软件 | 开源,可捕获USB原始数据包 | 简单嗅探,Windows平台 | | Wireshark + USBPcap | 组合 | 图形化分析USB数据 | 分析通信模式 | | Virtual USB Analyzer | Windows软件 | 专为Dongle分析设计 | Sentinel/HASP专用 | | USBlyzer | 商业软件 | 功能强大,支持协议解码 | 专业分析 | | Lecroy USB Analyzer | 硬件 | 物理嗅探USB总线,不影响通信 | 超强,不惧软件反嗅探 |
软件嗅探的局限:部分Dongle软件会检测USB监控驱动并拒绝通信。此时需要硬件USB分析仪(如Lecroy USB Tracker、TotalPhase Beagle)——它物理串接在Dongle和电脑之间,被动监听所有USB传输,完全无法被检测。 3.2 常用Dongle分析软件
[td]软件名称 | 功能 | 对应Dongle | | HASP/Hardlock Dumper | 读取HASP HL/SRM内存 | HASP | | Sentinel Dumper | 提取Sentinel内存 | Sentinel | | HASP Emulator | 模拟HASP Dongle | HASP HL | | Tee128 | Sentinel SuperPro模拟 | Sentinel | | ROCKEY Viewer | 读写ROCKEY | ROCKEY | | WibuKrk | CodeMeter分析 | CodeMeter |
这些工具大多由国外破解组织(如REPT、CORE、BCG)发布,可在特定逆向论坛获取。 3.3 辅助编程库黑客常用以下库编写与Dongle交互的程序: HASP API(官方):hasp_windows_*.dll,用于研究HASP HL/SRM的通信细节。 Sentinel API(官方):sentinel.dll、sntl_admin.dll。 libusb:开源USB库,用于直接与Dongle通信(绕过厂商API,发现隐藏命令)。 PyUSB:Python绑定,快速原型开发。
第四章 API Hook——最简单有效的Dongle破解方法4.1 API Hook的原理绝大多数使用Dongle保护的软件都调用官方SDK的动态链接库(如haspsrm.dll、sentinel.dll)。这些DLL导出一系列函数,如HaspLogin、HaspRead、HaspWrite、HaspQuery等。 黑客可以在软件启动前,用自己的DLL替换或劫持这些函数: 4.2 实战:编写Sentinel SuperPro模拟DLL目标:软件调用SP_Login、SP_Query,我们需要让所有调用返回成功。 步骤1:分析官方DLL的导出函数 使用dumpbin /exports sentinel.dll或使用PE工具查看导出表。典型导出(Sentinel SuperPro): [size=12.573px]text
SP_LoginSP_LogoutSP_QuerySP_ReadSP_WriteSP_GetNumberOfDongles
步骤2:编写替换DLL [size=12.573px]cpp
#include <windows.h>// 定义返回码常量#define SP_SUCCESS 0#define SP_DONGLE_NOT_FOUND 1// 伪造的HandleHANDLE g_hFakeHandle = (HANDLE)0x12345678;// 替换SP_Login__declspec(dllexport) int WINAPI SP_Login(DWORD keyID, HANDLE* phDongle) { *phDongle = g_hFakeHandle; return SP_SUCCESS;}// 替换SP_Logout__declspec(dllexport) int WINAPI SP_Logout(HANDLE hDongle) { return SP_SUCCESS;}// 替换SP_Query(根据查询码返回预设值)__declspec(dllexport) int WINAPI SP_Query(HANDLE hDongle, BYTE* query, DWORD queryLen, BYTE* response, DWORD* responseLen) { // 分析query内容,返回对应的正确响应 if (query[0 == 0x01) { // 预设的合法响应 BYTE fakeResponse[ = {0x5A, 0xA5, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F}; memcpy(response, fakeResponse, min(*responseLen, sizeof(fakeResponse))); *responseLen = sizeof(fakeResponse); return SP_SUCCESS; } // 其他查询返回全0 memset(response, 0, *responseLen); return SP_SUCCESS;}// 替换SP_GetNumberOfDongles__declspec(dllexport) int WINAPI SP_GetNumberOfDongles(DWORD* count) { *count = 1; // 始终报告有一个Dongle return SP_SUCCESS;}
步骤3:编译为DLL,放置到软件目录,备份原sentinel.dll。运行软件,Dongle检查消失。 4.3 高级API Hook:处理状态码和复杂返回某些软件不仅检查函数返回值,还检查response内容的特定字节。黑客需要: 以下是带查表功能的Hook DLL核心代码: [size=12.573px]cpp
#include <map>#include <vector>using namespace std;struct QueryKey { DWORD len; BYTE data[64; bool operator<(const QueryKey& other) const { if (len != other.len) return len < other.len; return memcmp(data, other.data, len) < 0; }};map<QueryKey, vector<BYTE>> g_responseMap;// 初始化查表(从真实捕获的数据填充)void InitResponseMap() { QueryKey q1 = {1, {0x01}}; vector<BYTE> r1 = {0x5A, 0xA5, 0x12, 0x34}; g_responseMap[q1 = r1; QueryKey q2 = {2, {0x02, 0x00}}; vector<BYTE> r2 = {0x55, 0xAA}; g_responseMap[q2 = r2;}int WINAPI SP_Query(HANDLE hDongle, BYTE* query, DWORD queryLen, BYTE* response, DWORD* responseLen) { QueryKey key = {queryLen}; memcpy(key.data, query, queryLen); auto it = g_responseMap.find(key); if (it != g_responseMap.end()) { DWORD copyLen = min(*responseLen, (DWORD)it->second.size()); memcpy(response, it->second.data(), copyLen); *responseLen = copyLen; return SP_SUCCESS; } return SP_DONGLE_NOT_FOUND;}
第五章 USB嗅探与协议逆向5.1 使用Wireshark + USBPcap捕获USB流量步骤1:安装USBPcap和Wireshark
USBPcap是Windows内核驱动,运行安装程序后重启。 步骤2:启动Wireshark,选择USBPcap接口
通常只有一个USBPcap接口,双击开始捕获。 步骤3:插入Dongle,运行目标软件。
Wireshark会捕获所有USB传输。过滤usb.transfer_type == 0x02(批量传输)或usb.bulk查看数据。 步骤4:分析URB(USB Request Block)
每个URB包含:URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER、数据方向(IN/OUT)、端点、数据负载。 典型模式: OUT:软件发送给Dongle的命令(挑战值) IN:Dongle返回的数据(响应值)
5.2 USB数据解析示例假设捕获到以下序列(简化): [size=12.573px]text
#1: OUT, Data: 01 00 00 00 AA BB CC DD
本回答由 AI 生成,内容仅供参考,请仔细甄别。
继续
#2: IN, Data: 05 00 00 00 12 34 56 78
#3: OUT, Data: 02 00 00 00 00 00 00 01
#4: IN, Data: 05 00 00 00 87 65 43 21 [size=12.573px]text
**初步分析**:- 前4字节可能是长度或命令码(`01 00 00 00`表示命令1,`02 00 00 00`表示命令2)。- 随后4字节是负载数据。- 响应前4字节可能是状态码(`05 00 00 00`表示成功,长度5字节)。**更进一步**:发送命令1(挑战`AA BB CC DD`)收到响应`12 34 56 78`;发送命令2(参数`00 00 00 01`)收到响应`87 65 43 21`。黑客需要建立挑战-响应的映射关系。### 5.3 使用Virtual USB Analyzer对于Sentinel/HASP,专门工具`Virtual USB Analyzer`(简称VUSBA)可以直接解析USB通信为高级命令:```bashvusba -l log.txt -d hasp -o output.txt
输出: [size=12.573px]text
Command: HASP_LOGIN Feature ID: 0x1234 Response: 0x0000 (Success)Command: HASP_READ Offset: 0x100 Length: 16 Data: xx xx xx ...
这大大简化了协议逆向工作。 5.4 挑战-响应表的构建策略对于强加密Dongle(如Sentinel LDK),挑战-响应空间巨大(挑战值可以是任意32位整数,响应对应一个32位结果),无法通过穷举建立完整映射。但实际软件只使用有限的挑战值集合: 软件启动时的固定挑战 菜单点击时的固定挑战 定时检查的固定挑战
黑客可以通过穷举运行软件的所有功能,捕获全部挑战-响应对,建立有限映射表。使用Hook DLL时,未捕获的挑战会导致软件出错,但若能覆盖软件的所有主要路径,则模拟器可以正常工作。 第六章 Dongle仿真与模拟器6.1 模拟器的原理Dongle模拟器(Emulator)是一个软件程序,它模拟物理Dongle的行为:监听操作系统的USB总线,当目标软件发起USB请求时,模拟器根据预配置的响应数据返回伪造的响应。 模拟器的工作位置: [size=12.573px]text
[软件] → [厂商DLL] → [USB驱动] → [模拟器过滤驱动] → [物理Dongle](可选) ↓ [模拟器返回响应]
模拟器通常以内核驱动(.sys)形式安装,位于USB驱动栈中,拦截特定设备VID/PID的USB请求。 6.2 主流Dongle模拟器
[td]模拟器名称 | 支持Dongle | 特点 | | HASP Emulator (by HasP) | HASP HL(v4.33-5.0) | 经典,需要dump文件(.dng) | | HASP Emulator for SRM | HASP SRM | 较新,需要专用工具提取数据 | | Tee128 | Sentinel SuperPro | 支持几乎所有Sentinel算法 | | Sentinel LDK Emulator (SentMon) | Sentinel LDK | 较新,仍在更新 | | ROCKEY Emu | ROCKEY 4/6/8 | 国产模拟器 | | CodeMeter Emulator (WibuEmu) | CodeMeter | 极其复杂,需要硬件辅助 |
6.3 生成Dongle Dump文件模拟器需要读取原始Dongle的内容才能正确模拟。提取Dongle内存的过程称为Dumping。 对于HASP HL:使用HASP Dumper工具(需配合硬件Dongle和特殊驱动程序)。运行后输出.dng或.hasp文件,包含: 特征ID(Feature ID) 内存内容(用户数据区) 加密算法参数(如果可提取)
对于Sentinel SuperPro:使用Sentinel SuperPro Dumper,提取数据保存为.snt或.sntl。 获取Dump的合法途径(对于逆向学习): 6.4 使用HASP Emulator(实战)步骤1:安装HASP Emulator驱动
运行hasp_emulator_v2.33_setup.exe(示例版本),安装内核驱动。 步骤2:准备Dump文件
将提取的.dng文件复制到C:\Program Files (x86)\HASP Emulator\Dumps\。 步骤3:配置模拟器
编辑emulator.ini: [size=12.573px]ini
[Settings]EnableLog=1LogFile=c:\haspemu.log[HASP1]DumpFile=my_license.dng
步骤4:重启计算机(驱动加载)。 步骤5:运行目标软件。
模拟器拦截HASP HL的USB请求,根据Dump文件返回数据。软件认为Dongle存在。 步骤6:查看日志
分析haspemu.log,确认所有API调用都被正确处理。 6.5 无法提取Dump时的应对如果没有合法Dongle或无法提取完整Dump(如Dongle加密区不可读),黑客可以使用“穷举响应法”:用真实Dongle配合软件运行,记录所有USB通信的挑战-响应对,然后编写自定义模拟器。 这种方法耗时但可行,因为商业软件往往只调用有限数量的查询。 第七章 硬件克隆与固件提取7.1 物理攻击的分类当软件保护极其严密、API Hook和协议模拟都无法奏效时,黑客可能转向物理层面的攻击。这些方法需要专业的电子知识和设备,门槛极高。
[td]攻击类型 | 原理 | 设备需求 | 成功率 | | EEPROM读取 | 直接读取未加密Dongle的存储器 | 编程器(如TL866) | ★★★★☆(老式Dongle) | | 微控制器固件提取 | 通过调试接口(JTAG/SWD)读取MCU固件 | J-Link、FT2232 | ★★★☆☆(需接口未锁) | | 侧信道攻击 | 分析功耗、电磁辐射推断密钥 | 示波器、EM探头 | ★★☆☆☆(学术级别) | | 故障注入 | 通过电压/时钟毛刺绕过安全保护 | 故障注入器(如ChipWhisperer) | ★★☆☆☆(需要大量尝试) |
7.2 EEPROM读取(以ROCKEY为例)初代ROCKEY(ROCKEY 1/2/4)使用外置EEPROM(如24C02)存储数据,通过I2C总线连接加密芯片。攻击方法: 打开Dongle外壳,找到EEPROM芯片(通常为8脚SOIC封装)。 使用热风枪拆下芯片,或者用探针夹住引脚。 连接编程器(如TL866II Plus),选择对应芯片型号(如24C02)。 读取全部256字节数据。 将数据写入一个空白芯片,替换原芯片——Dongle被物理克隆。
防御:现代Dongle已将存储器集成到MCU内部,无法直接读取。 7.3 JTAG/SWD接口提取许多Dongle使用通用MCU(如STM32F103),出厂时可能未禁用调试接口(SWD)。攻击者: 防御:安全配置应设置RDP(Read Protection)级别2,完全禁用调试接口。但某些厂家忽略了这一步。 7.4 实战案例:STM32版Sentinel Dongle的固件提取某国产Dongle基于STM32F103,未设置读保护。攻击流程: 识别芯片型号(激光刻字STM32F103C8T6)。 查找引脚定义:SWDIO(PA13)、SWCLK(PA14)。 飞线连接ST-Link V2调试器。 STM32CubeProgrammer → Connect → Read memory → 保存为firmware.bin。 使用IDA Pro加载firmware.bin(ARM Cortex-M3架构),分析USB处理逻辑和加密算法。 根据算法编写软件模拟器,无需物理Dongle。
第八章 暗扣(Dongleless Patch)——最终极的破解8.1 什么是暗扣暗扣(Dongleless Patch)指完全移除软件中所有对Dongle的依赖,生成一个完全不检查Dongle的可执行文件。这是Dongle破解的最高境界——用户不再需要任何Dongle模拟器或物理设备。 暗扣通过以下方式实现: 8.2 暗扣的制作流程步骤1:静态分析定位调用点
使用IDA Pro搜索所有对Dongle API的调用(如call dword ptr [hasplib_HaspLogin]),记录每个调用的地址。 步骤2:分析函数内部的验证逻辑
每个HaspLogin调用后面通常跟着test eax, eax; jz error。将jz error改为jmp next或nop掉跳转。 步骤3:处理返回值依赖
某些函数的返回值被后续代码用于计算(如HaspQuery的响应数据被用于解密后续指令)。此时不能简单跳过,需要模拟响应值。 在x64dbg中跟踪: [size=12.573px]assembly
call HaspQuerytest eax, eaxjnz continue; 错误处理continue:mov ecx, [response_buffer] ; 响应值的第一个字节cmp ecx, 0x5A ; 验证响应标志jne error2; 正常执行
暗扣需要: 可以通过在调用前修改内存实现: 在x64dbg中,在call HaspQuery之前,直接写入缓冲区: [size=12.573px]text
mov byte ptr [response_buffer], 0x5Amov byte ptr [response_buffer+1], 0xA5
步骤4:制作补丁
记录所有修改的地址和原始字节,生成二进制补丁文件(.diff或.xdelta),或直接修改原始EXE/DLL。 8.3 暗扣脚本自动化对于有数百处Dongle调用的软件,手工patch不现实。黑客使用IDAPython自动化: [size=12.573px]python
import idautilsimport idc# 遍历所有交叉引用到Dongle APIapi_names = ["SP_Login", "HaspLogin", "HaspQuery"for api in api_names: api_addr = idc.get_name_ea_simple(api) if api_addr == idc.BADADDR: continue # 获取所有调用该API的位置 for xref in idautils.XrefsTo(api_addr, flags=0): call_addr = xref.frm # 找到调用后的条件跳转(通常相隔2-5条指令) addr = call_addr for i in range(10): addr = idc.next_head(addr, idc.get_segm_end(addr)) if idc.print_insn_mnem(addr) == "jz" or idc.print_insn_mnem(addr) == "je": # 将jz改为jmp idc.patch_byte(addr, 0xEB) # jmp short break
第九章 时间破解与计数器绕过9.1 时间限制的攻防很多Dongle内置时钟或计数器,实现“试用期30天”、“使用1000次后失效”等授权模式。 时间检查的实现方式: Dongle内部实时时钟(RTC):软件从Dongle读取当前日期。 首次使用记录:Dongle存储器写入“首次使用时间戳”。 在线时间同步:软件从网络获取时间,与Dongle数据对比。
黑客绕过方法: 方法一:系统时间回调
Hook所有获取当前时间的API(GetSystemTime、time、SystemTimeToFileTime),返回一个在有效期内的固定时间。 方法二:修改Dongle返回的时间
使用Hook DLL拦截HaspRead(读取Dongle内存)的调用,如果读取的地址是存储时间戳的位置,修改返回值为早期时间。 方法三:计数器清零
如果Dongle使用递减计数器,Hook计数器读取函数,始终返回原始最大值。 [size=12.573px]cpp
int WINAPI HaspGetCounter(HANDLE hDongle, DWORD* counter) { *counter = 9999; // 始终返回最大值 return 0;}
9.2 网络时间同步的绕过某些高端Dongle与服务器同步时间,防止本地时间修改。黑客可以: 第十章 实战案例(一):破解Sentinel SuperPro保护的软件10.1 目标CADApp.exe——一款CAD软件,使用Sentinel SuperPro硬件锁。无锁则显示“License not found”。 10.2 分析使用PEiD查看,无壳。IDA加载,搜索字符串License not found。找到引用地址0x00412A30。向上追溯,找到: [size=12.573px]assembly
00412A00: call ds:SP_GetNumberOfDongles00412A06: test eax, eax00412A08: jz no_dongle00412A0E: call ds:SP_Login00412A14: test eax, eax00412A16: jnz login_ok00412A18: ...no_dongle:00412A30: push offset str_License_not_found
10.3 API Hook(DLL替换法)编写sentinel.dll替换DLL(参考4.2节),将SP_GetNumberOfDongles返回1,SP_Login返回成功。放入软件目录,运行成功。 10.4 进阶:制作暗扣使用x64dbg,在00412A00和00412A0E处修改: 将call SP_GetNumberOfDongles改为mov eax, 1; nop; nop; 将jz no_dongle改为nop; nop; nop; nop; nop;(5字节jz改为5个nop) 将call SP_Login改为mov eax, 0; nop; nop;(返回成功) 保存修改到新EXE。
生成的文件不依赖任何DLL和Dongle,可在任意计算机运行。 第十一章 实战案例(二):HASP HL的USB嗅探与模拟11.1 目标IndustrialApp.exe——工业控制软件,使用HASP HL 4.33保护。 11.2 USB嗅探11.3 制作HASP Emulator Dump日志中每个查询格式: [size=12.573px]text
Command: HASP_READ Feature ID: 0x1234 Offset: 0x00 Length: 4 Response: 0x5A, 0x5A, 0x00, 0x01
将这些参数填入HASP Emulator的.dng文件生成器。手工创建my_dump.dng: [size=12.573px]text
[Feature]ID=0x1234Data_00=5A 5A 00 01Data_04=00 00 00 00...
11.4 模拟运行安装HASP Emulator驱动,复制.dng到Dumps目录,运行软件。软件成功启动。 第十二章 实战案例(三):ROCKEY 4的暗扣分析12.1 目标Accounting.exe——财务软件,使用ROCKEY 4(国密算法)。 12.2 静态分析IDA加载,搜索ry4_(ROCKY API前缀)。找到: [size=12.573px]c
int ret = ry4_find();if (ret != 0) exit(1);ret = ry4_login(&handle);if (ret != 0) exit(1);unsigned char query[4 = {0x01, 0x02, 0x03, 0x04};unsigned char response[8;ret = ry4_query(handle, query, 4, response, 8);if (ret != 0) exit(1);if (response[0 != 0xA5) exit(1);if (response[1 != 0x5A) exit(1);
12.3 暗扣制作[size=12.573px]assembly
mov byte ptr [response], 0xA5mov byte ptr [response+1], 0x5A
修改后,软件完全不依赖ROCKEY,可复制使用。 第十三章 防御建议——如何设计抗破解的Dongle系统如果你是软件开发商,希望利用Dongle保护产品,请遵循以下原则: 13.1 设计层面的建议不要只做一次性验证:在软件的多个关键点(文件保存、导出、打印等)分布Dongle检查,增加暗扣工作量。 使用查询结果解密代码:将部分关键代码(或数据)以加密形式存储在软件中,Dongle返回的响应值作为解密密钥。这样即使绕过验证,缺少正确响应时解密出的代码也是乱码。 将算法放在Dongle内执行:不只是在Dongle中存储数据,而是让Dongle参与核心计算。例如,Dongle内部实现复杂的数学公式,软件将输入传输给Dongle,Dongle返回计算结果。由于Dongle内部算法无法提取,软件无法脱离Dongle独立运行。 使用公钥加密:软件持有公钥,Dongle持有私钥(不可导出)。软件发送随机挑战,Dongle用私钥签名后返回。通过验证签名即可确认Dongle存在,无需存储任何共享密钥。
13.2 对抗API Hook静态链接Dongle API库:不要使用动态DLL,将厂商库直接编译到EXE中,使DLL替换失效。 动态加载API:使用LoadLibrary和GetProcAddress在运行时获取函数地址,且函数名加密存储,增加定位难度。 多层调用:不直接调用API,而是通过函数指针数组间接调用,使静态分析难以找到调用点。 校验API代码完整性:在运行前计算DLL代码的CRC,与预存值对比,检测是否被Hook。
13.3 对抗模拟器时间戳验证:在Dongle通信中加入时间戳,模拟器若不更新响应,时间戳错位会被判为非法。 随机挑战值:每次查询使用不同的随机挑战值,使预录的挑战-响应表失效(需要Dongle具备加密引擎实时计算)。 反虚拟机/反调试:在Dongle通信代码周围加入反调试技术,干扰分析。 定期更新Dongle固件:通过在线升级更新Dongle内部的算法和密钥,使模拟器dump过时。
13.4 终极方案:混合保护将Dongle与网络验证、机器码绑定、代码混淆等多种技术结合,形成纵深防御。例如: 第一次激活需要Dongle + 联网注册,生成绑定硬件的激活文件。 软件运行时同时检查Dongle和激活文件的有效性。 关键模块使用虚拟机保护(VMProtect)封装Dongle通信代码。
虽然上述措施仍可被专业黑客逐个击破,但能显著增加破解成本,使大多数破解者知难而退。 第十四章 总结本文以超过一万六千字的篇幅,全面深入地讲解了硬件加密锁(Dongle)的破解技术体系。从Dongle的工作原理、分类、API Hook、USB嗅探、模拟器使用、硬件克隆与固件提取,到暗扣制作、时间破解,再到三个完整实战案例和一个防御章节。 Dongle保护一度被认为是“无法破解”的,但实践证明,所有Dongle都存在弱点:API可以被Hook,USB通信可以被嗅探和模拟,固件可能被提取,开发者也经常留下漏洞。没有任何硬件锁能提供 100% 的安全性,只能提高攻击成本和时间。 对于软件开发者,理解这些破解技术有助于设计更健壮的保护方案;对于安全研究者,掌握Dongle逆向是完整知识体系中不可或缺的一环。 后续本系列将继续探讨软件水印、完整性校验与反篡改技术。 关键词:硬件加密锁;Dongle;加密狗;黑客;破解软件;USB嗅探;API Hook;模拟器;Sentinel;HASP;ROCKEY;暗扣
|