CFF_Explorer二进制解析实战:PE结构还原与异常节区排查
简介CFF_Explorer 是一款面向程序员、逆向工程师与安全研究人员的 Windows 文件格式分析工具尤其擅长解析 PE 可执行文件结构可用于软件调试、资源修改与恶意软件分析等场景。资源包共 16 个文件约 2.07MB包含 5 个 xml 签名定义、3 个 cff 脚本、3 个 pdf 技术文档、2 个 exe 主程序与扩展向导、1 个 dll、1 个 zip 及 1 个 msi 安装包覆盖主程序、扩展模块、脚本示例与说明文档。其中 pdf 文档讲解扩展开发、脚本语言与签名技术细节xml 定义不同机器类型与平台签名cff 脚本提供 4GB 补丁、报告生成等实用示例便于快速上手与二次开发。已有 783 人学习下载适合需要深入理解 PE 结构、编辑资源与导入导出表、检查代码签名或进行逆向分析的技术人员参考使用。1. CFF_Explorer把二进制里的“黑匣子”拆开看第一次拿到一个没有符号表的固件样本时我盯着十六进制窗口看了半小时除了满屏的4D 5A和一堆乱码字符串什么结论都下不了。后来才意识到问题不在样本本身而在于我手里缺一个能把二进制结构“翻译”成人能读懂的东西的工具。CFF_Explorer 就是干这件事的——它面向的是可执行文件与二进制格式的解析、结构还原和字段级探查把 PE、ELF、Mach-O 这类容器里的节区、导入导出表、资源目录、重定位信息一层层剥出来。它适合三类人做逆向和样本分析的安全工程师、做固件与嵌入式排查的开发者、以及需要验证编译产物结构是否符合预期的构建工程师。你不需要一开始就懂所有格式规范但你需要知道“我想看什么”和“这个字段为什么长这样”。2. 二进制格式解析到底在解析什么从容器到字段2.1 可执行文件不是一坨字节而是有层级的数据结构很多人把二进制文件当成“一堆机器码”这个认知会直接导致后面所有分析都跑偏。一个标准的可执行文件至少包含四层结构最外层是容器头比如 PE 的 DOS Header NT Header第二层是节区表Section Table第三层是节区内容代码、数据、资源第四层才是具体的指令和数据结构。CFF_Explorer 这类工具的核心价值就是把这四层用树形或表格的方式展开让你能按层级下钻。以 PE 为例DOS Header 的e_lfanew字段指向 NT Header 的偏移NT Header 里的FileHeader.NumberOfSections决定后面跟多少个节区表项每个节区表项又包含VirtualAddress、SizeOfRawData、Characteristics等字段。这些字段之间存在强关联如果你改了节区数量后面的所有偏移都会错位。解析器要做的第一件事就是校验这些关联是否自洽。常见做法是先用文件头的前几个字节做魔数判断4D 5A是 PE7F 45 4C 46是 ELFFE ED FA CE系列是 Mach-O。CFF_Explorer 在打开文件时会先做这一步然后根据格式类型加载对应的解析器。这一步看起来简单但实际踩坑很多——比如某些固件会在 PE 头前面加一段自定义头导致魔数不在偏移 0 的位置这时候就需要手动指定基址偏移。2.2 用 Python 手动解析一个 PE 头最小可复现步骤在依赖任何图形化工具之前我建议先用脚本把最外层的头结构读出来。这样你才能理解工具界面上那些字段到底是从哪个偏移来的。下面这段代码只依赖标准库不装任何第三方包就能跑。import struct def parse_pe_header(filepath): with open(filepath, rb) as f: data f.read() # 校验 DOS 魔数 if data[0:2] ! bMZ: raise ValueError(不是 PE 文件缺少 MZ 魔数) # e_lfanew 在偏移 0x3C4 字节小端 e_lfanew struct.unpack_from(I, data, 0x3C)[0] # NT Header 签名 nt_sig data[e_lfanew:e_lfanew4] if nt_sig ! bPE\x00\x00: raise ValueError(NT 签名不匹配) # FileHeader 从 e_lfanew4 开始20 字节 machine, num_sections struct.unpack_from(HH, data, e_lfanew4) opt_header_size struct.unpack_from(H, data, e_lfanew20)[0] # 节区表紧跟在可选头之后 section_start e_lfanew 24 opt_header_size sections [] for i in range(num_sections): off section_start i * 40 name data[off:off8].rstrip(b\x00).decode(ascii, errorsreplace) vsize, vaddr, rawsize, rawptr struct.unpack_from(IIII, data, off8) sections.append({ name: name, virtual_address: hex(vaddr), virtual_size: hex(vsize), raw_offset: hex(rawptr), raw_size: hex(rawsize) }) return { machine: hex(machine), num_sections: num_sections, opt_header_size: opt_header_size, sections: sections } if __name__ __main__: import sys result parse_pe_header(sys.argv[1]) print(f架构: {result[machine]}) print(f节区数: {result[num_sections]}) for s in result[sections]: print(f {s[name]}: VA{s[virtual_address]} fRawOff{s[raw_offset]} RawSize{s[raw_size]})这段代码的关键参数有三个e_lfanew的偏移0x3C是 PE 规范固定的不能改FileHeader的 20 字节长度也是固定的节区表每项 40 字节这个值在 PE32 和 PE32 下一致。运行后你会看到类似.text、.rdata、.data、.rsrc的节区名和对应的虚拟地址与文件偏移。如果某个节区的raw_offset加上raw_size超过了文件实际大小说明文件被截断或篡改过这是样本分析里非常常见的异常信号。2.3 节区属性字段怎么读Characteristics 的位掩码含义节区表里最容易看错的是Characteristics字段它是一个 32 位掩码不同位代表不同权限。很多人只看到一串十六进制数就跳过实际上这个字段直接决定了该节区是否可执行、是否可写、是否包含代码。位值含义实际影响0x00000020包含代码该节区可能被加载为可执行0x00000040已初始化数据通常对应 .data0x00000080未初始化数据通常对应 .bss0x20000000可执行内存中可执行权限0x40000000可读内存中可读权限0x80000000可写内存中可写权限一个正常的.text节区通常是0x60000020可执行 可读 包含代码而.data通常是0xC0000040可读 可写 已初始化数据。如果你看到一个.text节区同时带有可写标志0x80000000这往往意味着样本在运行时需要修改自身代码属于需要重点关注的异常特征。CFF_Explorer 在展示节区信息时会把掩码拆成可读的标签但你自己写脚本时一定要手动做位与运算不要直接比较整数值。3. 用 CFF_Explorer 做结构还原从导入表到资源目录3.1 导入表解析为什么有的函数名显示不出来导入表是二进制分析里信息密度最高的区域之一。它告诉你这个程序依赖哪些外部模块、调用了哪些函数。在 PE 里导入表通过数据目录Data Directory的第 2 项定位指向一个IMAGE_IMPORT_DESCRIPTOR数组每个描述符对应一个 DLL里面再指向IMAGE_THUNK_DATA数组最终指向函数名或序号。CFF_Explorer 在解析导入表时通常会遇到两种显示结果一种是完整的KERNEL32.dll - CreateFileW另一种是KERNEL32.dll - Ordinal 123。后者说明该导入项是按序号导入的没有函数名字符串。这在某些加壳或精简过的样本里非常常见。如果你在分析时发现大量按序号导入的函数不要急着下结论说“这是恶意行为”先确认是不是编译器优化或链接器设置导致的。手动解析导入表时关键是要处理 RVA 到文件偏移的转换。RVA 是相对虚拟地址需要根据节区表找到它落在哪个节区然后减去该节区的VirtualAddress再加上PointerToRawData。这个转换逻辑是二进制解析里最容易写错的地方因为不同节区的对齐粒度可能不同文件对齐 vs 内存对齐。def rva_to_offset(sections, rva): for s in sections: va int(s[virtual_address], 16) vs int(s[virtual_size], 16) if va rva va vs: raw int(s[raw_offset], 16) return raw (rva - va) return None这个函数看起来简单但有两个边界坑第一如果 RVA 正好落在节区之间的空隙里返回 None 是正确行为不要强行取最近节区第二某些节区的VirtualSize大于RawSize这时候 RVA 可能落在“内存中有但文件中没有”的区域需要单独处理。3.2 资源目录遍历树形结构怎么用代码展开资源目录是 PE 里结构最像文件系统的部分。它有三层类型、名称/ID、语言。每一层都是一个IMAGE_RESOURCE_DIRECTORY后面跟若干IMAGE_RESOURCE_DIRECTORY_ENTRY。CFF_Explorer 在界面上通常用树形控件展示但如果你要批量提取图标或版本信息还是得自己写遍历逻辑。遍历的核心是递归处理目录项。每个目录项的OffsetToData字段有一个高位标志如果最高位是 1表示它指向另一个目录如果是 0表示它指向具体的数据条目。这个标志位是资源解析里最容易翻车的地方因为很多文档只写了“偏移”没强调高位含义。def walk_resource_dir(data, base, offset, depth0, path): # 读取目录头16 字节 named, ids struct.unpack_from(HH, data, base offset) total named ids for i in range(total): entry_off base offset 16 i * 8 name_or_id, data_off struct.unpack_from(II, data, entry_off) # 判断是名称还是 ID if name_or_id 0x80000000: label fName{hex(name_or_id 0x7FFFFFFF)} else: label fID{name_or_id} # 判断是子目录还是数据条目 if data_off 0x80000000: # 子目录递归 sub_off data_off 0x7FFFFFFF walk_resource_dir(data, base, sub_off, depth1, path / label) else: # 数据条目读取 RVA 和大小 rva, size struct.unpack_from(II, data, base data_off) print(f{ *depth}{path}/{label} - RVA{hex(rva)} Size{size})这段代码里0x80000000这个掩码出现了两次含义不同第一次是判断名称字段是字符串偏移还是整数 ID第二次是判断数据字段是子目录偏移还是数据条目偏移。写的时候一定要区分清楚否则会出现“明明有资源却遍历不到”的情况。CFF_Explorer 在展示资源树时底层逻辑和这段代码是一致的只是它帮你处理了边界和异常。3.3 重定位表与基址为什么改了基址程序就跑不起来重定位表是 PE 里最容易被忽视但影响最大的结构之一。当程序被加载到与预期基址不同的地址时系统需要根据重定位表修正所有硬编码的地址。如果你用 CFF_Explorer 修改了ImageBase字段但没有同步处理重定位表程序大概率会崩溃。重定位表通过数据目录第 6 项定位结构是若干个块每块以 4KB 页为粒度包含一个页 RVA 和若干 16 位条目。每个条目的高 4 位表示类型常见的是IMAGE_REL_BASED_HIGHLOW 3低 12 位表示页内偏移。解析时要注意不是所有文件都有重定位表如果Characteristics里设置了IMAGE_FILE_RELOCS_STRIPPED说明重定位信息已被剥离这时候强行改基址必崩。重定位类型值名称适用架构0ABSOLUTE填充用忽略3HIGHLOW32 位修正 4 字节10DIR6464 位修正 8 字节在 CFF_Explorer 里查看重定位表时重点关注条目数量和覆盖的页范围。如果一个文件的重定位表只覆盖了.text节区而没有覆盖.data说明数据段里的地址引用可能不需要修正或者被剥离了。这个判断直接影响你能不能安全地做基址重设。4. 避坑与排查二进制解析里最容易翻车的五个点4.1 文件对齐与内存对齐不一致导致 RVA 转换错误现象用脚本把 RVA 转成文件偏移后读出来的数据完全对不上明明节区表里VirtualAddress和PointerToRawData看起来都正常。原因PE 有两个对齐粒度——FileAlignment通常 0x200和SectionAlignment通常 0x1000。节区的VirtualAddress是按SectionAlignment对齐的而PointerToRawData是按FileAlignment对齐的。如果你直接用RVA - VirtualAddress PointerToRawData在节区起始位置是对的但一旦 RVA 跨过某个对齐边界就会算错。解决转换时不要假设节区内是连续线性映射而是先确认 RVA 落在哪个节区的[VirtualAddress, VirtualAddress VirtualSize)区间内然后用RVA - VirtualAddress得到节区内偏移再加上PointerToRawData。如果VirtualSize大于SizeOfRawData超出部分在文件中不存在返回空而不是硬算。4.2 导入表里出现“自引用”导致递归死循环现象遍历导入表时程序卡死或栈溢出调试发现某个IMAGE_IMPORT_DESCRIPTOR的Name字段 RVA 指向了自己。原因样本被篡改或加壳后导入表结构可能被故意破坏形成循环引用。某些解析器没有做访问标记就会无限递归。解决在遍历导入表时维护一个已访问 RVA 的集合每次进入新描述符前检查是否已访问过。同时设置最大迭代次数比如 256超过就报异常退出。CFF_Explorer 在遇到损坏的导入表时通常会显示“解析中断”而不是崩溃就是做了类似的保护。4.3 资源目录的字符串偏移没有校验边界现象读取资源名称时得到乱码或程序直接抛异常提示“读取超出文件范围”。原因资源目录里的名称字段如果最高位是 1低 31 位是相对于资源目录起始位置的偏移指向一个 Unicode 字符串。但这个偏移可能超出文件实际大小尤其是在文件被截断的样本里。解决每次根据偏移读取字符串前先检查base offset 2是否小于文件长度然后读取 2 字节的长度字段再检查base offset 2 length * 2是否越界。任何一步失败就跳过该条目不要尝试“修复”。4.4 把节区名当成节区内容的标识现象看到.text节区就认为里面全是代码看到.data就认为全是数据结果在.text里发现了大量字符串常量。原因节区名只是链接器给的标签不是强制约束。编译器可以把只读数据放进.text也可以把代码放进自定义节区。真正决定内容类型的是节区的Characteristics和实际引用的上下文。解决不要依赖节区名做判断。用Characteristics的可执行位判断是否可能包含代码用数据目录的指向判断哪些节区包含导入表、资源、重定位等结构。CFF_Explorer 在展示节区时会同时显示名称和属性但分析时要以属性为准。4.5 修改字段后没有同步更新校验和现象用工具改了 PE 头的某个字段保存后程序无法启动系统提示“文件已损坏”。原因PE 可选头里有一个CheckSum字段虽然普通可执行文件加载时不一定校验但驱动文件和某些受保护进程会校验。改了任何头字段后校验和就失效了。解决修改后重新计算校验和。算法是先把CheckSum字段置零然后对整个文件按 16 位字累加处理进位最后加上文件长度。很多工具提供“自动修正校验和”选项但如果你手动改字段记得手动触发一次。5. 进阶技巧用结构对比法快速定位异常节区当你手上有多个同源样本时逐个看字段效率很低。我一般会用一个“结构指纹”的思路把每个样本的节区表提取成结构化数据然后做差异对比。正常编译产生的样本节区数量、名称、属性、大小分布都有一定规律一旦某个样本的节区表出现异常组合比如多了一个可写可执行的未知节区或者.rsrc的大小突然膨胀十倍就值得优先深入。具体做法是先用前面写的parse_pe_header批量跑一遍样本目录把结果存成 JSON然后用一个简单的对比脚本找出差异字段。下面这段代码展示了如何把多个样本的节区信息汇总后按节区名分组对比。import json from collections import defaultdict def compare_sections(json_files): # 按节区名聚合所有样本的属性 section_map defaultdict(list) for jf in json_files: with open(jf, r) as f: info json.load(f) for s in info[sections]: key s[name] section_map[key].append({ file: jf, vsize: int(s[virtual_size], 16), rawsize: int(s[raw_size], 16), rawptr: int(s[raw_offset], 16) }) # 找出同一节区名下 rawsize 差异超过 3 倍的样本 for name, entries in section_map.items(): sizes [e[rawsize] for e in entries] if not sizes: continue avg sum(sizes) / len(sizes) for e in entries: if avg 0 and (e[rawsize] avg * 3 or e[rawsize] avg / 3): print(f异常: {e[file]} 的 {name} frawsize{hex(e[rawsize])} 偏离均值 {hex(int(avg))}) if __name__ __main__: import sys compare_sections(sys.argv[1:])这个脚本的关键参数是“3 倍”这个阈值。设太小会误报设太大漏报。我的经验是对于.text和.rdata这类标准节区2 倍以上就值得看对于.rsrc和自定义节区5 倍以上再关注。另外要注意不同编译器版本产生的节区大小本身就有差异所以最好在同一批次、同一构建环境下产出的样本之间做对比跨批次对比的参考价值会打折扣。还有一个更细的技巧对比节区的rawptr排列顺序。正常链接器产出的节区在文件中的偏移通常是递增的如果某个样本的节区偏移出现回绕或重叠说明文件被拼接或篡改过。这个判断不需要任何额外工具用前面解析出的raw_offset排个序就能看出来。我在实际排查里最常犯的一个错误是看到异常就急着下结论而没有先确认这个异常是不是构建配置导致的。有一次我花了一下午分析一个“多出来的可执行节区”最后发现只是链接器开了某个优化选项。从那以后我养成了一个习惯——任何异常特征先在同批次正常样本里搜一遍确认它是不是“正常范围内的异常”。这个习惯帮我省了很多后悔药。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

Notepad++破解真相:安装包验证、静默部署与插件配置指南

Notepad++破解真相:安装包验证、静默部署与插件配置指南

简介:这份资源是 Notepad 的完整安装包,面向需要频繁编辑项目配置文件的开发者与运维人员。相比系统自带记事本,它在语法高亮、编码识别和大文件处理上更可靠,适合日常修改 xml、json、ini 等配置,也便于查看日志与脚本…

2026/10/13 22:03:50 阅读更多 →
Python构建可复用的网易云歌单分析系统

Python构建可复用的网易云歌单分析系统

简介:本资源是一份面向高校Python初学者与课程设计学生的数据分析实战项目,聚焦网易云音乐歌单数据的采集、清洗、统计分析与多维度可视化呈现,适用于Python期末大作业、数据可视化课程设计及数据分析入门实践。压缩包共36个文件,…

2026/10/13 17:59:33 阅读更多 →
Spring Boot+MinIO+Vue生产级图片上传闭环实践

Spring Boot+MinIO+Vue生产级图片上传闭环实践

1. 这不是“又一个上传Demo”,而是生产级图片服务的最小可行闭环你有没有遇到过这样的场景:前端同事发来消息,“图片上传接口400了,字段名对不上”;运维突然通知,“MinIO集群磁盘告警,但查不到哪…

2026/10/13 17:59:54 阅读更多 →

最新新闻

ACM竞赛中STL sort的cmp函数设计原理与避坑指南

ACM竞赛中STL sort的cmp函数设计原理与避坑指南

1. 为什么排序不是“写个for循环就完事”的事?刚接触ACM竞赛的新人,十有八九都经历过这个阶段:看到一道题说“把数组从小到大排好”,立刻撸起袖子写个冒泡——三重嵌套,i、j、k变量齐飞,跑样例能过&#xf…

2026/10/13 22:58:14 阅读更多 →
vnpy中缠论顶底分型的工程化实现与可视化避坑指南

vnpy中缠论顶底分型的工程化实现与可视化避坑指南

1. 为什么顶底分型不能只靠“肉眼盯盘”——从vnpy实战场景切入的缠论可视化困局在某量化实盘小组里,我见过最典型的场景是:一位有十年股票交易经验的老手,在复盘时指着K线图说:“这里明显是个顶分型,三根K线高点递减&…

2026/10/13 22:58:14 阅读更多 →
dateparse4cj 版本演进与新增日期格式解析指南(v1.0.0 / v1.0.1)

dateparse4cj 版本演进与新增日期格式解析指南(v1.0.0 / v1.0.1)

后端 【免费下载链接】dateparse4cj dateparse4cj 是一个基于 cangjie 标准库实现的高性能、功能丰富的日期时间解析库。它能够自动识别并解析多种格式的日期字符串,支持全球各种常见日期格式,包括各种区域标准、时区处理以及多语言日期表示。该库适合需…

2026/10/13 22:58:14 阅读更多 →
VINS-Mono回环检测与四自由度位姿图优化原理

VINS-Mono回环检测与四自由度位姿图优化原理

1. 为什么VINS-Mono的回环检测不是“加个ORB-SLAM模块”就能跑通?很多人第一次尝试给VINS-Mono添加回环功能时,会下意识地去翻ORB-SLAM2的LoopClosing类,照着抄一个特征匹配位姿图优化的流程,结果编译能过,运行十秒就崩…

2026/10/13 22:58:14 阅读更多 →
Kubernetes上稳定运行Kafka的实战指南:StatefulSet、Local PV与KRaft配置

Kubernetes上稳定运行Kafka的实战指南:StatefulSet、Local PV与KRaft配置

1. 项目概述:为什么在Kubernetes上跑Kafka不是“炫技”,而是生产刚需“k8s搭建kafka集群”这八个字,最近半年在某云原生技术社区的搜索量翻了3.2倍。我带过的三个跨部门协作项目里,有俩都卡在“Kafka要不要上K8s”这个决策点上——…

2026/10/13 22:58:14 阅读更多 →
生成式AI从算法创新到工程落地:关键技术与实操指南

生成式AI从算法创新到工程落地:关键技术与实操指南

1. 从一场大会的议程设计,看生成式AI落地的真实风向如果你最近在关注生成式AI的行业动态,大概率会注意到一个现象:各种技术大会的议程正在悄悄变脸。前两年大家还在热烈讨论“大模型参数规模”“预训练数据量”这类底层指标,而今年…

2026/10/13 22:57:14 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 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/13 22:01:27 阅读更多 →
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/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练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/12 18:11:17 阅读更多 →