so .text段加密问题记录

测试环境:android 8.1
加密段:整个.text段

ELF 头文件占坑

需要在ELF头文件中找“坑”记录 section的偏移以及大小
ELF头文件可用空间

  • 0x06 - 0x0F 合计 10Bytes
  • 0x18 - 0x1B 合计 4Bytes
  • 0x24 - 0x2B 合计 8Bytes
    具体详情请参考:Android-SO库文件头分析
    这里讲的超级详细。

解密函数使用C实现 ,避免使用C++

尽量使用C函数实现的原因,比如

char* path=new char[128]

这里存在一个关键字new,使用IDA反编译查看,new 关键字变成了
operator new(unsigned int)导出符号为:_Znwj
而_Znwj的具体实现代码是在.text段中,由于.text段已经加密,肯定无法正常运行,所以要是使用C函数实现,其中还包括STL相关函数也不能使用。

section表清除

可能会遇到的问题 .dynamic section header was not found 处理
主要是在7.0以上的机器上,产生原因 e_shoff 被修改(我是这个原因)
解决办法:使用e_flags和e_entry来储存段的偏移和大小。这也是第一个要占坑的原因。

解密函数使用自定段

比如我的:#define section_1 attribute((section("section_1")))

解密时机

  1. _init
  2. init_array
    其中_init优先级最高

so section信息清除尝试(android 8.1)

尝试只保留“.dynamic”段,无法正常运行,错误日志如下
“.dynamic section has invalid link(4) sh_type: 0 (expected SHT_STRTAB)”
查看linker源码:

const ElfW(Shdr)* strtab_shdr = &shdr_table_[dynamic_shdr->sh_link];
    if (strtab_shdr->sh_type != SHT_STRTAB) {
        DL_ERR_AND_LOG("\"%s\" .dynamic section has invalid link(%d) sh_type: %d (expected SHT_STRTAB)",
                   name_.c_str(), dynamic_shdr->sh_link, strtab_shdr->sh_type);
    return false;
}

重点shdr_table_[dynamic_shdr->sh_link],查看.dynamic的sh_link值

Elf32_Word s_link 2h 636Ch 4h
值为2,根据查看指向的是.dynstr 段(可以使用010 Editer 查看)
所以 .dynstr section 信息要保留,尝试保留这个段,重新打包运行。
至此可以正常运行
没去深究linker源码,测试了4.4 7.0 8.1的系统 都木有问题。直接保存.dynstr 和 .dynamic 连个段的section信息就好,其他的信息可用直接清除。

你可能感兴趣的:(so .text段加密问题记录)