android使用C/C++呼叫SO庫
有時候,我們反編譯apk得到一個so庫,如果直接使用這個so庫的話,必須使用原來so庫同樣的package名字,才能用。
很明顯,這個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建立一個專案
2.在終端進入到專案的路徑soHello/bin/classes,執行命令:
guo@guo-desktop:~/workspace/soHello/bin/classes$ javah -jni so.hello.SoHelloActivity
在soHello/bin/classes目錄下會生成一個檔案so_hello_SoHelloActivity.h
3.寫一個so_hello_SoHelloActivity.cpp檔案
4.編寫Android.mk
然後這個so庫就可以用啦!
綜述:
這裡主要使用了dlopen、dlsym、dlclose三個函式來載入so庫:
這樣人家反編譯你的apk,就知道你侵犯了人家的版權。為了達到混淆的目的,我們可以再寫一個so庫呼叫人家的so庫,即把人家的so庫放到root的某個路徑下,用c/c++語言呼叫這個so庫。比如說,我得到一個APK,反編譯這個APK看到下面的程式碼:
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建立一個專案
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
/* 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檔案
#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
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;
}
相關文章
- Android JNI實現Java與C/C++互相呼叫,以及so庫的生成和呼叫(JNI方式呼叫美圖秀秀so)AndroidJavaC++
- 使用C++/CLI呼叫C#封裝類庫C++C#封裝
- 交叉編譯c++給android呼叫編譯C++Android
- flutter中呼叫C++的庫FlutterC++
- java動態呼叫c++庫JavaC++
- FFmpeg編譯Android使用的so庫編譯Android
- java呼叫c++動態庫之jni呼叫JavaC++
- linux下使用boost.python呼叫c++動態庫LinuxPythonC++
- C++庫封裝JNI介面——實現java呼叫c++C++封裝Java
- C++呼叫C#的動態庫dllC++C#
- C#呼叫C++動態連結庫C#C++
- lua——alien庫實現lua呼叫C動態連結庫(dll、so)
- Windows 下 c++ 呼叫 Rust 庫的例子WindowsC++Rust
- C++呼叫C介面C++
- Windows上Python使用swig呼叫C++WindowsPythonC++
- C++呼叫LuaC++
- Android Native C/C++ 使用OpenSSL EVP介面AndroidC++
- Python呼叫C/C++方式PythonC++
- Linux C/C++呼叫mongDBLinuxC++
- C#呼叫 C++的DLLC#C++
- c與c++的相互呼叫C++
- Linux下C++ libtorrent庫使用LinuxC++
- C++呼叫 c#生成的dllC++C#
- Python與C/C++呼叫之ctypesPythonC++
- Android native層動態載入so庫Android
- AndroidStudio使用NDK編譯C/C++程式碼使用原生庫Android編譯C++
- Android C++層使用Binder通訊的方法AndroidC++
- android層java如何呼叫cocos2dx c++程式碼 步驟AndroidJavaC++
- android NDK c++ libraryAndroidC++
- node中使用C++模組呼叫呼叫speex完成語音檔案壓縮C++
- C++標準庫、C++標準模版庫介紹C++
- C語言動態庫libxxx.so的幾種使用方法C語言
- python和c++的相互呼叫教程PythonC++
- C++如何解析函式呼叫C++函式
- C++中函式呼叫的用法C++函式
- Python呼叫C++編寫的方法PythonC++
- linux下qt用c++呼叫pythonLinuxQTC++Python
- 鴻蒙手機版JNI實戰(JNI開發、SO庫生成、SO庫使用)鴻蒙
- C++使用gnuplot-cpp庫繪製影像C++