IDA+C32ASM破解CrackMe:so静态分析与机器码修改实战

搞 Android 逆向的朋友应该都遇到过这种场景:拿到一个 CrackMe APK,装进模拟器里随便输入一串序列号,点击“验证”,屏幕上除了“验证失败”的 Toast 之外没有任何提示。这种题说难不难,但很多新手卡在不知道从哪下手。这篇就手把手带你走一遍我常用的方案:在 Windows 7 环境下,用 IDA 静态分析so里的校验逻辑,再用 C32ASM 精准修改机器码,最后回编译、签名、装回模拟器。只要工具备齐,跟着下面的流程走一遍,基本就能掌握 CrackMe 的通用打法。

这篇文章适合两类人:一类是刚入门 Android 逆向,只会用jadx看 Java 代码,想看so却不知道如何定位;另一类是原来搞 Windows 逆向,对 IDA 和 C32ASM 熟得很,但没转过 Android 文件格式。我会把每一步的操作意图和踩坑点都写清楚,尽量做到“照着做就能出结果”。下面假设你已经能正常运行模拟器,并且装好了 Java 环境,我们要做的事就是:拆包、找逻辑、改机器码、打包。

1. 准备工作与环境搭建

很多人会问,现在 Windows 10/11 都到 2025 年了,为什么还抱着 Win7 不放?很简单,Win7 对老工具链的兼容性太舒服了。IDA 7.x 在 Win7 上跑得很稳,C32ASM 这种老牌十六进制编辑器本来就是当时逆向的主力工具,字体和操作手感都很顺手。而且 Win7 资源占用低,挂模拟器跑 APK 不卡。如果你只有 Win10/11,步骤也完全一样,只是个别驱动或老版本 IDA 需要兼容模式运行。

1.1 工具清单与分工

先梳理一下我们要用到的工具,避免做一半发现缺东西。

工具作用安装注意
JDK 1.8运行 Apktool、keytool、apksigner 依赖的 Java 环境装 32 位或 64 位视系统而定,务必配好JAVA_HOME和PATH
Android SDK Build-Tools提供zipalign、apksigner、aapt2等工具版本建议 28.0.3 以上,能识别 V2 签名
Apktool 2.x解包和回编译 APK,得到 smali 资源文件下载apktool.jar,用java -jar调用
IDA Pro 7.x静态分析so文件,定位关键校验函数建议用 64 位版,能直接识别 ARM/Thumb 指令
C32ASM 2.x十六进制编辑与机器码修改绿色版即可,主要用于精确 patch 某个字节
模拟器或真机安装破解后的 APK,验证效果模拟器建议 API 24 以上,能支持 V2 签名安装

1.2 环境变量与基础配置

这一节非常基础,但翻车率相当高。很多新手不是在破解环节出问题,而是工具根本跑不起来。

首先确保java -version能输出 1.8 开头的版本。然后在系统变量里新建JAVA_HOME,指向 JDK 安装目录,再把%JAVA_HOME%\bin加到Path里。接着把 Android SDK 的build-tools目录也加进Path,这样后面可以直接敲zipalign和apksigner,不用每次写超长路径。

Apktool 我习惯把它放到一个固定目录,比如D:\tools\apktool.jar。每次运行用java -jar D:\tools\apktool.jar会比较啰嗦,你可以在D:\tools下新建一个apktool.bat,内容是:

@echo off java -jar D:\tools\apktool.jar %*

这样后续就能像原生命令一样使用apktool。C32ASM 不需要安装,解压后直接打开,最好把它固定到任务栏,待会儿要反复切窗口。

2. 破解思路与目标分析

拿到 CrackMe 之后不要急着乱点,也不要一上来就拖进 IDA。先想清楚目标:破解的本质是让程序在“错误输入”的情况下,也能走通成功分支。常见的思路无非三种:找出正确密码、让校验函数永远返回成功、直接跳过判断逻辑。我们用到的 IDA + C32ASM 组合,主要覆盖后两种。

CrackMe 的校验位置一般在两个地方:Java 层和 Native 层。Java 层写在classes.dex里,用 Apktool 解包后直接看 smali 就能改;Native 层写在lib/*/libxxx.so里,IDA 负责拆解,C32ASM 负责修改二进制。下面这个 Demo 是按“Java 层读取输入,Native 层校验字符串”的方式写的,这种结构在题里最常见,既能考验静态分析能力,又不会过于复杂。

2.1 CrackMe APK 的典型结构解剖

一个标准 APK 本质上是个 zip 包,解压后通常能看到这些关键文件:

  • classes.dex:Java 字节码,App 的业务逻辑全在这。
  • AndroidManifest.xml:入口 Activity、权限、组件声明。
  • lib/armeabi-v7a/、lib/arm64-v8a/:不同 CPU 架构的 Native 动态库。
  • res/:资源文件,包括布局、字符串、图片。

CrackMe 喜欢把校验放在so里,主要原因是为了防新人:Java 层太透明,用反编译工具扫一眼就能看到if (input.equals(key)),改成if (true)就结束;而so是编译后的机器码,可读性差很多。但也别害怕,CrackMe 的so一般不会做太高强度的混淆,IDA 的 F5 伪代码足够应付。

2.2 拆包后的摸排顺序

我建议的解包后顺序是:先看AndroidManifest.xml确定入口 Activity,再去 smali 目录找到入口类,顺着代码流找关键的check或verify方法。如果发现在某个 Java 方法调用了native函数,并且还有一个System.loadLibrary,那么重点基本就锁定到so文件了。

在这个步骤里,我一般不用jadx,而是直接用文本编辑器搜索 smali 中的字符串。因为jadx虽然直观,但有时候会把混淆后的调用关系整理得不直观。直接用findstr或 Notepad++ 的全局搜索更快:

findstr /s /i "验证失败\|verify\|checkSerial" crackme_src\smali\*.smali

Windows 7 的 cmd 里对中文支持一般,建议文件用 UTF-8 保存,或者干脆搜索英文方法名。定位效率更高。

2.3 IDA 和 C32ASM 的分工

我们把“破解”拆成“分析”和“修改”两个环节。IDA 做分析,C32ASM 做修改。为什么要分两个工具?因为 IDA 是反汇编器,它在屏幕上显示的地址是虚拟地址,而不是文件里的绝对偏移;而 C32ASM 是十六进制编辑器,它直接操作文件字节。你需要在 IDA 里找到“该改哪个地址、指令长什么样”,再到 C32ASM 里把对应字节改成目标机器码。

很多老手喜欢直接用 IDA 的 Edit -> Patch Program 功能,但它更适合打大型补丁,比如注入一段新代码。对于 CrackMe 这种只改一两个条件跳转的场景,C32ASM 明显更轻。你可以非常直观地看到周围字节,避免因为 IDA 缓存导致 patch 后文件没写对。

3. 实操过程:拆包、定位、修改、回编译

现在进入正题。我本地准备了一个实验 Demo,包名是com.example.crackdemo,APK 文件名是CrackDemo.apk。它的逻辑是:输入框输入字符串,点击按钮,Java 层调用CheckCode.checkSerial(input)这个 native 方法,返回true则弹“成功”,否则弹“验证失败”。我们的目标就是让它在任何输入下都返回true。

3.1 使用 Apktool 解包 APK

在命令行切到CrackDemo.apk所在目录,执行:

apktool d CrackDemo.apk -o crackme_src

参数d表示 decode,-o指定输出目录。解包成功后,crackme_src目录下会出现smali、res、lib、AndroidManifest.xml等文件。如果解包过程报资源相关错误,可以加-r参数跳过资源解码,只保留 dex 和 so:

apktool d -r CrackDemo.apk -o crackme_src

不过 CrakMe 一般不需要这样,直接完整解包即可。打开crackme_src\lib\armeabi-v7a,你会看到类似libcheckcode.so的文件,这就是校验逻辑所在的 Native 库。

3.2 从 smali 代码中找到 Native 入口

先看crackme_src\smali\com\example\crackdemo\CheckCode.smali。用文本编辑器打开,内容大致是这样:

.class public Lcom/example/crackdemo/CheckCode; .super Ljava/lang/Object; .method static constructor <clinit>()V .locals 1 const-string v0, "checkcode" invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V return-void .end method .method public static native checkSerial(Ljava/lang/String;)Z .end method

说明checkSerial是 native 方法,加载的库名是checkcode,对应文件就是libcheckcode.so。这里的类名和方法名都符合 JNI 的默认命名规则,所以 IDA 中函数名应该是Java_com_example_crackdemo_CheckCode_checkSerial。如果碰见方法名被混淆的情况,就需要通过RegisterNatives动态注册去找,这个后面常见问题里再展开。

3.3 IDA 静态分析 so 文件

打开 IDA,选择libcheckcode.so,处理器选择ARM little-endian。IDA 会问你文件类型,一般自动识别为ELF for ARM。如果打开后界面没有自动定位函数,按快捷键Ctrl+F,搜索checkSerial,可以找到导出函数名。

双击进入Java_com_example_crackdemo_CheckCode_checkSerial,然后在函数内部按F5转成伪代码。CrackMe 里的逻辑通常很直白,我这边得到的伪代码简化后类似:

jboolean __fastcall Java_com_example_crackdemo_CheckCode_checkSerial( JNIEnv *env, jobject thiz, jstring input) { const char *s = (*env)->GetStringUTFChars(env, input, 0); if (strcmp(s, "crackme_2025") == 0) { (*env)->ReleaseStringUTFChars(env, input, s); return 1; } (*env)->ReleaseStringUTFChars(env, input, s); return 0; }

这里有两个选择。如果你只想拿到正确答案,直接在字符串窗口里搜索crackme_2025就能交差。但题目要求“破解”,并且我们手头有 C32ASM,所以我选择更通用的做法:直接 patchstrcmp之后的条件跳转,让输入是crackme_2025时走失败分支,输入其他任意字符串时反而走成功分支。

这时切到 IDA 的汇编视图,找到strcmp后面的分支指令。在我这个 Demo 里对应的是:

BL strcmp CMP R0, #0 BEQ loc_12E0 MOV R0, #1 ... loc_12E0: MOV R0, #0

重点就在BEQ。这句的意思是if R0 == 0 then goto loc_12E0。当输入的字符串和正确密码相等时strcmp返回 0,于是跳转到返回 0 的位置。我们要把BEQ改成BNE,也就是“如果不相等才跳转失败”,这样输入错误密码时反而返回成功。

3.4 用 C32ASM 精确修改机器码

现在要用 C32ASM 动手了。先在 IDA 中查看这条BEQ指令所在的文件偏移。把光标停在BEQ一行,切换到 IDA 的 Hex View 窗口,状态栏会显示类似File offset: 000012D4的信息。这个偏移就是文件中的真实位置,记下它。

打开 C32ASM,加载libcheckcode.so。按Ctrl+G,输入0x12D4,回车后光标会跳到对应位置。在这里你会看到一小段二进制数据:

00 00 50 E3 0A 00 00 0A 01 00 A0 E3

这是 ARM 小端序机器码。对应关系是:

  • 00 00 50 E3是CMP R0, #0
  • 0A 00 00 0A是BEQ loc_12E0,高位字节是0A

把0A 00 00 0A的0A改成1A,也就是1A 00 00 0A,就变成了BNE。修改方法很简单,直接在当前字节上输入1A,然后保存文件。有一点要提醒:C32ASM 修改时会覆盖原文件,最好提前给原始so留个备份。

如果你的 CrakMe 的so是 Thumb 指令,情况稍微不同。Thumb 模式下BEQ通常是两条字节D0 xx,改成D1 xx就是BNE。在 IDA 中能看到指令地址是奇数还是偶数,比如地址末尾是1就说明处于 Thumb 模式。这个细节非常容易踩坑,改完发现逻辑没变,大概率就是模式没分清楚。

3.5 回编译、对齐、签名

Patch 完成后,回到crackme_src目录,执行回编译:

apktool b crackme_src -o crackme_patched.apk

回编译过程如果报错,大部分是资源编译问题。可以尝试加-r标志跳过资源混淆或处理。但当前的 Demo 一般能顺利通过。

回编译出来的crackme_patched.apk还没有签名,而且没有做 zipalign 对齐。先执行对齐:

zipalign -v 4 crackme_patched.apk crackme_aligned.apk

-v表示输出过程,数字4表示 4 字节对齐。接着生成一个调试用的签名证书。如果你之前已经有了 keystore,这一步可以跳过,我这里是完整演示:

keytool -genkey -v -keystore demo.keystore -alias demo -keyalg RSA -keysize 2048 -validity 10000

按提示填写姓名、组织等,密码统一即可。然后使用apksigner签名:

apksigner.bat sign --ks demo.keystore --out crackme_signed.apk crackme_aligned.apk

最后安装到模拟器:

adb install crackme_signed.apk

安装成功后打开 App,随便输入一串字符,点击验证,弹出的就是“成功”。到这里,一次完整的基于 IDA + C32ASM 的 CrackMe 破解流程就跑通了。

4. 常见问题与排查技巧实录

实际操作中不会每次都这么顺利。我把这几年折腾过程中遇到最多的几个问题整理了一下,方便你在卡壳时直接对照排查。

4.1 解包后发现 classes.dex 是加壳文件怎么办

现在的 CrackMe 虽然大多是裸奔,但有些题目为了增加难度,会加上腾讯乐固、爱加密之类的外壳。判断方法很简单:用 Apktool 解包后,如果发现smali目录里只有一个壳入口,或者classes.dex打开全是脱壳加载代码,那说明需要先脱壳。

脱壳不是这篇文章展开的重点,但思路可以给一下:运行 App,等到壳把真正的 dex 解密并加载到内存后,通过 dump 内存得到classes.dex。常用方案是 Frida 脚本,或者用现成的脱壳机。脱完壳再按上面的流程走,IDA 分析的目标不变。

4.2 IDA 虚拟地址和文件偏移换算总有偏差

这是新手最容易懵的地方。IDA 界面里看到的地址是虚拟地址,C32ASM 需要的是文件偏移。对于 ELF 格式的so,你当然可以像我刚才说的那样,在 IDA Hex View 状态栏直接读文件偏移。但如果 IDA 卡住了,或者你想验证一下,可以用readelf工具:

readelf -S libcheckcode.so

找到.text段的信息,比如:

[ 4] .text PROGBITS 00001234 00001234 000045 00 AX 0 0 4

这里Addr和Offset常常相同,所以很多老手直接拿虚拟地址当文件偏移用。但如果段的位置不同,换算公式就是:

文件偏移 = 目标虚拟地址 - 段的虚拟起始地址 + 段的文件偏移

用 C32ASM 跳转前,多按这个公式算一遍,能少走很多弯路。

4.3 回编译后安装报 INSTALL_PARSE_FAILED_NO_CERTIFICATES

这个报错代表 APK 没有签名或签名不完整。常见原因是apksigner路径没配对,或者签名时输出了错误文件。检查三步:确认使用的是apksigner.bat而不是jarsigner;确认输出参数--out和最后一个输入文件没有写反;确认当前 Build-Tools 版本足够新,能识别 V1+V2 签名。

另外还要注意,旧的 CrackMe 如果 targetSdkVersion 低于 30,签名 V1 就够了,但在 Android 7.0 以上安装时最好同时带 V2。apksigner默认会两种签名一起生成,所以优先用它。

4.4 Windows 7 下工具运行不起来怎么办

Win7 下最常见的环境坑是缺少 VC++ 运行库,IDA 打开直接报错。去装一个 VC++ 2008/2013 运行库合集能解决九成问题。其次是 Python 插件版本不匹配,如果 IDA 带 Python 插件但启动异常,不影响手动分析,可以忽略。

Apktool 跑不动则大概率是 Java 位数和apktool.jar版本不匹配。在 64 位 Win7 上务必安装 64 位 JDK,并用 64 位 cmd 窗口执行命令。如果提示Unable to access jarfile,检查路径写法,不要使用带中文或空格的目录。

4.5 在 so 里搜不到 checkSerial 导出函数怎么办

checkSerial作为 native 方法通常会导出,但偶尔会被strip或者用JNI_OnLoad动态注册隐藏。这时候先别急着硬搜,打开 IDA 的 Exports 窗口看有没有JNI_OnLoad。如果有,反编译它,通常会看到RegisterNatives调用,通过它就能拿到 Java 层 native 方法和 C 层函数指针的真正对应关系。

如果JNI_OnLoad也没有,那就是通过dlsym动态解析的。这种情况建议换用 Frida 在运行时 hook,直接看哪个函数被调用。逆向本身就是层层博弈,静态不行就动态补上。

最后分享一点经验

玩 Android CrackMe 这几年来,我最大的感受是:真正能卡住人的往往不是逆向技术,而是工具链没调好。IDA 和 C32ASM 的组合在 Windows 7 上非常经典,但如果你想长期搞逆向,早晚要接触 arm64 的分析和动态调试。CrackMe 只是个引子,通过它把 ELF 文件结构、JNI 调用流程、ARM/Thumb 指令、APK 签名机制都串起来,才是最有价值的部分。下次再拿到一个加固或混淆得厉害的样本,至少知道该往哪个方向使劲,不会被开局一个壳就吓退。

相关新闻

人工势场引导双向RRT*:三维无人机航迹规划与Matlab实践

人工势场引导双向RRT*:三维无人机航迹规划与Matlab实践

无人机三维路径规划这件事&#xff0c;真正上手之后你会发现&#xff0c;它核心不在“无人机”三个字&#xff0c;而在“路径规划”这四个字。三维空间的路线搜索和二维迷宫寻路完全不是一个量级&#xff0c;多出来的那个维度&#xff0c;会让采样效率、碰撞检测、内存开销都出…

2026/10/20 16:33:25 阅读更多 →
无人机三维路径规划:鸟群算法BOA的MATLAB实现与调参实战

无人机三维路径规划:鸟群算法BOA的MATLAB实现与调参实战

前阵子做了一个无人机三维路径规划的仿真项目&#xff0c;需求说起来简单&#xff1a;在一片带起伏山体和若干禁飞威胁区的三维地图上&#xff0c;从起点飞到终点&#xff0c;要求路径尽量短、飞行尽量安全、转弯尽量平缓。但真正动手才发现&#xff0c;从A*到RRT都有人在用&am…

2026/10/20 16:33:25 阅读更多 →
网络QoS实战:从分类标记到队列调度的服务质量保障方案

网络QoS实战:从分类标记到队列调度的服务质量保障方案

1. 先从“抢车道”说起&#xff1a;为什么网络也需要 QoS 要说清 QoS&#xff08;Quality of Service&#xff0c;服务质量&#xff09;&#xff0c;得先理解一个最常见的场景。想象一条四车道的城市主干道&#xff0c;早高峰的时候&#xff0c;公交车、私家车、救护车、运货的…

2026/10/20 16:32:24 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/21 9:32:40 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/21 9:32:40 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/21 9:32:40 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/21 9:32:40 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/21 9:32:40 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/21 9:31:32 阅读更多 →

日新闻

周新闻

基于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/21 21:32:28 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

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

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

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/21 21:50:56 阅读更多 →
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/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练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/21 16:24:48 阅读更多 →