House of Orange:无free堆题中从top chunk劫持到FSOP的完整利用链
年初打某场线下赛被一道菜单题卡了一晚上add和show两个功能堆溢出给得明明白白唯独没有delete。没有free意味着我熟悉的unsorted bin attack根本找不到触发点——你没机会把一个正常chunk释放进bin里改bk更是无从谈起。后来看前排队伍的wp才意识到这题的标准解法是house of orange。house of orange这套组合拳本质上是三件事劫持top chunk的size让malloc在分配失败时“借刀释放”旧top用unsorted bin attack把一次写操作落到_IO_list_all上最后构造IO_FILE结构在程序退出或报错时通过FSOP链把执行流带到system(/bin/sh)。它是无free菜单题的经典路数也是理解glibc堆管理器“内部动作”和IO_FILE vtable校验机制的绝佳样本。这篇文章就把整条链路从头到尾拆开讲顺便把我踩过的坑也一并写了。1. 无free菜单题的困局与House of Orange的解题思路1.1 常规攻击为什么全线失效在PWN堆题里最顺手的模型永远是“add edit show delete”四件套先打一个fastbin或tcache的double free或者构造unsorted bin attack改掉__malloc_hook或者__free_hook就收工。可一旦题目砍掉delete整套打法瞬间瘫痪。原因很简单glibc的bins里只会出现被释放的chunk。没有free程序自己永远不会把chunk归还给堆管理器你拿着溢出漏洞也只能改写已分配chunk的内容改不了fd/bk因为那些指针根本不存在。就算强行把某个chunk的头部改坏最多也就是让后续malloc报错崩溃谈不上可控利用。所以这类题的第一个思路转折点在于谁的释放不需要程序员手动调用答案是top chunk。当malloc发现top剩余空间不够时会在sysmalloc里做一次特殊的“内部释放”把旧top塞进unsorted bin然后重新划一片堆区当新top。攻击者如果能提前改坏top chunk的size字段就等于凭空制造了一次free。1.2 house of orange的完整链路这个技巧的利用链可以概括成四个阶段劫持top chunk size通过堆溢出把top的size改成一个较小且“看似合法”的值比如0xc1。触发sysmalloc的隐式释放申请一个超大块让malloc走sysmalloc路径旧top被释放进unsorted bin得到libc地址同时伪造fencepost上的新top size为下一轮做准备。unsorted bin attack再次触发释放与分配在unsorted chunk出链时篡改fd/bk把_IO_list_all写成main_arena88。FSOP getShell程序退出或malloc报错时glibc遍历_IO_list_all链表调用vtable里的函数指针最终执行system(/bin/sh)。整个链路没有依赖题目自带的free也没有用到任意地址写原语唯一的输入就是几次add的参数和溢出payload。这就是house of orange最漂亮的地方它让glibc自己的内存管理逻辑变成了攻击者的手。1.3 为什么需要组合拳而不只是unsorted bin attack很多新手会问unsorted bin attack本身只能写一个固定值到任意地址又不能直接控制RIP为什么要和IO_FILE扯上关系因为unsorted bin attack的写入内容固定是main_arena88附近的地址值我们只能控制写到哪里不能控制写入什么。单纯写__malloc_hook为main_arena88没有任何意义写__free_hook也一样程序又没有free调用。所以需要一个“把固定写操作升级为代码执行”的跳板_IO_list_all恰好是这样一个跳板它被写坏后会导致glibc把main_arena里残留的数据当作IO_FILE结构体指针使用而这些数据我们可以在前面的堆操作里“提前布置”成可控的假文件结构。这一环扣一环缺一不可。2. 让sysmalloc“代劳”freetop chunk劫持的底层逻辑2.1 溢出点与top size的物理位置先看堆布局。64位下一个chunk的用户区从chunk地址0x10开始用户数据区长度与size的关系是chunk_size 用户申请大小 0x10且按0x10对齐。top chunk则比较特殊它是arena最末端的大块空闲区size字段就写在它自己的chunk头里。大多数菜单题里add函数如果允许写满甚至写超过申请大小的数据就能从最后一个已分配chunk一路写到top的size字段。也就是说攻击者只需要在最后一次add的content末尾追加8字节这8字节就会覆盖到top的size上。这是整个house of orange的入口漏洞。实际操作时第一步通常先申请一个普通大小的chunk比如add(0x50)然后content写0x50字节占满再加8字节溢出写p64(0xc1)。为什么这样写下一节详细说。2.2 sysmalloc分支什么时候会释放旧top当用户请求大小为nb时malloc首先检查top剩余大小old_size是否够分。判断条件是if (old_size nb MINSIZE) { // 直接切top正常分配 }如果不够进入sysmalloc。sysmalloc里有一整段针对old_top的处理逻辑。核心伪代码大致如下if (old_size MINSIZE) { // 把旧top整块释放进unsorted bin _int_free(av, old_top, 1); // 用old_top的结束位置重新搭一个fencepost当新top av-top (mchunkptr)old_end; }也就是说只要top剩余大小大于最小chunk尺寸64位下MINSIZE是0x20sysmalloc就会先把旧top“丢进回收站”然后才去申请新的内存区。这就是我们要利用的“借刀释放”。释放之后旧top变成unsorted bin里的一个空闲chunk它的fd指针会被系统填成main_arena88unsorted bin的头地址。如果我们有show函数能打印这个旧top的用户区内容就能顺路把libc基地址泄露出来。2.3 修改top size的硬性条件想把top size改成一个能成功触发sysmalloc释放流程的值必须同时满足几个条件缺一个就可能崩条件要求原因最小值size 0x20小于0x20连MINSIZE都不满足直接走其他分支对齐按0x10对齐malloc内部对chunk size有对齐要求不对齐会触发assertPREV_INUSE位一般置1让_int_free认为前一个chunk已分配避免前向合并小于后续请求size nb MINSIZE只有top不够分才会进sysmalloc释放流程经典写法p64(0xc1)就是标准解低三位的标志位里最低位是PREV_INUSE置1表示前块使用中去掉标志后的实际size是0xc0192字节按0x10对齐大于0x20完全满足要求。有些wp写0xd1、0xe1也都可以只是后面布局时要跟着调。2.4 fencepost与新top为什么还要伪造第二轮很多第一次接触这个技巧的人会困惑旧top被释放后新top是谁答案是sysmalloc在旧top原来的位置算出一个fencepost用旧top的size计算出“旧top结束位置”old_end old_top old_size然后把old_end处当作新top的chunk头。这个新top的size字段实际上就是原来old_end那8字节的内容——攻击者是完全可控的。这就是经典exp第二步的由来第一次add(0x1000)触发释放后返回的大块chunk的content可以覆盖到fencepost区域于是顺手在新top的size位置写上0x61让新top只剩0x60大小。这样下一次add(0x60)时又会走一遍sysmalloc释放流程把这个只有0x60的小top也释放进unsorted bin。这个小块size刚好是后续unsorted bin attack需要的尺寸。简单说第二次释放的目的是在unsorted bin里制造一个大小可控的小chunk而不是单纯为了泄露libc。3. Unsorted bin attack为什么盯着_IO_list_all不放3.1 攻击的本质一次固定值的写操作unsorted bin attack的触发条件很经典当malloc从unsorted bin里取一个chunk出来用而这个chunk的bk字段被攻击者改写成了target - 0x10时unlink流程会执行victim-bk-fd unsorted_chunks(av);翻译成人话就是往target这个地址写入main_arena88的值。写入值不受我们控制永远是unsorted bin头地址控制权在“写到哪里”。这个原语看起来非常弱但恰好能用来破坏_IO_list_all。因为_IO_list_all是glibc维护IO_FILE链表头指针的全局变量把它改成一个指向main_arena88的地址等程序走到FSOP流程时glibc会把main_arena88处的数据当成一个_IO_FILE*指针来解引用。3.2 为什么不优先考虑__malloc_hook很多事情能做和值得做是两回事。理论上unsorted bin attack也可以写__malloc_hook触发点在下次malloc但实际利用价值很低写入值是main_arena88这个值不是one_gadget地址。想让main_arena88附近恰好是一个one_gadget或system地址需要极其苛刻的堆布局。后续malloc如果正好从那个地址分配chunk并写数据倒是能二次改写成one_gadget但house of orange的场景里请求的size往往由题目功能固定不好凑。_IO_list_all就不一样。它被写坏后glibc内部会遍历链表把链表上的“假FILE结构”当作真对象来调用只要布局凑好稳定可控不需要任何二次写原语。3.3 为什么需要0x60大小的小chunkhouse of orange经典exp里目标尺寸是0x60。原因藏在IO_FILE遍历的细节里。_IO_list_all被写成main_arena88后FSOP流程会把main_arena88当作fp也就是一个_IO_FILE*。这个地址附近的字节会被解释成IO_FILE的各个字段_IO_write_base、_IO_write_ptr、_chain、vtable全是main_arena里的数值。攻击者没法直接改main_arena但可以通过small bin的写入间接控制它当我们把一个0x60大小的chunk释放进small bin时glibc会把small bin链表的fd/bk写到对应的bin数组位置而这个位置经过偏移计算正好落在main_arena88附近。于是main_arena里的某些“字段”就被替换成了我们可控堆块的地址。这相当于用堆管理器自己的链表维护动作替我们把假FILE结构体的关键指针安插到了正确位置。这也是house of orange最精巧的部分不只是伪造IO_FILE而是把伪造工作拆成了几个堆管理器自动完成的步骤。4. FSOP落地把IO_FILE伪造到能直接getshell4.1 _IO_list_all遍历与触发时机FSOP的全称是File Stream Oriented Programming核心入口是_IO_list_all这个全局链表。glibc在程序退出exit、异常终止abort或部分malloc报错路径里会调用_IO_flush_all_lockp遍历_IO_list_all上每个FILE结构体对带缓冲的文件执行flush。flush过程中如果发现某个FILE的_IO_write_ptr _IO_write_base就会调用它的__overflow方法也就是vtable偏移0x18处的函数指针。一旦我们能控制这个vtable就相当于控制了一次间接调用。在house of orange的经典链路里_IO_list_all已经被写坏第二次add或程序退出时就会触发这条路径此时fp指向的是main_arena88附近的伪造结构。4.2 vtable替换与_IO_str_jumps64位下_IO_FILE结构体的末尾有一个vtable指针指向一组IO函数指针表。如果vtable被替换成_IO_str_jumps的地址那么__overflow对应的就是_IO_str_overflow函数。_IO_str_overflow是glibc用于“字符串流”扩容的函数。它的大致逻辑是如果当前缓冲区不够就调用fp-_s._allocate_buffer(new_size)来重新分配内存。问题在于_s._allocate_buffer这个字段在文件结构体里是一个函数指针——如果我们把假FILE里该字段改成system的地址再把另一个字段改成/bin/sh的地址那么_IO_str_overflow就会执行system(/bin/sh)。vtable校验这块传统house of orange基于glibc 2.23当时还没有IO_validate_vtable到了2.24以后glibc加了vtable地址段检查要求fp-vtable必须落在__libc_IO_vtables段内_IO_str_jumps本身就在这个段里所以2.24依然可以打。2.26以后tcache出现并且vtable检查更严链路就需要调整。4.3 假FILE结构的关键字段布局一个可用的伪造IO_FILE结构体关键位置要填这些内容偏移64位字段写入值0x00 ~ 0x17chunk头/占位按堆块布局填0x18_IO_write_base指向/bin/sh字符串的地址0x20_IO_write_ptr大于_IO_write_base的值触发flush0x28其他数据维持合法布局避免校验崩溃0xd8附近_chain指向下一个假FILE或NULLvtable偏移vtable指针_IO_str_jumps的地址house of orange的具体利用里这些“字段”常常不是直接写的而是main_arena88处本来就有的一些值经过small bin插入后恰好变得可用。所以实战中不建议死记偏移而是用gdb把触发FSOP时fp实际指向的内存dump下来再对着_IO_FILE结构体定义逐个核对。4.4 libc版本差异一览libc版本vtable校验tcachehouse of orange可用性2.23及以前无无经典打法稳定2.24IO_validate_vtable无_IO_str_jumps仍在vtables段总体可用2.26检查加强有链路需调整经典打法失效这也是为什么所有house of orange的wp都会强调“先查libc版本”。同一个exp在2.23的libc上弹shell换到2.24的libc可能就因为vtable校验直接崩了。5. 一段通用exp骨架从泄露地址到弹出shell5.1 题目功能抽象与泄露思路为了方便说清payload我把题目抽象成最简单的三个函数add(size, content)申请并写入show(idx)打印某个已分配chunk的内容均无delete。漏洞点是add的content长度可以超过size导致溢出。泄露libc的手段很自然第一次add(0x1000)触发sysmalloc后旧top已经进入unsorted binfd被写成main_arena88。旧top原来是哪个chunk它虽然被释放了但它的前一个chunk我们第一次add的0x60小chunk仍然是已分配状态show它时读取的是它自己的内容读不到旧top的fd。所以需要想个办法让show能够打印到unsorted bin chunk的fd。常见做法是第一次add的chunk不要和top相邻或者在第二次add之后show一个能通过偏移落到旧top区域的chunk索引。这属于题目细节但有个相对通用的技巧第一次溢出后第二次add返回的大chunk内容其实就出现在旧top之后如果程序对已分配chunk的内容不做长度限制show这个新chunk即可读到unsorted bin的fd。示例exp骨架如下from pwn import * context.arch amd64 def add(size, content): ru(b ) sendlineafter(badd, b1) # 按题目菜单调整 sendlineafter(bsize, str(size)) sa(bcontent, content) def show(idx): sendlineafter(b , b2) sendlineafter(bindex, str(idx)) return ru(b\n) # step1: 改坏top chunk size add(0x50, bA*0x50 p64(0xc1)) # step2: 触发sysmalloc释放旧top进unsorted bin伪造fencepost新top add(0x1000, fit({ 0x10: p64(0) p64(0x21), # 预置一个小chunk头给后续布局用 0x30: p64(0xf1), # 控制fencepost的size 0x50: p64(0x61), # 再伪造下一轮的top size })) # show某个能打到unsorted bin的索引拿libc基址 leak show(...) libc.address u64(leak) - libc.sym[main_arena] - 88 # step3: 布局unsorted bin attack 假IO_FILE payload fit({ # 在0x60的unsorted chunk上布置假IO关键偏移按libc计算 0x...: libc.sym[_IO_list_all] - 0x10, # 作为bk 0x...: p64(libc.sym[_IO_str_jumps]), 0x...: p64(libc.sym[system]), 0x...: binsh_addr, }) add(0x60, payload) # 触发FSOP ru(b ) sendline(b3) # exit p.interactive()5.2 三个add的payload逻辑拆解第一个add(0x50, bA*0x50 p64(0xc1))是入口。0x50是用户区大小实际chunk 0x60从用户区末再往后8字节正好是top的size字段。第二个add(0x1000)是整条攻击链的发动机。它同时完成了三件事触发旧top释放进unsorted bin泄露libc在返回的大chunk内容里覆盖fencepost伪造新top size为0x61提前埋下一部分后续需要的chunk头。fit里的偏移需要根据题目给的堆布局用gdb现场算不同题目差别很大。第三个add(0x60)是扣扳机。0x60的请求会让malloc把unsorted bin里那个0x60的小chunk取出来出链时执行unsorted bin attack把_IO_list_all写成main_arena88。同时这个0x60的chunk自身的数据区又被预置成假IO_FILE的各个字段等FSOP遍历时就是现成的弹药。5.3 调试时的观察点跑这个exp时建议在第三个add前后各下一次断点观察三处关键内存gdb-peda$ x/gx _IO_list_all gdb-peda$ x/20gx main_arena88 gdb-peda$ x/30gx 0x... # 伪造的IO_FILE所在堆块重点确认_IO_list_all是否变成了main_arena88附近的地址main_arena88处是否出现了一个可控堆块的指针假FILE结构的vtable是否指向_IO_str_jumps。任何一步不对都不要急着往下打先对比偏移。6. 翻车实录那些让exp失效的隐藏细节6.1 tcache的干扰与libc版本陷阱如果题目的libc是2.26及以上house of orange的经典链路会多出一个变数tcache。0x60大小的chunk释放后会先进tcache而不是unsorted bin这直接破坏了“小top释放进unsorted bin再被取出触发attack”的前提。所以拿到题先别急着写expchecksec看不了libc版本用pwninit或ldd确认一下。要是libc是2.27又想在无free题目里用unsorted bin attack就得考虑先填满tcache或者改用large bin attack的思路那又是另一套打法了。6.2 movaps栈对齐system就差这一下这是所有FSOP利用里最隐蔽的坑。64位glibc对很多函数调用加了SSE对齐要求当_IO_str_overflow最终调到system时如果rsp不满足16字节对齐system内部执行movaps指令会直接SIGSEGV。现象就是exp跑起来没有任何报错提示程序直接段错误gdb里看到崩溃在libc的memcpy或system内部。解决办法是在假FILE里做函数指针链时加一个ret gadget。比如把_allocate_buffer位置不直接填system而是填libc.address ret_gadget让栈指针先弹齐接着才真正进入system。每条链的栈偏移不一样只能靠gdb调。6.3 偏移计算与gdb调试心得布局偏移是整个house of orange里最容易错的地方。我自己踩过的坑包括_IO_list_all - 0x10少算、main_arena88误写成main_arena、0x60的chunk头占位导致数据区起点差8字节。经验是永远不要凭记忆写偏移用gdb算。在第二个add之后用x/gx查看返回chunk的地址和fencepost地址把两者的差记下来再回到exp里把fit的偏移替换成实测值。fp的vtable指向哪、_chain链到哪也全部以内存dump为准。6.4 没有show时的替代方案严格来说house of orange最标准的形态依赖show来泄露libc。如果题目连show都没有也不是完全没法打但难度陡增。常见方向是partial overwriteunsorted bin的fd低字节被写成本地已知的偏移盲打远程时爆破1~2字节或者通过报错信息把地址带出来。这些方案都有运气成分不推荐作为第一选择。拿到无free无show的题优先考虑能不能改stdout的IO结构来泄露或者直接上one_gadget做多阶段攻击反而更稳。最后讲一个我自己的调试习惯每到一个阶段就先把当前堆布局完整打印出来对比一遍预期。house of orange的每一环都高度依赖堆管理器“自动帮你做某事”一旦中间哪一步的size、fencepost、small bin指针没对齐后面全盘崩。所以宁可多花十分钟在gdb里确认fencepost的size也别直接拿完整的exploit去远程赌。这个习惯救了我好几次也推荐给所有第一次接触这套技巧的朋友。

相关新闻

基于WebSocket的实时对战游戏Demo:通信协议、状态同步与避坑实践

基于WebSocket的实时对战游戏Demo:通信协议、状态同步与避坑实践

简介:基于WebSocket的在线游戏开发Demo是一份面向游戏前端或Node.js/Go开发者的实战示例包。资源围绕WebSocket实时双向通信机制,展示了从HTTP升级握手、数据帧解析到客户端/服务器双向消息推送的完整链路,并给出玩家操作同步与服务器状态广播…

2026/10/13 8:22:27 阅读更多 →
从战略解码到结果应用:企业绩效管理全流程拆解与落地指南

从战略解码到结果应用:企业绩效管理全流程拆解与落地指南

前阵子在一批管理咨询材料里翻到一套编号为DG1067的企业绩效管理PPT资料,整整104页,信息密度相当高。这套资料不是市面上那种只讲KPI和打分表的基础教程,而是把战略解码、目标拆解、过程管理、绩效评价、结果应用、组织与个人联动这一整条链路…

2026/10/13 8:21:46 阅读更多 →
ER图转SQL建模实战:从习题PDF到可运行数据库

ER图转SQL建模实战:从习题PDF到可运行数据库

简介:本资源是一份面向数据库初学者与计算机专业学生的ER图专项训练题集,聚焦实体关系建模核心能力培养,覆盖商业运营、物流调度、教育管理、医疗系统、金融业务等15类真实行业场景。PDF文档共1个文件,大小83KB,内容精…

2026/10/13 8:21:46 阅读更多 →

最新新闻

Windows下MySQL安装配置与卸载全攻略:从版本选择到残留清理

Windows下MySQL安装配置与卸载全攻略:从版本选择到残留清理

如果你也在Windows上折腾过MySQL,应该能理解那种感受:下载页面一堆版本不知道选哪个,安装到一半卡住,装完了服务起不来,或者换版本时残留文件清不干净,重装总报错。这些坑我基本都踩过一遍,花了…

2026/10/13 11:04:15 阅读更多 →
Thingsboard接入Modbus协议的工程实践与稳定架构设计

Thingsboard接入Modbus协议的工程实践与稳定架构设计

1. 项目概述:为什么一个工业协议接入模块值得单独深挖?“Thingsboard modbus协议”——这六个字背后,不是一句轻飘飘的配置说明,而是一条横跨工业现场与云端管理的真实数据链路。我第一次在某智能配电柜远程监控项目里碰上这个组合…

2026/10/13 11:04:15 阅读更多 →
MySQL与Redis缓存一致性实战:从原理到架构选型

MySQL与Redis缓存一致性实战:从原理到架构选型

做后端这几年,我算是把“缓存和数据库数据对不上”这件事踩透了。团队经常半夜被叫醒,一查原因,十有八九是 Redis 里的旧数据还在服务,而 MySQL 里的记录早就改了。这问题听着朴素,真要讲清楚,背后牵扯到读…

2026/10/13 11:04:15 阅读更多 →
电商数据分析实战:从CLV到营收预测的完整链路

电商数据分析实战:从CLV到营收预测的完整链路

这种预测需求,在如今做电商数据分析的人手里,几乎每周都会撞上一次:老板在周会上盯着营收曲线,问"下个月能不能回到峰值""这批流失客户还值不值得砸券召回";运营拿着用户分群报表,却不…

2026/10/13 11:04:15 阅读更多 →
SpringBoot直连Hive:JDBC接入全流程与常见坑详解

SpringBoot直连Hive:JDBC接入全流程与常见坑详解

最近在给一个数据平台做数据接口,需要让SpringBoot服务通过JDBC直连Hive,把数仓里的离线结果表实时捞过来给前端展示。这个说起来好像就是连个数据库,但实际操作中,Hive和MySQL这些传统关系型数据库在驱动、依赖、协议、会话管理上…

2026/10/13 11:04:15 阅读更多 →
Java全栈演唱会售票系统开发与高并发优化实践

Java全栈演唱会售票系统开发与高并发优化实践

1. 项目概述与核心价值演唱会售票系统是连接演出主办方与观众的关键数字化桥梁。这个基于Java技术栈的全栈解决方案,通过SpringBoot/SSM后端Vue前端uniapp多端的组合架构,实现了从票务管理、在线选座到移动端购票的完整闭环。我在实际票务系统开发中发现…

2026/10/13 11:03:11 阅读更多 →

日新闻

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

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

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

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/12 0:16:38 阅读更多 →
影刀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/12 21:05:09 阅读更多 →
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/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练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 阅读更多 →