How to add one imported function to existing Android SO library? - android

I'm currently developing the SO plugin loader for the existing SO library (GTA SA for Android).
The SO libraries on Android are Unix ELF files.
Having no source code of the library I cannot simply add the imported function in source code and compile the SO library again.
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.
For EXE files on Windows there are plenty of programs to edit the imports and I'd use LordPE.
For ELF file I need a different solution however and I'm having a trouble with finding one.
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.
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.
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.
Essentially:
libGTASA.so - I want to add an imported symbol RunSOpluginLoader to this file.

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:
load the ELF file - create a representation of header, sections and program segments, dynamic table (pointed by PT_DYNAMIC)
added new section (.fastman92_code, with permissions 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.
added new string to string table (pointed by this->header.e_shstrndx), string "fastman92.code", it's the section name.
sections are rellocated and will be written at the end of file, elfManager.header.e_shoff had to be updated.
rellocated .dynstr (the section pointed by DT_STRTAB), adding two importedentries to it:
{"libFastman92pluginLoader.so"},
{"ProcessPluginLoading"}
rellocated .dynsym, adding these two entries to the array.
reallocated section pointed by DT_JMPREL from dynamic table, added one entry to point into ProcessLoadingPlugin, near my added Jni_OnLoad function
rellocated program segments, added PT_DYNAMIC entry, which is neccessary, because the program segments are longer a part of the first loadable segment. They're no longer a part of segment with virtual address of 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. A symbol "Jni_OnLoad" had to be pointed to my few function.
edited dynamic table, added DT_NEEDED with offset of string pointing to "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);
save a new .so file
If you want to learn more about or get the code, feel free to contact me.

Related

How to dynamically add stickers in the whatsapp-sticker pack [Android][Unity-Android plugin]?

I have used the repo to make an android plugin for my unity game, wherein I reward the player with some stickers at each level. So basically Im successful in calling the add sticker function from the android plugin and can add the sticker pack according to the desired identifier and name. (Here the contents.json, is already in the aar.)
But since i now need to edit the contents.json (we cant modify .aar files) so i copy the assets file content checkout the content provider code https://pastebin.com/urhXTs7z
And now the contents.json is in my Android/data/packagename/files/
From Unity I deserialize and serialize that json and just add items to the sticker pack list. And then overwrite the contents.json if (Application.platform == RuntimePlatform.Android)
{
System.IO.File.WriteAllText(Application.persistentDataPath + "/contents.json", contents);
}
It works for the original contents.json but after updating the stickerpack, the new items are not read by the ReadContentFile function
But this doesnt work, the plugin just reads the original contents.json. (Because copy assets is called in OnCreate, I tried using sharepreferences of android to call the copyassets function only once. But then my app crashes.)
I found people with similar questions here : https://github.com/WhatsApp/stickers/issues/340
But im not able to figure out what to do.
I dont know even it is possible to handle stickers addition dynamically when the code is inside a plugin.
Please refer to the code in the pastebin link
Would love any suggestions to alternative methods to do this.

Making sense of symbol table entry (when header function is not present)

I have a JNI function in a C++ library.
When I create the library using cmake (but forget to put function declaration) in the header file, the library is created successfully.
When I look for function name in library symbol table I get following output
nm libuserlibrary.so | grep printxx
00506e60 T _Z60Java_com_example_user_myapplication_userlibrary_printxxP7JNIEnv_P8_jobject
But when I give function declaration in the header file, I get following output
nm libuserlibrary.so | grep printxx
00506e50 T Java_com_example_user_myapplication_userlibrary_printxx
Why is there this difference between these two symbol table entries? What is the purpose of _Z60 and P7JNIEnv_P8_jobject around the function name?
I also noticed that in the first case, I cannot call the JNI funciton from Android java code (it says unsatisfied-linker-error, implementation not found).
C++ allows function overloads and namespaces like Java does. So, it annotated the function name with parameter information so the linker can bind to the correct overload.
JNI was designed for C which does not allow function overloads or namespaces. So it invented it's own annotation system and provides the javah tool to help you use it. The header can be used in C++ too. C++ was designed to allow some functions to be called as if they written in C. The header has code that indicates that to the compiler. So, put it all together and you can write Java-callable functions in C++.

How to rename dynamic symbols in arm elf .so file?

I need to modify a so inside an Android APK.
The task is to rename the dynamic symbols in side the so (which is the function name).
For example, change from Java_com_example_abc_.... to Java_com_yahoo_zzz_....
I try to use WinHex directly search and replace text words, the apk startup error.
Seems like the .hash section also needs to be updated, but i do not know how to update the .hash section.
My question is what is the correct or preferable way to rename the dynamic Symbol?
I heave been stuck for 3 days, please help me, thank you very much!
Found a post might related, but he didn't gave the alternative solution.
https://sourceware.org/ml/binutils/2006-03/msg00266.html
I heave been stuck for 3 days, please help me,
What you are trying to achieve is effectively impossible.
ELF files have complicated internal structure, and what you want to do requires that you break it up and re-assemble the parts. An analogy would be to break an Intel CPU into transistors and re-assemble an AMD CPU from them.
Found a post might related
It is related. Quote:
Basically it does the following:
loop over .dynsym and re-create .dynstr
re-create the .hash table from scratch
calculate new lma/vma, new memory layout (.dynstr size changed!)
fix the contents of .dynamic, according to the new layout
fix .rel.dyn
fix .rel.plt
fix .dynsym again
write out the new section contents
In copy_section: exclude the rewritten sections from being copyied.
Currently it seems to create a syntactically valid ELF file, but as
the distance between .plt and .got changes, the relative addressing in
.plt is broken. Additionally the .got has to be fixed again.
So the author managed to glue together something that looks like an AMD CPU, but which doesn't work.
Sure, you can spend another 2 weeks to understand what the author did, and then another 3 weeks to fix the remaining broken pieces. And after that, you may get something that kind of sometimes works.
Your time is likely better spent elsewhere.
Have a look at LIEF, but try to keep them the same length
native_lib = 'my_native_lib.so'
lib = lief.parse(native_lib)
for x in lib.exported_symbols:
if x.name == 'Java_com_example_abc':
x.name = 'Java_com_foobarr_zzz'
lib.write(native_lib) # overwrite
The ability to change names in shared libraries was added in Patchelf: https://github.com/NixOS/patchelf/commit/da035d6acee1e5a608aafe5f6572a67609b0198a
It should be available in the next release (after 0.17.2). Meanwhile you can build the tool following the instructions in https://github.com/NixOS/patchelf#compiling-and-testing
To use it, create a map file with two names (old and new) per line, and invoke Patchelf with:
$ patchelf --output libPatched.so --rename-dynamic-symbols map_file libOriginal.so
Please provide feedback if you find issues. Thanks!

what R.java file actually does and how

I have been working on a simple android tutorial and while browsing through the project folders I found this R.java file in gen folder...
When I opened it seemed to me as a mess...
first R itself is a class.
it had multiple Inner classes defined within eg drawable,id,layout,etc.
and that inner classes had lots of variables declared as below which were assigned with hex values
public static final int addr=0x7f080003;
...
...
and much more
R is auto generated and acts as some pointer for other files
Questions for R.java
what it is basically for
how it works
why
values are in hex
what role did it performs while the actual application is running
"Acts as some pointer to other files" is actually absolutely correct, now the question is which files it points to how it is done.
What does it contain?
R file contains IDs for all the resources in the res folder of your project and also some additional IDs that you define on your own (in the layouts, for example). The IDs are needed for the Android resource management system to retrieve the files from the APK. Each ID is basically a number which corresponds to some resource in the resource management system.
The file itself is needed so you can access or reference the resource from code by giving the ID of the resource to the resource manager. Say, if you want to set the view in the activity, you call
setContentView(R.layout.main);
main in the R file contains the number which is understood by the Android resource management system as the layout file which is called main.
Why is it better than just plain file names?
It's harder to make a mistake with the generated fields. If you write the field name incorrectly, your program won't compile and you will know that there's an error immediately. If you write an incorrect string, however, the application won't fail until it is launched.
If you want to read more on this topic, you should check the Android documentation, especially the Accessing Resources part.
This holds your resource ids. So when you do something like
TextView tv = (TextView) findViewById(R.id.mytextview);
it looks up your id here for that View, layout, etc... This way the app has an easy way to look up your ids while you can use easy to remember names. Anytime you create a resource it automatically creates an id for it and stores it here. That's why you never want to try and edit this file yourself.
One way to think about how valuable R.java is, imagine a world without it. Its amazing how android brings the xml and java world together to help avoid coding the UI manually completely. With legacy java building UI using the java language was a pain. Invaluable.
With Android you can not only build your UI using only xml, but also see it while you build it. Invaluable.
Every element in the xml can be referenced in the java code WITHOUT writing a single line of code to parse the xml :). Just R.id.nameOfElement. Invaluable.
Rapid development is beautifully done in android. Imagine if iPhone would have 5000 screens to fit that one piece of code, they would crumble on their XCode. Google has done a wonderful job with just R.java. Invaluable.

Issues in referencing new elements in an existing Android application

I have an existing android app. I wanted to change its menu structure without disturbing the existing code. For this I added 2 new java files and relative xmls in the existing project and updated the manifest.xml with the new starter activity.
The issue which I am facing is in the java code. I am not able to reference the elements of the new xmls xxx.findViewById(R.id.xxx)
The error coming up: cannot be resolved or is not a valid field
Please suggest something, I am a newbee
When you build an application, Android will create a file called "R.java". This file basically is an index to all resources in your project (strings, layouts, drawables, etc.). If you add new resources by hand, you cannot refer to these resources because they have no ID in the R class.
According to this page you can use the aapt tool to (re?)generate the R file, but I have no experience with this myself.

Categories

Resources