有时候,我们反编译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. import android.app.Activity;
  3. import android.os.Bundle;
  4. public class SoHelloActivity extends Activity {
  5. /** Called when the activity is first created. */
  6. @Override
  7. public void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.main);
  10. }
  11. static {
  12. try {
  13. System.loadLibrary("soHello");
  14. } catch (Throwable t) {
  15. }
  16. }
  17. public native int addFunction1(int a, int b);
  18. public native String getString1(String name);
  19. }

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. #ifndef _Included_so_hello_SoHelloActivity
  5. #define _Included_so_hello_SoHelloActivity
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class:     so_hello_SoHelloActivity
  11. * Method:    addFunction1
  12. * Signature: (II)I
  13. */
  14. JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
  15. (JNIEnv *, jobject, jint, jint);
  16. /*
  17. * Class:     so_hello_SoHelloActivity
  18. * Method:    getString1
  19. * Signature: (Ljava/lang/String;)Ljava/lang/String;
  20. */
  21. JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
  22. (JNIEnv *, jobject, jstring);
  23. #ifdef __cplusplus
  24. }
  25. #endif
  26. #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. void *filehandle = NULL;
  9. jint (*addFunc)(JNIEnv *,jobject,jint,jint) = NULL;
  10. jstring (*getStringFunc)(JNIEnv *, jobject, jstring) = NULL;
  11. JNIEXPORT jint JNICALL Java_so_hello_SoHelloActivity_addFunction1
  12. (JNIEnv *env, jobject obj, jint a, jint b);
  13. {
  14. jint mun = 0;
  15. //事先把libNativeExampleActivity放到root/system/lib/目录下
  16. filehandle = dlopen("/system/lib/libNativeExampleActivity.so", RTLD_LAZY);
  17. if(filehandle)
  18. {
  19. addFunc = (jint (*)(JNIEnv *,jobject,jint,jint))dlsym(filehandle, "Java_org_natives_example_NativeExampleActivity_addFunction");
  20. if(addFunc)
  21. mun = addFunc(env, obj, a, b);
  22. dlclose(filehandle);
  23. filehandle = NULL;
  24. }
  25. return mun;
  26. }
  27. /*
  28. * Class:     so_hello_SoHelloActivity
  29. * Method:    getString1
  30. * Signature: (Ljava/lang/String;)Ljava/lang/String;
  31. */
  32. JNIEXPORT jstring JNICALL Java_so_hello_SoHelloActivity_getString1
  33. (JNIEnv *, jobject, jstring name)
  34. {
  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 env->NewStringUTF(mun);
  49. }

4.编写Android.mk

  1. LOCAL_PATH := $(call my-dir)
  2. include $(CLEAR_VARS)
  3. LOCAL_LDLIBS := -llog
  4. LOCAL_C_INCLUDES += system/core/include/cutils
  5. LOCAL_SHARED_LIBRARIES := \
  6. libdl \
  7. libcutils
  8. LOCAL_PRELINK_MODULE := false
  9. LOCAL_MODULE      := libsoHello
  10. LOCAL_MODULE_TAGS := optional
  11. LOCAL_SRC_FILES   := so_hello_SoHelloActivity.cpp
  12. LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib -llog
  13. 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;
}

android使用C/C++调用SO库的更多相关文章

  1. android开发-c++代码调用so库

    Android项目的CMakeLists.txt代码如下,so文件放在项目的$Project/app/src/main/jniLibs/$arch下,$arch替换为arm64-v8a armv7a等 ...

  2. 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

    相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...

  3. Android JNI如何调用第三方库

    http://www.2cto.com/kf/201504/388764.html Android JNI找不到第三方库的解决方案 cannot load library 最近做一个jni项目,拿到的 ...

  4. [置顶] android利用jni调用第三方库——第三篇——编写库android程序整合第三方库libhello.so到自己的库libhelloword.so

    0:前言: 在第二篇中,我们主要介绍了丙方android公司利用乙方C++公司给的动态库,直接调用库中的方法,但是这样方式受限于: 乙方C++公司开发的动态库是否符合jni的规范,如果不规范,则不能直 ...

  5. [置顶] android利用jni调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so

    0:前言 1:本文主要作为丙方android公司的身份来写 2:作者有不对的地方,请指出,谢谢 [第一篇:android利用jni调用第三方库——编写库libhello.so] [第二篇:androi ...

  6. [置顶] android调用第三方库——第四篇——调用多个第三方库

    0:前言: 在前面三篇中我们介绍了android调用第三方库的形式,在这一篇中我们介绍调用多个第三方库的Android.mk的写法,由于其他三篇介绍的很详细,这里只给出Android.mk的内容. [ ...

  7. Android NDK开发及调用标准linux动态库.so文件

    源:Android NDK开发及调用标准linux动态库.so文件 预备知识及环境搭建 1.NDK(native development Kit)原生开发工具包,用来快速开发C.C++动态库,并能自动 ...

  8. 简单的调用OpenCV库的Android NDK开发 工具Android Studio

    前言 本博客写于2017/08/11, 博主非专业搞安卓开发, 只是工作的需要倒腾了下Android NDK相关的开发, 博文中有什么不正确.不严格的地方欢迎指正哈    本文后续也许还会有删改, 就 ...

  9. android调用第三方库——第二篇——编写库android程序直接调用第三方库libhello.so (转载)

    转自:http://blog.csdn.net/jiuyueguang/article/details/9449737 版权声明:本文为博主原创文章,未经博主允许不得转载. 0:前言 1:本文主要作为 ...

随机推荐

  1. 重装系统备份MYSQL数据(整库备份)

    今天要重装Windows 8系统,但是我的Mysql里面数据太多,要备份成sql文件实在太麻烦,于是我听说可以直接拷贝数据文件夹,所以就试了,结果还成果了. 具体如下: 我安装的时候把数据文件夹就放在 ...

  2. 使用JAX-RS创建RESTful Web Service

    guice resteasy http://www.cnblogs.com/ydxblog/p/7891224.html http://blog.csdn.net/withiter/article/d ...

  3. Guava Cache 使用笔记

    https://www.cnblogs.com/parryyang/p/5777019.html https://www.cnblogs.com/shoren/p/guava_cache.html J ...

  4. hdu 2227(树状数组+dp)

    Find the nondecreasing subsequences Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/3 ...

  5. Google的C++开源代码项

    转:http://blog.csdn.net/wenrenhua08/article/details/40040903 v8  -  V8 JavaScript EngineV8 是 Google 的 ...

  6. Linux磁盘的性能详细测试办法

    # 测试写入20Gb文件sync && time -p bash -c "(dd if=/dev/zero of=test.dd  bs=1000K count=20000; ...

  7. sublime text3 自己定义的不同浏览器的预览快捷键

    sublime text3 自己定义的不同浏览器的预览快捷键突然全部失效了,搞到现在一直没闹清楚怎么回事,翻看插件发现SideBarEnhancements这插件刚更新了,快捷键也是依赖这个插件弄得. ...

  8. Nginx+PHP “No input file specified”错误的解决办法

    配置官网商城php网站时候,界面报错“No input file specified” 原理: 任何对.php文件的请求,都简单地交给php-cgi去处理,但没有验证该php文件是否存在. PHP文件 ...

  9. 2018 icpc 徐州现场赛G-树上差分+组合数学-大佬的代码

    现场赛大佬打印的代码,观摩了一哈. 写了注释,贴一下,好好学习.%%%PKU 代码: //树上差分(LCA) #include<bits/stdc++.h> #define For(i,x ...

  10. 洛谷P1129 [ZJOI2007] 矩阵游戏

    题目传送门 分析:看到这题呢,首先想到的就是搜索,数据范围也不大嘛.但是仔细思考发现这题用搜索很难做,看了大佬们的题解后学到了,这一类题目要用二分图匹配来做.可以知道,如果想要的话,每一个子都可以移动 ...