简体   繁体   English

如何在现有的Android SO库中添加一个导入的函数?

[英]How to add one imported function to existing Android SO library?

I'm currently developing the SO plugin loader for the existing SO library (GTA SA for Android). 我目前正在为现有的SO库(适用于Android的GTA SA)开发SO插件加载程序。 The SO libraries on Android are Unix ELF files. Android上的SO库是Unix ELF文件。 Having no source code of the library I cannot simply add the imported function in source code and compile the SO library again. 没有该库的源代码,我不能简单地在源代码中添加导入的函数并再次编译SO库。

There is libGTASA.so, which I want to edit and alter the import table, adding a new symbol RunSOpluginLoader, which would be implemented in libFastman92pluginLoader.so, which is already loaded before libGTASA.so gets loaded, by Java code (classes.dex) that I also have modified. 有一个libGTASA.so,我想编辑和更改导入表,添加一个新符号RunSOpluginLoader,该符号将在libFastman92pluginLoader.so中实现,该文件已由Java代码(classes.dex ),我也进行了修改。

For EXE files on Windows there are plenty of programs to edit the imports and I'd use LordPE. 对于Windows上的EXE文件,有很多程序可以编辑导入,我会使用LordPE。 For ELF file I need a different solution however and I'm having a trouble with finding one. 对于ELF文件,我需要一个不同的解决方案,但是在寻找解决方案时遇到了麻烦。

I tried using HT Editor, which is supposed to open and edit the ELF files, but few seconds after libGTASA.so gets opened in HT Editor the application simply crashes. 我尝试使用HT编辑器,它应该打开并编辑ELF文件,但是libGTASA.so在HT编辑器中打开几秒钟后,应用程序便崩溃了。

I need a solution to add an import to SO library, preferably the solution that would run on Windows, but if there's none then I am willing to do it on Linux system. 我需要一个解决方案以将导入添加到SO库,最好是可以在Windows上运行的解决方案,但是如果没有解决方案,那么我愿意在Linux系统上进行。

After properly adding an import I am going to edit a bit of ARM code inside the libGTASA.so to actually call the newly imported function. 正确添加导入后,我将在libGTASA.so中编辑一些ARM代码,以实际调用新导入的函数。

Essentially: 实质上:
libGTASA.so - I want to add an imported symbol RunSOpluginLoader to this file. libGTASA.so-我想将导入的符号RunSOpluginLoader添加到此文件。

Few days after I wrote the question I figured out how to do this task. 在我写了问题的几天后,我就知道了如何完成这项任务。 I had written a simple ELF file manager class in C++ and program, which does the following: 我已经用C ++和程序编写了一个简单的ELF文件管理器类,该类执行以下操作:

  • load the ELF file - create a representation of header, sections and program segments, dynamic table (pointed by PT_DYNAMIC) 加载ELF文件-创建标题,节和程序段,动态表的表示(由PT_DYNAMIC指向)
  • added new section (.fastman92_code, with permissions RWX) 添加了新部分(.fastman92_code,具有RWX权限)
  • added new program segment that covers a new section 添加了涵盖新部分的新程序段
  • I noticed the program segment must be aligned, I made an alignment of 32768 and it worked. 我注意到程序段必须对齐,我对32768进行了对齐,然后它起作用了。
  • added new string to string table (pointed by this->header.e_shstrndx), string "fastman92.code", it's the section name. 在字符串表(由this-> header.e_shstrndx指向)中添加了新字符串,字符串“ fastman92.code”,这是节名。
  • sections are rellocated and will be written at the end of file, elfManager.header.e_shoff had to be updated. 节被重新分配并将写入文件的末尾,必须更新elfManager.header.e_shoff。
  • rellocated .dynstr (the section pointed by DT_STRTAB), adding two importedentries to it: 重新分配.dynstr(DT_STRTAB指向的部分),向其中添加两个导入的条目:
    {"libFastman92pluginLoader.so"}, {"ProcessPluginLoading"} {“ libFastman92pluginLoader.so”},{“ ProcessPluginLoading”}
  • rellocated .dynsym, adding these two entries to the array. 重新分配.dynsym,将这两个条目添加到数组中。
  • reallocated section pointed by DT_JMPREL from dynamic table, added one entry to point into ProcessLoadingPlugin, near my added Jni_OnLoad function 动态表中DT_JMPREL指向的重新分配部分,在我添加的Jni_OnLoad函数附近添加了一个条目以指向ProcessLoadingPlugin
  • rellocated program segments, added PT_DYNAMIC entry, which is neccessary, because the program segments are longer a part of the first loadable segment. 重新分配的程序段,则添加了PT_DYNAMIC条目,这是必要的,因为程序段较长,是第一个可装入段的一部分。 They're no longer a part of segment with virtual address of 0x0. 它们不再是虚拟地址为0x0的段的一部分。
  • added a simple function, a replacement of Jni_OnLoad which would call an imported symbol ProcessPluginLoading, which is implemented in libFastman92pluginLoader.so, then execute functions from .init_array, then call real an original Jni_OnLoad. 添加了一个简单的函数,替代了Jni_OnLoad,它将调用导入的符号ProcessPluginLoading,该函数在libFastman92pluginLoader.so中实现,然后从.init_array执行函数,然后真正调用原始的Jni_OnLoad。 A symbol "Jni_OnLoad" had to be pointed to my few function. 必须将符号“ Jni_OnLoad”指向我的几个函数。
  • edited dynamic table, added DT_NEEDED with offset of string pointing to "libFastman92pluginLoader.so" 编辑动态表,添加了DT_NEEDED,其字符串偏移量指向“ libFastman92pluginLoader.so”
  • edited dynamic table, disabled .init_array, set up a size of it to be zero (InitArraySzIt->d_un.d_val = 0;) where auto InitArraySzIt = elfManager.FindFirstEntryInDynamicTableWithTag(0x1B); 编辑的动态表,禁用.init_array,将其大小设置为零(InitArraySzIt-> d_un.d_val = 0;),其中自动InitArraySzIt = elfManager.FindFirstEntryInDynamicTableWithTag(0x1B);
  • save a new .so file 保存一个新的.so文件

If you want to learn more about or get the code, feel free to contact me. 如果您想了解更多信息或获取代码,请随时与我联系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM