1.代码覆盖率在性能优化上的码分一种可行应用
2.Nftables CVE-2023-0179提权利用
3.Redis radix tree 源码解析
4.XRender - 开源之路
5.Golang 汇编介绍
代码覆盖率在性能优化上的一种可行应用
在前端性能优化中,代码覆盖率扮演着关键角色。码分正如管理大师彼得·德鲁克所说:“你无法管理你无法衡量的码分事物。”代码覆盖率,码分作为衡量源代码执行程度的码分指标,对于识别并减少"无效"或"冗余"代码至关重要。码分数据分析系统源码
首先,码分"死代码"和"冗余代码"虽有所区别,码分但都属于未在运行时被执行的码分代码。死代码在编译时可通过工具如Tree Shaking剔除,码分而冗余代码则是码分特定业务场景下不会执行的代码。代码覆盖率则关注运行时的码分执行情况,即测试过程中实际执行的码分源代码比例。
Chrome浏览器的码分DevTools提供了一种实用的度量工具,而Istanbul(NYC)这个工具以其命名含义——伊斯坦布尔的码分地毯覆盖,成为了衡量JavaScript代码覆盖率的常用工具。通过插桩构建(如babel-plugin-istanbul),在代码中添加统计装饰,Istanbul能生成代码执行报告。
在iHome Rax开发套件Tbox中,代码覆盖率被应用于性能优化。当主bundle过大时,通过代码分割和动态加载组件,我们可以依据覆盖率来决定哪些代码可以瘦身。例如,React.lazy的动态加载特性可以配合低使用率组件的分析,实现更有效的代码组织。
尽管Istanbul提供了覆盖率分析,但引入的桩代码可能会增加额外负担。未来,利用无头浏览器的生死狙击明月源码Coverage API和sourceMap技术进行逆编译,可能是更理想的解决方案。总的来说,代码覆盖率是性能优化中的实用工具,帮助我们精细化管理代码,提升前端应用的加载速度。
Nftables CVE--提权利用
在分析了CVE---Nftables整型溢出漏洞的成因之后,本文接下来将深入探讨如何利用这一漏洞。首先,了解到payload_eval_copy_vlan函数中存在整型溢出问题,这使得我们可以将vlan头部结构拷贝至寄存器(NFT_REG_-NFT_REG_)中,而该变量位于栈上,因此可以覆盖到栈上的其他变量。
然而,观察源码后发现regs变量无法直接覆盖到返回地址。进一步分析后发现,jumpstack变量位于regs变量下方,因此可以利用整型溢出覆盖到jumpstack变量。接下来,我们关注nft_jumpstack结构体,该结构体在nft_do_chain函数中起作用,当状态寄存器被设置为JUMP条件时,程序将跳转至其他chain进行处理。保存完当前chain状态后,程序将跳转至目的chain,即存储在regs.verdict.chain中。
还原chain的过程涉及通过递减stackptr来取出存储在jumpstack变量中的chain、rule、lastrule,然后进行rule的解析。需要注意的仿扔赞源码是,在遍历rule时,循环条件为rule < lastrule。因此,在伪造lastrule时,需要确保其值大于rule,否则无法进入循环内部。
接着,观察nft_rule_dp结构体,发现其中包含用于存储nft_expr结构体指针的八个字节。通过篡改该指针,可以劫持程序流程。为了解决这一问题,作者从ctfiot.com/.html中学习了一个技巧:使用ptype /o struct xxx显示结构体信息与偏移。
构建流程如下:通过漏洞溢出至nft_jumpstack结构体,并修改rule变量指向可控内容的地址。同时,将lastrule值篡改为大于rule的值。接下来,在可控内容中伪造一个nft_rule_dp结构体,篡改第一个八个字节(填充位)和第二个八个字节(函数表指针)的值,使其分别指向可控内容的地址。之后,在该地址处伪造nft_expr,将ops变量指向所需执行的函数。
分析后得知,通过上述手段可以实现程序流程的劫持。接下来,需要考虑如何伪造上述结构体。在nft_payload_copy_vlan函数中,漏洞点在于将vlan头数据复制到寄存器中,千月源码授权由于vlan头地址低于寄存器地址,导致在复制完vlan头后会覆盖寄存器值。这里,我们可以通过控制NFT_REG_的值来实现对jumpstack结构体的篡改。
由于可以控制regs变量,首先泄露regs地址,然后在此基础上伪造rule并重新指向jumpstack。这里采用将last_rule设置为函数地址的技巧,以节省八个字节的空间。然而,仅控制八个字节的函数指针不足以构造完整的ROP链,因此需要使用栈迁移。栈迁移的目标是控制一段内存,选择regs作为目标。
在寻找合适的栈迁移gadget时,作者使用了vmlinux-to-elf工具提取符号表,然后利用ropper工具搜索gadget。但尝试后发现大部分gadget不可用。作者最后尝试使用objdump工具提取gadget,并通过搜索add rsp.*等指令找到栈迁移的gadget。进一步计算栈顶与regs函数地址的差值,找到相应的栈迁移gadget。
在提权方面,作者通过覆盖modprobe_path实现提权。选择合适的gadget将rdi设置为modprobe_path,rax设置为覆盖后的路径。然而,在返回到nf_hook_slow函数时,由于设置了rax值导致状态码无法正确设置,程序跳转至NF_DROP分支,在线赌场源码导致内核异常。最终,作者在rbp中找到了一个do_softirq函数,并尝试将其作为返回地址。运行后发现程序能够正常返回到用户态。
最后,验证新用户是否已写入至/etc/passwd文件中,完成提权过程。完整exploit代码可参考github.com/h0pe-ay/Vuln.../poc.c。相关资料参考链接包括github.com/TurtleARM/CV...
Redis radix tree 源码解析
Redis 实现了不定长压缩前缀的 radix tree,用于集群模式下存储 slot 对应的所有 key 信息。本文解析在 Redis 中实现 radix tree 的核心内容。
核心数据结构的定义如下:
每个节点结构体 (raxNode) 包含了指向子节点的指针、当前节点的 key 的长度、以及是否为叶子节点的标记。
以下是插入流程示例:
场景一:仅插入 "abcd"。此节点为叶子节点,使用压缩前缀。
场景二:在 "abcd" 之后插入 "abcdef"。从 "abcd" 的父节点遍历至压缩前缀,找到 "abcd" 空子节点,插入 "ef" 并标记为叶子节点。
场景三:在 "abcd" 之后插入 "ab"。ab 为 "abcd" 的前缀,插入 "ab" 为子节点,并标记为叶子节点。同时保留 "abcd" 的前缀结构。
场景四:在 "abcd" 之后插入 "abABC"。ab 为前缀,创建 "ab" 和 "ABC" 分别为子节点,保持压缩前缀结构。
删除流程则相对简单,找到指定 key 的叶子节点后,向上遍历并删除非叶子节点。若删除后父节点非压缩且大小大于1,则需处理合并问题,以优化树的高度。
合并的条件涉及:删除节点后,检查父节点是否仍为非压缩节点且包含多个子节点,以此决定是否进行合并操作。
结束语:云数据库 Redis 版提供了稳定可靠、性能卓越、可弹性伸缩的数据库服务,基于飞天分布式系统和全SSD盘高性能存储,支持主备版和集群版高可用架构。提供全面的容灾切换、故障迁移、在线扩容、性能优化的数据库解决方案,欢迎使用。
XRender - 开源之路
XRender,阿里飞猪孵化的开源产品,目前在GitHub上获得4.2k star。本文旨在分享XRender在过去一年内的发展和变革,以及它如何成为更多前端开发者的朋友。
一、前言
1. 什么是 XRender?XRender 是一套基于React.js框架的轻量、易用、易上手的中后台「表单 / 表格 / 图表」解决方案,已经在阿里飞猪内部服务三年,未来将持续为用户提供服务。
2. 为什么需要 XRender?对于中后台业务而言,表单+表格能覆盖%的业务场景,且大部分场景重复度高。开发人员无需浪费时间在切图上,XRender这类工具能有效提升开发效率。
二、XRender 的自我革新
三年前,FormRender作为表单解决方案在GitHub上开源,成为XRender家族的首成员。面对复杂业务场景,FormRender的旧技术方案面临挑战,内部决定升级FormRender,并增加更多Render方案,以提升内部前端开发者的效率。
现在的XRender包括FormRender、FRGenetator、TableRender和ChartRender四个组件,统称为XRender。
1.「FormRender」:协议驱动的表单解决方案。代码示例展示其核心功能不变,遵循「协议驱动渲染」原则。
代码重构,面向未来:FormRender 1.x 对内核进行彻底重构,全面拥抱React Hooks和Antd Design 4.x,增加Typescript类型定义,简化编写方式。新增beforeFinish、onFinish钩子,用于表单提交前的校验和数据提交,以及onMount方法,类似于React的componentDidMount。引入userForm方法,方便操作表单和schema,提供动态修改功能。新增watch变量,用于数据监听,增加组件丰富度,如rate、treeSelect等内置支持,以及通过JSON Schema的format属性自定义组件。
2.「表单设计器」:中后台表单可视化搭建工具,提供可拖拽、可搭建能力,并支持导出schema。
3.「TableRender」:表格解决方案,内置搜索、重置、分页功能,简化开发流程。
4.「ChartRender」:基于@ant-design/charts的图表解决方案,提供快速生成图表的能力。
三、适合场景
XRender广泛应用于阿里飞猪的中后台业务,同时被阿里云、高德、淘宝、蚂蚁等BU的开发者使用。对于面向运营的搭建平台,推荐使用XRender。
四、未来规划
1. 内置组件支持自定义:开放List、Array类型的嵌套组件样式定制化,满足不同业务需求。
2. XRender 2.0开发:计划于年中旬完成,支持移动端渲染引擎Rax和Ant Design Mobile v5。
五、结尾
感谢XRender的开发者,特别制作视频以致敬社区。如果你希望在项目中使用XRender,可访问文档站点快速上手。若对源代码感兴趣或有建议,欢迎访问GitHub仓库。如XRender对你有帮助,请在GitHub上给予支持。
Golang 汇编介绍
当你在深入研究 Golang 源代码时,可能会遇到汇编部分,这可能让阅读变得不那么顺畅。下面将简要概述 Golang 中的汇编语言特性。 Go语言的汇编主要遵循Plan9风格,区别于Intel和AT&T的传统风格。Plan9汇编是由Unix操作系统开发团队,特别是Bell实验室的成员所创建的,它为适应不同CPU架构提供了灵活性。尽管Go汇编基于Plan9,但考虑到现实中众多CPU架构的多样性,同一个方法在不同指令集下会有不同的实现。 要查看Go汇编代码,可以在Golang源代码中查找。让我们先了解基础概念:通用寄存器:与特定CPU架构相关,如amd架构提供了个通用寄存器,如rax, rbx, rbp等。在Plan9汇编中,这些被映射为AX, BX, BP, SP等。
虚拟寄存器:Go汇编中引入的4个虚拟寄存器,如R, SP等。
在指令层面,Go汇编包含:变量声明:通过DATA和GLOBL来定义全局变量,如NOPTR表示非指针,不需要垃圾回收。局部变量则根据堆栈帧自动管理。
函数声明:使用TEXT指令,如pkgname·funname(SB),flag,$framesize-argsize,其中flag如NOSPLIT用于优化,framesize和argsize分别表示栈帧大小和参数/返回值大小。
常见操作:如数据搬运(CMPQ), 条件和无条件跳转(JNE),以及更多复杂指令。
通过这些基础,你应该能开始理解和解析简单的汇编代码了。如果你想深入学习,这里推荐一些可供参考的源代码。