Java内存修改程序源码解析:进程读写与指针链偏移实战

简介:这是一份面向Java外挂开发入门者的内存修改程序源码资源,功能思路类似Cheat Engine,适合想了解进程内存读写、数据搜索与修改原理的开发者研究交流。资源包共86个文件,包含32个java源码、46个class编译文件、3个jar依赖库以及1个exe安装包,另有Eclipse工程配置与偏好设置文件,整体约25.27MB。源码可直接导入Eclipse,导入后需调整Build Path;打包好的JAR在已装Java的电脑上可直接运行,EXE安装包则支持无Java环境的机器。使用流程为打开进程、输入搜索数据、开始搜索、改变游戏数据后再次搜索变化值,最终完成内存修改。目前已有4953人学习下载,读者可借此理解JNA调用、内存地址定位与数据比对等核心思路,并基于现有工程结构进行二次调试与功能扩展。

1. 从一次内存翻车说起:Java 做内存修改到底行不行

去年帮一个做单机游戏辅助的朋友看代码,他用 Java 写了个内存修改的小工具,跑起来十次有七次读到的血量是错的,剩下三次直接把目标进程读崩了。他一口咬定是 JNA 的锅,我让他把代码发过来,翻到指针偏移那一段就笑了——他把long当int读,偏移量算出来差了整整四个字节。这件事让我意识到,Java 外挂开发这个方向,网上教程一抓一大把,但真正把内存修改讲透、把源码给全的少之又少。今天这篇就围绕一份 Java 内存修改程序源码,把进程内存读写、指针链解析、偏移定位这些硬骨头拆开讲,新手能照着跑通,熟手能对照着看自己的实现有没有踩同样的坑。

2. 内存修改程序的四个核心模块:从进程句柄到偏移链

2.1 进程枚举与句柄获取:为什么 Java 需要绕一圈

Java 本身没有直接操作进程内存的 API,所有内存修改工具都得借道 JNI 或者 JNA。这份源码走的是 JNA 路线,好处是不用写 C 代码,坏处是每次调用都要过一层接口映射,性能上比纯 C 实现差一截。但做单机游戏的辅助工具,这点性能损耗完全可以接受。

进程枚举这块,Windows 平台用CreateToolhelp32Snapshot配合Process32First和Process32Next遍历进程列表。源码里封装了一个ProcessUtils类,核心方法长这样:

// 获取目标进程 PID,传入进程名如 "notepad.exe" public static int getProcessId(String processName) { // 创建进程快照,TH32CS_SNAPPROCESS 表示枚举所有进程 HANDLE snapshot = Kernel32.INSTANCE.CreateToolhelp32Snapshot( WinNT.TH32CS_SNAPPROCESS, new DWORD(0)); if (snapshot == INVALID_HANDLE_VALUE) { throw new RuntimeException("创建进程快照失败,错误码:" + Kernel32.INSTANCE.GetLastError()); } PROCESSENTRY32 entry = new PROCESSENTRY32(); entry.dwSize = new DWORD(entry.size()); // 获取第一个进程 if (Kernel32.INSTANCE.Process32First(snapshot, entry)) { do { // 比对进程名,忽略大小写 if (processName.equalsIgnoreCase(entry.szExeFile)) { Kernel32.INSTANCE.CloseHandle(snapshot); return entry.th32ProcessID.intValue(); } } while (Kernel32.INSTANCE.Process32Next(snapshot, entry)); } Kernel32.INSTANCE.CloseHandle(snapshot); return -1; // 未找到目标进程 }

这里有个细节值得注意:PROCESSENTRY32的dwSize字段必须在调用Process32First之前赋值,否则函数直接返回失败。很多新手照着网上残缺的代码抄,漏了这一行,然后对着错误码 87 发呆半天。参数说明上,TH32CS_SNAPPROCESS是快照类型标志,表示只枚举进程;CloseHandle必须成对调用,不然句柄泄漏,跑久了系统资源会被吃光。

拿到 PID 之后,下一步是打开进程获取句柄。OpenProcess需要传入PROCESS_VM_READ、PROCESS_VM_WRITE、PROCESS_VM_OPERATION三个权限标志,缺一不可。源码里把这一步单独抽成openProcess方法,失败时返回的错误码能直接定位问题——5 表示权限不足,需要提权;87 表示参数错误,通常是 PID 传了 -1。

2.2 内存读写:ReadProcessMemory 的正确打开方式

内存读取的核心 API 是ReadProcessMemory,签名里有个容易踩坑的地方:最后一个参数lpNumberOfBytesRead在 JNA 映射里必须传IntByReference,不能传int。源码里封装的方法如下:

// 从目标进程读取指定长度的字节数组 public static byte[] readMemory(HANDLE process, long address, int size) { // 分配接收缓冲区 Memory buffer = new Memory(size); IntByReference bytesRead = new IntByReference(0); boolean success = Kernel32.INSTANCE.ReadProcessMemory( process, // 目标进程句柄 new Pointer(address), // 目标内存地址 buffer, // 接收缓冲区 size, // 读取字节数 bytesRead // 实际读取字节数(出参) ); if (!success) { int err = Kernel32.INSTANCE.GetLastError(); // 299 错误码表示部分读取成功,通常出现在跨页边界时 if (err != 299) { throw new RuntimeException("读取内存失败,地址:" + Long.toHexString(address) + ",错误码:" + err); } } return buffer.getByteArray(0, bytesRead.getValue()); }

这段代码里有个关键判断:错误码 299(ERROR_PARTIAL_COPY)不能当成失败处理。当读取范围跨越内存页边界,而下一页不可读时,系统会返回 299,但已经读到的部分数据是有效的。很多实现直接把这个当异常抛掉,结果就是某些地址明明能读到数据却一直报错。

写入内存用WriteProcessMemory,参数结构类似,但要注意写入前必须确保目标内存页有写权限。如果目标页是只读的,需要先用VirtualProtectEx改成PAGE_EXECUTE_READWRITE,写完再改回去。源码里提供了一个writeMemoryWithProtect方法,把这三步串在一起,避免新手忘记恢复权限导致目标进程行为异常。

2.3 指针链解析:多级偏移的递归查找

单机游戏里的关键数值(血量、金币、坐标)很少直接放在静态地址上,通常是通过多级指针链访问的。比如[[[基址 + 偏移1] + 偏移2] + 偏移3]这种结构,每一级都需要先读指针再叠加偏移。

源码里实现了一个resolvePointerChain方法,接收基址和偏移数组,返回最终地址:

// 解析多级指针链,offsets 数组按从外到内的顺序传入 public static long resolvePointerChain(HANDLE process, long baseAddress, int[] offsets) { long currentAddress = baseAddress; for (int i = 0; i < offsets.length; i++) { // 读取当前地址处的指针值(8 字节,64 位进程) byte[] pointerBytes = readMemory(process, currentAddress, 8); long pointerValue = bytesToLong(pointerBytes); // 叠加偏移 currentAddress = pointerValue + offsets[i]; // 最后一级不需要再读指针,直接返回地址 if (i == offsets.length - 1) { return currentAddress; } } return currentAddress; }

这里有个 32 位和 64 位进程的区别:32 位进程读 4 字节指针,64 位进程读 8 字节。源码里通过isWow64Process判断目标进程位数,动态调整读取长度。如果搞混了,读出来的指针值高位全是零,解析出来的地址完全不对。

偏移数组的顺序也很讲究。以[[[0x400000 + 0x10] + 0x20] + 0x30]为例,传入的 offsets 应该是[0x10, 0x20, 0x30],基址是0x400000。如果顺序反了,第一级就读到错误的地方,后面全盘皆输。

2.4 偏移定位:从已知数值反推地址

偏移定位是内存修改里最耗时间的一步。常见做法是先用精确数值搜索,比如血量是 100,就在内存里搜所有值为 100 的地址;然后让血量变化到 90,在之前的结果里筛选值为 90 的地址;反复几次就能锁定唯一地址。

源码里实现了一个简易的MemoryScanner类,支持精确搜索和范围搜索。核心逻辑是分块读取目标进程的内存区域,逐字节比对:

// 在指定内存范围内搜索目标值(4 字节整数) public static List<Long> scanMemory(HANDLE process, long startAddress, long endAddress, int targetValue) { List<Long> results = new ArrayList<>(); int blockSize = 4096; // 每次读一页,减少 API 调用次数 byte[] targetBytes = intToBytes(targetValue); for (long addr = startAddress; addr < endAddress; addr += blockSize) { try { byte[] block = readMemory(process, addr, blockSize); // 在块内逐字节比对 for (int i = 0; i <= block.length - 4; i++) { if (block[i] == targetBytes[0] && block[i+1] == targetBytes[1] && block[i+2] == targetBytes[2] && block[i+3] == targetBytes[3]) { results.add(addr + i); } } } catch (RuntimeException e) { // 不可读区域跳过,继续下一块 continue; } } return results; }

分块读取的大小选择有讲究:太小了 API 调用次数多,扫描慢;太大了单次分配内存多,容易触发 GC。4096 字节刚好是一页,兼顾了效率和内存占用。搜索时跳过不可读区域是必须的,否则扫到系统保留区域直接抛异常中断。

3. 避坑指南:内存修改程序最常见的五个翻车点

3.1 读到的值全是零或者乱码

现象:调用ReadProcessMemory返回成功,但读出来的字节数组全是 0 或者随机值。

原因:九成是地址搞错了。要么基址不对,要么偏移链解析时某一级读错了指针。还有一种可能是目标进程是 64 位的,但代码按 32 位读指针,高位被截断。

解决:先用 Cheat Engine 手动验证地址是否正确,确认无误后再对照代码检查指针读取长度。在resolvePointerChain里加日志,把每一级解析出的地址打出来,和 CE 的指针扫描结果逐级比对。

3.2 写入后目标进程崩溃

现象:调用WriteProcessMemory返回成功,但目标进程立刻闪退或者行为异常。

原因:写入了受保护的内存区域,或者写入的数据长度不对覆盖了相邻数据。比如只想改 4 字节的血量,结果写了 8 字节,把后面的坐标数据覆盖了。

解决:写入前先用VirtualQueryEx查询目标地址的内存属性,确认可写再操作。写入长度严格匹配数据类型,int就写 4 字节,float也写 4 字节,不要多写。源码里的writeMemoryWithProtect方法已经做了权限检查,直接调用即可。

3.3 扫描内存时程序卡死

现象:调用scanMemory后程序无响应,CPU 占用飙升。

原因:扫描范围太大,比如从 0x00000000 扫到 0x7FFFFFFF,中间大量不可读区域反复抛异常,异常处理本身开销就大。另外逐字节比对在 Java 层做,数据量大时性能很差。

解决:先用VirtualQueryEx枚举所有可读内存区域,只在这些区域内扫描,跳过保留区域。比对逻辑可以优化,比如先比对第一个字节,不匹配直接跳过,减少不必要的比较。源码里已经做了分块和异常跳过,但扫描大范围时还是建议加个进度回调,让用户知道程序没死。

3.4 指针链解析结果不稳定

现象:同样的基址和偏移,有时候能解析出正确地址,有时候解析出错误地址。

原因:目标进程使用了动态内存分配,基址对应的模块可能被重定位(ASLR)。每次启动进程,模块基址都不一样,写死的基址自然失效。

解决:不要硬编码基址,而是通过模块名获取模块基址。源码里提供了getModuleBaseAddress方法,用CreateToolhelp32Snapshot配合TH32CS_SNAPMODULE枚举模块,找到目标模块后取其基址,再叠加固定偏移。这样即使 ASLR 开启,也能正确定位。

3.5 权限不足导致 OpenProcess 失败

现象:OpenProcess返回 NULL,错误码 5。

原因:目标进程以管理员权限运行,而当前程序没有提权。或者目标进程有保护机制,拒绝了外部句柄请求。

解决:以管理员身份运行程序。如果目标进程有反调试或反注入保护,普通的OpenProcess会被拒绝,需要更高级的手段,但这已经超出内存修改的范畴了。源码里在openProcess失败时会打印明确的错误提示,引导用户提权后重试。

4. 从源码到实战:一个完整的修改流程

4.1 环境准备与依赖说明

这份源码基于 Java 8 及以上版本,依赖 JNA 库。项目结构很清晰:core包放进程操作和内存读写的基础封装,scanner包放内存扫描逻辑,utils包放字节转换和地址计算工具。没有用任何第三方框架,纯 JNA 加 JDK 自带库,导入 IDE 后配好 JNA 的 jar 包就能跑。

JNA 的版本建议用 5.13.0 以上,低版本在 64 位系统上有指针映射的 bug。Maven 依赖就一行:

<dependency> <groupId>net.java.dev.jna</groupId> <artifactId>jna</artifactId> <version>5.13.0</version> </dependency>

如果不用 Maven,直接下载 jna.jar 和 jna-platform.jar 加到 classpath 也行。jna-platform 里包含了Kernel32、User32等常用接口的映射,省得自己写。

4.2 实战演示:修改一个模拟程序的金币数值

假设有一个模拟程序,运行后金币数值存在某个动态地址上。操作流程分四步:

第一步,运行模拟程序,记下当前金币数,比如 1000。

第二步,启动内存修改工具,选择目标进程,用精确搜索找值为 1000 的地址。搜索结果可能有几十个,正常。

第三步,回到模拟程序,让金币变化到 800,然后在工具里用 800 筛选之前的结果。反复两三次,直到只剩一个地址。

第四步,调用writeMemory把该地址的值改成 99999,回到模拟程序看金币是否变化。

源码里提供了一个Main类作为入口,把上述流程串了起来。核心调用就三行:

int pid = ProcessUtils.getProcessId("target.exe"); HANDLE process = ProcessUtils.openProcess(pid); MemoryUtils.writeMemory(process, targetAddress, ByteUtils.intToBytes(99999));

targetAddress是通过扫描和筛选得到的最终地址。实际使用时,这个地址可以通过指针链解析自动获取,不需要每次手动搜索。

4.3 源码里的几个设计亮点

第一个亮点是异常处理的分层。底层 API 调用失败抛RuntimeException并附带错误码,上层扫描逻辑捕获异常后跳过当前块继续执行,不会因为一个不可读地址中断整个扫描。这种分层设计让代码既健壮又容易调试。

第二个亮点是字节转换工具类。ByteUtils里封装了intToBytes、bytesToInt、longToBytes、bytesToLong等方法,统一处理大小端问题。Windows 是小端序,Java 的ByteBuffer默认也是小端序,但手动拼接字节时容易搞反,用工具类统一处理省心很多。

第三个亮点是内存扫描的分块策略。前面提到过,4096 字节一块,既不会因为单次读取太大导致内存压力,也不会因为太小导致 API 调用过于频繁。这个数值是实测出来的,在扫描速度和内存占用之间取得了比较好的平衡。

5. 几个让效率翻倍的技巧

5.1 用模块基址加偏移替代硬编码地址

硬编码地址的代码活不过一次游戏更新。正确的做法是找到访问目标数值的指令,分析出模块基址和偏移链,然后在代码里动态计算。源码里的getModuleBaseAddress配合resolvePointerChain就是干这个的。虽然前期分析麻烦一点,但一次分析长期有效,游戏小版本更新通常不会改变偏移结构。

5.2 扫描时限定内存区域

全内存扫描是最笨的办法。用VirtualQueryEx先枚举可读区域,只扫这些区域,速度能提升好几倍。源码里的MemoryScanner已经内置了这个优化,调用scanMemory时传入区域列表即可。如果自己实现,记得跳过PAGE_GUARD和PAGE_NOACCESS的区域,这些地方读了必崩。

5.3 写入前先备份原值

修改内存是有风险的操作,写错了可能导致目标进程崩溃。源码里的writeMemoryWithProtect方法在写入前会先读取原值并返回,调用方可以保存下来,出问题时恢复。这个习惯在调试阶段特别有用,改错了能快速回滚,不用重启进程。

5.4 用日志代替断点调试

内存修改程序的调试环境比较特殊,断点停下来的时候目标进程的状态可能已经变了。源码里在关键路径上都加了日志输出,包括进程句柄值、每次读写的地址和长度、指针链每一级的解析结果。出问题时看日志比单步调试快得多,而且不会干扰目标进程的运行。

5.5 处理 32 位和 64 位进程的差异

32 位进程的指针是 4 字节,64 位是 8 字节。源码里通过IsWow64Process判断目标进程是否运行在 WOW64 环境下,动态选择指针读取长度。如果目标进程是 64 位的,但当前 Java 进程是 32 位的,OpenProcess会失败,需要换成 64 位的 JDK 运行。这个坑在混合环境下特别常见,源码的 README 里专门写了说明。

6. 最后说一个指针链解析的硬核技巧

指针链解析最怕的就是中间某一级指针失效。比如[[基址 + 0x10] + 0x20]这个结构,如果[基址 + 0x10]读出来是 0,那后面加多少偏移都没意义。源码里的resolvePointerChain在每一级读取后都会检查指针值是否在合理范围内——低于 0x10000 或者高于 0x7FFFFFFFFFFF 的值直接判定为无效,提前终止并返回 -1。这个检查看起来简单,但能避免大量无效的后续读取,也方便定位是哪一级出了问题。

另一个技巧是偏移量的符号处理。有些游戏的偏移是负数,比如[基址 - 0x40]。Java 的int是有符号的,直接相加没问题,但转成十六进制字符串打印时会显示成FFFFFFC0这种形式,看起来吓人。源码里的AddressUtils提供了toHexString方法,统一按无符号格式输出,日志看起来清爽很多。

回过头看,Java 做内存修改这件事,难点不在语言本身,而在对操作系统内存模型的理解。进程句柄、虚拟内存、指针链、内存保护属性,这些概念搞清楚了,用什么语言写都差不多。这份源码的价值在于把 Windows 平台的内存操作 API 用 JNA 完整映射了一遍,并且把常见的坑都填上了。新手可以拿它当模板改,熟手可以对照着检查自己的实现有没有遗漏边界情况。我每次写这类工具,都会先把ReadProcessMemory和WriteProcessMemory的错误码处理过一遍,确认 299 和 5 这两个特殊码都覆盖到了,再往下写业务逻辑。希望这份源码和上面的经验能帮你少走点弯路。

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

相关新闻

Windows Server 2003域控靶机搭建:从AD初始化到域渗透攻击复现

Windows Server 2003域控靶机搭建:从AD初始化到域渗透攻击复现

在本地虚拟化环境里复现一台Windows Server 2003域控制器&#xff0c;是理解Windows域认证机制、老式协议危害和横向移动手法的最直接路径。这篇文章不讲空话&#xff0c;直接记录我动手搭建靶机的完整过程&#xff1a;从基础系统安装到Active Directory初始化&#xff0c;从账…

2026/10/20 22:52:37 阅读更多 →
diagram-design:面向协同理解的四层视觉建模方法论

diagram-design:面向协同理解的四层视觉建模方法论

1. “diagram-design”不是画图软件&#xff0c;而是一套系统性视觉表达方法论“diagram-design”这个词组在当前技术社区和设计协作场景中高频出现&#xff0c;但它绝非某个具体工具的代称&#xff0c;也不是UI界面里拖拽连线的简易流程图功能。我最早在参与某高校跨学科课程共…

2026/10/20 22:51:31 阅读更多 →
9688雷霆战机移植记:JAVA ME弹幕游戏的性能调优与真机避坑

9688雷霆战机移植记:JAVA ME弹幕游戏的性能调优与真机避坑

简介&#xff1a;面向JAVA ME游戏入门者的《9688雷霆战机》个人移植版源码及解析资料包&#xff0c;以经典飞行射击游戏为实例&#xff0c;展示在J2ME平台下借助KVM虚拟机、MIDP/CLDC配置与Profile完成移动端游戏开发的完整路径&#xff0c;同时说明Java语言子集在受限环境中的…

2026/10/20 22:51:31 阅读更多 →

最新新闻

深入parakeet-redux架构:从24层TDT编码器到解码器的设计细节

深入parakeet-redux架构:从24层TDT编码器到解码器的设计细节

人工智能语音模型量化模型压缩 【免费下载链接】parakeet-redux 项目地址&#xff1a; https://ai.gitcode.com/hf_mirrors/moondream/parakeet-redux 点击查看 免费下载 &#x1f99c; parakeet-redux 是一个 1.58 bit 三值量化的自动语音识别&#xff08;ASR&#xff09;模型…

2026/10/21 1:25:00 阅读更多 →
戴森球计划工厂蓝图实战指南:3 条阶段线打通你的星际产线

戴森球计划工厂蓝图实战指南:3 条阶段线打通你的星际产线

戴森球计划工厂蓝图实战指南&#xff1a;3 条阶段线打通你的星际产线 【免费下载链接】FactoryBluePrints 游戏戴森球计划的**工厂**蓝图仓库 项目地址: https://gitcode.com/GitHub_Trending/fa/FactoryBluePrints FactoryBluePrints 是一个戴森球计划玩家可直接导入游…

2026/10/21 1:25:00 阅读更多 →
无名杀 noname 教程:浏览器直接玩,2000+ 武将的免费网页版三国杀

无名杀 noname 教程:浏览器直接玩,2000+ 武将的免费网页版三国杀

无名杀 noname 教程&#xff1a;浏览器直接玩&#xff0c;2000 武将的免费网页版三国杀 【免费下载链接】noname 项目地址: https://gitcode.com/GitHub_Trending/no/noname 无名杀&#xff08;noname&#xff09;是一个开源的网页版三国杀&#xff0c;把整个游戏放进浏…

2026/10/21 1:25:00 阅读更多 →
霞鹜文楷:免费商用的开源中文字体,排版与等宽一份搞定(新手向)

霞鹜文楷:免费商用的开源中文字体,排版与等宽一份搞定(新手向)

霞鹜文楷&#xff1a;免费商用的开源中文字体&#xff0c;排版与等宽一份搞定&#xff08;新手向&#xff09; 【免费下载链接】LxgwWenKai An open-source Chinese font derived from Fontworks Klee One. 一款开源中文字体&#xff0c;基于 FONTWORKS 出品字体 Klee One 衍生…

2026/10/21 1:25:00 阅读更多 →
DLSS Swapper 新手指南:免费 3 步完成游戏 DLSS 版本升级与回退

DLSS Swapper 新手指南:免费 3 步完成游戏 DLSS 版本升级与回退

DLSS Swapper 新手指南&#xff1a;免费 3 步完成游戏 DLSS 版本升级与回退 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper DLSS Swapper 是一款免费开源的 Windows 桌面工具&#xff0c;负责下载、管理并替换游戏里自…

2026/10/21 1:25:00 阅读更多 →
Apktool 安装与配置完整指南:APK 逆向工具从源码快速上手

Apktool 安装与配置完整指南:APK 逆向工具从源码快速上手

Apktool 安装与配置完整指南&#xff1a;APK 逆向工具从源码快速上手 【免费下载链接】Apktool A tool for reverse engineering Android apk files 项目地址: https://gitcode.com/GitHub_Trending/ap/Apktool 拿到一个闭源 APK&#xff0c;想改个字符串、挪个布局、动…

2026/10/21 1:23:59 阅读更多 →

日新闻

统一内存+量化:锐龙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 阅读更多 →