android JNI运行NDK编译成的可执行文件

1.android环境的可执行文件的生成


所谓的android下的可执行文件,其实就是一般的c/c++代码使用NDK编译出来的应用程序。它和linux下用gcc编译出来的程序和windows系统下的.exe文件是一样的。要将代码编译成可执行文件只需要将编译so的include $(BUILD_SHARED_LIBRARY)改成include $(BUILD_EXECUTABLE)就行。

Main.cpp

#include 
#include 
using namespace std;
#define LOG_TAG "JNI_LOG"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
int main(int argc, char **argv)
{
	LOGI("NativeFile Begin!");
	LOGI("This is a Test!");
	LOGI("NativeFile End!");
	return 0;
}


Android.mk

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
    Main.cpp 
LOCAL_MODULE := NativeFile
LOCAL_LDLIBS := -llog
include $(BUILD_EXECUTABLE)


Application.mk

APP_PLATFORM = android-8
APP_ABI := armeabi
APP_STL := stlport_static

2.android 应用使用JNI执行NDK编译的可执行文件.


1) 将上面生成的NativeFile可执行文件放在android工程的asset目录下面。

2) 将asset中的可执行文件拷贝到应用的data空间中。

3)使用linux的fork函数创建子进程,并使用execlp执行可执行文件.

4)此时apk所在的进程和可执行文件的进程分属于二个不同的进程,拥有不同的进程id,所以就算APK文件卸载了以后这个可执行文件还是在运行状态的,这样我们的应用就可以在apk被卸载了以后仍然能做很多的事情,比如向360一样显示一个卸载调查的网页,或者发送应用被卸载的消息给自己的服务器等等。


下面附上代码.


MainActivity.java

package com.example.testnative;

import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;

public class MainActivity extends Activity {
	static 
	{
		System.loadLibrary("TestNative");
	}
	native void ExecFile(AssetManager asset,String path);
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ExecFile(getAssets(),getCacheDir().toString());
	}
	
}


TestNative.cpp

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
extern "C"
{
#define LOG_TAG "JNI_LOG"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
char* Jstring2String(JNIEnv* env, jstring jstr)
{
	char* rtn = NULL;
	jclass clsstring = env->FindClass("java/lang/String");
	jstring strencode = env->NewStringUTF("utf-8");
	jmethodID mid = env->GetMethodID(clsstring, "getBytes",
			"(Ljava/lang/String;)[B");
	jbyteArray barr = (jbyteArray) env->CallObjectMethod(jstr, mid, strencode);
	jsize alen = env->GetArrayLength(barr);
	jbyte* ba = env->GetByteArrayElements(barr, JNI_FALSE);
	if (alen > 0)
	{
		rtn = (char*) malloc(alen + 1);
		memcpy(rtn, ba, alen);
		rtn[alen] = 0;
	}
	env->ReleaseByteArrayElements(barr, ba, 0);
	return rtn;
}
void ExecChildProcess(const char* fileName, const char* param)
{
	LOGI("Begin ExecCmdByChildProcess!\n");
	pid_t pid = fork();
	if (pid == 0)
	{
		pid_t pid2 = fork();
		if (pid2 == 0)
		{
			if (execlp(fileName, fileName, param, NULL) < 0)
				LOGI("ExecChildProcess %s error!\n", fileName);
			exit(0);
		}
		else
		{
			exit(0);
		}
	}
	else if (pid > 0)
	{
		int status = 0;
		waitpid(pid, &status, 0);
	}
	else
	{
		LOGE("ExecChildProcess Error!\n");
	}
}
void Java_com_example_testnative_MainActivity_ExecFile(JNIEnv* env, jobject obj,
		jobject asset, jstring path)
{
	AAssetManager* asMg = AAssetManager_fromJava(env, asset);
	AAsset* as = AAssetManager_open(asMg, "NativeFile", AASSET_MODE_UNKNOWN);
	char* tmp = Jstring2String(env, path);
	char cPath[256] =
	{ 0 };
	strcpy(cPath, tmp);
	strcat(cPath, "/NativeFile");
	free(tmp);
	if (as != NULL)
	{
		int len = AAsset_getLength(as);
		LOGI("len=%d", len);
		int file = open(cPath, O_WRONLY | O_CREAT, 0755);
		char* buf = new char[1024];
		while (len > 0)
		{

			int n = AAsset_read(as, buf, 1024);
			if (n < 0)
				break;
			write(file, buf, n);
			len -= n;
		}
		delete[] buf;
		AAsset_close(as);
		close(file);
	}
	ExecChildProcess(cPath, " ");
}
}


运行APK后的结果:

android JNI运行NDK编译成的可执行文件_第1张图片


源码下载链接:http://download.csdn.net/detail/csdn49532/9436882




你可能感兴趣的:(android安全和加固)