为了防止apk被轻易破解,想办法对java层的代码进行加密,防止反编译,代码混淆基本没什么效果,一般情况下我会对dex进行加密,通过动态加载的方法实现java层的代码尽量被隐藏,而动态加载的实现通过jni来完成,最大化的保护代码安全,其实java层这个时候只剩下继承于Application的启动类。

.h文件

 #ifndef __ANDROID_JNI_BOOT_HELPER_H__
#define __ANDROID_JNI_BOOT_HELPER_H__ #include <jni.h>
#include <string>
#include "android/asset_manager.h"
#include "android/asset_manager_jni.h" typedef struct JniMethodInfo_
{
JNIEnv * env;
jclass classID;
jmethodID methodID;
} JniMethodInfo; class JniBootHelper
{
public:
static void setJavaVM(JavaVM *javaVM);
static JavaVM* getJavaVM();
static JNIEnv* getEnv(); static bool setassetmanager(jobject activityinstance);
static AAssetManager* getAssetManager() { return _assetmanager; } static bool setFileDir(jobject activityinstance);
static bool setCacheDir(jobject activityinstance); static bool loadDexFile(jobject context,
const char* dexPath,
const char* dexOptDir); static bool loadClass(jobject context); static jobject invokeStaticMethod(JNIEnv *env,
const char* className,
const char* methodName,
jobjectArray pareTyple,
jobjectArray pareVaules); static jobject getFieldOjbect(JNIEnv *env,
const char* className,
const char* fieldName,
jobject obj);
static void setFieldOjbect(JNIEnv *env,
const char* className,
const char* fieldName,
jobject obj,
jobject filedVaule); static std::string jstring2string(jstring str); static std::string FileDir;
static std::string CacheDir; private:
static JNIEnv* cacheEnv(JavaVM* jvm); static bool getMethodInfo(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode); static JavaVM* _psJavaVM;
static AAssetManager* _assetmanager;
static jmethodID _loadclassMethod_methodID;
static jobject _classloader;
}; #endif // __ANDROID_JNI_BOOT_HELPER_H__

.cpp文件

 #include "JniBootHelper.h"
#include <android/log.h>
#include <string.h>
#include <pthread.h> #include "DexMarcoDef.h" static pthread_key_t g_key; void _detachCurrentThread(void* a) {
LOGD("DetachCurrentThread");
JniBootHelper::getJavaVM()->DetachCurrentThread();
} JavaVM* JniBootHelper::_psJavaVM = nullptr;
std::string JniBootHelper::FileDir = "";
std::string JniBootHelper::CacheDir = "";
AAssetManager* JniBootHelper::_assetmanager = nullptr;
jmethodID JniBootHelper::_loadclassMethod_methodID = nullptr;
jobject JniBootHelper::_classloader = nullptr; bool JniBootHelper::setassetmanager(jobject activityinstance) {
JniMethodInfo _getassetsMethod;
if (!JniBootHelper::getMethodInfo(_getassetsMethod,
"android/content/Context",
"getAssets",
"()Landroid/content/res/AssetManager;")) {
LOGE("getmethod getAssets() failed.");
return false;
} jobject _am = JniBootHelper::getEnv()->CallObjectMethod(activityinstance,
_getassetsMethod.methodID); if (nullptr == _am) {
LOGE("CallObjectMethod getAssets() failed.");
return false;
} JniBootHelper::_assetmanager = AAssetManager_fromJava(JniBootHelper::getEnv(), _am);
return true;
} bool JniBootHelper::setFileDir(jobject activityinstance)
{
JniMethodInfo _getFileDirMethod;
if (!JniBootHelper::getMethodInfo(_getFileDirMethod,
"android/content/Context",
"getFilesDir",
"()Ljava/io/File;")) {
LOGE("getmethod getFilesDir() failed.");
return false;
}
jobject _f = JniBootHelper::getEnv()->CallObjectMethod(activityinstance,
_getFileDirMethod.methodID);
if (nullptr == _f) {
LOGE("CallObjectMethod getFilesDir() failed.");
return false;
}
JniMethodInfo _getFilePathMethod;
if (!JniBootHelper::getMethodInfo(_getFilePathMethod,
"java/io/File",
"getAbsolutePath",
"()Ljava/lang/String;")) {
LOGE("getmethod getAbsolutePath() failed.");
return false;
}
jstring _p = (jstring)JniBootHelper::getEnv()->CallObjectMethod(_f,
_getFilePathMethod.methodID);
if (nullptr == _p) {
LOGE("CallObjectMethod getAbsolutePath() failed.");
return false;
} JniBootHelper::FileDir.assign(JniBootHelper::jstring2string(_p));
LOGD("apk FileDir : %s", JniBootHelper::FileDir.c_str());
JniBootHelper::getEnv()->DeleteLocalRef(_p);
return true;
} bool JniBootHelper::setCacheDir(jobject activityinstance)
{
JniMethodInfo _getFileDirMethod;
if (!JniBootHelper::getMethodInfo(_getFileDirMethod,
"android/content/Context",
"getCacheDir",
"()Ljava/io/File;")) {
LOGE("getmethod getCacheDir() failed.");
return false;
}
jobject _f = JniBootHelper::getEnv()->CallObjectMethod(activityinstance,
_getFileDirMethod.methodID);
if (nullptr == _f) {
LOGE("CallObjectMethod getCacheDir() failed.");
return false;
}
JniMethodInfo _getFilePathMethod;
if (!JniBootHelper::getMethodInfo(_getFilePathMethod,
"java/io/File",
"getAbsolutePath",
"()Ljava/lang/String;")) {
LOGE("getmethod getAbsolutePath() failed.");
return false;
}
jstring _p = (jstring)JniBootHelper::getEnv()->CallObjectMethod(_f,
_getFilePathMethod.methodID);
if (nullptr == _p) {
LOGE("CallObjectMethod getAbsolutePath() failed.");
return false;
} JniBootHelper::CacheDir.assign(JniBootHelper::jstring2string(_p));
LOGD("apk CacheDir : %s", JniBootHelper::CacheDir.c_str());
JniBootHelper::getEnv()->DeleteLocalRef(_p);
return true;
} bool JniBootHelper::loadClass(jobject context)
{
JNIEnv *env = JniBootHelper::getEnv();
if (!env) {
return false;
} jstring _jstrClassName = env->NewStringUTF("com/origingame/InApplicationMethod");
jclass _classid = (jclass) env->CallObjectMethod(JniBootHelper::_classloader,
JniBootHelper::_loadclassMethod_methodID,
_jstrClassName);
if(!_classid)
{
LOGE("can not find class com/origingame/InApplicationMethod");
}
jmethodID _mid = env->GetStaticMethodID(_classid, "onCreate", "(Landroid/content/Context;)V");
if(!_mid)
{
LOGE("failed to find methodID onCreate");
}
env->CallStaticVoidMethod(_classid, _mid, context);
env->DeleteLocalRef(_jstrClassName);
env->DeleteGlobalRef(JniBootHelper::_classloader);
} bool JniBootHelper::loadDexFile(jobject context,
const char* dexPath,
const char* dexOptDir)
{
JNIEnv *env = JniBootHelper::getEnv();
if (!env) {
return false;
} jstring dexPathString, dexOptDirString;
dexPathString = env->NewStringUTF(dexPath);
dexOptDirString = env->NewStringUTF(dexOptDir); jclass native_clazz = env->GetObjectClass(context);
jmethodID methodID_func = env->GetMethodID(native_clazz,
"getPackageName",
"()Ljava/lang/String;");
jstring packagename = (jstring) (env->CallObjectMethod(context, methodID_func));
std::string _packagename = JniBootHelper::jstring2string(packagename);
LOGD("packagename: %s",_packagename.c_str());
char libsDir[];
sprintf(libsDir, "/data/data/%s/lib", _packagename.c_str());
jstring jlibsDir = env->NewStringUTF(libsDir); jclass jActivityThread = env->FindClass("android/app/ActivityThread");
if(!jActivityThread)
{
LOGE("can not find class android/app/ActivityThread");
}
jmethodID jcATmid = env->GetStaticMethodID(jActivityThread, "currentActivityThread", "()Landroid/app/ActivityThread;");
jobject currentActivityThread = env->CallStaticObjectMethod(jActivityThread, jcATmid); jclass class_hashmap = env->FindClass("java/util/Map"); jobject obj_hashmap = JniBootHelper::getFieldOjbect(env,
"android.app.ActivityThread",
"mPackages",
currentActivityThread);
/*
jmethodID map_size = env->GetMethodID(class_hashmap,
"size",
"()I");
jint size = (jint)env->CallObjectMethod(obj_hashmap,
map_size
);
LOGD("map size : %d", (int)size);
*/
if(!obj_hashmap)
{
LOGE("obj_hashmap is null");
} jclass class_WeakReference = env->FindClass("java/lang/ref/WeakReference");
if (!class_WeakReference)
{
LOGE("class_WeakReference Not Found ");
} jmethodID WeakReference_get_method = env->GetMethodID(class_WeakReference,
"get",
"()Ljava/lang/Object;");
if (!WeakReference_get_method)
{
LOGE("WeakReference_get_method Not Found ");
} jmethodID get_func = env->GetMethodID(class_hashmap,
"get",
"(Ljava/lang/Object;)Ljava/lang/Object;");
if (!get_func) {
LOGE("method get Not Found ");
} jobject get_obj = env->CallObjectMethod(obj_hashmap,
get_func,
packagename);
if (!get_obj) {
LOGE("get_obj Not Found ");
} jobject get_get_obj = env->CallObjectMethod(get_obj,
WeakReference_get_method);
if (!get_get_obj) {
LOGE("get_get_obj Not Found ");
} /*
jclass class_DexClassloader = env->FindClass("dalvik/system/DexClassLoader");
if (!class_DexClassloader) {
LOGE("class_DexClassloader Not Found ");
} jmethodID DexClassloader_construct_method = env->GetMethodID(class_DexClassloader,
"<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
if (!DexClassloader_construct_method) {
LOGE("DexClassloader_construct_method Not Found ");
} jobject obj_DexClassloader = env->NewObject(class_DexClassloader,
DexClassloader_construct_method,
dexPathString,
dexOptDirString,
jlibsDir,
JniBootHelper::getFieldOjbect(env, "android.app.LoadedApk", "mClassLoader", get_get_obj));
if (!obj_DexClassloader) {
LOGE("obj_DexClassloader Not Found ");
}
*/
jclass class_DexClassloader = env->FindClass("dalvik/system/PathClassLoader");
if (!class_DexClassloader) {
LOGE("class_DexClassloader Not Found ");
} jmethodID DexClassloader_construct_method = env->GetMethodID(class_DexClassloader,
"<init>",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/ClassLoader;)V");
if (!DexClassloader_construct_method) {
LOGE("DexClassloader_construct_method Not Found ");
} jobject obj_DexClassloader = env->NewObject(class_DexClassloader,
DexClassloader_construct_method,
dexPathString,
jlibsDir,
JniBootHelper::getFieldOjbect(env, "android.app.LoadedApk", "mClassLoader", get_get_obj));
if (!obj_DexClassloader) {
LOGE("obj_DexClassloader Not Found ");
} JniBootHelper::_classloader = env->NewGlobalRef(obj_DexClassloader);
JniBootHelper::_loadclassMethod_methodID = env->GetMethodID(class_DexClassloader,
"loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;"); JniBootHelper::setFieldOjbect(env, "android.app.LoadedApk", "mClassLoader", get_get_obj, obj_DexClassloader);
env->DeleteLocalRef(dexPathString);
env->DeleteLocalRef(dexOptDirString);
env->DeleteLocalRef(jlibsDir);
LOGD("finish.");
return true;
} JavaVM* JniBootHelper::getJavaVM() {
pthread_t thisthread = pthread_self();
LOGD("JniBootHelper::getJavaVM(), pthread_self() = %ld", thisthread);
return _psJavaVM;
} void JniBootHelper::setJavaVM(JavaVM *javaVM) {
pthread_t thisthread = pthread_self();
LOGD("JniBootHelper::setJavaVM(%p), pthread_self() = %ld", javaVM, thisthread);
_psJavaVM = javaVM; pthread_key_create(&g_key, _detachCurrentThread);
} JNIEnv* JniBootHelper::cacheEnv(JavaVM* jvm) {
JNIEnv* _env = nullptr;
// get jni environment
jint ret = jvm->GetEnv((void**)&_env, JNI_VERSION_1_4); switch (ret) {
case JNI_OK :
// Success!
pthread_setspecific(g_key, _env);
return _env; case JNI_EDETACHED :
// Thread not attached
if (jvm->AttachCurrentThread(&_env, nullptr) < )
{
LOGE("Failed to get the environment using AttachCurrentThread()"); return nullptr;
} else {
// Success : Attached and obtained JNIEnv!
pthread_setspecific(g_key, _env);
return _env;
} case JNI_EVERSION :
// Cannot recover from this error
LOGE("JNI interface version 1.4 not supported");
default :
LOGE("Failed to get the environment using GetEnv()");
return nullptr;
}
} JNIEnv* JniBootHelper::getEnv() {
JNIEnv *_env = (JNIEnv *)pthread_getspecific(g_key);
if (_env == nullptr)
_env = JniBootHelper::cacheEnv(_psJavaVM);
return _env;
} bool JniBootHelper::getMethodInfo(JniMethodInfo &methodinfo,
const char *className,
const char *methodName,
const char *paramCode)
{
if ((nullptr == className) ||
(nullptr == methodName) ||
(nullptr == paramCode)) {
return false;
} JNIEnv *env = JniBootHelper::getEnv();
if (!env) {
return false;
} jclass classID = env->FindClass(className);
if (! classID) {
LOGE("Failed to find class %s", className);
env->ExceptionClear();
return false;
} jmethodID methodID = env->GetMethodID(classID, methodName, paramCode);
if (! methodID) {
LOGE("Failed to find method id of %s", methodName);
env->ExceptionClear();
return false;
} methodinfo.classID = classID;
methodinfo.env = env;
methodinfo.methodID = methodID; return true;
} std::string JniBootHelper::jstring2string(jstring jstr) {
if (jstr == nullptr) {
return "";
} JNIEnv *env = JniBootHelper::getEnv();
if (!env) {
return nullptr;
} const char* chars = env->GetStringUTFChars(jstr, nullptr);
std::string ret(chars);
env->ReleaseStringUTFChars(jstr, chars); return ret;
} jobject JniBootHelper::invokeStaticMethod(JNIEnv *env,
const char* className,
const char* methodName,
jobjectArray pareTyple,
jobjectArray pareVaules)
{
jstring jclassName, jmethodName;
jclassName = env->NewStringUTF(className);
jmethodName = env->NewStringUTF(methodName); jclass _class = env->FindClass("java/lang/Class");
if(!_class)
{
LOGE("invokeStaticMethod: Failed to find class java/lang/Class");
env->ExceptionClear();
return nullptr;
} jmethodID forname_func = env->GetStaticMethodID(_class,
"forName",
"(Ljava/lang/String;)Ljava/lang/Class;");
if(!forname_func)
{
LOGE("invokeStaticMethod: Failed to find method forName");
env->ExceptionClear();
return nullptr;
} jobject class_obj = env->CallStaticObjectMethod(_class,
forname_func,
jclassName); jclass class_java = env->GetObjectClass(class_obj); jmethodID getmethod_func = env->GetMethodID(class_java,
"getMethod",
"(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;");
if(!getmethod_func)
{
LOGE("invokeStaticMethod: Failed to find method getMethod");
env->ExceptionClear();
return nullptr;
} jobject method_obj = env->CallObjectMethod(class_obj,
getmethod_func,
jmethodName,
pareTyple);
if(!method_obj)
{
LOGE("invokeStaticMethod: Failed to CallObjectMethod.%s, %s",className, methodName);
env->ExceptionClear();
return nullptr;
} jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID invoke_func = env->GetMethodID(class_method_obj,
"invoke",
"(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;"); if(!invoke_func)
{
LOGE("invokeStaticMethod: Failed to find method invoke");
env->ExceptionClear();
return nullptr;
} jobject invoke_obj = env->CallObjectMethod(method_obj,
invoke_func,
NULL,
pareVaules); env->DeleteLocalRef(jclassName);
env->DeleteLocalRef(jmethodName);
env->DeleteLocalRef(class_java);
env->DeleteLocalRef(method_obj);
LOGD("invokeStaticMethod finish.");
return invoke_obj;
} jobject JniBootHelper::getFieldOjbect(JNIEnv *env,
const char* className,
const char* fieldName,
jobject obj)
{
jstring jclassName, jfieldName;
jclassName = env->NewStringUTF(className);
jfieldName = env->NewStringUTF(fieldName); jclass _class = env->FindClass("java/lang/Class");
jmethodID forname_func = env->GetStaticMethodID(_class,
"forName",
"(Ljava/lang/String;)Ljava/lang/Class;");
if(!forname_func)
{
LOGE("getFieldOjbect: Failed to find method forName");
env->ExceptionClear();
return nullptr;
}
jobject class_obj = env->CallStaticObjectMethod(_class,
forname_func,
jclassName);
jclass class_java = env->GetObjectClass(class_obj); jmethodID getfield_func = env->GetMethodID(class_java,
"getDeclaredField",
"(Ljava/lang/String;)Ljava/lang/reflect/Field;");
if(!getfield_func)
{
LOGE("getFieldOjbect: Failed to find method getDeclaredField");
env->ExceptionClear();
return nullptr;
}
jobject method_obj = env->CallObjectMethod(class_obj,
getfield_func,
jfieldName);
jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID setaccess_func = env->GetMethodID(class_method_obj,
"setAccessible",
"(Z)V");
if(!setaccess_func)
{
LOGE("getFieldOjbect: Failed to find method setAccessible");
env->ExceptionClear();
return nullptr;
}
env->CallVoidMethod(method_obj,
setaccess_func,
true); jmethodID get_func = env->GetMethodID(class_method_obj,
"get",
"(Ljava/lang/Object;)Ljava/lang/Object;");
if(!get_func)
{
LOGE("getFieldOjbect: Failed to find method get");
env->ExceptionClear();
return nullptr;
}
jobject get_obj = env->CallObjectMethod(method_obj,
get_func,
obj); env->DeleteLocalRef(class_java);
env->DeleteLocalRef(method_obj);
env->DeleteLocalRef(jclassName);
env->DeleteLocalRef(jfieldName);
return get_obj;
} void JniBootHelper::setFieldOjbect(JNIEnv *env,
const char* className,
const char* fieldName,
jobject obj,
jobject filedVaule)
{
jstring jclassName, jfieldName;
jclassName = env->NewStringUTF(className);
jfieldName = env->NewStringUTF(fieldName); jclass _class = env->FindClass("java/lang/Class");
if(!_class)
{
LOGE("setFieldOjbect: Failed to find java/lang/Class");
env->ExceptionClear();
return;
}
jmethodID forName_func = env->GetStaticMethodID(_class,
"forName",
"(Ljava/lang/String;)Ljava/lang/Class;");
if(!forName_func)
{
LOGE("setFieldOjbect: Failed to find method forname");
env->ExceptionClear();
return;
}
jobject class_obj = env->CallStaticObjectMethod(_class,
forName_func,
jclassName);
jclass class_java = env->GetObjectClass(class_obj); jmethodID getField_func = env->GetMethodID(class_java,
"getDeclaredField",
"(Ljava/lang/String;)Ljava/lang/reflect/Field;");
if(!getField_func)
{
LOGE("setFieldOjbect: Failed to find method getDeclaredField");
env->ExceptionClear();
return;
}
jobject method_obj = env->CallObjectMethod(class_obj,
getField_func,
jfieldName);
jclass class_method_obj = env->GetObjectClass(method_obj); jmethodID setaccess_func = env->GetMethodID(class_method_obj,
"setAccessible",
"(Z)V");
if(!setaccess_func)
{
LOGE("setFieldOjbect: Failed to find method setAccessible");
env->ExceptionClear();
return;
}
env->CallVoidMethod(method_obj, setaccess_func, true); jmethodID set_func = env->GetMethodID(class_method_obj,
"set",
"(Ljava/lang/Object;Ljava/lang/Object;)V");
if(!set_func)
{
LOGE("setFieldOjbect: Failed to find method set");
env->ExceptionClear();
return;
}
env->CallVoidMethod(method_obj,
set_func,
obj,
filedVaule); env->DeleteLocalRef(class_java);
env->DeleteLocalRef(method_obj);
env->DeleteLocalRef(jclassName);
env->DeleteLocalRef(jfieldName);
}

主入口

 #include "JniBootHelper.h"
#include "BootFileUtils.h"
#include "CPakReader.h" #include <android/log.h>
#include <jni.h> #include "DexMarcoDef.h" #define Dex_asstesPath "assets/OriginAPP.jar"
#define Dex_NAME "OriginClasses.jar"
#define Dex_RELEASEFLODER "OriginBoot"
#define Dex_CACHEFLODER "OriginBootCache" extern "C"
{
JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *reserved)
{
LOGD("JNI_OnLoad has been called.");
JniBootHelper::setJavaVM(vm); return JNI_VERSION_1_4;
} JNIEXPORT void JNI_OnUnLoad(JavaVM *vm, void *reserved)
{
LOGD("JNI_OnUnLoad has been called.");
} JNIEXPORT void Java_com_origingame_OriginShell_nativeLoadClass(JNIEnv* env, jobject thiz, jobject context)
{
JniBootHelper::loadClass(context);
} JNIEXPORT void Java_com_origingame_OriginShell_nativeBoot(JNIEnv* env, jobject thiz, jobject context)
{
bool _initsuccess = true; if(!JniBootHelper::setassetmanager(context)){
LOGE("setassetmanager failed!");
_initsuccess = false;
} if(!JniBootHelper::setFileDir(context)){
LOGE("setFileDir failed!");
_initsuccess = false;
} if(!JniBootHelper::setCacheDir(context)){
LOGE("setCacheDir failed!");
_initsuccess = false;
} if(_initsuccess)
{
LOGD("init success.");
bool _dirExist = false;
bool _exist = false;
BootFileUtils* fileutils = BootFileUtils::getInstance();
std::string _path = JniBootHelper::FileDir;
_path.append("/");
_path.append(Dex_RELEASEFLODER);
LOGD("check dir: %s", _path.c_str());
if(fileutils->isDirectoryExistInternal(_path))
{
_dirExist = true;
std::string _file = JniBootHelper::FileDir;
_file.append("/");
_file.append(Dex_RELEASEFLODER);
_file.append("/");
_file.append(Dex_NAME);
if(fileutils->isFileExistInternal(_file))
_exist = true;
} std::string _cachedirpath = JniBootHelper::FileDir;
_cachedirpath.append("/");
_cachedirpath.append(Dex_CACHEFLODER); if(!_dirExist)
{
LOGD("create dir.");
std::string _filedirpath = JniBootHelper::FileDir;
_filedirpath.append("/");
_filedirpath.append(Dex_RELEASEFLODER);
fileutils->createDirectory(_filedirpath); fileutils->createDirectory(_cachedirpath);
} std::string _dexPath = JniBootHelper::FileDir;
_dexPath.append("/");
_dexPath.append(Dex_RELEASEFLODER);
_dexPath.append("/");
_dexPath.append(Dex_NAME); if(!_exist)
{
LOGD("needed file is not exist.");
CPakReader* PakReader = CPakReader::Create(Dex_asstesPath, true);
TFileBlock fb;
PakReader->GetBlock(Dex_NAME, fb); LOGD("destfile: %s", _dexPath.c_str());
fileutils->writeData2File(_dexPath.c_str(), fb.oData, fb.index.oSize);
delete PakReader;
BootFileUtils::destroyInstance();
}
else
LOGD("needed file is exist."); JniBootHelper::loadDexFile(context, _dexPath.c_str(), _cachedirpath.c_str());
}
}
}

java层代码

 package com.origingame;

 import android.app.Application;
import android.content.Context;
import android.util.Log; public class OriginApplication extends Application {
@Override
protected void attachBaseContext(Context context){
super.attachBaseContext(context);
OriginShell.nativeBoot(context);
} @Override
public void onCreate() {
super.onCreate();
Log.d("OriginGame", "running......");
OriginShell.nativeLoadClass(getApplicationContext());
}
}

OriginShell实现

 package com.origingame;

 import android.content.Context;

 public class OriginShell {
static{
System.loadLibrary("originshell");
}
public static native void nativeBoot(Context context);
public static native void nativeLoadClass(Context context);
}

由于没怎么注释,所以讲一下基本的原理。

大致原理就是通过重写Application的attachBaseContext方法在c++层new一个PathClassLoader或者DexClassLoader对象,两者的具体区别网上已经有很多说明不在详解,通过new的新对象来加载包含dex的jar文件,最后通过反射机制替换掉app启动时原有的classloader,也就是重新给mClassLoader这个成员变量赋值我们最新的classloader

包含dex的jar文件我这里也有做加密处理,加载之前我是先做解密的,大家也可以自己实现自己的加密方式。

apk 加密的更多相关文章

  1. App山寨疯狂 爱加密Apk加密平台防破解

    App山寨疯狂 爱加密Apk加密平台防破解,Android系统由于其开源性,眼下已占领全球智能机近80%的市场,远超微软的WP系统和苹果的IOS系统.然而也正是由于开源性,Android盗版App在国 ...

  2. 需要MARK一下,奇怪的ANDROID SDK自带的APK加密功能的问题

    花了两天时间,各种调试APP,发现问题不在于代码. 在于用了SDK里的加密,导致运行其中一个多线程中的ACTIVITY, 就会黑屏,返回按钮也没用. 发现这个问题的思路是因为,我发现连手机直接调试,一 ...

  3. Android动态方式破解apk终极篇(加固apk破解方式)

    一.前言 今天总算迎来了破解系列的最后一篇文章了,之前的两篇文章分别为: 第一篇:如何使用Eclipse动态调试smali源码 第二篇:如何使用IDA动态调试SO文件 现在要说的就是最后一篇了,如何应 ...

  4. android黑科技系列——静态分析技术来破解Apk

    一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,And ...

  5. Android apk签名方法介绍

    还望支持个人博客站:http://www.enjoytoday.cn 参考博客:http://www.enjoytoday.cn/posts/203 为什么要签名 在介绍签名方法之前,首先我们来了解下 ...

  6. Android逆向之旅---静态分析技术来破解Apk

    一.前言 从这篇文章开始我们开始我们的破解之路,之前的几篇文章中我们是如何讲解怎么加固我们的Apk,防止被别人破解,那么现在我们要开始破解我们的Apk,针对于之前的加密方式采用相对应的破解技术,And ...

  7. 高效IO之Dex加密(三)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680 apk加固原理之dex加密 原理其实不复杂,加固其实就是加密dex文件,防止de ...

  8. c 开源代码

    阅读优秀代码是提高开发人员修为的一种捷径……1. WebbenchWebbench是一个在linux下使用的非常简单的网站压测工具.它使用fork()模拟多个客户端同时访问我们设定的URL,测试网站在 ...

  9. Android混淆那些事儿

    博客: 安卓之家 微博: 追风917 CSDN: 蒋朋的家 简书: 追风917 博客园:追风917 # Android混淆 Android混淆是Android开发者经常使用的一种用于代码防止被反编译的 ...

随机推荐

  1. EnCase v7 search hits in compound files?

    I used to conduct raw search in EnCase v6, and I'd like to see if EnCase v7 raw search could hit key ...

  2. dig out deledted chat messages

    One of my friends asked me to do a favor for her. She said her friend deleted some important chat me ...

  3. vm虚拟机里的桥接模式下“复制物理网络连接状态”作用

    前提:真实主机可以上网 勾选,虚拟机也可以上网 不勾选,虚拟机不可以上网

  4. projecteuler Smallest multiple

    2520 is the smallest number that can be divided by each of the numbers from 1 to 10 without any rema ...

  5. CentOS Linux下一个tomcat起停,查看日志的shell script

    CentOS 的tomcat安装目录:/usr/local/tomcat vi MyTomcatUitl.sh          创建文件chmod u+x MyTomcatUtil.sh   赋执行 ...

  6. linux下alias命令详解

    功能说明:设置指令的别名. 语 法:alias[别名]=[指令名称] 形如: alias cp=“cp -i” : 补充说明:用户可利用alias,自定指令的别名.若仅输入alias,则可列出目前所有 ...

  7. VS2008调试快捷键

    F5: 启动调试 Ctrl+F5: 开始执行(不调试) F10: 逐过程(不进入函数单步) F11: 逐语句(进入函数单步) Shift+F11跳出(实用) Ctrl+F10: 运行到光标处 F6: ...

  8. Ueditor图片缩放的设置

    最近在用Ueditor,功能绝逼强大,不过也有遗憾的地方,上传图片的时候自动缩放的小了,想要图片按宽度整体等比缩放,找了好久,研究了下,终于找到解决方法了. 先改前台的的dialogs/image/i ...

  9. Ubuntu安装wps for linux

    1.WPS For Linux 2013 还是只提供了32位版本,我用的是 64位 Ubuntu,如果您也是64位系统,还需要提前安装一些32位的库文件. sudo apt-get install i ...

  10. div+css的优势在哪?

    1.符合W3C标准.微软等公司都是他的支持者. 2.所搜引擎更加友好. 3.样式调整更加方便. 4.css简洁的代码,减少了带宽. 5.表现和结构分离.在团队开发中更容易分工 并不是取代table,t ...