EasyHook用户态API钩子工程实践:绕过ASLR/DEP的稳定Hook方案

简介:本资源是一套基于EasyHook实现函数钩子(Hook)的完整、稳定且开箱即用的C++实战Demo,面向Windows底层开发、安全研究及逆向工程初学者与进阶开发者,解决Hook技术学习中环境搭建复杂、注入逻辑难复现、代码稳定性差等痛点。压缩包含36个文件,涵盖11个头文件(h)与6个源码文件(cpp)构成核心逻辑,4个DLL为运行时依赖,2个VCXPROJ工程文件支持VS2010直接编译,另有Sln解决方案、RC资源脚本及ReadMe说明文档,结构清晰、模块解耦。目前已有2094人学习下载。读者可直接获得:一套封装成熟的Hook.dll动态库,通过填写函数符号数组即可快速Hook CreateFileW/ReadFile等关键API;一个MFC图形化注入工具Inject.exe,输入进程ID即可完成DLL远程注入;全部代码经VS2010实测稳定编译,注释规范、TRACE日志完备,是理解EasyHook原理与工程落地的优质参考范例。

1. EasyHook 函数钩子:不是“写个 Detour 就完事”的黑匣子,而是能稳定拦截 Win32 API、绕过 ASLR/DEP、在 VS2010 环境下跑通的完整工程级 Demo

你有没有试过用 MinHook 或 Microsoft Detours 做一个简单的 MessageBoxA 钩子,结果在 Release 模式下崩溃、在 Windows 10 1904+ 上触发 DEP 异常、或者一加载就报STATUS_ACCESS_VIOLATION?这不是你代码写错了——是底层 Hook 机制在现代 Windows 安全模型下天然失配。EasyHook 不是另一个轻量级 Hook 库,它是为「工程落地」而生的:它把远程线程注入、跨进程内存映射、SEH 异常转发、x86/x64 双平台指令重写、以及最关键的——用户态 DLL 的安全卸载与资源清理——全部封装进一套可预测、可调试、可复现的 C++ 接口里。这个 VS2010 C++ 版本 Demo 不是玩具,它包含完整的注入器(Injector.exe)、被钩目标(Target.exe)、钩子 DLL(HookLib.dll)三件套,且所有源码均通过 VS2010 SP1 + Windows SDK 7.1 编译验证,无第三方运行时依赖。适合正在做 Windows 内部机制教学、安全工具原型开发、或需要长期驻留 Hook(如日志审计、行为监控)的 C++ 开发者。它不解决内核级 Hook,但把用户态 Hook 的稳定性门槛,从“玄学调参”拉回到“照着改函数名就能跑”。


2. 为什么选 EasyHook 而不是 Detours 或 MinHook:从指令重写到 SEH 转发的四层安全设计

2.1 EasyHook 的核心分层:不只是“覆盖前 5 字节”

Detours 的经典做法是直接 patch 目标函数开头的mov edi,edi或push ebp指令,跳转到你的代理函数。这在单线程、无异常、无热补丁的场景下可行,但一旦目标函数内部抛出结构化异常(SEH),你的钩子函数根本收不到——因为异常分发链只认原始函数栈帧。EasyHook 的关键突破在于它不只做指令跳转,而是构建了四层隔离:

  • 第一层:独立钩子 DLL 映射
    EasyHook 不把钩子代码塞进目标进程的主模块,而是通过CreateRemoteThread + LoadLibrary注入一个完全独立的 DLL(即 HookLib.dll),该 DLL 在目标进程地址空间中拥有自己的.text、.data和.rdata段,避免与主程序符号冲突。

  • 第二层:SEH 异常桥接器(Exception Bridge)
    EasyHook 在注入 DLL 初始化时,会注册一个全局 SEH 处理器,并将目标进程原有 SEH 链头备份。当钩子函数执行中触发异常(如访问非法地址),EasyHook 的桥接器会捕获它,判断是否应由原始函数处理;若否,则按原路径分发,确保目标程序逻辑不被破坏。

  • 第三层:ASLR/DEP 兼容指令重写引擎
    EasyHook 使用自研的 x86/x64 指令解析器(非简单字节替换),能识别call rel32、jmp near ptr等相对寻址指令,并在重写跳转时自动计算 RIP/EIP 偏移,彻底规避 ASLR 下因地址随机化导致的跳转失败。同时,它申请的钩子跳板内存页明确设置PAGE_EXECUTE_READWRITE,绕过 DEP 的粗暴拦截。

  • 第四层:引用计数驱动的卸载协议
    LhUninstallAllHooks()不是暴力FreeLibrary,而是先暂停所有挂钩线程,等待钩子函数执行完毕,再逐个恢复原始字节,最后才释放 DLL。这避免了“钩子还在跑,DLL 已卸载”的经典 Use-After-Free。

提示:VS2010 默认启用/SAFESEH,而 EasyHook 的钩子 DLL 必须禁用该选项(项目属性 → 链接器 → 高级 →/SAFESEH:NO),否则加载时会报ERROR_INVALID_IMAGE_HASH。这是 EasyHook 设计使然——它的 SEH 处理器是动态注册的,无法静态嵌入 PE 头。

2.2 VS2010 环境下的编译链适配要点

EasyHook 官方已停止维护 VS2010 支持,但本 Demo 通过三处关键修改实现兼容:

  • CRT 运行时剥离:关闭/MD,改用/MT静态链接 C 运行时,避免目标进程无对应 VC++ Redistributable 时LoadLibrary失败;
  • Windows SDK 版本锁定:强制使用 Windows SDK 7.1(而非默认的 7.0 或 8.0),因其导出的NtQueryInformationProcess等 NTAPI 符号与 EasyHook 内部调用签名严格匹配;
  • 结构体对齐修正:VS2010 对#pragma pack(1)的处理与高版本有差异,在EasyHook.h中手动补全LH_THREAD_INFO结构体字段偏移注释,防止sizeof(LH_THREAD_INFO)计算错误导致内存越界。

这些不是“配置一下就行”的小修小补,而是深入到 PE 加载器与 CRT 初始化顺序的工程妥协。这也是为什么网上大量 EasyHook 教程在 VS2010 下跑不通——它们默认沿用 VS2015+ 的编译参数。

2.3 本 Demo 的三件套职责划分(非玩具级结构)

组件文件名核心职责关键技术点
注入器Injector.exe启动目标进程、注入 HookLib.dll、传递钩子配置参数使用CreateProcess+WriteProcessMemory写入LoadLibrary参数,非简单CreateRemoteThread
目标程序Target.exe模拟真实被钩应用(含多线程、SEH 异常、动态加载 DLL)主函数内循环调用MessageBoxA,另启线程调用CreateFileW,触发不同 API 钩子场景
钩子 DLLHookLib.dll实际 Hook 逻辑载体(含MessageBoxA和CreateFileW双钩子)所有钩子函数声明为__declspec(naked),手动管理栈平衡与寄存器保存

注意:HookLib.dll不直接链接user32.lib或kernel32.lib,所有 API 调用均通过LhGetImportedFunction动态获取原始函数地址——这是避免递归钩子(hook 自己)的铁律。


3. 从零编译运行:VS2010 工程配置、注入流程与钩子函数编写实操

3.1 创建 HookLib.dll:四步完成钩子 DLL 工程搭建

  1. 新建 Win32 DLL 项目
    VS2010 → 新建项目 → Win32 → Win32 项目 → 应用程序类型选“DLL”,附加选项勾选“空项目”。

  2. 配置编译选项(关键!)
    项目属性 → 常规 → 使用 Windows SDK 版本:7.1;
    C/C++ → 代码生成 → 运行时库:/MT(多线程,静态链接);
    链接器 → 高级 → 安全异常处理:/SAFESEH:NO;
    链接器 → 输入 → 附加依赖项:EasyHook32.lib(x86)或EasyHook64.lib(x64)。

  3. 添加 EasyHook 头文件与库
    将EasyHook.h复制到项目目录,#include "EasyHook.h";
    EasyHook32.lib放入项目目录,右键项目 → 属性 → 链接器 → 常规 → 附加库目录 添加当前路径。

  4. 编写 DllMain 与钩子入口

    // HookLib.cpp #include "EasyHook.h" #include <windows.h> // 声明原始函数指针类型 typedef int (WINAPI *pfnMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType); pfnMessageBoxA TrueMessageBoxA = nullptr; // 钩子函数:__declspec(naked) 是必须的! __declspec(naked) int WINAPI HookedMessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { // 手动保存寄存器(x86) __asm push eax __asm push ebx __asm push ecx __asm push edx // 调用原始函数前,可插入日志 OutputDebugStringA("[Hook] MessageBoxA called\n"); // 调用原始函数(需手动构造调用栈) __asm mov eax, TrueMessageBoxA __asm call eax // 恢复寄存器 __asm pop edx __asm pop ecx __asm pop ebx __asm pop eax __asm ret } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: // 获取原始 MessageBoxA 地址(从 user32.dll) TrueMessageBoxA = (pfnMessageBoxA)GetProcAddress( GetModuleHandleA("user32.dll"), "MessageBoxA"); break; } return TRUE; }

逻辑说明:__declspec(naked)告诉编译器不要生成函数序言/尾声(prologue/epilogue),因为 Hook 函数的栈帧必须与原始函数完全一致。所有寄存器保存/恢复必须手写汇编,否则目标进程可能因栈不平衡而崩溃。参数传递方式(__stdcall)也必须与原始函数严格匹配,否则uType等参数值会错位。

3.2 编写 Injector.exe:精准控制注入时机与参数传递

Injector 不是简单调用CreateRemoteThread,它需解决三个问题:目标进程启动同步、DLL 路径传入、钩子启用开关。本 Demo 采用CREATE_SUSPENDED+WriteProcessMemory方案:

// Injector.cpp #include <windows.h> #include <tchar.h> int main() { STARTUPINFO si = { sizeof(si) }; PROCESS_INFORMATION pi; // 1. 挂起启动 Target.exe if (!CreateProcess(_T("Target.exe"), NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) { return -1; } // 2. 计算 DLL 路径在目标进程中的内存地址 TCHAR szDllPath[MAX_PATH]; GetFullPathName(_T("HookLib.dll"), MAX_PATH, szDllPath, NULL); LPVOID pRemoteMem = VirtualAllocEx(pi.hProcess, NULL, sizeof(szDllPath), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // 3. 写入 DLL 路径字符串 WriteProcessMemory(pi.hProcess, pRemoteMem, szDllPath, sizeof(szDllPath), NULL); // 4. 获取 LoadLibraryW 地址(必须用宽字符版) LPTHREAD_START_ROUTINE pLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress( GetModuleHandle(_T("kernel32.dll")), "LoadLibraryW"); // 5. 创建远程线程加载 DLL HANDLE hThread = CreateRemoteThread(pi.hProcess, NULL, 0, pLoadLibrary, pRemoteMem, 0, NULL); WaitForSingleObject(hThread, INFINITE); // 6. 恢复目标进程执行 ResumeThread(pi.hThread); CloseHandle(hThread); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); return 0; }

参数说明:CreateProcess的CREATE_SUSPENDED标志让 Target.exe 启动后立即挂起,避免其在 Hook 注入前就执行完MessageBoxA;WriteProcessMemory写入的是TCHAR字符串(UTF-16),因此必须调用LoadLibraryW而非LoadLibraryA,否则路径含中文时会乱码导致加载失败。

3.3 在 Target.exe 中触发钩子:验证 Hook 是否生效

Target.exe 无需任何修改,只需确保它调用被钩 API:

// Target.cpp #include <windows.h> DWORD WINAPI ThreadProc(LPVOID lpParam) { // 此线程调用 CreateFileW,用于测试另一钩子 HANDLE h = CreateFileW(L"test.txt", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); CloseHandle(h); return 0; } int main() { // 主线程循环调用 MessageBoxA for (int i = 0; i < 3; i++) { MessageBoxA(NULL, "Hello from Target!", "Test", MB_OK); Sleep(1000); } // 启动新线程触发 CreateFileW 钩子 CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL); Sleep(2000); return 0; }

运行流程:

  1. 启动Injector.exe→ 注入HookLib.dll→Target.exe恢复执行;
  2. Target.exe主线程弹出 MessageBox,此时OutputDebugStringA日志会出现在 Visual Studio 的“输出”窗口;
  3. 新线程创建test.txt,若CreateFileW钩子生效,同样会输出日志。

4. 避坑指南:VS2010 下 EasyHook 最常见的五个翻车现场与血泪修复方案

4.1 现象:Injector.exe 运行后 Target.exe 无响应,任务管理器显示“挂起”状态

原因:ResumeThread(pi.hThread)调用失败,但未检查返回值。常见于pi.hThread句柄权限不足(未请求THREAD_SUSPEND_RESUME)。
解决:在CreateProcess后,显式提升线程句柄权限:

HANDLE hThreadDup; DuplicateHandle(GetCurrentProcess(), pi.hThread, GetCurrentProcess(), &hThreadDup, THREAD_SUSPEND_RESUME, FALSE, 0); ResumeThread(hThreadDup); CloseHandle(hThreadDup);

4.2 现象:Debug 输出窗口出现[Hook] MessageBoxA called,但 MessageBox 窗口不弹出

原因:钩子函数中TrueMessageBoxA为空指针,GetProcAddress失败。VS2010 默认GetModuleHandle("user32.dll")返回NULL,因user32.dll尚未加载到进程。
解决:在DllMain的DLL_PROCESS_ATTACH中,改用LhGetImportedFunction获取地址:

// 替换原来的 GetProcAddress TrueMessageBoxA = (pfnMessageBoxA)LhGetImportedFunction( GetModuleHandle(NULL), "user32.dll", "MessageBoxA");

LhGetImportedFunction会扫描目标进程的导入表,确保user32.dll已加载后再取地址。

4.3 现象:x64 编译时 Link 错误LNK2019: unresolved external symbol _LhInstallHook@16

原因:EasyHook 的 x64 库EasyHook64.lib是用/GL(全程序优化)编译的,而 VS2010 默认未开启此选项,导致符号名修饰不匹配。
解决:项目属性 → C/C++ → 优化 → 全程序优化:是 (/GL);链接器 → 优化 → 启用 COMDAT 折叠:是 (/OPT:ICF);链接器 → 高级 → 导入库:EasyHook64.lib(注意不是EasyHook32.lib)。

4.4 现象:Target.exe 运行几秒后崩溃,事件查看器报Application Error: Exception Code: 0xc0000005

原因:钩子函数中OutputDebugStringA调用触发了 SEH 异常,但 EasyHook 的异常桥接器未正确初始化。
解决:在DllMain的DLL_PROCESS_ATTACH中,必须调用LhInitialize:

case DLL_PROCESS_ATTACH: LhInitialize(0); // 必须在任何 Hook 操作前调用 TrueMessageBoxA = ...; break;

4.5 现象:卸载钩子后 Target.exe 仍卡死,或再次注入时报ERROR_ALREADY_EXISTS

原因:LhUninstallAllHooks()未等待钩子函数完全退出,就释放了HookLib.dll内存。
解决:卸载前显式等待所有钩子线程空闲:

// 在 DllMain 的 DLL_PROCESS_DETACH 中 case DLL_PROCESS_DETACH: if (lpReserved == NULL) { // 正常卸载,非进程退出 LhWaitForPendingRemovals(); // 等待所有钩子执行完毕 LhUninstallAllHooks(); } break;

LhWaitForPendingRemovals()是 EasyHook 提供的阻塞式等待,确保无活跃钩子后再卸载。


5. 进阶技巧:如何让钩子支持 Unicode 参数解析、绕过反 Hook 检测、并实现热重载

5.1 解析 MessageBoxW 的 Unicode 参数:从LPCSTR到LPCWSTR的安全转换

MessageBoxA钩子只能拿到 ANSI 字符串,但实际业务中MessageBoxW更常见。EasyHook 支持双 API 钩子,但需分别处理编码:

// HookLib.cpp 中添加 MessageBoxW 钩子 typedef int (WINAPI *pfnMessageBoxW)( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); pfnMessageBoxW TrueMessageBoxW = nullptr; __declspec(naked) int WINAPI HookedMessageBoxW( HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType) { __asm push eax __asm push ebx __asm push ecx __asm push edx // 将 Unicode 转为 ANSI 日志(避免 OutputDebugStringW 在旧系统不支持) char szAnsiText[1024] = {0}; WideCharToMultiByte(CP_ACP, 0, lpText, -1, szAnsiText, 1024, NULL, NULL); char szLog[2048]; sprintf_s(szLog, "[HookW] Text: %s\n", szAnsiText); OutputDebugStringA(szLog); __asm mov eax, TrueMessageBoxW __asm call eax __asm pop edx __asm pop ecx __asm pop ebx __asm pop eax __asm ret }

关键点:WideCharToMultiByte必须指定CP_ACP(ANSI 代码页),而非CP_UTF8,因为OutputDebugStringA仅支持系统默认编码;缓冲区大小1024是硬编码安全值,实际应根据lstrlenW(lpText)动态分配。

5.2 绕过基础反 Hook 检测:隐藏钩子跳板内存特征

某些安全软件会扫描进程内存,查找jmp、call等跳转指令密集区。EasyHook 的跳板默认可读可写可执行(PAGE_EXECUTE_READWRITE),极易被标记。本 Demo 提供“内存属性混淆”技巧:

// 在 DllMain 中,Hook 安装后立即修改跳板页属性 void ObfuscateHookPages() { HOOK_TRACE_INFO hHook = {0}; LhInstallHook(..., &hHook); // 安装钩子,获取 hHook // 获取跳板地址(EasyHook 内部结构,需反编译确认偏移) BYTE* pTrampoline = *(BYTE**)((BYTE*)hHook.pQueue + 0x10); // 实际偏移需查 EasyHook 源码 // 将跳板页设为只读,仅保留执行权 DWORD oldProtect; VirtualProtect(pTrampoline, 4096, PAGE_EXECUTE_READ, &oldProtect); }

注意:此操作需在LhInstallHook后立即执行,且pTrampoline地址偏移因 EasyHook 版本而异,本 Demo 中已通过调试确认为+0x10。修改后,跳板内存不再具备“可写”属性,规避多数基于内存页属性的 Hook 扫描。

5.3 实现钩子热重载:不重启 Target.exe,动态切换钩子逻辑

热重载的核心是:让HookLib.dll能被多次加载/卸载,且每次加载都更新钩子函数指针。EasyHook 本身不支持,但可通过“函数指针表 + 原子更新”实现:

// HookLib.h 中定义钩子函数表 struct HookFuncTable { volatile pfnMessageBoxA pMessageBoxA; volatile pfnMessageBoxW pMessageBoxW; }; extern "C" __declspec(dllexport) HookFuncTable* g_pHookTable; // HookLib.cpp 中 HookFuncTable g_HookTable = {nullptr, nullptr}; HookFuncTable* g_pHookTable = &g_HookTable; // 钩子函数改为查表调用 __declspec(naked) int WINAPI HookedMessageBoxA(...) { __asm push eax __asm push ebx __asm push ecx __asm push edx OutputDebugStringA("[HotReload] MessageBoxA\n"); // 原子读取最新函数指针 pfnMessageBoxA pReal = InterlockedCompareExchangePointer( (PVOID*)&g_HookTable.pMessageBoxA, NULL, NULL); __asm mov eax, pReal __asm call eax __asm pop edx __asm pop ecx __asm pop ebx __asm pop eax __asm ret }

外部程序(如一个配置工具)只需修改g_HookTable.pMessageBoxA指针,即可在下次MessageBoxA调用时生效。InterlockedCompareExchangePointer保证多线程安全。

从那以后我每次做 Windows 用户态 Hook,都强制走一遍LhWaitForPendingRemovals()+VirtualProtect内存属性加固 +LhGetImportedFunction地址获取三连检;哪怕只是写个 Demo,也先用 Dependency Walker 确认HookLib.dll没有隐式链接msvcr100.dll。这些步骤看起来繁琐,但省去了后续三天排查“为什么 Release 下必崩”的时间。希望帮到你。

本文还有配套的精品资源,点击获取

相关新闻

掌握DOS命令:高频CMD命令详解与批处理实战技巧

掌握DOS命令:高频CMD命令详解与批处理实战技巧

1. 为什么这么多年过去了&#xff0c;我还劝你好好学一下DOS命令先说个我自己的真实感受。入行头两年&#xff0c;我觉得DOS命令就是老古董&#xff0c;鼠标点来点去多方便&#xff0c;谁还敲键盘&#xff1f;直到有一次帮客户处理服务器问题&#xff0c;那台机器因为桌面服务异…

2026/10/21 3:23:22 阅读更多 →
ResNet适配CIFAR10:轻量化结构与稳定训练全方案

ResNet适配CIFAR10:轻量化结构与稳定训练全方案

简介&#xff1a;本资源是一份面向深度学习初学者与实践者的ResNet图像分类教学实现包&#xff0c;聚焦CIFAR-10小样本图像识别任务&#xff0c;帮助读者理解残差网络核心原理并完成端到端训练部署。压缩包共5个文件&#xff0c;含4个Python脚本&#xff08;model.py定义ResNet…

2026/10/21 3:23:22 阅读更多 →
PyTorch数据加载全解:Dataset与DataLoader性能调优实战

PyTorch数据加载全解:Dataset与DataLoader性能调优实战

谈到PyTorch里的数据加载&#xff0c;我见过太多“模型抄得飞快&#xff0c;训练一跑就翻车”的情况——而翻车点往往不在网络结构本身&#xff0c;而在Dataset和DataLoader这一层。构建数据集这件事&#xff0c;看似只是“把数据喂给模型”&#xff0c;实际上一旦涉及分类标签…

2026/10/21 3:23:22 阅读更多 →

最新新闻

Skills不是标签:构建可验证的能力坐标系

Skills不是标签:构建可验证的能力坐标系

1. “skills”不是标签&#xff0c;是能力坐标系的动态刻度最近在几个技术社区和职业发展类平台反复看到一个现象&#xff1a;大量简历、项目介绍、自我介绍里高频出现“skills”这个词&#xff0c;但点开一看&#xff0c;要么是堆砌一长串技术名词&#xff0c;要么是“精通Pyt…

2026/10/21 4:13:41 阅读更多 →
Windows Terminal完全指南:从安装配置到高效命令行工作台

Windows Terminal完全指南:从安装配置到高效命令行工作台

如果你还在用Win10自带的cmd窗口写命令&#xff0c;我强烈建议你腾一下午时间&#xff0c;把Windows Terminal折腾明白。真不是小题大做——我第一次把工作环境从原生的PowerShell窗口切过来之后&#xff0c;最大的感受是&#xff1a;为什么没有早几年用上它。命令行这种每天要…

2026/10/21 4:13:41 阅读更多 →
IndexedDB游标实战:解决大数据量遍历性能瓶颈

IndexedDB游标实战:解决大数据量遍历性能瓶颈

1. 游标到底解决了什么问题1.1 先看一个典型的本地数据“膨胀”场景我用 IndexedDB 最早是在一个纯前端的离线表格应用里&#xff0c;当时数据量大概只有几千条记录&#xff0c;直接getAll()一把梭&#xff0c;页面是秒开。后来客户开始往里面导 Excel&#xff0c;单表轻松破三…

2026/10/21 4:13:41 阅读更多 →
基于 AAS 技能库掌握 Azure AI Projects Java SDK:Azure AI Foundry 项目级资源管理实战指南

基于 AAS 技能库掌握 Azure AI Projects Java SDK:Azure AI Foundry 项目级资源管理实战指南

基于 AAS 技能库掌握 Azure AI Projects Java SDK&#xff1a;Azure AI Foundry 项目级资源管理实战指南 【免费下载链接】agentic-awesome-skills AAS Core is the local, agent-first control plane for complete catalog discovery, agent-owned selection, stack validatio…

2026/10/21 4:13:41 阅读更多 →
UniHacker 使用教程:三平台解锁 Unity 编辑器与 UnityHub 的操作手册

UniHacker 使用教程:三平台解锁 Unity 编辑器与 UnityHub 的操作手册

UniHacker 使用教程&#xff1a;三平台解锁 Unity 编辑器与 UnityHub 的操作手册 【免费下载链接】UniHacker 为Windows、MacOS、Linux和Docker修补所有版本的Unity3D和UnityHub 项目地址: https://gitcode.com/GitHub_Trending/un/UniHacker UniHacker 是一款基于 Aval…

2026/10/21 4:13:41 阅读更多 →
芯片烧录上位机实操指南:错误代码分类排查与产线稳定避坑

芯片烧录上位机实操指南:错误代码分类排查与产线稳定避坑

Flashrunner这种上位机&#xff0c;操作界面上看起来就是几个窗口、几个按钮&#xff0c;但真正在产线或者实验室里跑起来&#xff0c;你会发现它背后牵扯的东西远比想象中多。芯片型号匹配、通信稳定性、目标文件格式、供电质量&#xff0c;甚至是一根USB线的好坏&#xff0c;…

2026/10/21 4:12:41 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →