### Install libffi library and headers Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to install the compiled libffi library and header files to the system. By default, it installs under /usr/local. ```Shell make install ``` -------------------------------- ### Display all configure options for libffi Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to display all available configuration options for libffi's `configure` script. ```Shell configure --help ``` -------------------------------- ### Run libffi self-tests Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to run the self-tests for libffi to ensure proper functionality. Requires DejaGNU to be installed. ```Shell make check ``` -------------------------------- ### Build libffi using GNU Make Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to compile and build the libffi library after successful configuration. Requires GNU make. ```Shell make ``` -------------------------------- ### Configure libffi with LLVM clang-cl compiler Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to configure libffi for building on Windows platforms using the LLVM project's clang-cl compiler, setting the C and C++ compilers, linker, and preprocessor. ```Shell path/to/configure CC="path/to/msvcc.sh -clang-cl" CXX="path/to/msvcc.sh -clang-cl" LD=link CPP="clang-cl -EP" ``` -------------------------------- ### Configure libffi with Microsoft Visual C++ Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/libffi/README.md Command to configure libffi for building on Windows platforms using Microsoft's Visual C++ compiler. It sets the C and C++ compilers, linker, and preprocessor flags. For 64-bit builds, replace CC=path/to/msvcc.sh with CC="path/to/msvcc.sh -m64" and similarly for CXX. ```Shell path/to/configure CC=path/to/msvcc.sh CXX=path/to/msvcc.sh LD=link CPP="cl -nologo -EP" CPPFLAGS="-DFFI_BUILDING_DLL" ``` -------------------------------- ### Passing and Returning Structures by Value in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This example illustrates how to pass or return a structure by value in JNA. To achieve this, define an empty class that extends the structure and implements `com.sun.jna.Structure.ByValue`. This `ByValue` class is then used as the argument or return type in the JNA mapping. ```C // Original C code typedef struct _Point { int x, y; } Point; Point translate(Point pt, int dx, int dy); ``` ```Java // Equivalent JNA mapping class Point extends Structure { public static class ByValue extends Point implements Structure.ByValue { } public int x, y; } Point.ByValue translate(Point.ByValue pt, int x, int y); ... Point.ByValue pt = new Point.ByValue(); Point result = translate(pt, 100, 100); ``` -------------------------------- ### JNA Mapping for C Function Pointers as Return Values Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This example illustrates how JNA handles C functions that return function pointers. It defines a Java Callback interface to represent the C function pointer type and shows how the native function's return type is mapped to this Callback interface. ```C // Original C code typedef void (*sig_t)(int); sig_t signal(int signal, sig_t sigfunc); ``` ```Java // Equivalent JNA mapping public interface CLibrary extends Library { public interface SignalFunction extends Callback { void invoke(int signal); } SignalFunction signal(int signal, SignalFunction func); } ``` -------------------------------- ### Defining Structures with Nested Arrays in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This example demonstrates how to define structures that contain nested arrays in JNA. An explicit constructor is required for such structures to ensure that the native size of the structure is properly calculated. The calculation of the native size is deferred until the structure is actually used. ```C typedef struct _Buffer { char buf1[32]; char buf2[1024]; } Buffer; ``` ```Java class Buffer extends Structure { public byte[] buf1 = new byte[32]; public byte[] buf2 = new byte[1024]; } ``` -------------------------------- ### Returning Array of Structures from Native Code in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This example details how to handle the return of an array of structures from a native function in JNA. The method is declared to return a single `com.sun.jna.Structure` of the appropriate type. Subsequently, `com.sun.jna.Structure#toArray(int)` is invoked to convert it into an array of initialized structures. It's crucial that the `Structure` class has a no-args constructor, and the caller is responsible for freeing any returned native memory. ```C // Original C code struct Display* get_displays(int* pcount); void free_displays(struct Display* displays); ``` ```Java // Equivalent JNA mapping Display get_displays(IntByReference pcount); void free_displays(Display[] displays); ... IntByReference pcount = new IntByReference(); Display d = lib.get_displays(pcount); Display[] displays = (Display[])d.toArray(pcount.getValue()); ... lib.free_displays(displays); ``` -------------------------------- ### Defining Nested Structures with Pointers using ByReference in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This example shows how to define a nested structure where the inner structure is a pointer, not inlined. The `com.sun.jna.Structure.ByReference` tagging interface is used to indicate that the field should be treated as a pointer to the structure, rather than embedding the full structure directly. ```C // Original C code typedef struct _Line2 { Point* p1; Point* p2; } Line2; ``` ```Java // Equivalent JNA mapping class Point extends Structure { public static class ByReference extends Point implements Structure.ByReference { } public int x, y; } class Line2 extends Structure { public Point.ByReference p1; public Point.ByReference p2; } ``` -------------------------------- ### Download and Compile nmmp Project Source: https://github.com/maoabc/nmmp/blob/master/README.md 这些命令用于从GitHub克隆nmmp项目仓库,并进入nmm-protect目录,然后使用Gradle构建项目。成功后,可在build/libs目录下找到可直接执行的fatjar。 ```bash git clone https://github.com/maoabc/nmmp.git cd nmmp/nmm-protect ./gradlew arsc:build ./gradlew build ``` -------------------------------- ### Protect APK using vm-protect.jar Source: https://github.com/maoabc/nmmp/blob/master/README.md 执行此命令使用vm-protect.jar对APK进行加固。它需要输入APK文件、转换规则文件和映射文件。执行完成后,会在输入APK的同级目录下生成一个build目录,其中包含加固后的APK(build/input-protect.apk)以及完整的基于cmake的C项目dex2c和处理过程中生成的.dex文件。 ```bash java -jar vm-protect-xxx.jar apk input.apk convertRules.txt mapping.txt ``` -------------------------------- ### vmResolver Structure API Reference Source: https://github.com/maoabc/nmmp/blob/master/README.md vmResolver结构体包含一组函数指针,用于在虚拟机运行时解析符号,例如解析字段、方法、类型名、类对象以及字符串常量。它提供了虚拟机与外部环境交互的能力,以获取运行时所需的信息。 ```APIDOC 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; ``` -------------------------------- ### CMake Configuration for libdex Static Library Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/libdex/CMakeLists.txt This CMake script defines the build process for the `libdex` static library. It sets the minimum required CMake version, specifies include directories for `safe-iop`, lists all source files (`.cpp` files) that comprise the library, and links against the `z` and `log` libraries. ```CMake cmake_minimum_required(VERSION 3.6) project(libdex) include_directories(../) include_directories(../safe-iop/include) set(DEX_SRC_FILES CmdUtils.cpp DexCatch.cpp DexClass.cpp DexDataMap.cpp DexDebugInfo.cpp DexFile.cpp DexInlines.cpp DexOptData.cpp DexOpcodes.cpp DexProto.cpp DexSwapVerify.cpp DexUtf.cpp InstrUtils.cpp Leb128.cpp OptInvocation.cpp sha1.cpp SysUtil.cpp ZipArchive.cpp ) #include_directories(openssl/include) #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DLITTLE_ENDIAN") add_library(dex STATIC ${DEX_SRC_FILES}) target_link_libraries(dex z log) ``` -------------------------------- ### vmCode Structure API Reference Source: https://github.com/maoabc/nmmp/blob/master/README.md vmCode结构体定义了虚拟机执行所需的关键数据,包括指令、指令大小、寄存器、寄存器数据类型标记以及异常表。这些数据共同构成了虚拟机执行上下文。 ```APIDOC typedef struct { const u2 *insns; //指令 const u4 insnsSize; //指令大小 regptr_t *regs; //寄存器 u1 *reg_flags; //寄存器数据类型标记,主要标记是否为对象 const u1 *triesHandlers; //异常表 } vmCode; ``` -------------------------------- ### Protect AAB using vm-protect.jar Source: https://github.com/maoabc/nmmp/blob/master/README.md 此命令用于使用vm-protect.jar对Android App Bundle (AAB) 文件进行加固,需要指定输入AAB文件和转换规则文件。 ```bash java -jar vm-protect-xxx.jar aab test.aab convertRules.txt ``` -------------------------------- ### Configure ffi.h and Add Static libffi Library Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Configures the `ffi.h.in` template file to generate `ffi.h` in the binary output directory. It then defines a static library named `ffi_static` using the common and architecture-specific source files, sets public include directories, and links it. ```CMake configure_file(libffi/include/ffi.h.in ${out}/ffi.h @ONLY) add_library(ffi_static STATIC ${LIB_FFI_SRCS} ${ARCH_SRCS}) target_include_directories(ffi_static PUBLIC ${LIBFFI_INCLUDES} ${INCLUDE_DIRS}) target_link_libraries(ffi_static) ``` -------------------------------- ### Initialize CMake Project and Add Subdirectories Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This snippet sets the minimum CMake version, defines the project name 'nmmp', and includes 'vm' and 'libdex' as subdirectories for their respective build processes. ```CMake cmake_minimum_required(VERSION 3.6) project(nmmp) add_subdirectory(vm) add_subdirectory(libdex) ``` -------------------------------- ### vmInterpret Function API Reference Source: https://github.com/maoabc/nmmp/blob/master/README.md vmInterpret是dex虚拟机的主要入口函数。它接收JNIEnv指针、vmCode结构体(包含指令、寄存器等执行所需数据)和vmResolver结构体(包含运行时符号解析函数指针)。通过自定义这两个参数,可以实现不同的加固方式。 ```APIDOC jvalue vmInterpret( JNIEnv *env, const vmCode *code, const vmResolver *dvmResolver ); ``` -------------------------------- ### Configure CMake for safe-iop Project Build Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/safe-iop/CMakeLists.txt This CMakeLists.txt snippet defines the build configuration for the 'safe-iop' project. It specifies the minimum required CMake version, declares the project name, includes OpenSSL headers, sets strict compiler flags for C and C++, creates a static library 'libsafe_iop' from its source, and links it. ```CMake cmake_minimum_required(VERSION 3.6) project(safe-iop) #include_directories(openssl/include) set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Wno-unused-parameter ") add_library(libsafe_iop STATIC src/safe_iop.c) target_link_libraries(libsafe_iop) ``` -------------------------------- ### CMake Configuration for libvm Shared Library Build Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/mksrc/vm/CMakeLists.txt This CMakeLists.txt defines the build process for the 'libvm' project. It specifies the minimum required CMake version, includes directories for headers, lists all source files for the library, sets specific compiler flags for debug and release configurations, defines the output library name as 'nmmvm', and links it against the 'log' library. It also exposes the 'include' directory publicly. ```CMake cmake_minimum_required(VERSION 3.6) project(libvm) include_directories(..) include_directories(./include) set(VM_SRC_FILES DexCatch.cpp Exception.cpp Interp.cpp InterpC-portable.cpp GlobalCache.cpp JNIWrapper.c ) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLOG_INSTR ") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden -DNDEBUG") #设置vm库名称 set(LIBNMMVM_NAME "nmmvm" CACHE INTERNAL "lib nmmvm name") add_library(${LIBNMMVM_NAME} SHARED ${VM_SRC_FILES}) target_link_libraries(${LIBNMMVM_NAME} log) target_include_directories(${LIBNMMVM_NAME} PUBLIC include) ``` -------------------------------- ### Define Conversion Rules for Classes and Methods Source: https://github.com/maoabc/nmmp/blob/master/README.md 此代码段展示了用于指定需要转换的类和方法的规则语法。规则支持简单的继承关系和通配符匹配(*被转换为正则表达式的.*)。如果没有提供转换规则文件,默认会转换dex中所有类里的方法(除了构造方法和静态初始化方法)。 ```java //支持的规则比较简单,*只是被转成正则表达式的.*,支持一些简单的继承关系 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 ``` -------------------------------- ### CMake Configuration for JNA Shared Library Build Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/CMakeLists.txt This CMakeLists.txt file configures the 'jna' project. It sets the minimum CMake version, defines the project name, adds a preprocessor definition '-DNO_JAWT', includes the 'mylibffi' subdirectory, finds the 'log' system library, and builds a shared library 'jnidispatch' from 'dispatch.c' and 'callback.c', linking it with 'ffi_static' and the found 'log' library. ```CMake cmake_minimum_required(VERSION 3.10.2) project(jna) add_definitions(-DNO_JAWT) add_subdirectory(mylibffi) #message(FATAL_ERROR "unknown arch ${LIBFFI_INCLUDES}") find_library(log-lib log) add_library(jnidispatch SHARED dispatch.c callback.c) target_link_libraries(jnidispatch ffi_static ${log-lib}) ``` -------------------------------- ### Configure NDK and Android Environment Variables Source: https://github.com/maoabc/nmmp/blob/master/README.md 在使用vm-protect.jar之前,需要配置Android SDK、NDK和CMake的环境变量,以确保工具能够找到必要的路径。 ```bash 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 ``` -------------------------------- ### Sign Protected APK with apksigner Source: https://github.com/maoabc/nmmp/blob/master/README.md 加固后的APK需要使用apksigner进行签名才能安装和使用。新版本已使用zipflinger处理APK,通常不再需要单独使用zipalign进行对齐。 ```bash apksigner sign --ks ~/.myapp.jks build/input-protect-align.apk ``` -------------------------------- ### CMake Configuration for nmmp Shared Library Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/mksrc/CMakeLists.txt This CMake script defines the build process for the 'nmmp' project. It sets the minimum CMake version, includes the 'vm' subdirectory, specifies include directories, gathers generated source files, applies hidden visibility flags for release builds, and creates a shared library named 'nmmp' from specified sources, linking it with 'LIBNMMVM_NAME' and 'log'. ```CMake cmake_minimum_required(VERSION 3.6) project(nmmp) add_subdirectory(vm) include_directories(.) include_directories(generated/) file(GLOB GEN_SOURCES generated/*_functions.c generated/jni_init.c) set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -fvisibility=hidden ") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden ") #外部程序处理时替换 LIBNAME_PLACEHOLDER set(LIBNAME_PLACEHOLDER "nmmp") add_library(${LIBNAME_PLACEHOLDER} SHARED ConstantPool.c ${GEN_SOURCES} ) target_link_libraries(${LIBNAME_PLACEHOLDER} ${LIBNMMVM_NAME} log) ``` -------------------------------- ### Define CMake Project and Minimum Version Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Initializes the CMake project for libffi, specifying C and ASM as supported languages, and sets the minimum required CMake version to 3.10.2 to ensure compatibility with necessary CMake features. ```CMake project(libffi LANGUAGES C ASM) cmake_minimum_required(VERSION 3.10.2) ``` -------------------------------- ### Protect ARR using vm-protect.jar Source: https://github.com/maoabc/nmmp/blob/master/README.md 此命令用于使用vm-protect.jar对Android Archive (AAR) 模块进行加固,用法与APK加固类似,需要指定输入AAR文件和转换规则文件。 ```bash java -jar vm-protect-xxx.jar aar testModule.aar convertRules.txt ``` -------------------------------- ### CMake Configuration for libvm Shared Library Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/vm/CMakeLists.txt This CMake configuration defines the 'libvm' project, includes necessary directories, lists source files for the 'nmmvm' shared library, sets debug and release compiler flags, and links against the 'log' library. It also exposes public include directories for consumers of the library. ```CMake cmake_minimum_required(VERSION 3.6) project(libvm) include_directories(..) include_directories(./include) set(VM_SRC_FILES DexCatch.cpp Exception.cpp Interp.cpp InterpC-portable.cpp GlobalCache.cpp JNIWrapper.c ) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLOG_INSTR ") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden -DNDEBUG") #设置vm库名称 set(LIBNMMVM_NAME "nmmvm" CACHE INTERNAL "lib nmmvm name") add_library(${LIBNMMVM_NAME} SHARED ${VM_SRC_FILES}) target_link_libraries(${LIBNMMVM_NAME} log) target_include_directories(${LIBNMMVM_NAME} PUBLIC include) ``` -------------------------------- ### Define Source Files for nmmp Project Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This snippet uses `file(GLOB)` to find generated C sources and defines a list of source files (`TEST_SRC`) for the main project, including C++ and C files. ```CMake file(GLOB GEN_SOURCES test/*_functions.c) set(TEST_SRC test.cpp temp_jni_init.c temp_functions.c ) ``` -------------------------------- ### Define Common libffi Source Files and Output Directory Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Sets the build output directory to `CMAKE_CURRENT_BINARY_DIR` and defines the `LIB_FFI_SRCS` variable, listing the common C source files that are part of the libffi library, excluding `dlmalloc.c` which is commented out. ```CMake set(out ${CMAKE_CURRENT_BINARY_DIR}) set(LIB_FFI_SRCS # libffi/src/dlmalloc.c libffi/src/closures.c libffi/src/debug.c libffi/src/java_raw_api.c libffi/src/prep_cif.c libffi/src/raw_api.c libffi/src/types.c ) ``` -------------------------------- ### Map C Library Functions with JNA Interface Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Demonstrates how to map a C library function `atol` to a Java interface using JNA, allowing for dynamic loading of native libraries. ```Java public interface CLibrary extends Library { int atol(String s); } ``` -------------------------------- ### Configure Include Directories Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This section specifies additional directories to search for header files, including the current directory, 'test', and 'custom'. ```CMake include_directories(.) include_directories(test) include_directories(custom) ``` -------------------------------- ### Link Dependencies for 'test-jna' Library Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This command links the 'test-jna' library against the 'log' library. ```CMake target_link_libraries(test-jna log) ``` -------------------------------- ### Link Dependencies for 'nmmp' Library Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This command links the 'nmmp' library against other required libraries: `${LIBNMMVM_NAME}`, 'dex', and 'log'. ```CMake target_link_libraries(nmmp ${LIBNMMVM_NAME} dex log) ``` -------------------------------- ### JNA Native Library Name Mappings by OS Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Provides a reference table detailing how common native library names map to their corresponding JNA String identifiers across different operating systems, including special handling for Mac OS X Frameworks and the current process. ```APIDOC OS Library Name String Windows user32.dll user32 Linux libX11.so X11 Mac OS X libm.dylib m Mac OS X Framework /System/Library/Frameworks/Carbon.framework/Carbon Carbon Any Platform null ``` -------------------------------- ### APIDOC: Mapping for `android.support.v4.graphics.drawable.IconCompatParcelizer` Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/apkprotect/src/test/resources/mapping.txt This snippet provides the obfuscation mapping for the `android.support.v4.graphics.drawable.IconCompatParcelizer` class. It details the original and obfuscated signatures for its constructor, `read` method, and `write` method, which are used for handling `IconCompat` objects during parceling. ```APIDOC android.support.v4.graphics.drawable.IconCompatParcelizer -> android.support.v4.graphics.drawable.IconCompatParcelizer: 1:1:void ():11:11 -> 1:1:androidx.core.graphics.drawable.IconCompat read(androidx.versionedparcelable.VersionedParcel):13:13 -> read 1:1:void write(androidx.core.graphics.drawable.IconCompat,androidx.versionedparcelable.VersionedParcel):17:17 -> write ``` -------------------------------- ### Add Main Shared Library 'nmmp' Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This command creates a shared library named 'nmmp' from the specified source files, including 'ConstantPool.c' and those defined in `TEST_SRC`. ```CMake add_library(nmmp SHARED ConstantPool.c ${TEST_SRC}) ``` -------------------------------- ### JNA Mapping for C Varargs Functions Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet demonstrates how to map a C function that accepts a variable number of arguments (varargs) to a Java method using JNA. The C '...' syntax is directly translated to Java's '...' (varargs) syntax in the method signature. ```C // Original C code extern int printf(const char* fmt, ...); ``` ```Java // Equivalent JNA mapping interface CLibrary extends Library { int printf(String fmt, ...); } ``` -------------------------------- ### APIDOC: Mapping for `android.support.v4.app.RemoteActionCompatParcelizer` Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/apkprotect/src/test/resources/mapping.txt This snippet provides the obfuscation mapping for the `android.support.v4.app.RemoteActionCompatParcelizer` class. It details the original and obfuscated signatures for its constructor, `read` method, and `write` method, which are essential for parceling and unparceling `RemoteActionCompat` objects. ```APIDOC android.support.v4.app.RemoteActionCompatParcelizer -> android.support.v4.app.RemoteActionCompatParcelizer: 1:1:void ():11:11 -> 1:1:androidx.core.app.RemoteActionCompat read(androidx.versionedparcelable.VersionedParcel):13:13 -> read 1:1:void write(androidx.core.app.RemoteActionCompat,androidx.versionedparcelable.VersionedParcel):17:17 -> write ``` -------------------------------- ### Map C Library Functions with JNA Direct Mapping Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Shows an alternative method for mapping a C library function `atol` directly to a static native method in a Java class, with certain restrictions. ```Java public class CLibrary { public static native int atol(String s); } ``` -------------------------------- ### Sign Protected AAB with jarsigner Source: https://github.com/maoabc/nmmp/blob/master/README.md 加固后的AAB文件需要使用jarsigner进行签名。也可以集成signflinger进行签名。 ```bash jarsigner -keystore ~/.myapp.jks -storepass pass -keypass pass test-protect.aab keyAlias ``` -------------------------------- ### Add Shared Library 'test-jna' Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This command creates another shared library named 'test-jna' from the 'test_jna.c' source file. ```CMake add_library(test-jna SHARED test_jna.c) ``` -------------------------------- ### APIDOC: Mapping for `androidx.activity.ComponentActivity` Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/apkprotect/src/test/resources/mapping.txt This extensive snippet details the obfuscation mapping for the core `androidx.activity.ComponentActivity` class. It includes mappings for its key internal fields such as `mLifecycleRegistry` and `mOnBackPressedDispatcher`, along with a comprehensive list of its methods like `getLifecycle`, `onCreate`, and `onSaveInstanceState`, showing their original and obfuscated signatures. ```APIDOC ``` -------------------------------- ### Configure C Compiler Flags for libffi Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Appends a set of common C compiler flags to `CMAKE_C_FLAGS`. This includes `-Wall` for all warnings, `-Werror` to treat warnings as errors, and numerous `-Wno-error` and `-Wno-` flags to suppress specific warnings that might arise during libffi compilation. ```CMake set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror \ -Wno-error=incompatible-pointer-types \ -Wno-error=unused-label \ -Wno-incompatible-pointer-types \ \ -Wno-deprecated-declarations \ -Wno-missing-field-initializers \ -Wno-null-pointer-arithmetic \ -Wno-pointer-arith \ -Wno-sign-compare \ -Wno-unused-parameter \ -Wno-unused-result") ``` -------------------------------- ### Define Bitness Based on Android ABI Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This conditional block checks the `ANDROID_ABI` variable to define `_32_BIT` or `_64_BIT` preprocessor macros, depending on whether the target architecture is 32-bit (armeabi-v7a, x86) or 64-bit (arm64-v8a, x86_64). ```CMake if (${ANDROID_ABI} STREQUAL "armeabi-v7a" OR ${ANDROID_ABI} STREQUAL "x86") add_definitions("-D_32_BIT") elseif (${ANDROID_ABI} STREQUAL "arm64-v8a" OR ${ANDROID_ABI} STREQUAL "x86_64") add_definitions("-D_64_BIT") endif () ``` -------------------------------- ### APIDOC: Mapping for `androidx.activity.Cancellable` Source: https://github.com/maoabc/nmmp/blob/master/nmm-protect/apkprotect/src/test/resources/mapping.txt This snippet provides the obfuscation mapping for the `androidx.activity.Cancellable` interface. It shows the mapping from its original fully qualified name to its obfuscated counterpart. ```APIDOC androidx.activity.Cancellable -> a.a.a: ``` -------------------------------- ### Select Architecture-Specific Source Files and Includes for Android ABIs Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Conditionally sets `TARGET`, `ARCH_SRCS`, and `LIBFFI_INCLUDES` based on the `ANDROID_ABI` variable. This block handles different Android architectures (arm64-v8a, armeabi-v7a, x86, x86_64) by including their respective assembly and C source files and include paths. It also applies architecture-specific ASM flags for x86 and x86_64 builds. ```CMake if (${ANDROID_ABI} STREQUAL "arm64-v8a") set(TARGET AARCH64) set(ARCH_SRCS libffi/src/aarch64/sysv.S libffi/src/aarch64/ffi.c ) set(LIBFFI_INCLUDES libffi/src/aarch64 myconfig/aarch64) elseif (${ANDROID_ABI} STREQUAL "armeabi-v7a") set(TARGET ARM) set(ARCH_SRCS libffi/src/arm/sysv.S libffi/src/arm/ffi.c ) set(LIBFFI_INCLUDES libffi/src/arm myconfig/arm) elseif (${ANDROID_ABI} STREQUAL "x86") set(TARGET X86) set(ARCH_SRCS libffi/src/x86/sysv.S libffi/src/x86/ffi.c ) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -DHAVE_AS_X86_PCREL -DHAVE_AS_ASCII_PSEUDO_OP") set(LIBFFI_INCLUDES libffi/src/x86 myconfig/x86) elseif (${ANDROID_ABI} STREQUAL "x86_64") set(TARGET X86_64) set(ARCH_SRCS libffi/src/x86/ffi64.c libffi/src/x86/ffiw64.c libffi/src/x86/unix64.S libffi/src/x86/win64.S ) set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -DHAVE_AS_X86_PCREL -DHAVE_AS_ASCII_PSEUDO_OP") set(LIBFFI_INCLUDES libffi/src/x86 myconfig/x86) else () message(FATAL_ERROR "unknown arch") endif () ``` -------------------------------- ### Mapping Native Libraries in Java with JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Illustrates two primary methods for mapping a native shared library (e.g., the C library) in Java using JNA: an interface-mapped class and a direct-mapped class. Both approaches enable Java code to interact with functions exported by the native library. ```Java // Alternative 1: interface-mapped class, dynamically load the C library public interface CLibrary extends Library { CLibrary INSTANCE = (CLibrary)Native.load("c", CLibrary.class); } // Alternative 2: direct-mapped class (uses a concrete class rather than an // interface, with a slight variation in [method // declarations](#direct-mapping)). public class CLibrary { static { Native.register("c"); } } ``` -------------------------------- ### JNA Mapping for Variable-Sized C Structures Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Demonstrates how to map a C structure with a variable-sized array (flexible array member) to a JNA `Structure`. It shows the C `typedef` and the corresponding Java `class` with a constructor to allocate the buffer dynamically. ```C typedef struct _Header { int flags; int buf_length; char buffer[1]; } Header; ``` ```Java class Header extends Structure { public int flags; public int buf_length; public byte[] buffer; public Header(int bufferSize) { buffer = new byte[bufferSize]; buf_length = buffer.length; allocateMemory(); } } ``` -------------------------------- ### Set Global FFI Configuration Variables Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/cpp/mylibffi/CMakeLists.txt Initializes `HAVE_LONG_DOUBLE` and `FFI_EXEC_TRAMPOLINE_TABLE` to 0. These variables likely control specific features or optimizations within the libffi build process, disabling them by default. ```CMake set(HAVE_LONG_DOUBLE 0) set(FFI_EXEC_TRAMPOLINE_TABLE 0) ``` -------------------------------- ### Enable JNA VM Crash Protection Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Configure JNA to catch native memory access errors as Java exceptions instead of crashing the JVM. This feature's availability depends on the platform and requires `libjsig.so` for proper signal chaining. ```Java Native.setProtected(true) ``` -------------------------------- ### JNA Callback Thread Management API Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This section details JNA's API for managing the thread context of native callbacks, including how to customize thread properties and control VM attachment for performance or proper VM exit. ```APIDOC com.sun.jna.CallbackThreadInitializer: Description: Interface to customize the thread context for JNA callbacks. Methods: isDaemon(callback: com.sun.jna.Callback): boolean Description: Determines if the native thread should be left attached as a daemon thread. Parameters: callback (com.sun.jna.Callback): The callback object. Returns: boolean - True if the thread should be a daemon, false otherwise. // Other methods (implied by text): for setting thread name, group, and attachment state. com.sun.jna.Native: Description: Utility class for JNA native operations. Methods: detach(maintainAttachment: boolean): void Description: Detaches the current native thread from the Java Virtual Machine. Parameters: maintainAttachment (boolean): If true, the thread attachment is maintained; otherwise, it is detached. Returns: void ``` -------------------------------- ### JNA Structure API for Native Struct Mapping Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This section describes the com.sun.jna.Structure class, which represents native C structs in Java. It explains how JNA handles struct pointers versus by-value structs and the automatic data synchronization between Java and native memory. ```APIDOC com.sun.jna.Structure: Description: Represents a native C 'struct'. Default Behavior: - As parameter/return value: Treated as a pointer to structure ('struct *'). - As structure field: Interpreted by value. Tagging Interfaces: - com.sun.jna.Structure.ByValue: Forces interpretation as by value. - com.sun.jna.Structure.ByReference: Forces interpretation as by reference (pointer). Data Synchronization: - Automatically written to native memory before native function call. - Automatically read from native memory after native function returns. ``` -------------------------------- ### JNA Mapping for C Function Pointers within Structures Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet demonstrates how to map a C struct containing function pointers to a Java Structure using JNA. It shows the definition of nested Callback interfaces for each function pointer and how to invoke them from Java after the structure is initialized by the native library. ```C // Original C code struct _functions { int (*open)(const char*,int); int (*close)(int); }; ``` ```Java // Equivalent JNA mapping public class Functions extends Structure { public static interface OpenFunc extends Callback { int invoke(String name, int options); } public static interface CloseFunc extends Callback { int invoke(int fd); } public OpenFunc open; public CloseFunc close; } ... Functions funcs = new Functions(); lib.init(funcs); int fd = funcs.open.invoke("myfile", 0); funcs.close.invoke(fd); ``` -------------------------------- ### JNA Union Type Usage Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Documents the `Union` type in JNA, which allows multiple fields to overlay the same native memory space. It details how to specify the active field for writing using `setType` and explains which fields are initialized on read. ```APIDOC Unions: Description: A special type of Structure where each declared field within the union overlays the same space in native memory. Behaviors: Writing: Method: setType(Class fieldClass) Description: Must specify which field is to be written by supplying the desired field's class. Reading: Description: All non-pointer-based fields will be initialized from native memory. Structure, String, and WString members will NOT be initialized unless they are selected via setType. ``` -------------------------------- ### JNA Java to Native Type Conversions Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This section details the supported type conversions between Java and native C types for marshalling and unmarshalling data when interacting with native libraries using JNA. It lists C types, their native representations, and corresponding Java types. ```APIDOC JNA Type Mappings: Supported by JNA Library (C to Java): - C Type: char Native Representation: 8-bit integer Java Type: byte - C Type: wchar_t Native Representation: platform-dependent Java Type: char - C Type: short Native Representation: 16-bit integer Java Type: short - C Type: int Native Representation: 32-bit integer Java Type: int - C Type: int Native Representation: boolean flag Java Type: boolean - C Type: enum Native Representation: enumeration type Java Type: int (usually) - C Type: long long, __int64 Native Representation: 64-bit integer Java Type: long - C Type: float Native Representation: 32-bit floating point Java Type: float - C Type: double Native Representation: 64-bit floating point Java Type: double - C Type: pointer (e.g. void*) Native Representation: platform-dependent (32- or 64-bit pointer to memory) Java Type: java.nio.Buffer, com.sun.jna.Pointer - C Type: pointer (e.g. void*), array Native Representation: 32- or 64-bit pointer to memory (argument/return), contiguous memory (struct member) Java Type: [] (array of primitive type) Automatically Handled by JNA Java Library (Java to C): - Java Type: long C Type: com.sun.jna.NativeLong Notes: platform-dependent (32- or 64-bit integer) - Java Type: const char* C Type: java.lang.String Notes: NUL-terminated array (native encoding or jna.encoding) - Java Type: const wchar_t* C Type: com.sun.jna.WString Notes: NUL-terminated array (unicode) - Java Type: char** C Type: java.lang.String String[] Notes: NULL-terminated array of C strings - Java Type: wchar_t** C Type: com.sun.jna.WString WString[] Notes: NULL-terminated array of wide C strings - Java Type: void** C Type: com.sun.jna.Pointer Pointer[] Notes: NULL-terminated array of pointers - Java Type: struct*, struct C Type: com.sun.jna.Structure Notes: pointer to struct (argument or return) (com.sun.jna.Structure.ByReference or explicitly), struct by value (member of struct) (com.sun.jna.Structure.ByValue or explicitly) - Java Type: union C Type: com.sun.jna.Union Notes: same as Structure - Java Type: struct[] C Type: com.sun.jna.Structure Structure[] Notes: array of structs, contiguous in memory - Java Type: void (*FP)() C Type: com.sun.jna.Callback Notes: function pointer (Java or native) - Java Type: pointer ( *) C Type: com.sun.jna.PointerType Notes: same as Pointer - Java Type: other C Type: com.sun.jna.IntegerType Notes: integer type - Java Type: other C Type: com.sun.jna.NativeMapped Notes: custom mapping, depends on definition General Notes: - Unsigned values may be passed by assigning the corresponding two's-complement representation to the signed type of the same size. - Java arrays of primitive type may be wrapped by java.nio.Buffer in order to access a subset of the array (changing the effective size and/or offest). - Java arrays of primitive type and non-direct java.nio.Buffers are only valid for use within the scope of a single call. If the native code keeps a reference to the memory, use com.sun.jna.Memory or direct java.nio.ByteBuffer instead. - Primitive arrays and structures as members of a structure are overlaid on the parent structure memory. - Bitfields must be ``` -------------------------------- ### JNA Error Handling: Retrieving Last System Error Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Explains how JNA handles system errors like `errno` or `GetLastError()`. It recommends declaring `LastErrorException` in JNA mappings for better performance, or using `Native.getLastError()` as an alternative. ```APIDOC Error Handling: System Error Properties: errno, GetLastError() Methods: 1. LastErrorException: Description: If a function sets the system error property, the error code will be thrown as a com.sun.jna.LastErrorException if declared in your JNA mapping. Benefit: Preferred due to better performance. 2. Native.getLastError(): Description: Alternatively, retrieve the last system error code using this method. Method Signature: com.sun.jna.Native#getLastError() ``` -------------------------------- ### Mapping C Multi-dimensional Arrays to JNA Single-dimensional Arrays Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Demonstrates how to map a C multi-dimensional array to an equivalent single-dimensional Java array when using JNA. This approach simplifies handling multi-dimensional data by flattening it into a linear structure in Java, while preserving the original data layout logic. ```C // Original C code #define DIM0 2 #define DIM1 3 int array[DIM0][DIM1]; int i,j; for (i=0;i < DIM0;i++) { for (j=0;j < DIM1;j++) { array[i][j] = i*DIM1 + j; } } ``` ```Java // Equivalent JNA code final int DIM0 = 2; final int DIM1 = 3; int[] array = new int[6]; for (int i=0;i < DIM0;i++) { for (int j=0;j < DIM1;j++) { array[i*DIM1 + j] = i*DIM1 + j; } } ``` -------------------------------- ### Passing Pointer to Structure Arguments in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet demonstrates how to pass a pointer to a C structure as an argument to a native function using JNA. The Java structure subclass automatically handles the pointer to native data memory, ensuring that the structure's contents are passed to the function and updated upon return. Structures are packed according to the platform's default C `struct` alignment rules. ```C // Original C code typedef struct _Point { int x, y; } Point; Point* translate(Point* pt, int dx, int dy); ``` ```Java // Equivalent JNA mapping class Point extends Structure { public int x, y; } Point translate(Point pt, int x, int y); ... Point pt = new Point(); Point result = translate(pt, 100, 100); ``` -------------------------------- ### Passing Array of Structure Arguments in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet demonstrates how to pass an array of structures to a native function using JNA. A Java array of the desired structure type is used. If the array is uninitialized, JNA will automatically initialize it before the function call, simplifying the interaction with native code expecting a structure array. ```C // Original C code void get_devices(struct Device[], int size); ``` ```Java // Equivalent JNA mapping int size = ... Device[] devices = new Device[size]; lib.get_devices(devices, devices.length); ``` -------------------------------- ### Set Release Compiler Flags Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/nmmvm/src/main/cpp/CMakeLists.txt This line appends the `-fvisibility=hidden` flag to the release CXX compiler flags, which helps in reducing symbol visibility for shared libraries. ```CMake set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fvisibility=hidden") ``` -------------------------------- ### Converting Single Structure Instance to Array in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This alternative method shows how to reallocate a single `Structure` instance into an array of structures. The `toArray(size)` method is invoked on the `Structure` instance to create an array of initialized structures, which can then be cast to the specific structure type if needed. ```Java Device dev = new Device(); // As an array of Structure Structure[] structs = dev.toArray(size); // As an array of Device Device[] devices = (Device[])dev.toArray(size); ``` -------------------------------- ### Defining Inlined Nested Structures in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet demonstrates how nested structures are handled in JNA, where they are treated as consecutive memory blocks rather than pointers. Explicit initialization of nested structures is not required, as JNA automatically creates and maps them to the parent structure's memory as needed. ```C // Original C code typedef struct _Point { int x, y; } Point; typedef struct _Line { Point start; Point end; } Line; ``` ```Java // Equivalent JNA mapping class Point extends Structure { public int x, y; } class Line extends Structure { public Point start; public Point end; } ``` -------------------------------- ### Defining Nested Structures with Generic Pointers in JNA Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html This snippet illustrates the more general case of defining a field as a pointer to memory within a structure, without necessarily defining the inner structure itself. This is analogous to declaring a struct without defining it in C, allowing for flexible memory management and assignment of pointers to existing structure instances. ```C // Original C code typedef struct _Line2 { Point* p1; Point* p2; } Line2; ``` ```Java // Equivalent JNA mapping class Line2 extends Structure { public Pointer p1; public Pointer p2; } Line2 line2; Point p1, p2; ... line2.p1 = p1.getPointer(); line2.p2 = p2.getPointer(); ``` -------------------------------- ### Defining Read-Only Fields in JNA Structures Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Illustrates how to use the `final` keyword to prevent Java code from modifying `Structure` fields. It emphasizes initializing final fields in the constructor and the implications of calling `read()` on such structures. ```Java class ReadOnly extends com.sun.jna.Structure { // Do not initialize the field here, or the compiler will inline the value! public final int refCount; { // Initialize fields here, to ensure the values are not inlined refCount = -1; read(); // refCount might now have a different value } } ... ReadOnly ro = new ReadOnly(); // Will not compile! ro.refCount = 0; ``` -------------------------------- ### Marking JNA Structure Fields as Volatile Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Explains the use of the `volatile` keyword for JNA `Structure` fields. It prevents JNA from automatically updating native memory from Java values, useful for fields modified asynchronously or read-only. Manual updates are possible via `writeField`. ```Java class Data extends com.sun.jna.Structure { public volatile int refCount; public int value; } ... Data data = new Data(); ``` -------------------------------- ### Disable Auto-Synchronization for Large JNA Structures Source: https://github.com/maoabc/nmmp/blob/master/nmmvm/jna-android/src/main/java/com/sun/jna/overview.html Improve performance with very large JNA structures by disabling automatic field synchronization. This allows developers to manually control which fields are read or written, reducing reflection overhead. ```Java Structure.setAutoSynch(false) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.