为了分析竞品对手的定位精度,破解了竞品的SO库,调用加密,Post 到竞品服务器上。得到竞品定位效果,难题出在竞品用的是ARM,必须用手机来进行加密,想用服务器直接加密。开始使用第一种方案,嘻嘻,IDA 反编译 SO库 得到加密函数,分析反汇编代码,得到加密逻辑,重新写一下,真心写了一半了,后来发现了X86的SO库,靠~! 那就可以直接JNI调用SO库。
为了不暴漏代码用hello.so来替代解决方案如下:
首先,就假装写一个库函数是
#include <stdio.h> void hello(void) { printf("hello\n"); }
编译 gcc -shared -o hello.so hello.c
先包装一个CPP 调用hello.so,然后编译为新的SO库, 然后用JNI调用
先来java代码
public class Hello { static { System.load("/home/xietian/java_hello.so"); } //public native static void encode(char[] trans, String src, int len); public native static void hello(); public static void main(String[] args) { hello(); } }
javac Hello.java
javah -jni Hello
得到Hello.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Hello */ #ifndef _Included_Hello #define _Included_Hello #ifdef __cplusplus extern "C" { #endif /* * Class: Hello * Method: hello * Signature: ()V */ JNIEXPORT void JNICALL Java_Hello_hello (JNIEnv *, jclass); #ifdef __cplusplus } #endif #endif
编写CPP 就完成了
#include "Hello.h" #include <stdlib.h> #include <fcntl.h> #include <stdio.h> #include <stdarg.h> #include <dlfcn.h> void *filehandle = NULL; //void (*encode)(JNIEnv *, jclass, jchar *, jchar *, jint) = NULL; void (*hello)(JNIEnv *, jclass) = NULL; JNIEXPORT void JNICALL Java_Hello_hello (JNIEnv * env, jclass obj) { filehandle = dlopen("/home/xietian/hello.so", RTLD_LAZY); if(filehandle) { //encode = (void (*)(JNIEnv *, jclass, jchar *, jchar *, jint))dlsym(filehandle, "encode"); //const char *str = (*env)->GetStringUTFChars(env, b, 0); hello = (void (*)(JNIEnv *, jclass))dlsym(filehandle,"hello"); if(hello) hello(env, obj); dlclose(filehandle); filehandle = NULL; } }
注意编译这个CPP的时候
一定要加上jni的路径哦
g++ -I/usr/java/jdk1.6.0_45/include/ -I/usr/java/jdk1.6.0_45/include/linux/ -shared -o java_hello.so Hello.cpp -fPIC
然后
java Hello
完成,成功。
其实怎么知道的竞品的SO库里有什么函数?
gdb->info functions