对某APP的逆向之旅(1)
来源:互联网 发布:3dmax测试软件 编辑:程序博客网 时间:2024/06/05 08:40
最近在研究游戏辅助相关的技术,因此有了下面的文章。
前面的准备工作,再此就不多介绍了,直接进入主题。
java层代码如下:
static { System.loadLibrary("encode"); } public static int a(Context arg4) { if(Thread.currentThread().getName().equals("main")) { throw new IllegalStateException("runRootCommand can\'t run on main thread."); } int v0 = -1; try { String v1 = String.valueOf(arg4.getFilesDir().getAbsolutePath()) + "/gearcorez"; String v2 = System.getProperty("os.arch"); if(v2 != null && !v2.contains("arm")) { return v0; } RootManager.a(arg4, "gearcore", v1); RootManager.a(arg4, "speedman", arg4.getFilesDir() + "/libspeedman.so"); String v0_2 = String.valueOf(arg4.getFilesDir().getAbsolutePath()) + "/gearcore"; RootManager.decode(arg4.getApplicationContext(), v1, v0_2); v0 = RootManager.a(arg4.getApplicationContext(), v0_2); ag.a("suc=" + v0); } catch(IOException v0_1) { IOException v1_1 = v0_1; v0 = -2; v1_1.printStackTrace(); } arg4.deleteFile("gearcore"); return v0; }
可以看到加载了encode动态库,并在函数a(Context arg4)中进行处理。过程为首先通过RootManager.a(, ,)函数进行文件拷贝,然后通过RootManager.decode函数进行解密,最后通过函数RootManager.a(,)运行解密后的文件。
其中函数RootManager.a(, ,)如下:
private static void a(Context arg5, String arg6, String arg7) { int v3; BufferedInputStream v1 = new BufferedInputStream(arg5.getAssets().open(arg6)); FileOutputStream v2 = new FileOutputStream(arg7); byte[] v0 = new byte[4096]; try { while(true) { label_6: v3 = v1.read(v0); if(v3 != -1) { goto label_14; } v2.flush(); break; } } catch(Throwable v0_1) { goto label_17; } v2.close(); v1.close(); return; try { label_14: v2.write(v0, 0, v3); goto label_6; } catch(Throwable v0_1) { label_17: v2.close(); v1.close(); throw v0_1; } }
将assets中文件拷贝到指定目录中,函数比较简单。
本节,我们主要来分析下解密函数
IDA载入encode动态库文件,来到decode函数处
F5,其中参数名和变量名,是我修改过的,这个根据个人习惯,分析时修改即可。
获取包名
然后,通过一个算法解密字符串,算法如下:
然后,将解密后的字符传和包名比较,根据比较结果,进行文件的解密操作。
最后,附上算法还原后的代码(我也写到了so文件中),如下:
static unsigned char key[48] = { 0x70,0,0xc8,0,0x74,0,0x6a,0,0x32,0, 0x78,0,0x68,0,0x7b,0,0x77,0,0x78,0, 0x76,0,0x7e,0,0x3a,0,0x74,0,0x6f,0, 0x7c,0,0x75,0,0x84,0,0x82,0,0x78,0, 0x79,0,0x79,0,0x16,0,0};JNIEXPORT void JNICALL Java_example_com_applications_MainActivity_decode(JNIEnv *env, jobject obj, jobject context, jstring encodePath, jstring decodePath){ char temp[48]; char decodeKey[24]; //Context的类 jclass context_clazz = env->GetObjectClass(context); // 得到 getPackageName 方法的 ID jmethodID methodId_package = env->GetMethodID(context_clazz, "getPackageName", "()Ljava/lang/String;"); if (methodId_package != NULL) { // 获得当前应用的包名 jstring appPackageName = (jstring)env->CallObjectMethod(context, methodId_package); const char* strPackage = env->GetStringUTFChars(appPackageName, 0); LOGD("package name: %s", strPackage); memcpy(temp, key, 0x2e); int value = -1, index = 0, salt = 0; for (int i = 0, j = 1; j < 23; ++i, ++j, ++value) { salt = 0; index = i; if (i > 0) { if (i == 1) continue; index = value; salt = value; } decodeKey[index] = temp[2 * i] - 1 - salt; } char* pMem = NULL; pMem = (char*)malloc(0x16); snprintf(pMem, 0x16, "%s", decodeKey); LOGD("decodeKey: %s", decodeKey); //简单的保护工作 if (!strcmp(strPackage, pMem)) { const char* strEncodePath = env->GetStringUTFChars(encodePath, 0); const char* strDecodePath = env->GetStringUTFChars(decodePath, 0); FILE *fpEncode = fopen(strEncodePath, "rb"); if (fpEncode) { FILE *fpDecode = fopen(strDecodePath, "wb"); if (fpDecode) { fseek(fpEncode, 0, 0); uint8_t nextByte; fread(&nextByte, 1, 1, fpEncode); uint8_t xorKey = nextByte; uint8_t decodeByte; while (fread(&nextByte, 1, 1, fpEncode)) { decodeByte = ~((nextByte - 30) ^ xorKey) & 0xFF; nextByte = decodeByte; fputc(decodeByte, fpDecode); } fclose(fpDecode); chmod(strDecodePath, 0x1ED); } fclose(fpEncode); } remove(strEncodePath); env->ReleaseStringUTFChars(encodePath, strEncodePath); env->ReleaseStringUTFChars(decodePath, strDecodePath); env->ReleaseStringUTFChars(appPackageName, strPackage); free(pMem); } else { env->ReleaseStringUTFChars(appPackageName, strPackage); free(pMem); } }}
其中上面解密后的字符串为
分析过程比较简单,仅供娱乐!
0 0
- 对某APP的逆向之旅(1)
- 对某APP的逆向之旅(2)
- 对某APP的逆向之旅(3)
- 对某游戏发包流程的一次逆向之旅
- 对恶意APP"Roidsec"的逆向分析
- 对一个免费通话恶意APP的逆向分析
- 对恶意APP"淘宝宝贝分享图"的逆向分析
- Android逆向之旅---分析某直播App的协议加密原理以及调用加密方法进行协议参数构造
- Android逆向之旅---某直播APP的协议加密原理分析以及调用加密方法进行协议参数构造
- APP逆向(上)
- APP逆向(中)
- Android逆向之旅---获取加固后应用App的所有方法信息
- 逆向实战之对某航软件URL参数的解密
- 一次函数调用过程对堆栈的逆向分析之旅
- 对深蓝少年之机甲勇士的逆向分析
- 对好搜小说app哈希算法的一次逆向
- 逆向某停车app(原创)
- apktool(android app逆向)
- Hadoop安装教程_单机/伪分布式配置_CentOS6.4/Hadoop2.6.0
- spring boot 学习之controller
- 监听和通知
- 指针数组和数组指针
- 第9周课后实践 阅读程序,请写出这些程序的运行结果(1)
- 对某APP的逆向之旅(1)
- bitmap格式分析
- 类与对象及继承多态
- ArduBlock 多久没更新了-安装很简单on mac
- LeetCode:Find the Duplicate Number
- android开发笔记之网络编程—使用TCP协议和URL进行网络编程
- 各种浏览器内核的比较
- 项目笔记0001
- Facebook推荐系统的原理、性能及使用情况