dex-vm implementation, used to protect the classes.dex file

Related tags

Miscellaneous nmmp
Overview

nmmp

基于dex-vm运行dalvik字节码从而对dex进行保护,增加反编译难度。 项目分为两部分nmm-protect是纯java项目,对dex进行转换,把dex里方法及各种数据转为c结构体,处理apk生成c项目,编译生成so,输出处理后的apk。nmmvm是一个安卓项目,包含dex-vm实现及各种dalvik指令的测试等。

nmm-protect

  • 简单使用

不编译nmm-protect,可以直接看使用它生成项目及最后的apk,对es文件管理器加固的示例

当前只支持linux环境,先安装好JDK及android sdk和ndk。

下载nmm-protect.jar,配置好环境变量ANDROID_SDK_HOME、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

然后运行jar:

java -jar nmm-protect-xxx.jar input.apk

执行完毕会在input.apk所在的目录下生成一个build目录,里面包含最后输出的apk(build/input-protect.apk),完整的c项目dex2c(基于cmake)及处理过程中生成的.dex等

生成的apk需要使用zipalign对齐及apksigner签名才能安装使用

zipalign 4 build/input-protect.apk build/input-protect-align.apk
apksigner sign --ks ~/.myapp.jks build/input-protect-align.apk
  • 下载及编译项目
git clone [email protected]:maoabc/nmmp.git
cd nmmp/nmm-protect
./gradlew arsc:build
./gradlew build

成功后会在build/libs生成可直接执行的fatjar。

  • 需要保护的类及规则处理

这个目前没在简单测试的jar上实现,需要自己改源码实现,内部有对应接口。

nmmvm

nmmvm是dex虚拟机具体实现,入口就一个函数:

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提供执行所需要的指令、异常表及寄存器空间,vmResolver它包含一组函数指针,提供运行时的符号,比如field,method等。通过自定义这两个参数来实现不同的加固强度,比如项目里的test.cpp有一个简单的基于libdex实现的vmResolver,它主要用于开发测试。而nmm-protect实现的是把.dex相关数据转换为c结构体,还包含了opcode随机化等,基本可实际使用。

Issues
  • 为什么在数组aget时,int类型和short类型使用了不同的实现,导致数组越界读写时,aget int时不会报ArrayIndexOutOfBoundsException错误

    为什么在数组aget时,int类型和short类型使用了不同的实现,导致数组越界读写时,aget int时不会报ArrayIndexOutOfBoundsException错误

    如题我看int/long数组的aget用的是

    HANDLE_OP_AGET(OP_AGET, "", {
        u4 *arrData = (u4 *) env->GetPrimitiveArrayCritical(arrayObj, NULL);
        u4 val = arrData[idx];
        env->ReleasePrimitiveArrayCritical(arrayObj, arrData, JNI_ABORT);
    
        SET_REGISTER(vdst, val);
    
    })
    

    而short/bool数组使用的

    HANDLE_OP_AGET(OP_AGET_BYTE, "-byte", {
        jbyte val;
        env->GetByteArrayRegion((jbyteArray) arrayObj, idx, 1, &val);
        SET_REGISTER(vdst, val);
    })
    

    使用了不同的实现方式是有什么考虑么?

    我发现使用GetPrimitiveArrayCritical时,数组越界是不会报ArrayIndexOutOfBoundsException,会取出一个未初始化的数字 使用Get***ArrayRegion函数,会报这个ArrayIndexOutOfBoundsException 想知道当时使用不同实现方式的考虑

    bug 
    opened by bwmaples 5
  • 编译失败

    编译失败

    error: implicit declaration of function 'bcopy' is invalid in C99 [-Werror,-Wimplicit-function-declaration] memcpy ((void*) raw->data, (void*)*args, (*tp)->size); ^ 怎么解决?

    opened by xmutzlq 0
  • Android 6.0 上与 JNA 兼容性问题

    Android 6.0 上与 JNA 兼容性问题

    你好,在 Android 6.0 的机器上,加固JNA调用方式的代码会出现崩溃(加固下面这段代码)

    public class MyApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            Log.e("MyApplication", "test.");
            String str = "jna test";
            TestJna.INSTANCE.test_jna(str);
            Log.e("MyApplication", "test end.");
    
        }
    }
    

    TestJna的代码:

    import com.sun.jna.Library;
    import com.sun.jna.Native;
    
    public interface TestJna extends Library {
        TestJna INSTANCE = Native.load("native-test-jna", TestJna.class);
        void test_jna(String msg);
    }
    

    native-test-jna 中的代码:

    void test_jna(jstring msg) {
        LOGE("method = %s", __FUNCTION__);
    }
    
    

    模拟器中的错误日志:

    2022-01-18 19:04:20.476 4644-4644/com.example.jnatestapplication E/MyApplication: test.
    2022-01-18 19:04:20.483 4644-4644/com.example.jnatestapplication E/art: JNI ERROR (app bug): accessed stale weak global reference 0x745f545b (index 54550 in a table of size 31)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: use of deleted weak global reference 0x745f545b
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]     from void com.example.jnatestapplication.MyApplication.onCreate()
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410] "main" prio=5 tid=1 Runnable
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   | group="main" sCount=0 dsCount=0 obj=0x75a82710 self=0x7fdcce5fba00
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   | sysTid=4644 nice=0 cgrp=default sched=0/0 handle=0x7fdcd1f7d200
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   | state=R schedstat=( 0 0 0 ) utm=1 stm=2 core=0 HZ=100
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   | stack=0x7fffaac24000-0x7fffaac26000 stackSize=8MB
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   | held mutexes= "mutator lock"(shared held)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #00 pc 00000000005678e7  /system/lib64/libart.so (art::DumpNativeStack(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, int, char const*, art::ArtMethod*, void*)+215)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #01 pc 0000000000530b30  /system/lib64/libart.so (art::Thread::Dump(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) const+208)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #02 pc 000000000039cde9  /system/lib64/libart.so (art::JavaVMExt::JniAbort(char const*, char const*)+1177)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #03 pc 000000000039e5c3  /system/lib64/libart.so (art::JavaVMExt::JniAbortF(char const*, char const*, ...)+227)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #04 pc 0000000000529078  /system/lib64/libart.so (art::Thread::DecodeJObject(_jobject*) const+312)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #05 pc 00000000004f64e2  /system/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue*)+754)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #06 pc 00000000003cb51f  /system/lib64/libart.so (art::JNI::CallVoidMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+511)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #07 pc 00000000001aaa6b  /system/lib64/libart.so (art::CheckJNI::CallMethodA(char const*, _JNIEnv*, _jobject*, _jclass*, _jmethodID*, jvalue*, art::Primitive::Type, art::InvokeType)+1755)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #08 pc 00000000001ab551  /system/lib64/libart.so (art::CheckJNI::CallVoidMethodA(_JNIEnv*, _jobject*, _jmethodID*, jvalue*)+33)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #09 pc 0000000000021dda  /data/app/com.example.jnatestapplication-1/lib/x86_64/libnmmvm.so (vmInterpret+34442)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #10 pc 000000000000136e  /data/app/com.example.jnatestapplication-1/lib/x86_64/libnmmp.so (???)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #11 pc 0000000000b7e589  /data/app/com.example.jnatestapplication-1/oat/x86_64/base.odex (void com.example.jnatestapplication.MyApplication.onCreate()+157)
    2022-01-18 19:04:20.488 4644-4644/com.example.jnatestapplication A/art: art/runtime/java_vm_ext.cc:410]   native: #12 pc 0000000000b78aa5  /data/dalvik-cache/x86_64/[email protected]@boot.oat (???)
    

    我单独在jni测试调用 TestJna.INSTANCE.test_jna() 是可以的。

    bug 
    opened by shawnbc 5
  • nmmp加固之后只在 Android 6.0 上会crash,是否有方式debug?

    nmmp加固之后只在 Android 6.0 上会crash,是否有方式debug?

    感谢提供 nmmp 工具。目前测试之后加固效果良好。 不过实际使用中碰到一个问题。目前经过nmmp加固之后只在Android6.0上会crash。其他Android版本没问题。不加固前在Android 6.0也没问题。 现在会直接crash,但是看了crash日志没有什么线索。只能看到一些寄存器报错。是否有什么方式可以debug能直接定位到具体是哪些代码引起的?

    感谢

    12-16 14:57:34.266  9989  9989 I AEE/AED : Build fingerprint: 'vivo/PD1612/PD1612:6.0/MRA58K/1617884953:user/release-keys'
    12-16 14:57:34.266  9989  9989 I AEE/AED : Revision: '0'
    12-16 14:57:34.266  9989  9989 I AEE/AED : ABI: 'arm'
    12-16 14:57:34.267  9989  9989 I AEE/AED : pid: 9914, tid: 9914, name: com.xxx.app  >>> com.xxx.app <<<
    12-16 14:57:34.267  9989  9989 I AEE/AED : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x80a20558
    12-16 14:57:34.283  9989  9989 I AEE/AED :     r0 70c1fb0c  r1 0003c3e4  r2 03f80278  r3 70c1fb7c
    12-16 14:57:34.284  9989  9989 I AEE/AED :     r4 13383d80  r5 03f80277  r6 ffd34f9c  r7 ffd34ec0
    12-16 14:57:34.284  9989  9989 I AEE/AED :     r8 ffd34f94  r9 1355a7cc  sl ffd350e8  fp d7667d78
    12-16 14:57:34.284  9989  9989 I AEE/AED :     ip 00000006  sp ffd34eb8  lr 70cee780  pc f3b0a184  cpsr 000d0030
    12-16 14:57:34.287  9989  9989 I AEE/AED : 
    12-16 14:57:34.287  9989  9989 I AEE/AED : backtrace:
    12-16 14:57:34.287  9989  9989 I AEE/AED :     #00 pc 0031b184  /system/lib/libart.so (_ZN3art35InvokeVirtualOrInterfaceWithJValuesERKNS_33ScopedObjectAccessAlreadyRunnableEP8_jobjectP10_jmethodIDP6jvalue+119)
    12-16 14:57:34.287  9989  9989 I AEE/AED :     #01 pc 00268cad  /system/lib/libart.so (_ZN3art3JNI17CallObjectMethodAEP7_JNIEnvP8_jobjectP10_jmethodIDP6jvalue+328)
    12-16 14:57:34.288  9989  9989 I AEE/AED :     #02 pc 0001243b  /data/app/com.xxx.app-2/lib/arm/libnmmvm.so (vmInterpret+24130)
    12-16 14:57:34.288  9989  9989 I AEE/AED :     #03 pc 000dfc23  /data/app/com.xxx.app-2/lib/arm/libnmmp.so
    12-16 14:57:34.288  9989  9989 I AEE/AED :     #04 pc 03b6b77f  /data/app/com.xxx.app-2/oat/arm/base.odex (offset 0x3268000)
    12-16 14:57:34.793  9989  9989 I AEE/AED : 
    12-16 14:57:34.793  9989  9989 I AEE/AED : Tombstone written to: /data/tombstones/tombstone_01
    12-16 15:01:24.088 10523 10523 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x80a20558 in tid 10523 (com.xxx.app)
    12-16 15:01:24.096 10599 10599 I AEE/AED : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
    
    bug 
    opened by XuNeal 14
Protect your Discord token from malicious grabbers!

Discord Token Protector Protect your Discord token from malicious grabbers! This project is still under development! You might face some unstability i

Andro24 147 Jun 23, 2022
Protect files under a specific folder from deleting or moving by explorer.exe.

Explorer-Delete-Protection Protect files under a specific folder from deleting or moving by explorer.exe. Requierments: Microsoft Detours Library - ht

null 4 Jan 2, 2022
PHP Encoder, protect PHP scripts in PHP 8 and PHP 7, High Performance, Compitable with X86_64, MIPS, ARM platform and Ubuntu/Centos/OpenWRT system.

What's FRICC2? FRICC2 is a PHP Script encryption tool. When you are developing a commercial software using PHP, the script can be distributed as encry

Hoowa Sun 29 May 19, 2022
A Discord Bot to protect your server from spam, invitations, fake nitro ads and more written in C++

Antispambot An efficient Discord Bot to prevent spam written in C++. Tested on a large discord server and mitigates around 90% spam. Its well commente

Phil 4 May 1, 2022
The pico can be used to program other devices. Raspberry pi made such an effort. However there is no board yet, that is open-source and can be used with OpenOCD as a general-purpose programmer

pico-probe-programmer The pico can be used to program other devices. Raspberry pi made such an effort. However there is no board yet, that is open-sou

martijn 20 Jan 27, 2022
GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.

GLSL optimizer ⚠️ As of mid-2016, the project is unlikely to have any significant developments. At Unity we are moving to a different shader compilati

Aras Pranckevičius 1.5k Jun 23, 2022
The AudioUnitSDK contains a set of base classes as well as utility sources required for Audio Unit development.

The AudioUnitSDK contains a set of base classes as well as utility sources required for Audio Unit development.

Apple 68 May 17, 2022
(R) Efficient methods and operators for the sparse matrix classes in 'Matrix' (esp. CSR format or "RsparseMatrix")

MatrixExtra MatrixExtra is an R package which extends the sparse matrix and sparse vector types in the Matrix package, particularly the CSR or Rsparse

null 13 Jun 20, 2022
Library of useful C++ snippets and reusable classes I've created as I build out Arduino Uno and ESP32 projects.

Arduino Snippets Library of useful C++ snippets and reusable classes I've created as I build out Arduino Uno and ESP32 projects. Button A simple butto

Max Lynch 7 Feb 5, 2022
Helper C++ classes to quickly preintegrate IMU measurements between SLAM keyframes

mola-imu-preintegration Integrator of IMU angular velocity readings. This repository provides: IMUIntegrator and RotationIntegrator: C++ classes to in

The MOLA SLAM framework 9 Feb 11, 2022
This is some utility functions/classes for having a nice way to communicate with a pico board RP2040

PicoScreenTerminal This is some utility functions/classes for having a nice way to communicate with a pico board RP2040 How to build First follow the

GuillaumeG. 4 Nov 15, 2021
Itpp - IT++ library mirror/fork. C++ library of mathematical, signal processing and communication classes and functions.

Introduction ************ IT++ is a C++ library of mathematical, signal processing and communication classes and functions. Its main use is in simula

null 18 Apr 9, 2022
The Synthesis ToolKit in C++ (STK) is a set of open source audio signal processing and algorithmic synthesis classes written in the C++ programming language.

The Synthesis ToolKit in C++ (STK) By Perry R. Cook and Gary P. Scavone, 1995--2021. This distribution of the Synthesis ToolKit in C++ (STK) contains

null 783 Jun 23, 2022
Le trio de l'enfer 2 Jan 23, 2022
Process Ghosting - a PE injection technique, similar to Process Doppelgänging, but using a delete-pending file instead of a transacted file

Process Ghosting This is my implementation of the technique presented by Gabriel Landau: https://www.elastic.co/blog/process-ghosting-a-new-executable

hasherezade 457 Jun 21, 2022
"Sigma File Manager" is a free, open-source, quickly evolving, modern file manager (explorer / finder) app for Windows, MacOS, and Linux.

"Sigma File Manager" is a free, open-source, quickly evolving, modern file manager (explorer / finder) app for Windows, MacOS, and Linux.

Aleksey Hoffman 892 Jun 27, 2022
Cobalt Strike Beacon Object File (BOF) that takes the name of of a PE file as an argument and spawns the process in a suspended state

Beacon Object File (BOF) that spawns an arbitrary process from beacons memory. Supports Parent Process ID (PPID) spoofing & blocking non-MS signed DLLs from loading into the processes memory (some EDR DLLs).

boku 329 Jun 27, 2022
Hobbyist Operating System targeting x86_64 systems. Includes userspace, Virtual File System, An InitFS (tarfs), Lua port, easy porting, a decent LibC and LibM, and a shell that supports: piping, file redirection, and more.

SynnixOS Epic Hobby OS targeting x86_64 CPUs, it includes some hacked together functionality for most essential OSs although, with interactivity via Q

RaidTheWeb 40 May 27, 2022