测试环境: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")))
解密时机
- _init
- 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信息就好,其他的信息可用直接清除。
网友评论