为了防止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. 【IHttpHandler】了解 IHttpHandler

    1 .概述 说明:HttpHandler是一个HTTP请求的真正处理中心.在HttpHandler容器中,ASP.NET Framework才调用HttpHandler的ProcessRequest成 ...

  2. leetcode 121

    121. Best Time to Buy and Sell Stock Say you have an array for which the ith element is the price of ...

  3. Android IOS WebRTC 音视频开发总结(四八)-- 从商业和技术的角度看视频行业的机会

    本文主要从不同角度介绍视频行业的机会,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,欢迎关注个人微信公众号blacker ----------------------------- ...

  4. IOS CLLocationManager定位反编码位置信息

    //获取位置和坐标#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1        if (IOS_VERSION >= 8.0) {   ...

  5. CentOS学习笔记--JDK安装

    JDK安装 大部分的服务都离不开JAVA环境,CentOS里都是OpenJDK,显然我们还是使用JAVA的JDK好.(注:minimal版没有安装OpenJDK,其它版本需要删除这个.) JDK下载 ...

  6. 搭建高性能计算环境(一)、Linux操作系统的安装和配置

    一般课题组刚开始做计算,往往没有专门的集群,主要用自己的PC机.工作站或者买几台服务器来跑跑:小伙伴们摸索Linux的使用.编译一些开源软件.甚至写点Shell脚本需要耗费很多时间,耽搁了读文献.码论 ...

  7. CentOS 6.X版本升级PHP

    #-----------------------------CentOS 6.X版本升级PHP------------------#! /bin/sh #1.关闭selinuxcp -rp /etc/ ...

  8. Clearing Search Values

      Use the SearchClear() method which is part of the Field class to clear search values on a particul ...

  9. 实例化新的一个(new)

    今天越到了一个特别尴尬的问题,其实特别简单就一句代码的事. PlayList pModel = new PlayList(); foreach (XmlNode xn1 in xnl) { ····· ...

  10. c#中操作word文档-三、MSDN文档

    这是关于word读写的MSDN内容,基本所有的方法都可以在这上面找到 https://msdn.microsoft.com/zh-cn/library/office/ff837519.aspx