I cannot get objcopy --rename-sym
working.
In a new Android project, I have created the directory jni and the file stub.c:
#include <jni.h>
#include "dlog.h"
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
DLOG("~~~~~~~~~~~~~~~~~~~~~~~ JNI_OnLoad ~~~~~~~~~~~~~~~~~~~~~~~~~");
return JNI_VERSION_1_6;
}
int myfunc() { return 0; }
the command ~/an/ndk-build -j 4
says:
[armeabi-v7a] Install : libTest.so => libs/armeabi-v7a/libTest.so
[armeabi] Install : libTest.so => libs/armeabi/libTest.so
[x86] Install : libTest.so => libs/x86/libTest.so
[mips] Install : libTest.so => libs/mips/libTest.so
(There are links:
an -> ~/android-ndk-r9d/
ax -> android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86/bin/
ay -> ~/android-ndk-r9d/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/
)
Then I do
~/ax/arm-linux-androideabi-objcopy --redefine-sym myfunc=ourfunc libTest.so libTest-x.so
and get an identical libTest-x.so. I, of course, tried ~/ay/*objcopy
, with the same result.
I get no error messages. And myfunc() is still there, and no ourfunc().
How do I rename a function in the .so file?
The easiest way to rename a function is to change the name in place without changing the length and without changing the hash value.
Keeping the same hash value is a bit tricky, you have to understand how elf_hash()
works::
elfhash.c:
#include <stdio.h>
unsigned long
elf_hash(const unsigned char *name)
{
unsigned long h = 0 , g ;
while (*name)
{
h = ( h << 4 ) + * name ++ ;
if (g = h & 0xf0000000) {
h ^= g >> 24 ;
}
h &= ~g ;
}
return h ;
}
int main(int argc, char**argv) {
char* name = argv[1];
printf("[%s]\n",name);
unsigned long hash = elf_hash(name);
printf("0x%lx\n",hash);
return 0;
}
[[EDIT: a newer version is at
https://github.com/18446744073709551615/reDroid/blob/master/hosttools/elfhash.c
(it finds a name with the same hash)
]]
gcc
it, and the usage is:
$ ./a.out myFunc
[myFunc]
0x74ddc43
$ ./a.out myFums
[myFums]
0x74ddc43
$ ./a.out myFuoC # Note: a different hash value
[myFuoC]
0x74ddc33
$ ./a.out myFupC
[myFupC]
0x74ddc43
The relevant part of the ASCII table is:
! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O
P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o
p q r s t u v w x y z { | } ~
Then either
sed s/myFunc/myFums/g <libStuff.so >libStufx.so
or a manual replace via hexedit libStuff.so
.