
dex-vm utilizzato per proteggere il file classes.dex di Android
Esegue il bytecode dalvik basandosi su dex-vm per proteggere il dex e aumentare la difficoltà di decompilazione. Il progetto è diviso in due parti: nmm-protect è un progetto puramente Java, converte il dex, trasforma i dati nel dex in strutture C, randomizza gli opcode e genera un progetto ndk; dopo la compilazione produce un apk rafforzato. nmmvm è un progetto Android che include l'implementazione di dex-vm e vari test delle istruzioni dalvik.
Senza compilare nmm-protect, puoi vedere direttamente come usarlo per generare il progetto e l'apk finale, un esempio di elaborazione dell'apk.
L'esempio è stato testato in ambiente Linux, anche Windows dovrebbe funzionare senza problemi, installa prima JDK, Android SDK e NDK.
Scarica vm-protect.jar, configura le variabili d'ambiente ANDROID_SDK_HOME e ANDROID_NDK_HOME:
export ANDROID_SDK_HOME=/opt/android-sdk
export ANDROID_NDK_HOME=/opt/android-sdk/ndk/22.1.7171670
export CMAKE_PATH=/opt/android-sdk/cmake/3.18.1/ #可选,不配置的话直接使用/bin/cmake
java -jar vm-protect-xxx.jar apk input.apk convertRules.txt mapping.txt
Al termine dell'esecuzione, nella directory in cui si trova input.apk verrà generata una directory build, che contiene l'apk finale (build/input-protect.apk), il progetto C completo dex2c (basato su cmake) e i file .dex generati durante il processo, ecc. Dopo la prima esecuzione, nella posizione del jar verrà generata la directory tools, che contiene config.json, dove è possibile modificare la configurazione dei percorsi relativi ad Android SDK e NDK.
Un amico ha scritto un'interfaccia GUI, che può essere più comoda da usare, chi ne ha bisogno può provarla, https://github.com/TimScriptov/nmmp
L'apk generato deve essere allineato con zipalign (le nuove versioni utilizzano già zipflinger per gestire l'apk, quindi non è necessario usare zipalign separatamente) e firmato con apksigner per poter essere installato e utilizzato
apksigner sign --ks ~/.myapp.jks build/input-protect-align.apk
java -jar vm-protect-xxx.jar aab test.aab convertRules.txt
Successivamente è necessario firmare con jarsigner, oppure è possibile integrare signflinger per la firma
jarsigner -keystore ~/.myapp.jks -storepass pass -keypass pass test-protect.aab keyAlias
java -jar vm-protect-xxx.jar aar testModule.aar convertRules.txt
git clone https://github.com/maoabc/nmmp.git
cd nmmp/nmm-protect
./gradlew arsc:build
./gradlew build
成功后会在build/libs生成可直接执行的fatjar。
无转换规则文件,则会转换dex里所有class里的方法(除了构造方法和静态初始化方法)。规则只支持一些简单的情况:
//支持的规则比较简单,*只是被转成正则表达式的.*,支持一些简单的继承关系
class * extends android.app.Activity
class * implements java.io.Serializable
class my.package.AClass
class my.package.* { *; }
class * extends java.util.ArrayList {
if*;
}
class A {
}
class B extends A {
}
class C extends B {
}
//比如'class * extends A' 只会匹配B而不会再匹配C
nmmvm è l'implementazione concreta della macchina virtuale dex, con un'unica funzione di ingresso:
jvalue vmInterpret(
JNIEnv *env,
const vmCode *code,
const vmResolver *dvmResolver
);
typedef struct {
const u2 *insns; //指令
const u4 insnsSize; //指令大小
regptr_t *regs; //寄存器
u1 *reg_flags; //寄存器数据类型标记,主要标记是否为对象
const u1 *triesHandlers; //异常表
} vmCode;
typedef struct {
const vmField *(*dvmResolveField)(JNIEnv *env, u4 idx, bool isStatic);
const vmMethod *(*dvmResolveMethod)(JNIEnv *env, u4 idx, bool isStatic);
//从类型常量池取得类型名
const char *(*dvmResolveTypeUtf)(JNIEnv *env, u4 idx);
//直接返回jclass对象,本地引用需要释放引用
jclass (*dvmResolveClass)(JNIEnv *env, u4 idx);
//根据类型名得到class
jclass (*dvmFindClass)(JNIEnv *env, const char *type);
//const_string指令加载的字符串对象
jstring (*dvmConstantString)(JNIEnv *env, u4 idx);
} vmResolver;
vmCode fornisce le istruzioni necessarie all'esecuzione, la tabella delle eccezioni e lo spazio dei registri; vmResolver contiene un insieme di puntatori a funzione che forniscono i simboli a runtime, come field, method e così via. Personalizzando questi due parametri si realizzano diverse modalità di hardening; ad esempio, il file test.cpp nel progetto contiene un semplice vmResolver basato su libdex, utilizzato principalmente per lo sviluppo e i test. nmm-protect invece converte i dati relativi al .dex in strutture C e include anche la randomizzazione degli opcode, risultando sostanzialmente utilizzabile in pratica.
Attualmente è già stato implementato l'hardening relativo ai moduli, con un utilizzo simile all'hardening degli apk; in caso di problemi è possibile aprire una issue.
nmm-protect è rilasciato con licenza gpl, nmm-protect licence, la parte dex-vm è rilasciata con licenza Apache, nmmvm licence. Solo la parte vm viene inclusa nell'apk; nmm-protect si limita a convertire il dex, quindi la licenza non influisce sul risultato generato.