• 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. }  
    7. public native int addFunction(int a, int b);  
    8. 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);  
    21. }  
    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. }  
    28. #endif  
    29. #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. {  
    16.     jint mun = 0;  
    17.     //事先把libNativeExampleActivity放到root/system/lib/目录下  
    18.     filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);  
    19.     if(filehandle)  
    20.     {  
    21.         addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");  
    22.         if(addFunc)  
    23.             mun = addFunc(env, obj, a, b);  
    24.         dlclose(filehandle);   
    25.         filehandle = NULL;  
    26.     }  
    27.     return mun  
    28. }  
    29.   
    30. /*  
    31.  * Class:     so_hello_SoHelloActivity  
    32.  * Method:    getString1  
    33.  * Signature: (Ljava/lang/String;)Ljava/lang/String;  
    34.  */  
    35. JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1  
    36.   (JNIEnv *, jobject, jstring name)  
    37. {  
    38.     jstring mun = 0;  
    39.     //事先把libNativeExampleActivity放到root/system/lib/目录下  
    40.     filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);  
    41.     if(filehandle)  
    42.     {  
    43.         getStringFunc = (jstring (*)(JNIEnv *,jobject,jstring))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_getString");  
    44.         if(getStringFunc)  
    45.         {  
    46.             mun = getStringFunc(env, obj, name);  
    47.         }  
    48.         dlclose(filehandle);   
    49.         filehandle = NULL;  
    50.     }  
    51.     return mun  
    52. }  

    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)  

    使用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;
    }
  • 相关阅读:
    智器SmartQ T7实体店试用体验
    BI笔记之SSAS库Process的几种方案
    PowerTip of the Day from powershell.com上周汇总(八)
    PowerTip of the Day2010071420100716 summary
    PowerTip of the Day from powershell.com上周汇总(十)
    PowerTip of the Day from powershell.com上周汇总(六)
    重新整理Cellset转Datatable
    自动加密web.config配置节批处理
    与DotNet数据对象结合的自定义数据对象设计 (二) 数据集合与DataTable
    在VS2003中以ClassLibrary工程的方式管理Web工程.
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318719.html
Copyright © 2020-2023  润新知