如何修改代码避免ASAN检测到的.text段解析全局缓冲区溢出
.text段解析的全局缓冲区溢出修复方案
问题说明
原代码解析Android原生应用.text段时,因内存范围判断逻辑不严谨,被ASAN检测到全局缓冲区溢出。需要修改代码,确保仅在合法的.text段内存区域内解析,避免越界访问。
原问题代码
extern char __ehdr_start; extern char etext; ElfW(Ehdr) *elfhdr = (ElfW(Ehdr) *) &__ehdr_start; int i; for (i = 3; (unsigned long)(&__ehdr_start + elfhdr->e_entry + i) < (unsigned long)(&etext); i = i + 4) { if ((unsigned char)*(&__ehdr_start + elfhdr->e_entry + i) == 0x01 ) { if(((unsigned char)*(&__ehdr_start + elfhdr->e_entry + i - 1) == 0x02) && ((unsigned char)*(&__ehdr_start + elfhdr->e_entry + i - 2) == 0x03) && ((unsigned char)*(&__ehdr_start + elfhdr->e_entry + i - 3) == 0x04)) { ....
修复后的代码
#include <elf.h> // 声明链接器导出的符号 extern char __ehdr_start; extern char __etext; extern char __text_start; int main() { ElfW(Ehdr) *elf_hdr = (ElfW(Ehdr) *)&__ehdr_start; ElfW(Phdr) *phdr = (ElfW(Phdr))((char *)elf_hdr + elf_hdr->e_phoff); char *text_start = NULL; char *text_end = NULL; // 遍历程序头表,定位可执行的PT_LOAD段(即.text段) for (int i = 0; i < elf_hdr->e_phnum; i++) { if (phdr[i].p_type == PT_LOAD && (phdr[i].p_flags & PF_X)) { text_start = (char *)elf_hdr + phdr[i].p_vaddr; text_end = text_start + phdr[i].p_memsz; break; } } // 确认找到.text段后执行解析逻辑 if (text_start && text_end) { // 遍历指针始终限定在.text段范围内,避免越界 for (char *ptr = text_start + 3; ptr + 1 <= text_end; ptr += 4) { if ((unsigned char)*ptr == 0x01) { // 检查前三个字节前,先确认指针未越界到.text段起始之前 if (ptr - 3 >= text_start && (unsigned char)*(ptr - 1) == 0x02 && (unsigned char)*(ptr - 2) == 0x03 && (unsigned char)*(ptr - 3) == 0x04) { // 此处添加你的业务处理逻辑 .... } } } } return 0; }
核心修复要点
- 精准定位.text段:不再通过
e_entry估算起始位置,而是遍历ELF程序头表,找到具备可执行权限的PT_LOAD段,这是.text段的准确内存范围。 - 双重边界校验:
- 遍历循环中限制
ptr + 1 <= text_end,防止访问.text段末尾之外的内存; - 检查前三个字节前,先判断
ptr - 3 >= text_start,避免越界访问.text段起始前的内存区域。
- 遍历循环中限制
- 符号适配Android环境:部分Android链接器导出的.text段结束符号为
__etext而非etext,__text_start是更可靠的起始符号,若程序头表遍历不适用,可直接使用这些符号定义.text段范围。
内容的提问来源于stack exchange,提问作者Zaubrack
相关产品推荐
相关产品推荐

