You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.text段解析时出现全局缓冲区溢出问题求助

解决方案:修复内存扫描时的缓冲区溢出问题

问题根源分析

  1. 循环条件错误:原代码的j + ALIGNMENT < current->p_memsz无法保证访问p+3时不越界——当扫描到段末尾附近时,p+3会超出段的内存范围。
  2. 变量类型不匹配:用32位int遍历64位段大小(ElfW(Addr)类型),当段大小超过2^31-1时会触发整数溢出,导致循环错误执行。
  3. 扫描范围不当:p_memsz包含段的BSS未初始化数据区,这部分没有可执行指令,且可能存在权限或映射问题,不应纳入扫描范围。

修复后的代码

extern char __ehdr_start;

ElfW(Ehdr)* elfheader = (ElfW(Ehdr)*)&__ehdr_start;
android_log("Self_textParser: ELF header [%1$p]", elfheader);

ElfW(Phdr)* programHeader = (ElfW(Phdr)*)((uintptr_t)elfheader + elfheader->e_phoff);

// 遍历所有程序段
for (ElfW(Phdr)* current = programHeader; current < programHeader + elfheader->e_phnum; ++current) {
    if (current->p_type != PT_LOAD) {
        android_log("Self_textParser: Discarding no loadable segment: p_offset (%1$p), p_vaddr (%2$p), p_paddr (%3$p), p_filesz (%4$p), p_memsz (%5$p), p_flags (%6$p)",
             current->p_offset, current->p_vaddr, current->p_paddr, current->p_filesz, current->p_memsz, current->p_flags & 0xF);
        continue;
    }

    android_log("Self_textParser: Found a loadable segment: p_offset (%1$p), p_vaddr (%2$p), p_paddr (%3$p), p_filesz (%4$p), p_memsz (%5$p), p_flags (%6$p)",
         current->p_offset, current->p_vaddr, current->p_paddr, current->p_filesz, current->p_memsz, current->p_flags & 0xF);

    // 只处理可执行段(PF_X标志)
    if ((current->p_flags & PF_X) != 0) {
        // 计算正确的段加载基地址:load_bias = 实际加载地址 - 段的虚拟地址
        uintptr_t loadBias = (uintptr_t)elfheader - current->p_vaddr;
        // 段在内存中的起始地址
        unsigned char* segmentStart = (unsigned char*)(current->p_vaddr + loadBias);
        // 扫描范围限制为段的实际加载大小(p_filesz,不含BSS区)
        ElfW(Addr) scanSize = current->p_filesz;

        android_log("Self_textParser: Segment start: %1$p, scan len: %2$p", segmentStart, scanSize);

        // 遍历扫描,确保每次检查4字节序列时不越界
        // 使用ElfW(Addr)避免整数溢出
        for (ElfW(Addr) j = 0; j <= scanSize - 4; j++, segmentStart++) {
            if (*(segmentStart + 3) == 0x04 && *(segmentStart + 2) == 0x03 && *(segmentStart + 1) == 0x02 && *segmentStart == 0x01) {
                android_log("Instruction found at address: %1$p", segmentStart);
            }
        }
    }
}

关键修改点说明

  • 修正循环条件:改为j <= scanSize -4,确保每次访问segmentStart+3时,指针不会超出段的有效内存范围。
  • 变量类型修正:用ElfW(Addr)类型的循环变量j,匹配64位系统下的段大小类型,避免整数溢出。
  • 缩小扫描范围:用p_filesz替代p_memsz,只扫描实际加载的代码段,跳过无指令的BSS区。
  • 正确计算段起始地址:通过loadBias = 实际ELF头地址 - 段虚拟地址计算,适配所有PT_LOAD段的加载地址计算,而非仅针对p_vaddr=0的情况。

内容的提问来源于stack exchange,提问作者Zaubrack

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 22:00:53