https://github.com/NixOS/patchelf
动机
增加项目的维护能力。
关注点
- 新增segment流程 ; 新增到文件末尾,增大program header的空间(可能会与section 发生堆叠),写入记录。
- dynamic 拓展空间、并移动流程;原始的dynamic都会被删除,被修改的section 会被追加到文件末尾,修改section header 记录, 修改.dynamic 内部数据
启动参数:
patchelf --add-needed libjjrt.so home/pareto/Desktop/libil2cpp.so --output libil2cpp.so
代码分析
mainWrapped 函数中处理命令行参数选项 。
将需要添加的so依赖名称存入neededLibsToAdd
目标so 名称放入fileNames
调用patchElf2
patchElf2
- 获取dynamic 和 dynstr 段。
- 创建新的dynstr 和 新的dynamic,并写入新的数据。
- rewriteSection ,判断是动态库,rewriteSectionLibrary ,
- 写文件
rewriteSectionLibrary
startPage 新增Segment 的起始地址
- 增加program header table 的大小,可能会导致第一个section 和program header 的内存堆叠,需要移动前几块segments。
- 获取被占用的section ,后续将其写到文件尾部。
- 获取文件需要新增的空间 ,包含新增的dynstr 、 dynamic 和 section。
- 创建新的program header。
- normalizeNoteSegments() ,这个操作有点神奇,猜测为被占用section 新建program header ,并写入相应数据, 后续可以细看。
- writeReplacedSections , 将原section 覆盖为’X’ , 依次将新曾的section 写入文件,并修改相应的section header entry , 如果sectionName == “.dynamic” , 同时修改dynamic Segment。
- rewriteHeaders , 修改program table 中PT_PHDR segment , 修改program header,需要dynamic段内部字段。
rdi ,改变相应的数据类型的端序。
template<ElfFileParams>
template<class I>
I ElfFile<ElfFileParamNames>::rdi(I i) const
{
I r = 0;
if (littleEndian) {
for (unsigned int n = 0; n < sizeof(I); ++n) {
r |= ((I) *(((unsigned char *) &i) + n)) << (n * 8);
}
} else {
for (unsigned int n = 0; n < sizeof(I); ++n) {
r |= ((I) *(((unsigned char *) &i) + n)) << ((sizeof(I) - n - 1) * 8);
}
}
return r;
}
0 条评论