dma-cardkey-evo-crack
SkillDev toolsA complete reverse-engineering and localized-bypass workflow for the card-key authorization chain of DMA hardware cheats (Evo / EVO PASS / scheats.club / freakluke.me family). Use when the user asks to analyze card-key validation in DMA cheats, crack Evo_Crack.exe / evo.exe authorization, capture or
Available today. Use it from your connected AI after setup.
No other account needed.
Add ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
Then ask your AI: use the dma-cardkey-evo-crack skill
What this skill tells your AI
The instructions your AI receives, as published by alicewe1/alice_skill in _modules/dma-cardkey-evo-crack/SKILL.md and read by ahel’s review.
零、适用范围声明(重要 —— 先读这一节)
本技能记录的是 DMA 外挂卡密破解的其中一种思路,不是全部 DMA 软件都这么干。 其它厂商/其它产品的授权链可能完全不同,切勿照搬。
本案例(Evo 系:Evo_Crack.exe + evo.exe + scheats.club)走的是
「本地授权服务器伪造 + TLS 中间人」 路线。它成立需要同时满足 4 个前提:
- 授权校验走网络请求(HTTPS 到远端授权服务器);
- 客户端信任本机根证书库(没有做 certificate pinning);
- 校验结果最终落在本地文件或可预测的内存态(这里
C:\Evo\user.dat); - 主程序有 CRC / 虚拟机保护,直接 patch 二进制不现实。
其它 DMA 软件可能是完全不同的形态,例如:
| 形态 | 特征 | 对应思路(不在本技能覆盖内) |
|---|---|---|
| 纯本地离线算法 | 无网络请求,卡密 = 序列号 / 签名 | 逆算法 + keygen |
| 硬件绑定卡 | 卡密绑 DMA 卡序列号 / FTDI 芯片 ID | 伪造硬件指纹读取 |
| 服务端计算 + 强制心跳 | 每次启动必须联网,本地不留凭证文件 | 伪造 / 重放心跳 |
| 驱动级校验 | 校验在内核驱动里,用户态看不到 | 驱动逆向 / 内核绕过 |
| 双向 TLS(mTLS) | 客户端证书 + 证书固定 | 需先解 pinning |
| 卡密 + 机器码双因子 | 服务端把机器码写死绑定 | 伪造 HWID 上报 |
判定流程:
- 先做「二、静态侦察」:看导入表有没有
WinHttp*/WS2_32/bcrypt; - 再做「三、动态侦察」:钩
WinHttpSendRequest/connect,看它到底联不联网; - 联网 → 本技能适用;不联网 → 转入离线算法逆向 + keygen 路线(另一套技能);
- 联网但证书 pinning → 先解决 pinning,再用本技能;
- 联网但校验在内核 → 先做驱动逆向,再用本技能。
只有确认是「网络授权 + 本地落盘」型,本技能的思路才可直接套用。 本技能的所有脚本(探针 / mock / dump 分析)都是通用的, 但「hosts 劫持 + 根证书 + 本地 TLS」这条具体绕过链只对上述第 1~4 条全都成立的样本有效。
一、目标画像(先认产品,再动手)
DMA 外挂(Direct Memory Access cheat)的典型文件布局:
| 文件 | 作用 | 识别特征 |
|---|---|---|
| 主程序(evo.exe / EC1.1.exe) | 外挂本体 | 段名含 .themida / .boot / 空段名;熵 7.9+ |
| 破解/加载器(Evo_Crack.exe) | 卡密绕过工具 | 随机段名(.Oh5/.3p[)+ 每 DLL 只留 1 个导入 + 高熵 |
vmm.dll | PCILeech VMM(内存读写引擎) | 导出 VMMDLL_* |
leechcore.dll | LeechCore(DMA 通信层) | 导出 LcCreate/LcRead/LcWrite/LcCommand |
leechcore_driver.dll | 内核驱动 | 20 KB 级 |
FTD3XX.dll | FTDI FT60x USB3 驱动 | 导出 FT_*(47 个) |
tinylz4.dll | LZ4 | 导出 LZ4_compress_default / LZ4_decompress_safe |
info.db | 数据缓存 | SQLite format 3 |
cloudflared.exe | 穿透隧道 | Cloudflare Quick Tunnel |
判据:见到 vmm.dll + leechcore.dll + FTD3XX.dll 三件套 = DMA 卡外挂,不是普通软件。
判据:见到 Evo_Crack.exe 这类"卡密破解器" = 它不会真去改主程序,而是伪造授权服务端。
二、静态侦察(Phase 1)
2.1 PE 结构快筛
import pefile
pe = pefile.PE(path)
for s in pe.sections:
print(s.Name, hex(s.VirtualAddress), hex(s.Misc_VirtualSize),
hex(s.PointerToRawData), hex(s.SizeOfRawData), hex(s.Characteristics))
关键判读:
RAW=0 / RS=0的段 → 运行时才填充(VM 解包目标区 / 壳数据)- 段名随机化(
.Oh5.2d8ld.ASLpfR)→ VMProtect 3.x 或自研壳 - 段名
.themida/.boot→ Themida / WinLicense - 熵
>7.9的代码段 → 代码加密 - 熵
≈6.0的大块 → 典型 VM 字节码区(本案例.3p[的 0x8 万-0x200 万区间)
2.2 导入表伪造识别(关键指纹)
逐 DLL 统计导入数量:
for e in pe.DIRECTORY_ENTRY_IMPORT:
print(e.dll, len(e.imports), [i.name for i in e.imports][:3])
每个系统 DLL 只有 1 个导入(且是随机的、通常不重要的那个函数)→
壳把真实 IAT 抹掉,运行时由 VM 解密后 LoadLibrary + GetProcAddress 重建。
本案例实测(23 个 DLL 各 1 个):
ADVAPI32.dll -> GetTokenInformation
KERNEL32.dll -> AreFileApisANSI
WS2_32.dll -> accept
WINHTTP.dll -> WinHttpCloseHandle
bcrypt.dll -> BCryptCloseAlgorithmProvider
MSVCP140.dll -> ??0?$basic_ios@...
2.3 字符串侦察的陷阱
加壳文件里搜不到明文是正常的,但要注意编码:
- 本案例
Evo_Crack.exe静态文件:25419 条 ASCII 串、0 条 UTF-16 串、0 条 GBK 中文 - 但内存 dump 后:中文提示串全部是 UTF-16LE(
请输入卡密=c7ebcae4c8ebbfa8c3dc的 utf-16le 编码) - 不要只搜 GBK。中文 Windows 程序有用 GBK 也有用 UTF-16 的,两个都要试:
for enc in ("gbk", "utf-16le", "utf-8"):
hits = [hex(i) for i in [0] ] # d.find(s.encode(enc))
print(enc, d.count("卡密".encode(enc)))
2.4 上行动力:找"破解开关"的名字
加壳程序的特征字符串(错误消息、环境变量名、事件名)通常不加密, 因为它们在壳的自解密 stub 里就要用到。搜这些模式命中率极高:
import re
for m in sorted(set(re.findall(rb'EVO_[A-Z0-9_]+', d))): print(m)
for m in sorted(set(re.findall(rb'[a-z][a-z0-9_]{4,40}(?:_mode|_fixture|_fallback|_accept|_failed|_ready|_skipped)', d))): print(m)
for m in sorted(set(re.findall(rb'/[a-z][a-z0-9_./-]{3,50}', d))): print(m) # API 路径
本案例一击命中:
EVO_PASS_ACCEPT_ANY_AUTH ← 破解总开关
EVO_PASS_PRESERVE_INVALID_AUTH ← 诊断开关
EVO_PASS_DEV_ONLY
/user/authorize /session/validate /v2/user/subscription/ /v2/product/
三、动态侦察(Phase 2)—— 本技能的重心
3.1 提权运行(必须)
这类工具 manifest 是 requireAdministrator。
非提权 Start-Process 报「请求的操作需要提升」;frida.spawn 报 NotSupportedError 0x2e4。
三种可用提权方式(按可靠性排序):
A. schtasks 计划任务(最可靠,推荐)
schtasks /create /tn ALICE_Run /tr "cmd.exe /c <ASCII工作目录>\scripts\run.cmd" /sc once /st 23:59 /rl HIGHEST /f
rem 本包 scripts\boot_schtasks.cmd 已封装: 传工作目录当第一个参数即可
schtasks /run /tn ALICE_Run
用一次性 Start-Process -Verb RunAs boot.cmd(用户 UAC 静默放行)去创建并触发任务,
任务本体跑在 HIGHEST 上下文且完全脱离会话,父进程被中断也不影响。
B. Start-Process -Verb RunAs(简单,但生命周期绑定调用者)
Start-Process -FilePath 'app.cmd' -Verb RunAs -PassThru -WindowStyle Hidden
C. Frida 提权(要做插桩时)
dev = frida.get_local_device()
pid = dev.spawn([EXE], cwd=CWD, stdio="pipe", env={"EVO_PASS_ACCEPT_ANY_AUTH": "1"})
⚠️ 中文路径陷阱:Windows PowerShell 5.1 处理含中文的路径会乱码 (
F:\alice破甲→F:\alice鐮寸敳),Out-File/schtasks/Start-Process全部失败。 所有提权脚本必须放在纯 ASCII 路径(本案例用C:\alice_evoc\), 且.cmd文件用 GBK(936) 编码保存、.ps1用 UTF-8 with BOM。
3.2 Frida 探针(Frida 17+ API 必读)
⚠️⚠️ Frida 17 移除了
Module.getExportByName()。 旧代码用它会导致所有钩子静默失败(脚本不报错,但一个事件都不产生)。 这是本案例最初两轮 frida 只输出模块列表、零行为事件的根本原因。
正确写法:
function resolve(modName, expName){
if (modName) {
try { const m = Process.getModuleByName(modName);
const p = m.getExportByName(expName); if (p) return p; } catch(e){}
}
try { const p2 = Module.getGlobalExportByName(expName); if (p2) return p2; } catch(e){}
return null;
}
其它要点:
spawn必须带stdio="pipe",否则dev.input()喂不进 stdin(程序卡在"请输入卡密:")- RPC 导出名
script.exports_sync.dump_range()里的下划线会被自动转 camelCase; 建议 RPC 用无下划线名(dumprange/saverange/findkey) - exit gate(在
ExitProcess/exit里while(!released){})能冻结进程供 dump, 但冻结期间脚本会超时销毁,dump 必须在 JS 侧用File直接落盘,不能走 RPC
3.3 必钩清单(本案例 96 钩子,命中率见右)
【输入】 getchar / _getch / fgets / gets / scanf / ReadConsoleW/A ← 抓卡密输入
【输出】 WriteConsoleW/A / WriteFile(stdout) ← 抓提示文本
【文件】 CreateFileW/A / WriteFile / ReadFile / CopyFileW / DeleteFileW
【内存】 VirtualProtect / VirtualAlloc / WriteProcessMemory ← 抓自解密/自补丁
【模块】 LoadLibraryW/A/ExW / GetProcAddress ← 抓延迟导入
【网络】 connect / getaddrinfo / DnsQuery_A/W / send / WSASend / recv / WSARecv
WinHttpOpen / WinHttpConnect / WinHttpOpenRequest / WinHttpSendRequest / WinHttpReadData
【进程】 CreateProcessW/A / ShellExecuteExW / WinExec / system
【注册表】 RegCreateKeyExW / RegSetValueExW / RegOpenKeyExW
【加密】 BCryptOpenAlgorithmProvider / BCryptEncrypt / BCryptDecrypt / BCryptGenerateSymmetricKey
【反调试】 IsDebuggerPresent / NtQueryInformationProcess
【凭据】 GetComputerNameW / GetVolumeInformationW / GlobalMemoryStatusEx / GetAdaptersInfo
【证书】 CertAddEncodedCertificateToStore ← 抓根证书植入
完整探针见 scripts/hook_agent.js(24 KB,可直接复用)。
3.4 WriteProcessMemory 自我补丁的解读
壳启动时会对自身进程(proc = 0xffffffffffffffff)做几十次 WriteProcessMemory:
WPM(proc=0xffffffffffffffff, addr=0x7fffxxxxxxx, size=5) e9 ab 17 ef ff ← jmp rel32
WPM(proc=0xffffffffffffffff, addr=..., size=6) ff 25 00 00 00 00 ← jmp [rip+0]
VirtualProtect(addr=..., size=0x1000, prot=0x20) ← PAGE_EXECUTE_READ
这是 VM/壳的 IAT 混淆:把已加载 DLL 的 IAT 槽改写成跳到 VM 桩的 jmp。
看到这个模式就能确认壳类型,且说明所有 API 调用都会经过 VM。
四、突破口:Evo_Crack.exe 的真实工作原理
下列链条是 Evo 系(本例)特有的破解链。换一个产品,链条可能完全不同—— 但"先判定授权形态,再选绕过路线"的方法论是通用的。
4.1 完整链条(内存 dump 还原)
[1] 自检提权 OpenProcessToken + GetTokenInformation(20)
未提权 -> 日志 elevation_skipped + 提示 "run elevated or add 127.0.0.1 scheats.club"
[2] hosts 劫持 改写 %WINDIR%\System32\drivers\etc\hosts
把 scheats.club / www.scheats.club / api.scheats.club 指向 127.0.0.1
随后执行 ipconfig /flushdns >nul 2>&1
失败 -> hosts_override_failed
[3] 证书植入 从 PE 资源取内嵌 CER(日志 "embedded CER win32="),
装入 local-machine ROOT store(本机受信任根)
已存在 -> certificate_already_trusted
失败 -> certificate_trust_failed
[4] 本地 TLS bind/listen 127.0.0.1:443
用 SSPI 实现 TLS 服务端:
AcquireCredentialsHandleW / AcceptSecurityContext /
CompleteAuthToken / QueryContextAttributes(STREAM_SIZES) / DecryptMessage
就绪 -> tls_listener_ready
[5] 拉起本体 找同目录 EVO.exe / evo.exe -> CreateProcessW(EVO)
找不到 -> "same-directory EVO.exe/evo.exe not found"
[6] 伪造授权 拦截并伪造以下请求的响应:
/user/authorize 登录授权(读 authorization: Bearer + password)
/session/validate 会话校验
/v2/user/subscription/ 订阅状态(决定 VIP 是否有效)
/v2/product/ 产品信息
重写响应体: "Hwid":"..." / "UserId":"..." / "server_time":"..."
[7] 发放凭据 本地生成 token + user_id -> local_auth_identity_issued
EVO_PASS_ACCEPT_ANY_AUTH 时:接受任意非空凭据 -> local_auth_any_accept
[8] 写授权文件 create C:\Evo -> 写临时 user.dat -> 原子替换 C:\Evo\user.dat
失败链:create C:\Evo failed / create temporary user.dat failed /
write temporary user.dat failed / replace C:\Evo\user.dat failed
[9] 记日志 evo_pass.jsonl(JSON Lines)
4.2 破解开关
| 开关 | 形式 | 作用 |
|---|---|---|
EVO_PASS_ACCEPT_ANY_AUTH | 环境变量 / --accept-any-auth | 本地接受任意非空凭据,不要求上游通过 |
EVO_PASS_PRESERVE_INVALID_AUTH | 环境变量 / --preserve-invalid-auth | 保留上游无效响应(诊断,不伪造) |
EVO_PASS_DEV_ONLY | 环境变量 | 开发模式(触发 DecryptMessage failed 分支) |
--elevated | CLI | 标记已提权 |
内部标识:EVO_PASS(用于识别自身环境/子进程)、UA EVO_PASS/1.0
4.3 上游协议(实测)
POST /1 HTTP/1.1
connection: close
content-length: 378
host: freakluke.me:8880
<378 字节二进制 body>
body 结构(三次采样一致):
off 0 uint32 LE = 378 自描述长度
off 4 uint32 LE = 变化值 nonce / tick
采样: 0x00067429 / 0x0006a4e3 / 0x000892a0 / 0x000900a0
off 8.. 高熵密文 AES-256-CBC
证据: BCryptOpenAlgorithmProvider("AES") + BCryptSetProperty(ChainingModeCBC)
+ BCryptGenerateSymmetricKey + BCryptEncrypt/Decrypt
尾部 8 字节 0 对齐 + 24~32 字节尾块(HMAC/校验)
响应 JSON 字段:Hwid / UserId / server_time / user_id / username / token
4.4 中文提示串全表(UTF-16LE,dump 0x28190-0x28400)
请输入卡密:
未配置服务器信息 连接服务器失败 发送失败 接收失败
无效数据包 无效数据 数据损坏 客户端版本停止服务
客户端版本已过期 未知错误 失败: 错误码
初始化 卡密不能为空。 卡密长度超过 511 字节。
卡密必须以 EVO 开头。 卡密验证 登录完整性校验 登录成功
4.5 错误码对照(实测)
| 错误码 | 触发条件 |
|---|---|
| 4 | 无网络 / 服务器不可达(接收失败) |
| 8 | 服务器返回非法响应(响应解析失败) |
| 1201 | 真实服务器响应但业务拒绝,或响应解密失败 |
判读技巧:错误码从 4 → 8 → 1201 变化,说明链路在推进(DNS → TCP → 业务), 可以用来定位卡在哪一环。
五、复现与验证流程(Phase 3)
5.1 Mock 上游服务器
# scripts/mock8880.py —— 捕获 + 应答
import socket, threading
def build_resp(body, ctype="application/octet-stream", status="200 OK"):
hdr = ("HTTP/1.1 %s\r\nContent-Type: %s\r\nContent-Length: %d\r\nConnection: close\r\n\r\n"
% (status, ctype, len(body))).encode()
return hdr + body
s = socket.socket(); s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0", 8880)); s.listen(16)
必须提权才能 bind 8880(本案例真实端口;若冲突改成 userspace 端口 + hosts 指向)。
配套 hosts 劫持(务必用完还原):
copy /y "%WINDIR%\System32\drivers\etc\hosts" hosts.bak
echo 127.0.0.1 freakluke.me >> "%WINDIR%\System32\drivers\etc\hosts"
echo 127.0.0.1 scheats.club >> "%WINDIR%\System32\drivers\etc\hosts"
ipconfig /flushdns >nul 2>&1
:: ... 跑目标 ...
copy /y hosts.bak "%WINDIR%\System32\drivers\etc\hosts"
ipconfig /flushdns >nul 2>&1
5.2 环境隔离提示
- 目标机器可能装有 Clash / 代理(
198.18.1.0/15= fake-IP 段)。 看到 DNS 解析出198.18.x.x就是被代理接管了 → 抓包会看到 TCP 通但无 HTTP 响应。 - 用 DoH 拿真实 IP 绕过本地 DNS:
https://1.1.1.1/dns-query?name=<host>&type=A - 本案例真实 IP:
freakluke.me -> 172.67.190.7 / 104.21.73.124(Cloudflare)scheats.club -> 172.67.220.124 / 104.21.17.33
六、常见坑(血泪清单)
| # | 坑 | 症状 | 解法 |
|---|---|---|---|
| 1 | Frida 17 API 变更 | 钩子全静默失效,脚本无报错 | 用 Process.getModuleByName(n).getExportByName(e) |
| 2 | spawn 缺 stdio="pipe" | 卡在"请输入卡密",喂不进输入 | 加 stdio="pipe" |
| 3 | 中文路径 + PowerShell 5.1 | 路径乱码、文件操作全失败 | 提权脚本放纯 ASCII 路径 |
| 4 | .cmd 编码 | 中文路径在 cmd 里变问号 | .cmd 存 GBK(936),.ps1 存 UTF-8 BOM |
| 5 | schtasks 非提权创建 | Access is denied | 用一次性 RunAs 去创建 |
| 6 | RPC 下划线 | unable to find method 'dumpRange' | RPC 名不要用下划线 |
| 7 | exit gate 内调 RPC | script has been destroyed | gate 内用 JS File 直接落盘 |
| 8 | 只搜 GBK | 找不到中文串 | 中文 Windows 程序也可能是 UTF-16LE |
| 9 | 静态搜域名 | 0 命中就放弃 | 加壳程序明文只在内存里,必须 dump |
| 10 | 直接改 exe | 壳自校验/CRC 失败 | 走"伪造服务端"路线,不改二进制 |
七、交付物清单
- 内存 dump:
mod_<name>.bin(主模块 + 全部 DLL + RWX 段) 本案例主模块 37 MB、熵 7.79,反汇编可读 - 静态报告:PE 结构 / 段熵 / 导入表 / 字符串分类
- 行为报告:完整 API 调用时序(含时间戳)
- 协议报告:请求头 + body 结构 + 响应字段 + 错误码表
- Mock 服务端:可复现的
mock8880.py - 探针:
hook_agent.js(96 钩子,Frida 17 兼容) - 运行器:
frida_run.py(spawn + 喂卡密 + dump) - 提权脚手架:
boot.cmd/run.cmd(schtasks 路线)
八、脚本索引
| 脚本 | 用途 |
|---|---|
scripts/hook_agent.js | Frida 17 兼容探针,96 钩子 + RPC(modules/ranges/dumprange/saverange/findkey/ctxdump) |
scripts/frida_run.py | 提权 spawn + dev.input 喂卡密 + 自动 dump |
scripts/mock8880.py | Mock 上游服务器(多响应模式:echo/empty200/raw64/json_true/zeros) |
scripts/boot_schtasks.cmd | schtasks 提权脚手架(需要一次性 RunAs 创建) |
scripts/analyze_dump.py | 内存 dump 分析:段熵 / ASCII / UTF-16LE / GBK / 证书 / 事件名 / API 路径 |
scripts/pe_recon.py | PE 结构 + 导入表 + 段熵快筛 |
九、参考
references/evo-case.md—— 本案例完整实测记录(时间线 + 证据 + 原始日志摘要)references/gotchas.md—— 环境与工具链坑位详解(13 类坑,含 Frida 17 API 变更 / 中文路径 / 提权 / 编码)assets/error-codes-and-protocol.md—— 错误码表 + 8 组验证矩阵 + 请求/响应结构 + 域名解析表assets/README.md—— 资产说明(不含真实卡密)references/cleanup.md—— 分析完成后的环境还原/清理清单(计划任务 / hosts / 根证书 / 授权文件 / 基线比对)
使用方式
启动器(EvoFree)命令行速查
EvoFree.exe # 正常启动 (自动提权)
EvoFree.exe --dry-run # ★ 零副作用自检: 只起服务, 不碰 hosts/证书/evo
EvoFree.exe --cleanup # 精确还原本次改动 (按 evofree.state.json)
EvoFree.exe --restore # 彻底还原 (额外清残留 OpenSSL 目录)
EvoFree.exe --evo "D:\evoc\evo.exe"
EvoFree.exe --server-only # 只起服务, 方便调试
EvoFree.exe --no-elevate # 已提权时跳过
EvoFree.exe --ports 8443,8880 # 自定义监听端口 (默认 443,8880,80)
EvoFree.exe --force-ports # 端口被占用时抢占 (默认只告警)
环境变量:
EVO_SUB_DELAY=5 订阅响应延迟秒数 (0~20, 给 frida attach 留窗口)
EVO_SRV_VER=9.9.9 服务端发布版本 (避免客户端升级后重新打包)
MOCK_MODE=echo mock8880 响应模式 (echo/empty200/raw64/json_true/zeros)
MOCK_PORT=8880 mock8880 监听端口
MOCK_LOG=<path> mock8880 日志路径
配套脚本速查
python scripts\mock8880.py --port 8880 --mode echo # 抓请求/试响应
python scripts\frida_run.py --exe "D:\evoc\Evo_Crack.exe"
python scripts\frida_run.py --list # 只列候选目标
python scripts\pe_recon.py "D:\evoc\evo.exe" # PE 结构+导入表+段熵
python scripts\analyze_dump.py dumps\main.bin # dump 分析
python scripts\evofree\start_evofree.py --evo "..." # 服务+attach 一键
python scripts\evofree\build.py --pack <pack目录> # PyInstaller 打包
所有脚本的路径都相对自身位置推导,可整包搬到任意目录/中文路径运行。 目标 exe 支持自动探测,也可用
--exe/--evo显式指定。
标准作业流程
当用户给出 DMA 外挂目录 + 要求"破解卡密"时:
- 先判定授权形态(见「零」):静态看网络导入 -> 动态钩网络 API -> 确认是否"网络授权 + 本地落盘"。 不是这一类就换路线,别硬套本技能。
- 先跑
pe_recon.py确认产品类型(vmm/leechcore/FTD3XX 三件套) - 建立基线快照(hosts / 服务 / 注册表 Run / 文件 hash)
- 用 schtasks 脚手架提权,先裸跑一次记录错误码与输出
- 用
hook_agent.js做插桩运行,抓输入 / 网络 / 文件 / 内存四条线 - 触发 exit 或手动
gatedump,拿到内存镜像 - 在镜像里搜 UTF-16LE 中文 +
EVO_*常量 +/api/path+ 事件名 → 还原逻辑 - 起 mock 服务器 + hosts 劫持,观察错误码变化定位协议层
- 输出报告 + mock 工具
- 清理现场:删计划任务、还原 hosts、查根证书、确认无
C:\Evo残留(见references/cleanup.md)
不要:
- 不看授权形态就套用本技能的 hosts + 证书链(别的 DMA 可能根本不联网)
- 直接改主程序 exe(壳自校验会让进程自杀)
- 暴力猜卡密(纯联网校验,猜不出来)
- 只搜 ASCII/GBK 就断言"没有明文"(也可能是 UTF-16LE,或压根没 dump)
- 拿
--demo当自检用(会改系统;自检请用--dry-run)
十一、变更记录
v1.0.2(2026-09-18)—— 可用性修复
| # | 问题 | 修复 |
|---|---|---|
| 1 | mock8880.py 写死 C:\alice_evoc\logs\,目录不存在时直接崩 | 日志路径改为按优先级探测(<包>/logs/ → %TEMP% → stderr),自动建目录;新增 --port/--mode/--log/--host |
| 2 | 11 个文件硬编码 C:\Users\alicewe\Desktop\evoc、C:\alice_evoc、F:\alice破甲\... | frida_run.py / start_evofree.py / build.py / mkembed.py / hook_agent.js / boot_schtasks.cmd 全部改为相对脚本位置推导 + 命令行覆盖;目标 exe 自动探测 |
| 3 | --demo 会写 hosts + 装根证书,不是沙箱 | 新增 --dry-run:只起内嵌服务自检,不碰 hosts / 不装证书 / 不拉 evo;--demo 保留但显式告警 |
| 4 | --cleanup 靠字符串模糊匹配,会误删同名注释行 | 改为标记 + 状态文件双轨:hosts 加 # EvoFree local-auth redirect (auto-added),所有改动记入 evofree.state.json,还原时精确删除;新增 --restore 兜底 |
| 5 | 启动时无条件 taskkill 占用 443/80/8880 的进程 | 默认只告警不杀;需抢占加 --force-ports;新增 --ports 自定义端口 |
| 6 | SUB_DELAY 硬编码 5.0;文档章节号重复(两个「九」) | SUB_DELAY 可用 EVO_SUB_DELAY 覆盖;章节号重排为 零~十一 |
| 7 | hook_agent.js dump 目录写死 C:\alice_evoc\dumps\ | 改为多候选探测(C:\alice_evoc → C:\EvoFree → 进程工作目录),取第一个可写的 |
| 8 | docstring 中 \w \. 触发 SyntaxWarning | 全部改为 raw docstring |
验证方式(本轮实测):
--dry-run 自检 -> 3 端点全 200, 且 hosts/证书/SSL 目录零改动 ✅
patch_hosts+install_ca -> hosts 16->22 行, 证书装入, 状态文件已记录 ✅
unpatch+uninstall -> hosts 与基线逐字节一致, 证书归零, SSL 目录移除 ✅
mock8880 干净目录启动 -> 正常监听, 日志自动落到 <包>/logs/ ✅
py_compile 10/10 + node --check 2/2 通过 ✅
十、免卡密本地代理(Themida 版 evo.exe)
完整实现见
references/evofree-local-proxy.md,可运行成品在scripts/evofree/。
若目标 evo.exe 是 Themida 加壳版(与自研 VM 的 Evo_Crack.exe 不同),
走「本地授权服务 + frida 内存补齐」路线:
10.1 三时间字段是真正的门槛
登录是扁平 JSON 很好伪造;订阅响应才卡人。响应会解析进 Authorization+0xC0
的结构体,判定用三个 qword:
| 偏移 | 含义 |
|---|---|
sub+0x40 | 激活时间 |
sub+0x48 | 过期时间 |
sub+0xe8 | 服务器当前时间 |
必须严格 激活 < 服务器时间 < 过期(判定函数 0x1480A0 用 jbe,相等即失败)。
Authorization 自身:+0x100 激活 / +0x108 过期 / +0x180 HTTP 状态 /
+0x188 消息串 / +0x1a8 服务器时间 / +0x1b0 has-response。
UI 状态机在 0x177EDC(每帧调用),要求 status==200 && has!=0 && 服务器时间 < 过期。
10.2 方法学要点(血泪)
- frida.spawn 会被 Themida 察觉(进程不发 HTTP 请求、hook 不触发)→ 改 attach 已运行进程。
- 订阅请求在登录后 ~45ms 就发出 → 必须在服务端给订阅响应加 5~8 秒延迟制造 attach 窗口;
超过 20 秒会触发客户端超时(错误串变
Failed to get subscription data)。 - 加壳目标的字符串必须用运行时 dump 镜像;Themida VM stub 尾部会 push 真实返回地址
(
mov qword [rsp], 0x1469e8→ fetch 真身0x1469E8)。 - 该结构体的时间字段无法用扁平 JSON 键填充(34 组 schema 全失败,
0x14CCA0即 JSON getkey 在订阅路径 0 次调用)→ 内存补齐是唯一可行路径。 - frida 16.x
writeU64需uint64对象,用writePointer(ptr(t));onEnter(args)的args[0]未必是this(0x177EDC的对象在this.context.rsi)。
10.3 成功判据
[info] Current Version : 1.5.12
[info] Got valid subscription until 2036-09-15 19:04:03
且窗口标题变为 Evo Overlay(透明覆盖层 = 进入功能界面)。
Signals
- GitHub stars
- 26
- Forks
- 4
- Last commit
- Sep 2026
ahel review
K1binfo
installs-packages (in scripts/evofree/start_evofree.py)K1binfo
installs-packages (in scripts/frida_run.py)
Automated review, not a security audit. Ruleset v1+k2.
Advanced
- Item type
- skill
- Key
dma-cardkey-evo-crack- Source
- github.com/alicewe1/alice_skill