Android------使用C/C++调用SO库

有时候,我们反编译apk得到一个so库,如果直接使用这个so库的话,必须使用原来so库同样的package名字,才能用。
这样人家反编译你的apk,就知道你侵犯了人家的版权。为了达到混淆的目的,我们可以再写一个so库调用人家的so库,即把人家的so库放到root的某个路径下,用c/c++语言调用这个so库。比如说,我得到一个APK,反编译这个APK看到下面的代码:

  1. static { 
  2.     try { 
  3.         System.loadLibrary("NativeExampleActivity"); 
  4.     } catch (Throwable t) { 
  5.     } 
  6. public native int addFunction(int a, int b); 
  7. public native String getString(String name); 
    static {
        try {
            System.loadLibrary("NativeExampleActivity");
        } catch (Throwable t) {
        }
    }
    public native int addFunction(int a, int b);
    public native String getString(String name);
很明显,这个so库是libNativeExampleActivity.so, 库里面有两个native函数addFunction和getString。
虽然知道了这两个native函数,但是我们还不能直接使用,因为这两个native函数在so库里面的真实函数名不是addFunction和getString,
它在native函数名之前还有包名,所以必须使用nm命令,查看so库里面的函数名。
显示so库函数的命令:
nm -A libNativeExampleActivity.so
或者
nm -D libNativeExampleActivity.so
这样我们看到so库里的主要信息:
Java_org_natives_example_NativeExampleActivity_addFunction
Java_org_natives_example_NativeExampleActivity_getString
看到没有,在addFunction函数前面还有包名,这就是为什么直接使用人家的so库的时候,一定要使用原来的package名字!
好了,现在是怎么调用这两个函数了,4个步骤完成。
1.用Eclipse创建一个项目
  1. package so.hello; 
  2.  
  3. import android.app.Activity; 
  4. import android.os.Bundle; 
  5.  
  6. public class SoHelloActivity extends Activity { 
  7.     /** Called when the activity is first created. */ 
  8.     @Override 
  9.     public void onCreate(Bundle savedInstanceState) { 
  10.         super.onCreate(savedInstanceState); 
  11.         setContentView(R.layout.main); 
  12.     } 
  13.     static { 
  14.         try { 
  15.             System.loadLibrary("soHello"); 
  16.         } catch (Throwable t) { 
  17.         } 
  18.     } 
  19.     public native int addFunction1(int a, int b); 
  20.     public native String getString1(String name); 
package so.hello;

import android.app.Activity;
import android.os.Bundle;

public class SoHelloActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    static {
        try {
            System.loadLibrary("soHello");
        } catch (Throwable t) {
        }
    }
    public native int addFunction1(int a, int b);
    public native String getString1(String name);
}
2.在终端进入到项目的路径soHello/bin/classes,执行命令:
guo@guo-desktop:~/workspace/soHello/bin/classes$ javah -jni so.hello.SoHelloActivity
在soHello/bin/classes目录下会生成一个文件so_hello_SoHelloActivity.h

  1. /* DO NOT EDIT THIS FILE - it is machine generated */ 
  2. #include <jni.h> 
  3. /* Header for class so_hello_SoHelloActivity */ 
  4.  
  5. #ifndef _Included_so_hello_SoHelloActivity 
  6. #define _Included_so_hello_SoHelloActivity 
  7. #ifdef __cplusplus 
  8. extern "C" { 
  9. #endif 
  10. /* 
  11. * Class:     so_hello_SoHelloActivity 
  12. * Method:    addFunction1 
  13. * Signature: (II)I 
  14. */ 
  15. JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1 
  16.   (JNIEnv *, jobject, jint, jint); 
  17.  
  18. /* 
  19. * Class:     so_hello_SoHelloActivity 
  20. * Method:    getString1 
  21. * Signature: (Ljava/lang/String;)Ljava/lang/String; 
  22. */ 
  23. JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1 
  24.   (JNIEnv *, jobject, jstring); 
  25.  
  26. #ifdef __cplusplus 
  27. #endif 
  28. #endif 
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class so_hello_SoHelloActivity */

#ifndef _Included_so_hello_SoHelloActivity
#define _Included_so_hello_SoHelloActivity
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     so_hello_SoHelloActivity
 * Method:    addFunction1
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
  (JNIEnv *, jobject, jint, jint);

/*
 * Class:     so_hello_SoHelloActivity
 * Method:    getString1
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
  (JNIEnv *, jobject, jstring);

#ifdef __cplusplus
}
#endif
#endif

3.写一个so_hello_SoHelloActivity.cpp文件

  1. #include "so_hello_SoHelloActivity.h"  
  2. #include <stdlib.h> 
  3. #include <fcntl.h> 
  4. #include <android/log.h> 
  5. #include <stdio.h>   
  6. #include <stdarg.h>   
  7. #include <dlfcn.h>  
  8.  
  9. void *filehandle = NULL
  10. jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL; 
  11. jstring (*getStringFunc)(JNIEnv *, jobject, jstring) = NULL; 
  12.  
  13. JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1 
  14.   (JNIEnv *env, jobject obj, jint a, jint b); 
  15.     jint mun = 0
  16.     //事先把libNativeExampleActivity放到root/system/lib/目录下 
  17.     filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY); 
  18.     if(filehandle) 
  19.     { 
  20.         addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction"); 
  21.         if(addFunc) 
  22.             mun = addFunc(env, obj, a, b); 
  23.         dlclose(filehandle);  
  24.         filehandle = NULL
  25.     } 
  26.     return mun 
  27.  
  28. /* 
  29. * Class:     so_hello_SoHelloActivity 
  30. * Method:    getString1 
  31. * Signature: (Ljava/lang/String;)Ljava/lang/String; 
  32. */ 
  33. JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1 
  34.   (JNIEnv *, jobject, jstring name) 
  35.     jstring mun = 0
  36.     //事先把libNativeExampleActivity放到root/system/lib/目录下 
  37.     filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY); 
  38.     if(filehandle) 
  39.     { 
  40.         getStringFunc = (jstring (*)(JNIEnv *,jobject,jstring))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_getString"); 
  41.         if(getStringFunc) 
  42.         { 
  43.             mun = getStringFunc(env, obj, name); 
  44.         } 
  45.         dlclose(filehandle);  
  46.         filehandle = NULL
  47.     } 
  48.     return mun 
#include "so_hello_SoHelloActivity.h" 
#include <stdlib.h>
#include <fcntl.h>
#include <android/log.h>
#include <stdio.h>  
#include <stdarg.h>  
#include <dlfcn.h> 

void *filehandle = NULL;
jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL;
jstring (*getStringFunc)(JNIEnv *, jobject, jstring) = NULL;

JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
  (JNIEnv *env, jobject obj, jint a, jint b);
{
	jint mun = 0;
	//事先把libNativeExampleActivity放到root/system/lib/目录下
	filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
	if(filehandle)
	{
		addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");
		if(addFunc)
			mun = addFunc(env, obj, a, b);
		dlclose(filehandle); 
		filehandle = NULL;
	}
	return mun
}

/*
 * Class:     so_hello_SoHelloActivity
 * Method:    getString1
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
  (JNIEnv *, jobject, jstring name)
{
	jstring mun = 0;
	//事先把libNativeExampleActivity放到root/system/lib/目录下
	filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
	if(filehandle)
	{
		getStringFunc = (jstring (*)(JNIEnv *,jobject,jstring))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_getString");
		if(getStringFunc)
		{
			mun = getStringFunc(env, obj, name);
		}
		dlclose(filehandle); 
		filehandle = NULL;
	}
	return mun
}

4.编写Android.mk

  1. LOCAL_PATH := $(call my-dir) 
  2.  
  3. include $(CLEAR_VARS) 
  4.  
  5. LOCAL_LDLIBS := -llog 
  6. LOCAL_C_INCLUDES += system/core/include/cutils 
  7. LOCAL_SHARED_LIBRARIES := \ 
  8.     libdl \ 
  9.     libcutils 
  10.  
  11. LOCAL_PRELINK_MODULE := false 
  12. LOCAL_MODULE      := libsoHello 
  13. LOCAL_MODULE_TAGS := optional 
  14. LOCAL_SRC_FILES   := so_hello_SoHelloActivity.cpp 
  15. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog 
  16.  
  17. include $(BUILD_SHARED_LIBRARY) 
LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_LDLIBS := -llog
LOCAL_C_INCLUDES += system/core/include/cutils
LOCAL_SHARED_LIBRARIES := \
    libdl \
    libcutils

LOCAL_PRELINK_MODULE := false
LOCAL_MODULE      := libsoHello
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES   := so_hello_SoHelloActivity.cpp
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog

include $(BUILD_SHARED_LIBRARY)

使用mm命令编译so_hello_SoHelloActivity.cpp,便可以生成libsoHello.so库。
然后这个so库就可以用啦!

综述:
这里主要使用了dlopen、dlsym、dlclose三个函数来加载so库:
void *filehandle = NULL;
jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL;
jint mun = 0
//事先把libNativeExampleActivity放到root/system/lib/目录下
filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
if(filehandle)
{
    addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");
    if(addFunc)
        mun = addFunc(env, obj, a, b);
    dlclose(filehandle);
    filehandle = NULL;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值