保护DLL调用说明
EXE一键保护后,验证DLL已打包进EXE内部。程序启动时自动加载DLL并弹出登录窗口,登录成功后继续执行。
DLL文件说明
| 打包名称 | 说明 |
| onion.dll | 统一打包名称,32位/64位程序都使用此名称 |
系统会根据软件的登录模式(login_mode)和EXE架构自动选择正确的DLL进行保护,打包后统一命名为 onion.dll。
DLL命令声明(易语言)
.版本 2
' 注意:打包后DLL名称统一为 onion.dll
' 以下示例以32位为例
' ========== 核心函数 ==========
' --- 心跳(保持在线,建议30秒调用一次) ---
' 返回: 1=成功, -1=失败(掉线/token过期)
.DLL命令 Heartbeat, 整数型, "onion.dll", "Heartbeat"
' --- 退出登录 ---
' 返回: 0=成功
.DLL命令 Logout, 整数型, "onion.dll", "Logout"
' --- 二次验证(检查登录状态是否有效) ---
' 返回: 1=有效, -1=无效
.DLL命令 Verify, 整数型, "onion.dll", "Verify"
' --- 扣点 ---
' 返回: 0=成功, -1=失败(点数不足或已掉线)
.DLL命令 Deduct, 整数型, "onion.dll", "Deduct"
.参数 点数, 整数型
' ========== 信息获取函数 ==========
' --- 获取用户名 ---
' 返回: "用户名|时间戳" 格式
.DLL命令 GetUsername, 文本型, "onion.dll", "GetUsername"
' --- 获取到期时间 ---
' 返回: "到期时间|时间戳" 格式
.DLL命令 GetExpireTime, 文本型, "onion.dll", "GetExpireTime"
' --- 获取心跳返回的到期时间 ---
' 返回: "到期时间|时间戳" 格式
.DLL命令 GetHeartbeatExpireTime, 文本型, "onion.dll", "GetHeartbeatExpireTime"
' --- 获取剩余点数 ---
.DLL命令 GetPoints, 整数型, "onion.dll", "GetPoints"
' --- 获取机器码 ---
.DLL命令 GetMachineCodeStr, 文本型, "onion.dll", "GetMachineCodeStr"
' --- 获取重要数据 ---
.DLL命令 GetSecretData, 文本型, "onion.dll", "GetSecretData"
' --- 获取当前Token ---
.DLL命令 GetToken, 文本型, "onion.dll", "GetToken"
' --- 获取当前时间戳 ---
.DLL命令 GetTimestamp, 整数型, "onion.dll", "GetTimestamp"
' --- 获取验证状态 ---
' 返回: 1=已验证, 0=未验证
.DLL命令 GetStatus, 整数型, "onion.dll", "GetStatus"
' ========== 检查函数 ==========
' --- 主动检查(弹窗提示) ---
' 返回: 1=通过, 0=失败
.DLL命令 Check, 逻辑型, "onion.dll", "Check"
' --- 静默检查(失败直接退出进程) ---
.DLL命令 CheckSilent, , "onion.dll", "CheckSilent"
' --- 完整性校验 ---
' 返回: 1=通过, 0=失败
.DLL命令 CheckIntegrity, 逻辑型, "onion.dll", "CheckIntegrity"
' ========== 封禁函数 ==========
' --- 封禁(检测到破解时调用) ---
' 参数: 类型(user/machine/ip/all), 原因
' 返回: 0=成功
.DLL命令 Ban, 整数型, "onion.dll", "Ban"
.参数 类型, 文本型
.参数 原因, 文本型
导出函数详细说明
| 函数名 | 参数 | 返回值 | 说明 |
| Init | 无(自动) | 无 | 系统自动调用,弹出登录窗口,登录成功后返回 |
| Heartbeat | 无 | 整数型 | 心跳保活,1=成功,-1=失败(需重新登录) |
| Logout | 无 | 整数型 | 退出登录,0=成功 |
| Verify | 无 | 整数型 | 二次验证token有效性,1=有效,-1=无效 |
| Deduct | 点数(整数) | 整数型 | 扣点,0=成功,-1=失败 |
| GetUsername | 无 | 文本型 | 获取用户名,格式: "数据|时间戳" |
| GetExpireTime | 无 | 文本型 | 获取登录时的到期时间 |
| GetHeartbeatExpireTime | 无 | 文本型 | 获取最新心跳返回的到期时间 |
| GetPoints | 无 | 整数型 | 获取剩余点数 |
| GetMachineCodeStr | 无 | 文本型 | 获取当前机器码 |
| GetSecretData | 无 | 文本型 | 获取后台设置的重要数据 |
| GetToken | 无 | 文本型 | 获取当前登录Token |
| GetTimestamp | 无 | 整数型 | 获取当前Unix时间戳 |
| GetStatus | 无 | 整数型 | 获取验证状态,1=已验证,0=未验证 |
| Check | 无 | 逻辑型 | 主动检查,失败弹窗提示,1=通过 |
| CheckSilent | 无 | 无 | 静默检查,失败直接退出进程 |
| CheckIntegrity | 无 | 逻辑型 | 完整性校验,检测是否被篡改 |
| Ban | 类型,原因 | 整数型 | 封禁,类型=user/machine/ip/all,0=成功 |
使用示例(易语言)
.版本 2
' 辅助函数:从DLL返回值中提取实际数据(去掉|时间戳后缀)
.子程序 取返回数据, 文本型
.参数 原始数据, 文本型
.局部变量 位置, 整数型
位置 = 倒找文本 (原始数据, "|", , 假)
.如果 (位置 > 0)
返回 (取文本左边 (原始数据, 位置 - 1))
.否则
返回 (原始数据)
.如果结束
.子程序 _启动窗口_创建完毕
' Init()已由系统自动调用,到这里说明登录成功
标签_用户.标题 = "用户: " + 取返回数据 (GetUsername ())
标签_到期.标题 = "到期: " + 取返回数据 (GetExpireTime ())
标签_点数.标题 = "点数: " + 到文本 (GetPoints ())
' 启动心跳定时器(30秒一次)
时钟_心跳.时钟周期 = 30000
.子程序 _时钟_心跳_周期事件
.如果 (Heartbeat () ≠ 1)
时钟_心跳.时钟周期 = 0
信息框 ("掉线了,请重新登录", 0, "提示")
结束 ()
.如果结束
' 心跳成功后更新显示
标签_到期.标题 = "到期: " + 取返回数据 (GetHeartbeatExpireTime ())
标签_点数.标题 = "点数: " + 到文本 (GetPoints ())
.子程序 _按钮_功能_被单击
' 执行功能前先检查
.如果 (Check () ≠ 1)
信息框 ("验证失败,请重新登录", 0, "提示")
返回 ()
.如果结束
' 扣点
.如果 (Deduct (1) ≠ 0)
信息框 ("点数不足或已掉线", 0, "提示")
返回 ()
.如果结束
' 更新点数显示
标签_点数.标题 = "点数: " + 到文本 (GetPoints ())
' ... 执行实际功能 ...
.子程序 _启动窗口_将被销毁
时钟_心跳.时钟周期 = 0
Logout ()
注意事项
- 所有导出函数均为
__stdcall 调用约定,与易语言默认一致
- 文本型返回值格式为 "数据|时间戳",需用辅助函数提取实际数据
- Heartbeat 成功返回 1(非0),失败返回 -1
- Verify 有效返回 1,无效返回 -1
- Check 通过返回 1,失败返回 0
- Deduct 成功返回 0,失败返回 -1
- 建议对程序加VMP保护防止逆向分析
- 心跳间隔建议30秒,不要太频繁也不要太长