有时候,我们反编译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 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;
}

http://blog.csdn.net/mirkerson/article/details/8642280

http://www.qtcn.org/bbs/read-htm-tid-61200.html

Android Java调用Qt写的so库的更多相关文章

  1. Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)

    下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this ...

  2. java调用dll或so动态库文件(c++/c)

    java调用dll或so动态库文件(c++/c) 博客分类:  工作 CC#C++JavaEclipse  java调用dll或so动态库文件(c++/c)开发平台:Eclipse3.3.1.1+CD ...

  3. 【转载】java调用C++写的DLL

    用java调用C++写的DLL一直以来都是一个比较麻烦但又很常见的问题. 我们知道,使用 JNI 调用 .dll/.so 共享类库是非常非常麻烦和痛苦的. 如果有一个现有的 .dll/.so 文件,如 ...

  4. c++ c# java 调用 c++ 写的dll

    1. vs 中新建win32 dll 项目   testdll 添加实现文件       test.cpp #include "stdafx.h" #include <ios ...

  5. 在Android中调用C#写的WebService(附源代码)

    由于项目中要使用Android调用C#写的WebService,于是便有了这篇文章.在学习的过程中,发现在C#中直接调用WebService方便得多,直接添加一个引用,便可以直接使用将WebServi ...

  6. Android 如何调用自写APK和非自写APK

    由于项目需要,调用一个现成的APK,总结之余,顺便把怎么调用自写APK的方法也写上,以做比较 1.如何调用现成的APK: 先上调用代码,然后再一一解释: Intent mIntent = new In ...

  7. 通过COM组件方式实现java调用C#写的DLL文件

    转自这里 最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资 ...

  8. 通过COM组件方式实现java调用C#写的DLL文件 转

    最近一段时间单位在做一个Web项目,工程师用JAVA语言,需要公用人员信息,统一用户名和密码,原有的平台中是用C#语言开发的,在网上查找解决方法,通过JAVA调用C#的DLL文件实现.网上资料很多,自 ...

  9. 实现通过COM组件方式实现java调用C#写的DLL文件的完整demo

    最近因为工作需要,客户那边工程师使用的是JAVA语言开发的程序,我们这边平台中是用C#语言开发的,因为有些操作必须统一,所以我在网上查找解决方法,自己也实践过,在这里做个笔记吧,分享一下. 声明:下面 ...

随机推荐

  1. 【codeforces 787A】The Monster

    [题目链接]:http://codeforces.com/contest/787/problem/A [题意] 把b一直加a->得到x 把d一直加c->得到y 然后问你x和y可不可能有相同 ...

  2. Live Unit Testing

    Live Unit Testing 相对于传统的Unit Test,VS2017 带来了一个新的功能,叫Live Unit Testing,从字面意思理解就是实时单元测试,在实际的使用中,这个功能就是 ...

  3. setTimeout里的函数是何时进入任务队列里的

    先看一段代码 setTimeout(function () { console.log('abc') }, 1000) for (var i = 0; i <= 800000000; i++) ...

  4. Mint UI 使用指南

    上来直接在webpack里将Mint UI引入项目,发现各种问题.饿了么组件库文档太坑了,好多地方写错,有些该说明的地方没说,比如例子里单文件.vue组件里用的类post-css处理器,我一直使用SA ...

  5. Method and apparatus for encoding data to be self-describing by storing tag records describing said data terminated by a self-referential record

    A computer-implemented method and apparatus in a computer system of processing data generated by a f ...

  6. 一个简易版的Function.prototype.bind实现

    重新看<JavaScript设计模式与开发实践>一书,第32页发现个简易版的Function.prototype.bind实现,非常容易理解,记录在这了. Function.prototy ...

  7. Configuring a remote m-phy

    An interface for low power, high bandwidth communications between units in a device in provided here ...

  8. No_Sql总结

    NoSQL简介 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",是对不同于传统的关系型数据库的数据库管理系统的统称.在现代的计算系统上每天网络上都 ...

  9. python 左旋转字符串

    比较简单的一道题 汇编语言中有一种移位指令叫做循环左移(ROL),现在有个简单的任务,就是用字符串模拟这个指令的运算结果.对于一个给定的字符序列S,请你把其循环左移K位后的序列输出.例如,字符序列S= ...

  10. WPF 窗体基类实现的体验及实现回车到下一控件

    原文:WPF 窗体基类实现的体验及实现回车到下一控件 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jsyhello/article/details ...