Wintel平台C/C++反逆向实战:一条反调试、混淆与自校验的加固链
在Windows Intel这条软件分发主路径上C/C编译出来的Native程序一直是“逆向破解”的重灾区。很多开发者花几个月写出来的算法、协议、授权校验到了别人手里可能一个晚上就被定位到关键函数然后几行汇编补丁就绕过。所谓的“Wintel机器代码反逆向”其实就是围绕x86/x64原生代码做防御反调试、反静态分析、防篡改、关键逻辑保护把这些手段组合成一条链条让破解的成本远高于重新实现一个功能的成本。这篇要聊的是C/C在Windows/Intel平台下做反逆向破解保护的思路和实战细节。适合正在维护Windows客户端、自己写授权体系、或者被“核心算法必须藏在本地”这种需求折磨过的开发者。我会把这些年在真实项目里踩过的坑、验证过的做法、以及最终我认为值得投入的方向按比较实操的顺序讲清楚。1. 先搞清楚反逆向在防谁威胁模型比技术更重要很多人一上来就堆反调试、加壳、虚拟机保护结果保护强度没上去维护成本却翻了好几倍。我个人的经验是动手写第一行保护代码之前至少要回答三个问题对手是普通用户还是专业逆向人员他们最想拿到的是一段代码、一个算法还是一个授权逻辑你这套软件能接受多少性能损耗和兼容性风险先把威胁模型想清楚后面所有技术选型都会变得非常明确。1.1 逆向攻击的常规路径在Wintel平台上攻击者拿到一个C/C编译的PE文件通常会按这条路径走先跑字符串提取、导入表分析快速判断程序做了什么。比如代码里有明显的“Invalid License”“Activation failed”那授权逻辑就在附近。再用反汇编器对照伪代码定位关键函数。C/C的符号表如果没清干净等于直接把地图交给对方。接着开调试器下断点、单步跟踪观察程序在哪个位置读取了关键数据、做了比较。找到跳转分支后直接用十六进制编辑或调试器改一个字节把“跳转”改成“不跳转”或者把“不跳转”改成“跳转”。这条路径里最廉价也最致命的其实是第一步字符串和导入表。很多团队把时间全花在高级保护上却忘了把调试符号、PDB、版本信息这些基础“导线”剪断。我见过一个商业软件的demo版PDB文件直接躺在安装目录里逆向人员连断点都懒得找直接用源码级调试。这个教训比任何技术都值钱。1.2 保护目标与成本反逆向的保护目标通常可以分成三类保护“授权/许可”逻辑防止序列号被绕过、破解版被传播。保护“核心算法/协议”不被提取比如同类产品想抄你的特征提取逻辑。保护“完整性/信誉”防止你的安装包被二次打包植入广告或木马后还挂着你的签名。这三种目标的防御重点完全不同。保护授权重点做反调试和反补丁保护算法重点做代码混淆和虚拟化保护完整性重点做签名校验和自校验。如果你想一套方案通吃保护强度会分散性能和兼容性也会出问题。成本方面我的建议是“分层递进”基础层负责把90%的普通用户挡在门外中层级让熟练的逆向工程师多花几个小时最高层只保护三五个最核心的函数。不要试图做到绝对不可逆那是伪命题。只要破解成本高于重新实现的成本保护就是成功的。2. C/C 代码里能落地的反逆向手法Wintel平台下的反逆向手段很多但真的能在C/C项目里稳定落地、不至于把自己坑死的我想重点讲四个方向。2.1 反调试尽量把调试器挡在运行前反调试是所有保护的第一道关卡。为什么因为如果对方连调试器都开不起来静态分析就会被混淆和加密折腾得很难受。Windows下常见的反调试检测点包括IsDebuggerPresent()检查进程环境块里的调试器标志。NtQueryInformationProcess查询ProcessDebugPort、ProcessDebugFlags等。CheckRemoteDebuggerPresent。时间差检测正常指令执行和单步调试下的耗时差异很大。硬件断点扫描遍历线程上下文检查Dr0~Dr3寄存器的值。SetUnhandledExceptionFilter配合特殊异常看异常处理链是否被调试器干预。从一个防守者的角度我不会只依赖某一个检测点而是把三五个检测点分散到程序不同阶段。比如启动前两秒先检测时间差进入核心函数前再扫描硬件断点授权校验时再查一次调试端口。这样即使对方用插件把其中一个检测点屏蔽了剩下的检测点还是会拖慢进度。写C/C反调试代码有个很现实的坑Release 优化编译后逻辑很容易被编译器重排或内联掉。比如你写了一个空函数里面只有反调试检测调用点没有被外部观察到编译器可能直接删除整段调用。解决办法是让检测函数的返回值参与后续计算并且用一个volatile或者外部不可见的方式“消费”这个结果让编译器认为它是有副作用的。2.2 反静态分析混淆与控制流平坦化反调试不是万能的对方可以用静态分析先把逻辑读一遍再决定要不要动态调试。所以需要让静态读代码这件事变得足够痛苦。C/C程序在Wintel平台上的静态分析痛点主要在几个层面函数识别。原来清晰的函数边界被打乱后反汇编器的函数列表就和真实结构对不上了。控制流结构。正常if/else/for循环的块状结构如果被改写成一张跳转表人脑很难快速理清。字符串和常量。一旦字符串被加密静态搜索“关键提示”这条路就没那么好走。关键比较运算。把等于0的校验改成某种复杂的位运算干扰伪代码的可读性。具体实现上比较常用的思路是“控制流平坦化”。正常的程序流程像一个树或者一条直线攻击者可以从A点顺着走到B点。控制流平坦化会把原来的分支逻辑全部摊到同一个层次通过一个状态变量来决定下一个执行块是哪个。原来一眼能看懂的“校验失败跳转到错误处理”变成了一堆switch式跳转并且块与块之间没有明显的语义顺序。C/C开发者不需要自己从零写一个混淆器。现在主流的做法是在LLVM层加混淆Pass直接在编译期生成平坦化之后的机器代码。这样你维护的还是正常C/C源码只是编译产物已经面目全非。需要提醒的是混淆会明显影响性能尤其是循环密集的算法。我通常只对关键函数开启控制流平坦化而不是全工程开。2.3 完整性校验与防篡改反调试、反静态分析都防不住一个最简单粗暴的攻击找到跳转指令改一个字节。所以程序必须能感知到“自己已经被修改”。完整性校验的基本思路很直白程序在运行前或运行过程中对自己内存中的代码段、关键数据结构做哈希和编译时预埋的基准值比对。一旦发现不一致就拒绝运行或走一段看起来正常但结果错误的逻辑。这里有一个很重要的设计技巧不要在发现被篡改时立刻弹窗或退出。那种“Your program is modified”的弹窗反而是给破解者一个明确信号让他知道哪里有校验改哪里。更实用的做法是“静默污染”检测到代码段被改动后程序继续正常运行但在后续某个无关紧要的路径里悄悄改掉一个关键计算结果甚至让程序在几小时后随机崩溃。这种不确定性的反制会让破解者非常难受因为他很难定位到底是哪里触发了逻辑错误。当然自校验也不是没有代价。代码段哈希的基准值如果放在外部配置文件里对方替换配置文件就绕过了如果放在程序内对方可以通过补丁跳过校验代码。所以完整性校验必须和前面的反调试、混淆配合形成一条互相保护的链反调试保护校验代码不被跳过校验代码保护后面的关键逻辑不被篡改。2.4 关键逻辑的加密执行与虚拟化保护如果核心算法实在敏感C/C代码层面还有一个更重的方向把关键函数转换成一组自定义字节码在运行时由一个解释器逐条执行。这样对方看到的不再是原生x86指令而是一套你自己定义的指令集。虚拟化保护本质上是“用解释器换安全”。它能让静态分析彻底失去抓手因为反汇编器不认识你的指令集动态调试也会很痛苦因为单步看到的只是解释器的分派循环而不是原始算法。缺点是性能开销非常大通常会比原生代码慢一个数量级而且一旦自定义指令集设计得不好崩溃排查会非常头疼。在实际项目里我很少把整个程序做虚拟化通常只挑“授权验证”“密钥派生”“核心算法入口”这三类函数。这三个点一旦被攻破整个保护体系就可能被拆穿值得付出性能代价。另外虚拟化环境的稳定性比普通代码更难保证一定要在不同CPU、不同Windows版本上做充分测试。3. 一个可参考的加固链路把反调试、解密、自校验串起来很多初学者把反调试、混淆、加壳当成一个个孤立的“秘密武器”其实这恰恰是最容易出问题的。单独某个检测点只要被定位就很难防住但把它们串成一条“加固链”每层之间互相掩护破解者的工作量就会指数上升。下面分享一套我在模拟项目X上实际跑通过的思路。3.1 先设计启动链路谁先跑、谁保护谁我习惯把加固之后的程序启动顺序设计成这样加载器先执行完成最基础的反调试检测和运行环境检查。加载器读取加密的核心模块解密到内存。对内存中的核心模块做完整性校验确认没有被替换或修改。校验通过后再跳转到真正的程序入口执行。这样的好处是核心逻辑不会以明文形式直接出现在磁盘上攻击者没办法直接把文件拖进反汇编器慢慢看。他必须动态运行程序让解密过程发生在内存里才能看到真正的代码。而动态运行这一步又被第一层的反调试挡了一部分。用C/C来实现这个链路时最简单的落地方式是把项目拆成两个模块一个是轻量级的加载器一个是包含核心功能的DLL或另一个EXE。加载器负责启动时环境检查DLL负责真正的业务逻辑。发布时不直接分发DLL而是分发一份加密后的数据文件由加载器在内存中解密加载。这个方案比直接加壳更可控也更容易排查问题。3.2 加载器里的关键代码片段先看一个最简单的反调试检测函数在实际项目里我会把它和其他检测点组合使用// Windows Visual C 环境 #include windows.h bool CheckDebuggerBasic() { // 方式1PEB 标志 if (IsDebuggerPresent()) { return true; } // 方式2检查远程调试器 BOOL isRemote FALSE; if (CheckRemoteDebuggerPresent(GetCurrentProcess(), isRemote)) { if (isRemote) { return true; } } // 方式3关键时间差检测 DWORD64 start GetTickCount64(); // 做一些简单计算 volatile int dummy 0; for (int i 0; i 1000; i) { dummy i; } DWORD64 elapsed GetTickCount64() - start; if (elapsed 500) { // 单步调试时这个时间会异常 return true; } return false; }注意这里的时间差阈值不能固定得过于严格。在慢速机器或者系统高负载时正常程序也可能超过阈值造成误报警。我的做法是取多次测量的中位数而不是单次测量就下结论。加载器解密核心模块的伪代码使用Windows API大致如下bool LoadAndRunCore(const wchar_t* encryptedPath) { // 读取加密后的数据文件 std::vectorunsigned char encryptedData; if (!ReadFileToBuffer(encryptedPath, encryptedData)) { return false; } // 用自己的密钥和算法解密 std::vectorunsigned char coreData; if (!DecryptBuffer(encryptedData, coreData)) { return false; } // 校验解密后内存镜像的哈希 if (!VerifyImageHash(coreData)) { return false; } // 创建内存模块并调用入口 // 这里的实现涉及内存加载器生产环境建议使用成熟方案 // 或者把解密后的数据写入临时文件后正常LoadLibrary // 不过写临时文件会引入新的攻击面需要额外清理。 return ExecuteMemoryModule(coreData); }这个流程看起来简单但实际上每一行都有细节。比如解密函数本身的密钥不要硬编码在加载器里建议通过“机器特征 用户授权信息”动态派生。这样即使对方拿到了加载器也没法直接提取出密钥去解密所有机器上的核心模块。3.3 给出路核心模块内部的运行时自校验加载器只能保证核心模块从磁盘到内存的过程是安全的。模块运行后还要在代码段内部做运行时自校验防止对方直接在内存里改指令。在x64 Windows下获取当前函数所在内存地址可以用编译器内置函数_ReturnAddress()结合Module32First/Module32Next等方式定位模块基址再对代码段做哈希。关键点是哈希函数和基准值不要在同一个函数里连续执行中间穿插一些其他业务代码让攻击者不能通过一个断点就同时抓完整个校验逻辑。还要注意一个很实际的坑如果程序自己做了内存加载Windows的GetModuleHandle、GetProcAddress这类API不一定能正常解析内存模块。很多成熟的加载器会自己维护导入表重定位。如果你只是想要一个可控的方案我更推荐优先采用“商业壳”或者“加密DLL 常规LoadLibrary”的方式而不是自己写内存加载器除非团队里有人对PE结构非常熟。下面是一个运行时校验的示例片段#include windows.h #include intrin.h // 对当前模块代码段做简单哈希 DWORD HashCodeSection() { HMODULE mod GetModuleHandleW(NULL); if (!mod) return 0; // 读取DOS头、NT头获取代码段地址和大小 auto* dos reinterpret_castconst IMAGE_DOS_HEADER*(mod); if (dos-e_magic ! IMAGE_DOS_SIGNATURE) return 0; auto* nt reinterpret_castconst IMAGE_NT_HEADERS*( reinterpret_castconst BYTE*(mod) dos-e_lfanew); if (nt-Signature ! IMAGE_NT_SIGNATURE) return 0; const IMAGE_SECTION_HEADER* sec IMAGE_FIRST_SECTION(nt); for (WORD i 0; i nt-FileHeader.NumberOfSections; i) { if ((sec[i].Characteristics IMAGE_SCN_MEM_EXECUTE) ! 0) { const BYTE* start reinterpret_castconst BYTE*(mod) sec[i].VirtualAddress; SIZE_T size sec[i].Misc.VirtualSize; // 这里用自己实现的哈希函数计算 return ComputeHash(start, size); } } return 0; }真正生产时不要用这种“遍历节表”的通用逻辑因为攻击者可以在GetModuleHandleW返回后立刻下断点然后把所有校验逻辑一次性扫掉。更可靠的做法是启动时先做一次代码段哈希并保存结果然后在程序运行到不同阶段时重新计算代码段的关键部分与保存值比对。4. 常见问题与排查技巧实录做反逆向加固最难受的其实不是对抗攻击者而是被自己的保护逻辑搞崩溃。下面这些坑我在实际项目里都踩过列出来供参考。4.1 反调试误报合法用户无法启动国产系统环境、云端虚拟主机、杀毒软件沙箱、远程桌面场景下反调试检测经常会误报。因为沙箱环境和调试器在系统API层面的表现非常相似时间差和PEB标志都容易被触发。我的排查经验是先在代码里加一个“环境诊断”开关。通过命令行参数或环境变量把每个检测项的结果输出到日志文件。这样用户反馈无法启动时直接看日志就知道是哪一步拦截了。线上版本关闭这个开关只保留日志记录。不要一开始就设计成“检测到就退出”设计成“检测到就降级”会更容易维护。4.2 编译器优化把反调试代码优化掉了早期我写过一段反调试逻辑写在单独函数里返回值没人用结果Release编译后整个函数被优化删除。后来所有检测函数都改成返回布尔值并且用一个volatile全局变量在main函数里累加结果保证检测代码不会被删。volatile int g_protectionFlags 0; bool RunAntiDebugCheck() { bool found false; if (IsDebuggerPresent()) found true; if (CheckRemoteDebuggerPresent(GetCurrentProcess(), isDebug) isDebug) found true; g_protectionFlags found ? 1 : 0; return found; }只要g_protectionFlags在程序的某个关键分支里被读取整个检测链就不会被轻易优化掉。4.3 加了混淆后模块崩溃却定位不到原因控制流平坦化有一个典型的问题局部变量生命周期被拉长寄存器分配变得很激进原本正常的C异常处理、setjmp/longjmp、线程局部存储都可能出问题。我在模拟项目X里开启全工程混淆后程序在某个特定CPU上频繁崩溃最后只能改成只混淆授权校验相关函数崩溃才消失。所以如果你的程序里用了大量异常、线程、动态加载插件不要对全工程开重型混淆。先做灰度先在一个模块上验证再逐步扩大范围。同时保留一份未混淆的Release构建用于对比测试这能大大缩短排查时间。4.4 完整性校验和Windows更新补丁冲突动态链接到系统DLL的程序如果完整性校验把系统模块也算进去Windows更新后哈希基准值就会失效。正确的做法是只校验自己的模块代码段不校验系统DLL。并且基准值的生成不要写在程序里而是在构建脚本里生成作为资源文件嵌入。这样每次版本更新基准值自动更新不用在代码里手改。4.5 安全软件把加固后的程序误报为木马很多加密壳、虚拟化保护的字节码特征与恶意软件很像。加壳后程序被杀毒软件查杀这不一定是技术问题而是信任问题。处理思路是优先做数字签名并且保证每次发版都用正式证书签名不要在测试机上频繁切换不同壳或混淆参数稳定的指纹会降低误报率如果误报来自某个特定杀毒引擎走厂商的误报申诉流程通常提交样本和说明即可解决。不要为了躲杀软而把程序藏起来这会让你们产品的信誉受到更大损害。5. 这块内容后续还能怎么扩展反逆向破解是一个动态对抗的过程没有一劳永逸的方案。我把这套加固链路跑通之后后续最想做的方向是这几个。一个是把解密密钥和机器指纹、用户行为数据绑定更紧密做到“一机一密一用户一密”。这样即使核心模块被脱壳提取也无法批量用于其他机器。另一个是引入云端授权和服务端行为校验客户端每个一段时间生成一次性随机挑战带上本地签名服务端校验后返回运行许可。一旦客户端的二进制被篡改签名不匹配授权自然失效。这种组合方案比纯本地保护强很多适合有网络环境的业务。还有一个方向是“拖延式防御”不追求让程序永不破解而是让破解版在时间和功能上逐渐劣化。比如检测到异常修改后第一次触发时正常第二次跳过一个非关键功能第三次在随机延迟后抛出错误。这会把破解者的验证周期拉得很长让破解一个版本的成本变得难以接受。我个人在实际操作中的体会是反逆向保护最核心的其实不是某一段高深代码而是工程化管理。你能不能在需要排查时快速定位问题你能不能在不影响用户体验的前提下提高攻击成本你能不能把保护和产品功能解耦这些才是决定一套反逆向方案能否长期运行的真正因素。先把威胁模型设计清楚再把反调试、混淆、自校验这些手段串成一条链最后用足够的测试来兜底这条路会比一味堆“玄学保护”踏实得多。

相关新闻

AI视觉识别破局UI自动化元素定位:模板匹配与OCR实战解析

AI视觉识别破局UI自动化元素定位:模板匹配与OCR实战解析

做了这么多年UI自动化,如果说有什么环节能把人逼疯,元素定位一定排前三。XPath写得太死,页面一改版全崩;id不按规矩来,定位器写得跟猜谜一样;再遇上动态渲染、跨端差异这些情况,你连一个稳定的锚…

2026/10/19 12:53:38 阅读更多 →
Web安全面试题备考指南:从SQL注入到CSRF,构建攻击面思维与防御闭环

Web安全面试题备考指南:从SQL注入到CSRF,构建攻击面思维与防御闭环

这段时间帮几个准备安全岗面试的朋友做复盘,我发现一个特别扎眼的问题:大家拿到一份“42道高频Web安全面试题合集”之后,第一反应都是逐道背答案。背完SQL注入背XSS,背完XSS背CSRF,背到SSRF基本已经晕了,结…

2026/10/19 12:53:38 阅读更多 →
3D海森堡模型蒙特卡洛模拟:Wolff聚类更新与临界慢化破解

3D海森堡模型蒙特卡洛模拟:Wolff聚类更新与临界慢化破解

简介:面向统计物理与计算物理学习者的经典三维海森堡模型模拟项目,来自南康涅狄格州立大学PHY 471顶点课程,作者用C语言实现了各向同性三维海森堡模型的蒙特卡罗研究,并结合数值求解常微分方程方法,完整呈现从晶格构建…

2026/10/19 12:53:38 阅读更多 →

最新新闻

MCP Server 集群化部署:从 Docker 到 Kubernetes 的完整实践

MCP Server 集群化部署:从 Docker 到 Kubernetes 的完整实践

我在团队里负责 AI 基础服务,前几个月被 MCP Server 折腾得够呛。MCP 是模型上下文协议,说白了就是让大语言模型能通过标准化接口调用外部工具和数据源。最开始我们每个人在本机起一个 MCP Server,工具定义各改各的,代码一更新就要…

2026/10/20 14:49:35 阅读更多 →
从零搭建SpringBoot+Vue商城系统:核心设计与部署全攻略

从零搭建SpringBoot+Vue商城系统:核心设计与部署全攻略

自己动手把一套网上商城从零搭到能上线,这事听起来工程量大,实际上踩完一轮坑之后回头看,最值钱的不是那几万行代码,而是整个链路里每个环节你都知道它为什么这么设计。这个项目用的是Java后端技术栈里最经典的组合:Sp…

2026/10/20 14:49:34 阅读更多 →
innodb_flush_log_at_trx_commit全解析:性能与数据安全如何取舍

innodb_flush_log_at_trx_commit全解析:性能与数据安全如何取舍

做MySQL维护和调优的朋友,十有八九都听过innodb_flush_log_at_trx_commit这个参数。有人叫它“安全开关”,有人说它是“性能与数据安全的天平”,其实都不过分。很多压测报告里,把这个参数从1改成2,TPS能肉眼可见地涨一…

2026/10/20 14:49:34 阅读更多 →
MCP Server云原生集群化实战:Docker与K8s弹性伸缩指南

MCP Server云原生集群化实战:Docker与K8s弹性伸缩指南

MCP(Model Context Protocol)这两年火得很快,身边搞 AI 应用的同学几乎都在接。但大部分人把 MCP Server 部署得比较随意——一台机器,一个进程,能跑就行。直到流量上来、工具越接越多,才发现单机模式处处碰…

2026/10/20 14:49:34 阅读更多 →
MySQL参数详解:innodb_flush_log_at_trx_commit的性能与安全取舍

MySQL参数详解:innodb_flush_log_at_trx_commit的性能与安全取舍

我处理过不少数据库卡顿和“丢了几秒数据”的现场,最后基本都绕回到一个老参数上: innodb_flush_log_at_trx_commit 。它字面意思很简单,就是控制事务提交时InnoDB怎么刷redo log,可真正把它讲透、用对的人并不多。很多后端开发…

2026/10/20 14:49:34 阅读更多 →
Frida动态插桩实战:从Hook到内存扫描的完整指南

Frida动态插桩实战:从Hook到内存扫描的完整指南

做移动端安全测试这些年,我见过太多人把大量时间花在反编译和读汇编上,遇到加了壳的应用就只能干瞪眼。后来我开始把 Frida 动态插桩作为主要分析手段,很多原本要折腾半天的任务,现在几分钟就能拿到结果。这篇文章我会从最基础的 …

2026/10/20 14:48:08 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* 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 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* 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 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* 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 1:01:30 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在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 阅读更多 →