JNI---uint8_t array转string

本文介绍了一种通过USB接口获取传感器产品信息的方法,并详细展示了如何将获取到的数据转化为易于处理的字符串形式。该过程包括定义数据结构、进行数据读取及格式转换等步骤。
#define  SOFTWARE_VSERSION_LEN                   16+1  //加1代表数组末尾追加'\0'
#define  GLXSS_ID_LEN                            8+1  //加1代表数组末尾追加'\0'

typedef struct sensor_product_info{
 uint8_t software_version[SOFTWARE_VSERSION_LEN];
 uint8_t glxss_id[GLXSS_ID_LEN];
}sensor_product_info_t;

转化代码如下:
int HID::sensor_get_product_info(product_info product){
if(mHIDDev == NULL) {
      LOGE("native dev not initialized");
      return HID_NOT_INIT;
  }

  int ret;
  uint8_t data[sizeof(*product)-2];

  ret = libusb_control_transfer(mHIDDev->handle, BM_REQUEST_TYPE, GET_CHIP_INFO, 0,
                                HID_INTERFACE_INDEX, data, sizeof(*product)-2, TIME_OUT);
    LOGE("sensor_get_product_info:ret=%d",ret);
    if (ret == sizeof(*product)-2) {
      for(int i=0;i<16;i++){
          product->software_version[i] = data[i];
       }
        product->software_version[16]='\0';//字符串末尾追加'\0',方便上层char *vdata= (char *) product->software_version直接转化
        for(int i=16;i<24 ;i++) {
           product->glxss_id[i-16] = data[i];
       }
        product->glxss_id[8]='\0';//字符串末尾追加'\0',方便上层 char *gdata=(char*)product->glxss_id直接转化
       return HID_SUCCESS;
  } else {
      return ret;
  }
}



char *vdata= (char *) product->software_version;
char *gdata=(char*)product->glxss_id;
jstring jversion=env->NewStringUTF(vdata);
jstring jglxssid=env->NewStringUTF(gdata);

注:
转化时,需要手动在末尾添加‘\0’
讲解下面的关于蓝牙的代码: /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define LOG_TAG "BluetoothA2dpServiceJni" #define LOG_NDEBUG 0 #include "android_runtime/AndroidRuntime.h" #include "com_android_bluetooth.h" #include "hardware/bt_av.h" #include "utils/Log.h" #include <string.h> #include <shared_mutex> namespace android { static jmethodID method_onConnectionStateChanged; static jmethodID method_onAudioStateChanged; static jmethodID method_onCodecConfigChanged; static struct { jclass clazz; jmethodID constructor; jmethodID getCodecType; jmethodID getCodecPriority; jmethodID getSampleRate; jmethodID getBitsPerSample; jmethodID getChannelMode; jmethodID getCodecSpecific1; jmethodID getCodecSpecific2; jmethodID getCodecSpecific3; jmethodID getCodecSpecific4; } android_bluetooth_BluetoothCodecConfig; static const btav_source_interface_t* sBluetoothA2dpInterface = nullptr; static std::shared_timed_mutex interface_mutex; static jobject mCallbacksObj = nullptr; static std::shared_timed_mutex callbacks_mutex; static void bta2dp_connection_state_callback(const RawAddress& bd_addr, btav_connection_state_t state) { ALOGI("%s", __func__); std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; ScopedLocalRef<jbyteArray> addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { ALOGE("%s: Fail to new jbyteArray bd addr", __func__); return; } sCallbackEnv->SetByteArrayRegion( addr.get(), 0, sizeof(RawAddress), reinterpret_cast<const jbyte*>(bd_addr.address)); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onConnectionStateChanged, addr.get(), (jint)state); } static void bta2dp_audio_state_callback(const RawAddress& bd_addr, btav_audio_state_t state) { ALOGI("%s", __func__); std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; ScopedLocalRef<jbyteArray> addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(sizeof(RawAddress))); if (!addr.get()) { ALOGE("%s: Fail to new jbyteArray bd addr", __func__); return; } sCallbackEnv->SetByteArrayRegion( addr.get(), 0, sizeof(RawAddress), reinterpret_cast<const jbyte*>(bd_addr.address)); sCallbackEnv->CallVoidMethod(mCallbacksObj, method_onAudioStateChanged, addr.get(), (jint)state); } static void bta2dp_audio_config_callback( const RawAddress& bd_addr, btav_a2dp_codec_config_t codec_config, std::vector<btav_a2dp_codec_config_t> codecs_local_capabilities, std::vector<btav_a2dp_codec_config_t> codecs_selectable_capabilities) { ALOGI("%s", __func__); std::shared_lock<std::shared_timed_mutex> lock(callbacks_mutex); CallbackEnv sCallbackEnv(__func__); if (!sCallbackEnv.valid() || mCallbacksObj == nullptr) return; jobject codecConfigObj = sCallbackEnv->NewObject( android_bluetooth_BluetoothCodecConfig.clazz, android_bluetooth_BluetoothCodecConfig.constructor, (jint)codec_config.codec_type, (jint)codec_config.codec_priority, (jint)codec_config.sample_rate, (jint)codec_config.bits_per_sample, (jint)codec_config.channel_mode, (jlong)codec_config.codec_specific_1, (jlong)codec_config.codec_specific_2, (jlong)codec_config.codec_specific_3, (jlong)codec_config.codec_specific_4); jsize i = 0; jobjectArray local_capabilities_array = sCallbackEnv->NewObjectArray( (jsize)codecs_local_capabilities.size(), android_bluetooth_BluetoothCodecConfig.clazz, nullptr); for (auto const& cap : codecs_local_capabilities) { jobject capObj = sCallbackEnv->NewObject( android_bluetooth_BluetoothCodecConfig.clazz, android_bluetooth_BluetoothCodecConfig.constructor, (jint)cap.codec_type, (jint)cap.codec_priority, (jint)cap.sample_rate, (jint)cap.bits_per_sample, (jint)cap.channel_mode, (jlong)cap.codec_specific_1, (jlong)cap.codec_specific_2, (jlong)cap.codec_specific_3, (jlong)cap.codec_specific_4); sCallbackEnv->SetObjectArrayElement(local_capabilities_array, i++, capObj); sCallbackEnv->DeleteLocalRef(capObj); } i = 0; jobjectArray selectable_capabilities_array = sCallbackEnv->NewObjectArray( (jsize)codecs_selectable_capabilities.size(), android_bluetooth_BluetoothCodecConfig.clazz, nullptr); for (auto const& cap : codecs_selectable_capabilities) { jobject capObj = sCallbackEnv->NewObject( android_bluetooth_BluetoothCodecConfig.clazz, android_bluetooth_BluetoothCodecConfig.constructor, (jint)cap.codec_type, (jint)cap.codec_priority, (jint)cap.sample_rate, (jint)cap.bits_per_sample, (jint)cap.channel_mode, (jlong)cap.codec_specific_1, (jlong)cap.codec_specific_2, (jlong)cap.codec_specific_3, (jlong)cap.codec_specific_4); sCallbackEnv->SetObjectArrayElement(selectable_capabilities_array, i++, capObj); sCallbackEnv->DeleteLocalRef(capObj); } ScopedLocalRef<jbyteArray> addr( sCallbackEnv.get(), sCallbackEnv->NewByteArray(RawAddress::kLength)); if (!addr.get()) { ALOGE("%s: Fail to new jbyteArray bd addr", __func__); return; } sCallbackEnv->SetByteArrayRegion( addr.get(), 0, RawAddress::kLength, reinterpret_cast<const jbyte*>(bd_addr.address)); sCallbackEnv->CallVoidMethod( mCallbacksObj, method_onCodecConfigChanged, addr.get(), codecConfigObj, local_capabilities_array, selectable_capabilities_array); } static btav_source_callbacks_t sBluetoothA2dpCallbacks = { sizeof(sBluetoothA2dpCallbacks), bta2dp_connection_state_callback, bta2dp_audio_state_callback, bta2dp_audio_config_callback, }; static void classInitNative(JNIEnv* env, jclass clazz) { jclass jniBluetoothCodecConfigClass = env->FindClass("android/bluetooth/BluetoothCodecConfig"); android_bluetooth_BluetoothCodecConfig.constructor = env->GetMethodID(jniBluetoothCodecConfigClass, "<init>", "(IIIIIJJJJ)V"); android_bluetooth_BluetoothCodecConfig.getCodecType = env->GetMethodID(jniBluetoothCodecConfigClass, "getCodecType", "()I"); android_bluetooth_BluetoothCodecConfig.getCodecPriority = env->GetMethodID(jniBluetoothCodecConfigClass, "getCodecPriority", "()I"); android_bluetooth_BluetoothCodecConfig.getSampleRate = env->GetMethodID(jniBluetoothCodecConfigClass, "getSampleRate", "()I"); android_bluetooth_BluetoothCodecConfig.getBitsPerSample = env->GetMethodID(jniBluetoothCodecConfigClass, "getBitsPerSample", "()I"); android_bluetooth_BluetoothCodecConfig.getChannelMode = env->GetMethodID(jniBluetoothCodecConfigClass, "getChannelMode", "()I"); android_bluetooth_BluetoothCodecConfig.getCodecSpecific1 = env->GetMethodID( jniBluetoothCodecConfigClass, "getCodecSpecific1", "()J"); android_bluetooth_BluetoothCodecConfig.getCodecSpecific2 = env->GetMethodID( jniBluetoothCodecConfigClass, "getCodecSpecific2", "()J"); android_bluetooth_BluetoothCodecConfig.getCodecSpecific3 = env->GetMethodID( jniBluetoothCodecConfigClass, "getCodecSpecific3", "()J"); android_bluetooth_BluetoothCodecConfig.getCodecSpecific4 = env->GetMethodID( jniBluetoothCodecConfigClass, "getCodecSpecific4", "()J"); method_onConnectionStateChanged = env->GetMethodID(clazz, "onConnectionStateChanged", "([BI)V"); method_onAudioStateChanged = env->GetMethodID(clazz, "onAudioStateChanged", "([BI)V"); method_onCodecConfigChanged = env->GetMethodID(clazz, "onCodecConfigChanged", "([BLandroid/bluetooth/BluetoothCodecConfig;" "[Landroid/bluetooth/BluetoothCodecConfig;" "[Landroid/bluetooth/BluetoothCodecConfig;)V"); ALOGI("%s: succeeds", __func__); } static std::vector<btav_a2dp_codec_config_t> prepareCodecPreferences( JNIEnv* env, jobject object, jobjectArray codecConfigArray) { std::vector<btav_a2dp_codec_config_t> codec_preferences; int numConfigs = env->GetArrayLength(codecConfigArray); for (int i = 0; i < numConfigs; i++) { jobject jcodecConfig = env->GetObjectArrayElement(codecConfigArray, i); if (jcodecConfig == nullptr) continue; if (!env->IsInstanceOf(jcodecConfig, android_bluetooth_BluetoothCodecConfig.clazz)) { ALOGE("%s: Invalid BluetoothCodecConfig instance", __func__); continue; } jint codecType = env->CallIntMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecType); jint codecPriority = env->CallIntMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecPriority); jint sampleRate = env->CallIntMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getSampleRate); jint bitsPerSample = env->CallIntMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getBitsPerSample); jint channelMode = env->CallIntMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getChannelMode); jlong codecSpecific1 = env->CallLongMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecSpecific1); jlong codecSpecific2 = env->CallLongMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecSpecific2); jlong codecSpecific3 = env->CallLongMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecSpecific3); jlong codecSpecific4 = env->CallLongMethod( jcodecConfig, android_bluetooth_BluetoothCodecConfig.getCodecSpecific4); btav_a2dp_codec_config_t codec_config = { .codec_type = static_cast<btav_a2dp_codec_index_t>(codecType), .codec_priority = static_cast<btav_a2dp_codec_priority_t>(codecPriority), .sample_rate = static_cast<btav_a2dp_codec_sample_rate_t>(sampleRate), .bits_per_sample = static_cast<btav_a2dp_codec_bits_per_sample_t>(bitsPerSample), .channel_mode = static_cast<btav_a2dp_codec_channel_mode_t>(channelMode), .codec_specific_1 = codecSpecific1, .codec_specific_2 = codecSpecific2, .codec_specific_3 = codecSpecific3, .codec_specific_4 = codecSpecific4}; codec_preferences.push_back(codec_config); } return codec_preferences; } static void initNative(JNIEnv* env, jobject object, jint maxConnectedAudioDevices, jobjectArray codecConfigArray) { std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex); std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { ALOGE("%s: Bluetooth module is not loaded", __func__); return; } if (sBluetoothA2dpInterface != nullptr) { ALOGW("%s: Cleaning up A2DP Interface before initializing...", __func__); sBluetoothA2dpInterface->cleanup(); sBluetoothA2dpInterface = nullptr; } if (mCallbacksObj != nullptr) { ALOGW("%s: Cleaning up A2DP callback object", __func__); env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } if ((mCallbacksObj = env->NewGlobalRef(object)) == nullptr) { ALOGE("%s: Failed to allocate Global Ref for A2DP Callbacks", __func__); return; } android_bluetooth_BluetoothCodecConfig.clazz = (jclass)env->NewGlobalRef( env->FindClass("android/bluetooth/BluetoothCodecConfig")); if (android_bluetooth_BluetoothCodecConfig.clazz == nullptr) { ALOGE("%s: Failed to allocate Global Ref for BluetoothCodecConfig class", __func__); return; } sBluetoothA2dpInterface = (btav_source_interface_t*)btInf->get_profile_interface( BT_PROFILE_ADVANCED_AUDIO_ID); if (sBluetoothA2dpInterface == nullptr) { ALOGE("%s: Failed to get Bluetooth A2DP Interface", __func__); return; } std::vector<btav_a2dp_codec_config_t> codec_priorities = prepareCodecPreferences(env, object, codecConfigArray); bt_status_t status = sBluetoothA2dpInterface->init( &sBluetoothA2dpCallbacks, maxConnectedAudioDevices, codec_priorities); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed to initialize Bluetooth A2DP, status: %d", __func__, status); sBluetoothA2dpInterface = nullptr; return; } } static void cleanupNative(JNIEnv* env, jobject object) { std::unique_lock<std::shared_timed_mutex> interface_lock(interface_mutex); std::unique_lock<std::shared_timed_mutex> callbacks_lock(callbacks_mutex); const bt_interface_t* btInf = getBluetoothInterface(); if (btInf == nullptr) { ALOGE("%s: Bluetooth module is not loaded", __func__); return; } if (sBluetoothA2dpInterface != nullptr) { sBluetoothA2dpInterface->cleanup(); sBluetoothA2dpInterface = nullptr; } env->DeleteGlobalRef(android_bluetooth_BluetoothCodecConfig.clazz); android_bluetooth_BluetoothCodecConfig.clazz = nullptr; if (mCallbacksObj != nullptr) { env->DeleteGlobalRef(mCallbacksObj); mCallbacksObj = nullptr; } } static jboolean connectA2dpNative(JNIEnv* env, jobject object, jbyteArray address) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return JNI_FALSE; } RawAddress bd_addr; bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr)); bt_status_t status = sBluetoothA2dpInterface->connect(bd_addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed A2DP connection, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } static jboolean disconnectA2dpNative(JNIEnv* env, jobject object, jbyteArray address) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return JNI_FALSE; } RawAddress bd_addr; bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr)); bt_status_t status = sBluetoothA2dpInterface->disconnect(bd_addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed A2DP disconnection, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } static jboolean setSilenceDeviceNative(JNIEnv* env, jobject object, jbyteArray address, jboolean silence) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); RawAddress bd_addr = RawAddress::kEmpty; if (addr) { bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr)); } if (bd_addr == RawAddress::kEmpty) { return JNI_FALSE; } bt_status_t status = sBluetoothA2dpInterface->set_silence_device(bd_addr, silence); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed A2DP set_silence_device, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } static jboolean setActiveDeviceNative(JNIEnv* env, jobject object, jbyteArray address) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); RawAddress bd_addr = RawAddress::kEmpty; if (addr) { bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr)); } if (bd_addr == RawAddress::kEmpty) { return JNI_FALSE; } bt_status_t status = sBluetoothA2dpInterface->set_active_device(bd_addr); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed A2DP set_active_device, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } static jboolean setCodecConfigPreferenceNative(JNIEnv* env, jobject object, jbyteArray address, jobjectArray codecConfigArray) { ALOGI("%s: sBluetoothA2dpInterface: %p", __func__, sBluetoothA2dpInterface); std::shared_lock<std::shared_timed_mutex> lock(interface_mutex); if (!sBluetoothA2dpInterface) { ALOGE("%s: Failed to get the Bluetooth A2DP Interface", __func__); return JNI_FALSE; } jbyte* addr = env->GetByteArrayElements(address, nullptr); if (!addr) { jniThrowIOException(env, EINVAL); return JNI_FALSE; } RawAddress bd_addr; bd_addr.FromOctets(reinterpret_cast<const uint8_t*>(addr)); std::vector<btav_a2dp_codec_config_t> codec_preferences = prepareCodecPreferences(env, object, codecConfigArray); bt_status_t status = sBluetoothA2dpInterface->config_codec(bd_addr, codec_preferences); if (status != BT_STATUS_SUCCESS) { ALOGE("%s: Failed codec configuration, status: %d", __func__, status); } env->ReleaseByteArrayElements(address, addr, 0); return (status == BT_STATUS_SUCCESS) ? JNI_TRUE : JNI_FALSE; } static JNINativeMethod sMethods[] = { {"classInitNative", "()V", (void*)classInitNative}, {"initNative", "(I[Landroid/bluetooth/BluetoothCodecConfig;)V", (void*)initNative}, {"cleanupNative", "()V", (void*)cleanupNative}, {"connectA2dpNative", "([B)Z", (void*)connectA2dpNative}, {"disconnectA2dpNative", "([B)Z", (void*)disconnectA2dpNative}, {"setSilenceDeviceNative", "([BZ)Z", (void*)setSilenceDeviceNative}, {"setActiveDeviceNative", "([B)Z", (void*)setActiveDeviceNative}, {"setCodecConfigPreferenceNative", "([B[Landroid/bluetooth/BluetoothCodecConfig;)Z", (void*)setCodecConfigPreferenceNative}, }; int register_com_android_bluetooth_a2dp(JNIEnv* env) { return jniRegisterNativeMethods( env, "com/android/bluetooth/a2dp/A2dpNativeInterface", sMethods, NELEM(sMethods)); } }
09-18
// JOKAR.cpp - NO CRASH | SAFE PATCHING AFTER LIBRARY LOAD #include <jni.h> #include <unistd.h> #include <dlfcn.h> #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> #include <sys/mman.h> #include <android/log.h> #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, "JOKAR", __VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, "JOKAR", __VA_ARGS__) // === Helper Functions (No Literal Arrays in Macros) === static const char* get_libue4_name() { static const char name[] = {'l','i','b','U','E','4','.','s','o',0}; return name; } static const char* get_libanogs_name() { static const char name[] = {'l','i','b','a','n','o','g','s','.','s','o',0}; return name; } // === Build Instructions Safely === static uint32_t build_br_x0() { // BR X0 = 0xD6 0x5F 0x03 0xC0 → little-endian word: 0xC0035FD6 return 0xC0035FD6; } static uint32_t build_movz_w0_0() { // MOVZ W0, #0 = 0xD2 0x80 0x00 0x00 → 0x000080D2 return 0x000080D2; } // === Find Library Base Address === static uintptr_t findLibrary(const char* libName) { FILE* f = fopen("/proc/self/maps", "r"); if (!f) { LOGE("Failed to open /proc/self/maps"); return 0; } char line[512]; uintptr_t addr = 0; while (fgets(line, sizeof(line), f)) { if (strstr(line, libName) && strstr(line, "r-xp")) { addr = strtoul(line, NULL, 16); LOGI("Found %s @ 0x%lx", libName, addr); break; } } fclose(f); return addr; } // === Wait Until Library Is Fully Loaded === static uintptr_t waitForLibrary(const char* libName, int maxRetries = 200) { for (int i = 0; i < maxRetries; ++i) { uintptr_t addr = findLibrary(libName); if (addr != 0) { usleep(100000); // Give time to fully load return addr; } usleep(100000); // 100ms delay } LOGE("Timeout waiting for %s", libName); return 0; } // === Apply Single Instruction Patch Safely === static bool patchOffset(uintptr_t base, uintptr_t offset, uint32_t instruction) { if (!base) return false; uint32_t* target = (uint32_t*)(base + offset); void* page_start = (void*)((uintptr_t)target & ~(0x1000 - 1)); // Make page writable if (mprotect(page_start, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { LOGE("mprotect failed for offset 0x%lx", offset); return false; } *target = instruction; // Restore exec mprotect(page_start, 0x1000, PROT_READ | PROT_EXEC); LOGI("Patched 0x%lx + 0x%lx = 0x%lx with 0x%08x", base, offset, (uintptr_t)target, instruction); return true; } // === Dual Instruction Patch: MOVZ W0, #0; BR X0 === static bool patchMovzBr(uintptr_t base, uintptr_t offset) { if (!base) return false; uint32_t* target = (uint32_t*)(base + offset); void* page_start = (void*)((uintptr_t)target & ~(0x1000 - 1)); mprotect(page_start, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC); target[0] = 0x000080D2; // MOVZ W0, #0 target[1] = 0xC0035FD6; // BR X0 mprotect(page_start, 0x1000, PROT_READ | PROT_EXEC); LOGI("Patched MOVZ+BR at 0x%lx + 0x%lx", base, offset); return true; } // === Thread Function === static void* Rayyan_thread(void*) { LOGI("Waiting for libUE4.so and libanogs.so..."); // Wait until both libraries are loaded uintptr_t libUE4Base = waitForLibrary(get_libue4_name()); if (!libUE4Base) { LOGE("Failed to locate libUE4.so"); return nullptr; } uintptr_t libanogsBase = waitForLibrary(get_libanogs_name()); if (!libanogsBase) { LOGE("Failed to locate libanogs.so"); return nullptr; } LOGI("Both libraries loaded. Starting patches..."); // Important: Do not dlopen/dlclose here — we use direct base access // === Apply Patches One by One With Delays === usleep(200000); // Use MOVZ+BR where function returns value patchMovzBr(libanogsBase, 0x507938); patchMovzBr(libanogsBase, 0x2F7FF4); patchMovzBr(libanogsBase, 0x31F408); patchMovzBr(libanogsBase, 0x47B5CC); // Critical: Only BR X0 if it's a pure bypass (no return) patchOffset(libanogsBase, 0x228560, build_br_x0()); patchMovzBr(libUE4Base, 0x6FEE04C); patchMovzBr(libUE4Base, 0x9DFF6BC); patchMovzBr(libUE4Base, 0x702784C); patchMovzBr(libUE4Base, 0x71F5640); LOGI("All patches applied successfully."); // Fake loop while (true) { usleep(1000000); } return nullptr; } // === Entry Point === __attribute__((constructor)) static void mainload() { pthread_t ptid; if (pthread_create(&ptid, nullptr, Rayyan_thread, nullptr) != 0) { LOGE("Failed to create thread"); } } Make this undected structure getting very extreme hard from server
最新发布
12-12
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲暇部落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值