本分析还是基本上以AndroidNativeEmU模拟器分析日志为主。不过为了保证函数可以正常运行,部分数据来自真实环境,并还原到原偏移地址中,保证模拟器正常执行。本次分析还首次在模拟器中实现art模式下的Dex加载过程,不用到真实环境中去dump dex了。
Executing syscall mprotect(cbfab000, 00001000, 00000003) at 0xcbffd165
call mprotect:0xcbfab000 ç基地址,即so头地址
======================= Registers =======================
R0=0xcbfab034 R1=0x0 R2=0x1 R3=0x1
R4=0x7ffce8 R5=0x7ffce8 R6=0x7ffe90 R7=0x7ffff8 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0x7ffce0 SP=0x7ffce0
LR=0xcbffd165 PC=0xcbffd60c
======================= Disassembly =====================
0xcbffd60c: 0170 strb r1, [r0] ç开始把so头清零
0xcbffd60e: 6e48 ldr r0, [pc, #0x1b8]
0xcbffd610: 7f49 ldr r1, [pc, #0x1fc]
0xcbffd612: 7944 add r1, pc
0xcbffd614: 4018 adds r0, r0, r1
======================= Registers =======================
R0=0x47 R1=0xcbfae6f1 R2=0x7ffe60 R3=0x7ffe58
R4=0x7ffcf8 R5=0x7ffdd8 R6=0x7ffe90 R7=0x7ffff8 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xffff1c30 SP=0x7ffce0
LR=0xcbffe2f3 PC=0xcbffca94
======================= Disassembly =====================
0xcbffca94: 0870 strb r0, [r1] < --R1=0xcbfae6f1
0xcbffca96: 1878 ldrb r0, [r3]
0xcbffca98: 1168 ldr r1, [r2]
0xcbffca9a: 0870 strb r0, [r1]
0xcbffca9c: 1020 movs r0, #0x10
0xcbfae9c4: f0b5 push {r4, r5, r6, r7, lr}
0xcbfae9c6: 03af add r7, sp, #0xc
0xcbfae9c8: 89b0 sub sp, #0x24
0xcbfae9ca: 6e46 mov r6, sp
0xcbfae9cc: 3162 str r1, [r6, #0x20]
>dump 0xcbfab000
CBFAB000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
CBFAB010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
CBFAB020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
CBFAB030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
Called dlopen(libc.so)
Loading module 'vfs/system/lib/libc.so'.
call malllos size:0x9 at 0xcbfc15e7
malloc addr:0x2022000
Called dlsym(0xcbbdf000, _exit) at 0xcbfb1669
symbol:_exit addr->: 0xcbc2780c
call malllos size:0x9 at 0xcbfc166f
malloc addr:0x2023000
Called dlsym(0xcbbdf000, exit) at 0xcbfb167f
#libc_fun_name = ["_exit","exit","pthread_create","pthread_join","memcpy","malloc","calloc","memset","fopen","fclose","fgets","strtoul","strtoull","strstr","ptrace","mprotect","strlen","sscanf","free","strdup","strcmp","strcasecmp","utime","mkdir","open","close","unlink","stat64","time","snprintf","strchr","strncmp","pthread_detach","pthread_self","opendir","readdir","closedir","mmap","munmap","lseek","fstat","read","select","bsd_signal","fork","prctl","setrlimit","getppid","getpid","waitpid","kill","flock","write","execve","execv","execl","sysconf","__system_property_get","ftruncate","gettid","pread64","pwrite64","pread","pwrite"," ","statvfs"]
JNIEnv->FindClass(com/app/protect/A) was called
JNIEnv->RegisterNatives(1, 0x007fff58, 4) was called
Register native ('n001', '(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZ)V',function->'0xcbfaf829') failed on class com_app_protect_A.
Register native ('n002', '(Landroid/content/Context;)V',function->'0xcbfaf999') failed on class com_app_protect_A.
Register native ('n003', '()[Ljava/lang/String;',function->'0xcbfaf9f9') failed on class com_app_protect_A.
Register native ('n004', '()V',function->'0xcbfafad5') failed on class com_app_protect_A.
protected void attachBaseContext(Context arg8) {
StubApplication.mContext = arg8;
StubApplication.mBootStrapApplication = this;
AppInfo.APKPATH = arg8.getApplicationInfo().sourceDir;
AppInfo.DATAPATH = StubApplication.getDataFolder(arg8.getApplicationInfo().dataDir);
if(!Debug.isDebuggerConnected()) {
StubApplication.loadLibrary();
A.n001(AppInfo.PKGNAME, AppInfo.APPNAME, AppInfo.APKPATH, AppInfo.DATAPATH, Build.VERSION.SDK_INT, AppInfo.REPORT_CRASH);
}
if(AppInfo.APPNAME != null && AppInfo.APPNAME.length() > 0) {
StubApplication.mRealApplication = MonkeyPatcher.createRealApplication(AppInfo.APPNAME);
}
super.attachBaseContext(arg8);
if(StubApplication.mRealApplication != null) {
MonkeyPatcher.attachBaseContext(arg8, StubApplication.mRealApplication);
}
}
00000040: 30 82 02 31 30 82 01 9A A0 03 02 01 02 02 04 4E 0..10..........N
00000050: 25 42 6B 30 0D 06 09 2A 86 48 86 F7 0D 01 01 05 %Bk0...APP.H......
00000060: 05 00 30 5D 31 0B 30 09 06 03 55 04 06 13 02 43 ..0]1.0...U....C
00000070: 4E 31 10 30 0E 06 03 55 04 08 13 07 62 65 69 6A N1.0...U....beij
.text:CBFB71CE 28 4D LDR R5, =(_GLOBAL_OFFSET_TABLE_ - 0xCBFB71D4)
.text:CBFB71D0 7D 44 ADD R5, PC ; _GLOBAL_OFFSET_TABLE_
.text:CBFB71D2 44 19 ADDS R4, R0, R5 ; byte_CC00F664
.text:CBFB71D4 20 46 MOV R0, R4
.text:CBFB71D6 39 46 MOV R1, R7
.text:CBFB71D8 1B F0 E8 FA BL Fun_md5 ; 获取apk 数字签名,然后MD5这个签名,给后面的dex decode 做key
2020-11-11 17:39:40,906 DEBUG androidemu.native.hooks | call memcpy (len:0x10)
2020-11-11 17:39:40,906 DEBUG androidemu.native.hooks | memcpy_data:0xcc00f664-->0x20cdb11
2020-11-11 17:39:40,907 INFO androidemu.native.hooks | addr -->0xcbfb6f9b
2020-11-11 17:39:40,907 DEBUG androidemu.native.hooks |
CC00F664: 05 86 74 2E 88 A2 E6 A1 9E 99 65 98 EC 33 6B 61 ..t.......e..3ka <== md5
2020-11-16 14:23:04,042 INFO androidemu.native.hooks | string-->'assets/appprotect1.jar'
2020-11-16 14:23:04,045 DEBUG androidemu.native.hooks | call memcmp;data1->0x21435d9,data2->0x7ff8d8,len->24
2020-11-16 14:23:04,045 DEBUG androidemu.native.hooks | mem1_data:
2020-11-16 14:23:04,045 DEBUG androidemu.native.hooks |
021435D9: 61 73 73 65 74 73 2F 62 61 69 64 75 70 72 6F 74 assets/appprot
021435E9: 65 63 74 31 2E 6A 61 72 ect1.jar
2020-11-19 11:23:30,452 DEBUG androidemu.native.memory | call malllos size:0x7e62dc at 0xcbfd291b
2020-11-19 11:23:30,455 INFO androidemu.native.memory | malloc addr:0x21db000 ß申请到的空间,后面存放解压数据。size:0x7e62dc 是appprotect1.jar的大小。
if ( !j_inflateInit2_(&v19, 0xFFFFFFF1, "1.2.3", 0x38) )
{
if ( j_inflate(&v19, 4) == 1 )
{
v10 = v23;
j_inflateEnd(&v19);
if ( v10 == v9 )
{
LABEL_13:
v6 = 1;
if ( APP(_DWORD APP)&v16 >= 0x8001u )
0);
goto LABEL_16;
}
}
else
{
j_inflateEnd(&v19);
}
}
======================= Registers =======================
R0=0x21db000 R1=0x7ff758 R2=0x20cdc3c R3=0xcbff04f9
R4=0x21db000 R5=0x7ff7b0 R6=0x1000 R7=0xcbff04f9 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00eef8 SP=0x7ff720
LR=0xcbff0e11 PC=0xcbff0ca8
======================= Disassembly =====================
0xcbff0ca8: b847 blx r7 <=解密函数
0xcbff0caa: 3b46 mov r3, r7
0xcbff0cac: 2868 ldr r0, [r5]
0xcbff0cae: 029a ldr r2, [sp, #8]
0xcbff0cb0: 1168 ldr r1, [r2]
>dump 0x20cdc3c // APP 签名hash生成的解密key
020CDC3C: 4D 23 BC 03 9D 27 9A 95 B2 85 D7 ED 76 C3 3D BA M#...'......v.=.
020CDC4C: 10 D7 1A A0 C0 A0 FE FA 1D E9 14 58 9D C1 CD AE ...........X....
020CDC5C: 52 4B 9B 2D D0 77 E4 5A DD 49 EA A2 80 28 D9 F6 RK.-.w.Z.I...(..
020CDC6C: 7C 0A 2B 97 82 3C 7F 77 0D 3E 0E F8 5D 61 33 54 |.+..<.w.>..]a3T
>dump 0x21db000 // dex 密文数据
021DB000: E3 7A E6 20 86 8C 4B 89 F8 74 A9 AF 65 5B 06 78 .z. ..K..t..e[.x
021DB010: 69 DD 9E C2 C2 68 85 1E A5 A7 35 E0 88 96 E4 4F i....h....5....O
021DB020: 38 16 B1 B7 84 AB 0A E8 7F E1 5D 3C 74 A6 24 FF 8.........]<t.$.
021DB030: 82 CB 1D 61 60 AF 48 8C 9F 50 11 BF C9 72 98 2E ...a`.H..P...r..
======================= Registers =======================
R0=0x76e69e89 R1=0x195a3f R2=0x7ff758 R3=0xcbff04f9
R4=0x21dc000 R5=0x7ff7b0 R6=0x0 R7=0xcbff04f9 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00eef8 SP=0x7ff720
LR=0xcbff0cab PC=0xcbff0ce6
======================= Disassembly =====================
0xcbff0ce6: 0b98 ldr r0, [sp, #0x2c]
0xcbff0ce8: 0a99 ldr r1, [sp, #0x28]
======================= Registers =======================
R0=0x21db000 R1=0x7e62dc R2=0x0 R3=0xcbff04f9
R4=0x0 R5=0x21db000 R6=0x7ff804 R7=0xcbc3064d R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00eef8 SP=0x7ff7d8
LR=0xcbff0cab PC=0xcbfd2954
======================= Disassembly =====================
0xcbfd2954: e8f79efc bl #0xcbfbb294 //解密并填充回被移动走的代码的函数。
2020-11-19 15:40:58,411 DEBUG androidemu.native.hooks | call memcpy (len:0x739dc)
2020-11-19 15:40:58,411 DEBUG androidemu.native.hooks | memcpy_data:0x2944514-->0x28d06ac
2020-11-19 15:40:58,412 INFO androidemu.native.hooks | addr -->0xcbfc1003
2020-11-19 15:40:58,412 DEBUG androidemu.native.hooks |
02944514: 33 A9 E7 6F C3 9B 4C DD F2 82 6E 56 D5 0D 40 91 3..o..L...nV..@.
02944524: C3 FA A6 2C 82 F1 5A 6A 57 24 C8 F3 68 92 4C A0 ...,..ZjW$..h.L.
02944534: 93 0B C4 13 AF DC 0A A0 B0 FE 26 36 89 D2 1E F1 ..........&6....
02944544: C2 D9 97 1D 30 43 95 04 2B 5B B7 8F 0D 56 9A 75 ....0C..+[...V.u
02944554: 7B 63 AC 1B F4 D8 1C 8E A1 D1 78 1B 8B D3 23 CC {c........x...#.
02944564: AA 69 35 BF 11 61 AA 4F 72 01 ED D5 0E 3B E5 09 .i5..a.Or....;..
.text:CBFB56A6 7C 69 LDR R4, [R7,#0x74+var_60] dex 个数计数器
.text:CBFB56A8 1E F0 DC FB BL sub_CBFD3E64 //获取总个数
.text:CBFB56AC 00 F0 DA F8 BL sub_CBFB5864
.text:CBFB56B0 84 42 CMP R4, R0 //循环解压解密加载所有的dex
.text:CBFB56B2 44 DA BGE loc_CBFB573E
.text:CBFB56B4 FF E7 B loc_CBFB56B6
JNIEnv->FindClass(com/app/protect/A) was called
JNIEnv->RegisterNatives(57, 0x007ff984, 10) was called
Register native ('V', '(ILjava/lang/Object;[Ljava/lang/Object;)V',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('Z', '(ILjava/lang/Object;[Ljava/lang/Object;)Z',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('B', '(ILjava/lang/Object;[Ljava/lang/Object;)B',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('C', '(ILjava/lang/Object;[Ljava/lang/Object;)C',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('S', '(ILjava/lang/Object;[Ljava/lang/Object;)S',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('I', '(ILjava/lang/Object;[Ljava/lang/Object;)I',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('J', '(ILjava/lang/Object;[Ljava/lang/Object;)J',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('F', '(ILjava/lang/Object;[Ljava/lang/Object;)F',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('D', '(ILjava/lang/Object;[Ljava/lang/Object;)D',function->'0xcbfd9ed9') failed on class com_app_protect_A.
Register native ('L', '(ILjava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;',function->'0xcbfd9ed9') failed on class com_app_protect_A.
======================= Registers =======================
R0=0x2100000 R1=0x29be544 R2=0x2c80 R3=0x2100028
R4=0x7ff928 R5=0x7ff940 R6=0x7ff998 R7=0x7ffa08 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0x0 SP=0x7ff920
LR=0xcbfdac4d PC=0xcbfe62a0
======================= Disassembly =====================
0xcbfe62a0: f0b5 push {r4, r5, r6, r7, lr} //初始化vmp函数
0xcbfe62a2: 03af add r7, sp, #0xc
0xcbfe62a4: 93b0 sub sp, #0x4c
0xcbfe62a6: 6e46 mov r6, sp
0xcbfe62a8: 7262 str r2, [r6, #0x24]
>dump 0x29be544 0x2c80 //vmp 数据偏移 和 长度
029BE544: 42 44 30 35 32 37 26 00 00 00 01 00 00 00 26 00 BD0527&.......&.
029BE554: 00 00 00 00 00 00 00 00 00 00 80 00 00 00 2C 00 ..............,.
029BE564: 00 00 80 2B 00 00 02 00 00 00 4C 00 00 00 00 0A ...+......L.....
.text:CBFE7338 ; ---------------------------------------------------------------------------
.text:CBFE7338
.text:CBFE7338 loc_CBFE7338 ; CODE XREF: sub_CBFE62A0+108C↑j
.text:CBFE7338 ; sub_CBFE62A0+1092↑j ...
.text:CBFE7338 01 20 MOVS R0, #1
.text:CBFE733A 30 64 STR R0, [R6,#0x40]
.text:CBFE733C 24 21 MOVS R1, #0x24 ; '$'
.text:CBFE733E 11 F0 1F F9 BL j_calloc // 申请128个长度为0x24的空间创建索引
CODE:006CCB0C # Source file: SourceFile
CODE:006CCB0C public void com.app.apptranslate.reading.dailyreading.fragment.PunchReadingScoreappFragment.onCreate(
CODE:006CCB0C android.os.Bundle p0)
CODE:006CCB0C this = v4
CODE:006CCB0C p0 = v5
CODE:006CCB0C .line 88
CODE:006CCB0C const v1, 0xA00007F
CODE:006CCB12 .line 89
CODE:006CCB12 const v3, 1
CODE:006CCB18 new-array v0, v3, <t: Object[]>
CODE:006CCB1C const v3, 0
CODE:006CCB22 check-cast p0, <t: Object>
CODE:006CCB26 aput-object p0, v0, v3
CODE:006CCB2A invoke-static {v1, this, v0}, <void A.V(int, ref, ref) imp. @ _def_A_V@VILL>
CODE:006CCB30
CODE:006CCB30 locret:
CODE:006CCB30 return-void
CODE:006CCB30 Method End
CODE:006CCB30 # ---------------------------------------------------------------------------
.text:CBFDACA4 B1 6C LDR R1, [R6,#0x48]
.text:CBFDACA6 13 F0 CD F8 BL sub_CBFEDE44 ; 初始化vmp JAVA类型
.text:CBFDACAA 02 B0 ADD SP, SP, #8
.text:CBFDACAC 01 21 MOVS R1, #1
JNIEnv->FindClass([F) was called
JNIEnv->FindClass([D) was called
JNIEnv->FindClass(java/lang/Boolean) was called
JNIEnv->FindClass(java/lang/Byte) was called
JNIEnv->FindClass(java/lang/Character) was called
JNIEnv->FindClass(java/lang/Short) was called
JNIEnv->FindClass(java/lang/Integer) was called
JNIEnv->FindClass(java/lang/Long) was called
JNIEnv->FindClass(java/lang/Float) was called
JNIEnv->FindClass(java/lang/Double) was called
JNIEnv->FindClass(java/lang/Object) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Boolean'>, <init>, (Z)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Byte'>, <init>, (B)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Character'>, <init>, (C)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Short'>, <init>, (S)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Integer'>, <init>, (I)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Long'>, <init>, (J)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Float'>, <init>, (F)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Double'>, <init>, (D)V) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Boolean'>, booleanValue, ()Z) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Byte'>, byteValue, ()B) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Character'>, charValue, ()C) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Short'>, shortValue, ()S) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Integer'>, intValue, ()I) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Long'>, longValue, ()J) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Float'>, floatValue, ()F) was called
JNIEnv->GetMethodId(<class '__main__.java_lang_Double'>, doubleValue, ()D) was called
com.app.apptranslate.activity. MainActivity.onCreate函数是个被vmp保护的dex函数。
// com.app.apptranslate.common.base.BaseObserveActivity
protected void onCreate(Bundle arg5) {
A.V(0xA000011, this, new Object[]{((Object)arg5)});
}
======================= Registers =======================
R0=0xe11f2a00 R1=0x11 R2=0x7ffc70 R3=0xe11f2f00
R4=0xfffffff8 R5=0xcc00ee9c R6=0x7ffc08 R7=0x7ffc60 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0x7ffff8 SP=0x7ffbc0
LR=0xcbfda033 PC=0xcbfde9b2
======================= Disassembly =====================
0xcbfde9b2: 0bf0adfe bl #0xcbfea710
======================= Registers =======================
R0=0xe3a26f60 R1=0x44 R2=0x7ffc70 R3=0xe11f2f00
R4=0xfffffff8 R5=0xcc00ee9c R6=0x7ffc08 R7=0x7ffc60 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0x7ffff8 SP=0x7ffbc0
LR=0xcbfde9b7 PC=0xcbfde9b6
======================= Disassembly =====================
R0 vmp 数据资源地址:
>dump 0xe3a26f60
E3A26F60: 11 00 00 0A 42 01 00 00 04 00 00 00 01 00 05 00 ....B...........
E3A26F70: 02 00 06 00 00 00 95 00 D7 8B 71 D1 00 00 00 00 ..........q.....
E3A26F80: 00 00 00 00 00 00 00 00 12 00 00 0A 38 00 00 00 ............8...
E3A26F90: 04 00 00 00 01 00 01 00 02 00 02 00 00 00 10 00 ................
.text:CBFE0328 31 88 LDRH R1, [R6]
======================= Registers =======================
R0=0xcbfe51a2 R1=0x2056 R2=0xff R3=0xe11f2f00
R4=0x2056 R5=0xe11f2f00 R6=0xd1718bd7 R7=0x0 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00efc0 SP=0x7ffa98
LR=0xcbfe0315 PC=0xcbfe0348
======================= Disassembly =====================
>dump 0xd1718bd7 //这个就是vmp的code
D1718BD7: 56 20 54 87 54 00 6F 05 FF 40 8B 00 1B 1F 47 10 V [email protected].
D1718BE7: 49 DB 00 00 6F 01 F8 A3 54 20 53 DB 10 00 77 00 I...o...T S...w.
D1718BF7: 60 DB 00 00 2E 01 54 30 50 DB 10 02 54 10 5D DB `.....T0P...T.].
D1718C07: 00 00 42 00 77 20 FB 0F 05 00 77 00 60 DB 00 00 ..B.w ....w.`...
>dump 0xd1718bc7
D1718BC7: 04 00 00 00 01 00 05 00 02 00 06 00 00 00 95 00 ................
D1718BD7: 56 20 54 87 54 00 6F 05 FF 40 8B 00 1B 1F 47 10 V [email protected].
D1718BE7: 49 DB 00 00 6F 01 F8 A3 54 20 53 DB 10 00 77 00 I...o...T S...w.
D1718BF7: 60 DB 00 00 2E 01 54 30 50 DB 10 02 54 10 5D DB `.....T0P...T.].
>dump 0xe3a26f60
E3A26F60: 11 00 00 0A 42 01 00 00 04 00 00 00 01 00 05 00 ....B...........
E3A26F70: 02 00 06 00 00 00 95 00 D7 8B 71 D1 00 00 00 00 ..........q.....
E3A26F80: 00 00 00 00 00 00 00 00 12 00 00 0A 38 00 00 00 ............8...
E3A26F90: 04 00 00 00 01 00 01 00 02 00 02 00 00 00 10 00 ................
.text:CBFE0328 31 88 LDRH R1, [R6]
.text:CBFE032A FF 22 MOVS R2, #0xFF
.text:CBFE032C 16 92 STR R2, [SP,#0x10C+var_B4]
.text:CBFE032E 08 46 MOV R0, R1
.text:CBFE0330 10 40 ANDS R0, R2
======================= Registers =======================
R0=0x56 R1=0x2056 R2=0xff R3=0xe11f2f00
R4=0xe11f3304 R5=0xe11f2f00 R6=0xd1718ed3 R7=0x7ffb68 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00efc0 SP=0x7ffa98
LR=0xcbfe0315 PC=0xcbfe0332
======================= Disassembly =====================
0xcbfe0332: 8000 lsls r0, r0, #2
0xcbfe0334: 1818 adds r0, r3, r0
0xcbfe0336: 0430 adds r0, #4
0xcbfe0338: 0024 movs r4, #0
0xcbfe033a: 1494 str r4, [sp, #0x50]
>dump 0xd1718ed3
D1718ED3: 56 20 54 87 21 00 54 10 B2 80 01 00 42 02 B7 02 V T.!.T.....B...
D1718EE3: 0B 00 54 10 B2 80 01 00 42 02 EC 00 00 04 54 30 ..T.....B.....T0
D1718EF3: 71 13 02 00 86 02 39 00 0C 7F 54 20 C4 80 21 00 q.....9...T ..!.
D1718F03: 77 10 CF CF 01 00 42 02 78 12 6F 4C 77 00 58 E3 w.....B.x.oLw.X.
.text:CBFE0332 80 00 LSLS R0, R0, #2
.text:CBFE0334 18 18 ADDS R0, R3, R0
.text:CBFE0336 04 30 ADDS R0, #4
.text:CBFE0338 00 24 MOVS R4, #0
.text:CBFE033A 14 94 STR R4, [SP,#0x10C+var_BC]
.text:CBFE033C 00 68 LDR R0, [R0]
======================= Registers =======================
R0=0xe11f305c R1=0x2056 R2=0xff R3=0xe11f2f00
R4=0xe11f3304 R5=0xe11f2f00 R6=0xd1718ed3 R7=0x7ffb68 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00efc0 SP=0x7ffa98
LR=0xcbfe0315 PC=0xcbfe0338
======================= Disassembly =====================
0xcbfe0338: 0024 movs r4, #0
0xcbfe033a: 1494 str r4, [sp, #0x50]
0xcbfe033c: 0068 ldr r0, [r0]
0xcbfe033e: 0d94 str r4, [sp, #0x34]
0xcbfe0340: 0b94 str r4, [sp, #0x2c]
>dump 0xe11f2f00 //跳转表
E11F2F00: 00 2A 1F E1 5C 3C FE CB 9E 46 FE CB 16 05 FE CB .*..<...F......
E11F2F10: 94 2B FE CB 52 4E FE CB 18 06 FE CB FA 36 FE CB .+..RN.......6..
E11F2F20: D0 52 FE CB AC 44 FE CB AC 04 FE CB BC 20 FE CB .R...D....... ..
E11F2F30: 20 24 FE CB F8 2D FE CB FA 03 FE CB 00 22 FE CB $...-......."..
.text:CBFE9CE2 loc_CBFE9CE2 ; CODE XREF: sub_CBFE96A8+62E↑j
.text:CBFE9CE2 ; sub_CBFE96A8+634↑j ...
.text:CBFE9CE2 28 68 LDR R0, [R5]
.text:CBFE9CE4 19 68 LDR R1, [R3]
.text:CBFE9CE6 80 00 LSLS R0, R0, #2
.text:CBFE9CE8 09 18 ADDS R1, R1, R0
.text:CBFE9CEA 09 68 LDR R1, [R1]
.text:CBFE9CEC 32 69 LDR R2, [R6,#0x10]
.text:CBFE9CEE 10 18 ADDS R0, R2, R0
.text:CBFE9CF0 00 6B LDR R0, [R0,#0x30]
.text:CBFE9CF2 22 68 LDR R2, [R4]
.text:CBFE9CF4 80 00 LSLS R0, R0, #2
.text:CBFE9CF6 10 18 ADDS R0, R2, R0
.text:CBFE9CF8 01 60 STR R1, [R0]
.text:CBFE9CFA 6B 48 LDR R0, =(dword_CC01355C - 0xCC00EE9C)
.text:CBFE9CFC 7A 49 LDR R1, =(_GLOBAL_OFFSET_TABLE_ - 0xCBFE9D02)
.text:CBFE9CFE 79 44 ADD R1, PC ; _GLOBAL_OFFSET_TABLE_
.text:CBFE9D00 40 18 ADDS R0, R0, R1 ; dword_CC01355C
.text:CBFE9D02 02 68 LDR R2, [R0]
.text:CBFE9D04 69 48 LDR R0, =(dword_CC013574 - 0xCC00EE9C)
.text:CBFE9D06 40 18 ADDS R0, R0, R1 ; dword_CC013574
.text:CBFE9D08 00 68 LDR R0, [R0]
.text:CBFE9D0A 51 1E SUBS R1, R2, #1
.text:CBFE9D0C 51 43 MULS R1, R2
.text:CBFE9D0E 01 22 MOVS R2, #1
.text:CBFE9D10 11 42 TST R1, R2
.text:CBFE9D12 04 D0 BEQ loc_CBFE9D1E
.text:CBFE9D14 FF E7 B loc_CBFE9D16
2020-11-24 11:16:53,878 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9a6a, data value = 0x0
2020-11-24 11:16:53,885 Memory WRITE at 0xe11f3060, data size = 4, pc: cbfe9cf8, data value = 0xcbfe034a
2020-11-24 11:16:53,888 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x1
2020-11-24 11:16:53,895 Memory WRITE at 0xe11f2fa0, data size = 4, pc: cbfe9cf8, data value = 0xcbfe0360
2020-11-24 11:16:53,898 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x2
2020-11-24 11:16:53,904 Memory WRITE at 0xe11f3074, data size = 4, pc: cbfe9cf8, data value = 0xcbfe0396
2020-11-24 11:16:53,907 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x3
2020-11-24 11:16:53,913 Memory WRITE at 0xe11f32c4, data size = 4, pc: cbfe9cf8, data value = 0xcbfe03ca
2020-11-24 11:16:53,916 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x4
2020-11-24 11:16:53,922 Memory WRITE at 0xe11f2f38, data size = 4, pc: cbfe9cf8, data value = 0xcbfe03fa
2020-11-24 11:16:53,925 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x5
2020-11-24 11:16:53,932 Memory WRITE at 0xe11f2f88, data size = 4, pc: cbfe9cf8, data value = 0xcbfe0438
2020-11-24 11:16:53,935 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x6
2020-11-24 11:16:53,941 Memory WRITE at 0xe11f32ac, data size = 4, pc: cbfe9cf8, data value = 0xcbfe0474
2020-11-24 11:16:53,944 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x7
2020-11-24 11:16:53,951 Memory WRITE at 0xe11f2f28, data size = 4, pc: cbfe9cf8, data value = 0xcbfe04ac
2020-11-24 11:16:53,954 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0x8
2020-11-24 11:16:53,960 Memory WRITE at 0xe11f3190, data size = 4, pc: cbfe9cf8, data value = 0xcbfe04e2
……………
2020-11-24 11:16:56,224 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0xfb
2020-11-24 11:16:56,230 Memory WRITE at 0xe11f3034, data size = 4, pc: cbfe9cf8, data value = 0xcbfe4e52
2020-11-24 11:16:56,233 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0xfc
2020-11-24 11:16:56,239 Memory WRITE at 0xe11f313c, data size = 4, pc: cbfe9cf8, data value = 0xcbfe4e52
2020-11-24 11:16:56,242 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0xfd
2020-11-24 11:16:56,249 Memory WRITE at 0xe11f3264, data size = 4, pc: cbfe9cf8, data value = 0xcbfe4e52
2020-11-24 11:16:56,251 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0xfe
2020-11-24 11:16:56,258 Memory WRITE at 0xe11f3280, data size = 4, pc: cbfe9cf8, data value = 0xcbfe4e52
2020-11-24 11:16:56,261 Memory WRITE at 0x7ffa40, data size = 4, pc: cbfe9e1c, data value = 0xff
2020-11-24 11:16:56,267 Memory WRITE at 0xe11f2f98, data size = 4, pc: cbfe9cf8, data value = 0xcbfe4e52
.text:CBFE0328 31 88 LDRH R1, [R6] 获取opcode
.text:CBFE032A FF 22 MOVS R2, #0xFF
.text:CBFE032C 16 92 STR R2, [SP,#0x10C+var_B4]
.text:CBFE032E 08 46 MOV R0, R1
.text:CBFE0330 10 40 ANDS R0, R2
.text:CBFE0332 80 00 LSLS R0, R0, #2
.text:CBFE0334 18 18 ADDS R0, R3, R0 定位表偏移
.text:CBFE0336 04 30 ADDS R0, #4
.text:CBFE0338 00 24 MOVS R4, #0
.text:CBFE033A 14 94 STR R4, [SP,#0x10C+var_BC]
.text:CBFE033C 00 68 LDR R0, [R0] 获取执行代码地址
.text:CBFE033E 0D 94 STR R4, [SP,#0x10C+var_D8]
.text:CBFE0340 0B 94 STR R4, [SP,#0x10C+var_E0]
.text:CBFE0342 06 94 STR R4, [SP,#0x10C+var_F4]
.text:CBFE0344 27 46 MOV R7, R4
.text:CBFE0346 0C 46 MOV R4, R1
.text:CBFE0348 87 46 MOV PC, R0 跳转到执行代码地址
======================= Registers =======================
R0=0xcbfe51a2 R1=0x2056 R2=0x54 R3=0xe11f2f00
R4=0x2056 R5=0xe11f2f00 R6=0xd1718bd7 R7=0x0 R8=0x0
R9=0x0 R10=0x0 R11=0x0 R12=0xcc00efc0 SP=0x7ffa98
LR=0xcbfe0315 PC=0xcbfe51a6
======================= Disassembly =====================
0xcbfe51a6: 0f20 movs r0, #0xf
0xcbfe51a8: 1040 ands r0, r2
0xcbfe51aa: 002f cmp r7, #0
0xcbfe51ac: 00d0 beq #0xcbfe51b0
0xcbfe51ae: 1046 mov r0, r2
>dump 0xd1718bd7 //code
D1718BD7: 56 20 54 87 54 00 6F 05 FF 40 8B 00 1B 1F 47 10 V [email protected].
D1718BE7: 49 DB 00 00 6F 01 F8 A3 54 20 53 DB 10 00 77 00 I...o...T S...w.
D1718BF7: 60 DB 00 00 2E 01 54 30 50 DB 10 02 54 10 5D DB `.....T0P...T.].
D1718C07: 00 00 42 00 77 20 FB 0F 05 00 77 00 60 DB 00 00 ..B.w ....w.`...
JNIEnv->FindClass
(com/app/apptranslate/common/base/BaseObserveActivity) was called
JNIEnv->GetMethodId
(<class '__main__.com_app_apptranslate_common_base_BaseObserveActivity'>, onCreate, (Landroid/os/Bundle;)V) was called
import codecs
import leb128
def Get_uleb128(vmp_addr,mode):
if mode == 1:
offset = leb128.u.encode(vmp_addr)
if mode == 2:
offset = leb128.u.decode(vmp_addr)
return offset
def ReadFile(file, address, len,flag=0):
add = int(address)
file.seek(add)
if flag == 0:
data = int.from_bytes(file.read(len), byteorder="little", signed=False)
else:
data =file.read(len)
return data
def main():
"""
opcode长度表,按照这个长度表获取每条指令的长度,才能查询到下条指令
"""
opcode_Length = [2, 2, 4, 4, 4, 4, 4, 2, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 6, 4, 4, 6, 10, 4, 4, 4, 4, 4, 2, 4, 4,
2, 4, 4, 6, 6, 6, 2, 2, 4, 4, 6, 6, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 6, 4, 6, 6, 6, 6, 6, 4, 4, 2, 4, 2, 4, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 6, 4, 6, 4, 4, 4, 4, 4, 4, 4, 6, 6, 6, 6, 4, 4, 4, 4]
"""
利用IDA建立的vmp_fun_ID与方法索引表的方法索引地址关联表。利用这个表修正方法索引中的offset地址,这个offset地址是uleb128格式的,需要转换下。
"""
vmp_dex_fun_idtomethod_id = [0xA000001, 0x6F8559, 0xA000003, 0x6F9EF5, 0xA000005, 0x6FA139, 0xA000006, 0x6FAA81,
0xA000002, 0x6F9E75, 0xA000000, 0x6F84D8, 0xA000008, 0x6FB05F, 0xA000007, 0x6FAD9B,
0xA000004, 0x6F9FDD, 0xA000009, 0x72B90C, 0xA00000A, 0x72BEFC, 0xA00000B, 0x72CC31,
0xA00000C, 0x72CC75, 0xA00000D, 0x72CF40, 0xA000010, 0x72D0E3, 0xA000011, 0x72D3C9,
0xA000013, 0x72D592, 0xA000014, 0x72D6E1, 0xA000016, 0x72D78F, 0xA000017, 0x72D806,
0xA000018, 0x72D977, 0xA000019, 0x72DA58, 0xA00001A, 0x72DAD2, 0xA00001B, 0x72DBAE,
0xA00001C, 0x72DD1E, 0xA00001D, 0x72DE8F, 0xA00001E, 0x72DF14, 0xA00001F, 0x72DFC2,
0xA000020, 0x72E0E5, 0xA000021, 0x72E29A, 0xA000022, 0x72E334, 0xA000023, 0x73178C,
0xA00000F, 0x72D06C, 0xA000012, 0x72D466, 0xA000015, 0x72D739, 0xA000025, 0x738125,
0xA000026, 0x73E615, 0xA000027, 0x744157, 0xA000028, 0x744267, 0xA000029, 0x7443EB,
0xA00002A, 0x7445DE, 0xA00002B, 0x74482A, 0xA00002C, 0x7449F1, 0xA00002D, 0x74600C,
0xA00002E, 0x747E40, 0xA00002F, 0x74E453, 0xA000030, 0x74E4C5, 0xA000031, 0x74E541,
0xA000032, 0x74E727, 0xA000033, 0x74E7BB, 0xA000034, 0x74E843, 0xA000035, 0x74E90B,
0xA000036, 0x74E971, 0xA000037, 0x74EA36, 0xA000038, 0x74EAD0, 0xA000039, 0x74EC03,
0xA00003A, 0x74ED09, 0xA00003B, 0x74EDAD, 0xA00003C, 0x74EE7A, 0xA00003D, 0x74EEE9,
0xA00003E, 0x74EF78, 0xA00003F, 0x74F045, 0xA000040, 0x7500A6, 0xA000041, 0x7505F4,
0xA000042, 0x7507A4, 0xA000043, 0x7508C5, 0xA000044, 0x750937, 0xA000045, 0x750981,
0xA000046, 0x750A09, 0xA000047, 0x750A99, 0xA000048, 0x750B6C, 0xA000049, 0x750D70,
0xA00004A, 0x750E71, 0xA00004B, 0x750F22, 0xA00004D, 0x7512BE, 0xA00004E, 0x751306,
0xA00004F, 0x7513F8, 0xA000050, 0x751436, 0xA000051, 0x7514AE, 0xA000052, 0x7517AB,
0xA000053, 0x7518B5, 0xA000054, 0x751961, 0xA000055, 0x751993, 0xA000056, 0x751A4D,
0xA000057, 0x751AA1, 0xA000058, 0x751B27, 0xA000059, 0x751BF1, 0xA00005A, 0x751DC3,
0xA00005B, 0x751E84, 0xA00004C, 0x7510D3, 0xA00005C, 0x7520E2, 0xA00005D, 0x752534,
0xA00005E, 0x7526E1, 0xA00005F, 0x75292C, 0xA000060, 0x752AB6, 0xA000061, 0x753A08,
0xA000062, 0x75694D, 0xA000063, 0x757072, 0xA000064, 0x75B38B, 0xA000065, 0x75B49E,
0xA000066, 0x75B54D, 0xA000067, 0x75B5E0, 0xA000068, 0x75B799, 0xA000069, 0x75C4CC,
0xA00006A, 0x75C5CA, 0xA00006B, 0x75C6FF, 0xA00006C, 0x75CAAE, 0xA00006D, 0x75CB1C,
0xA00006E, 0x75CD6F, 0xA00006F, 0x75CEB2, 0xA000070, 0x75CF32, 0xA000071, 0x75CFE3,
0xA000072, 0x75D02D, 0xA000073, 0x75D04F, 0xA000074, 0x75D0ED, 0xA000075, 0x75D4F8,
0xA000076, 0x75E83D, 0xA000077, 0x75E8B4, 0xA000078, 0x762043, 0xA000079, 0x762284,
0xA00007A, 0x762434, 0xA00007B, 0x763175, 0xA00007C, 0x763233, 0xA00007D, 0x76334C,
0xA00007E, 0x763696, 0xA00007F, 0x765011, 0xA000024, 0x731856, 0xA00000E, 0x72CFA9]
vmp_dex2_fun_idtomethod_id = [0xa010000, 0x752ecf, 0xa010001, 0x757ba7, 0xa010002, 0x757cc4, 0xa010003, 0x757e5f,
0xa010004, 0x757f52, 0xa010005, 0x757fb2, 0xa010006, 0x758003, 0xa010007, 0x758056,
0xa010008, 0x7580a7, 0xa010009, 0x758104, 0xa01000a, 0x75815f, 0xa01000b, 0x7581ac,
0xa01000c, 0x75822c, 0xa01000d, 0x7588a8, 0xa01000e, 0x75ab80, 0xa01000f, 0x75b2a0,
0xa010010, 0x75d394, 0xa010011, 0x75d57f, 0xa010012, 0x75f249, 0xa010013, 0x75f8a1,
0xa010014, 0x76479b, 0xa010015, 0x764d50, 0xa010016, 0x764d7a, 0xa010017, 0x76e7b4,
0xa010018, 0x76f81c, 0xa010019, 0x76ff10, 0xa01001a, 0x771356, 0xa01001b, 0x77f579,
0xa01001c, 0x7857ca, 0xa01001d, 0x785886, 0xa01001e, 0x7863be, 0xa01001f, 0x786646,
0xa010020, 0x78a519, 0xa010021, 0x78f2d7, 0xa010022, 0x790310, 0xa010023, 0x7908c5,
0xa010024, 0x790bb0, 0xa010025, 0x790d67, 0xa010026, 0x790d91, 0xa010027, 0x791787,
0xa010028, 0x791a94, 0xa010029, 0x791de6, 0xa01002a, 0x791f58, 0xa01002b, 0x79200e,
0xa01002c, 0x793a62, 0xa01002d, 0x793c5d, 0xa01002e, 0x793d61, 0xa01002f, 0x793e04,
0xa010030, 0x793e84, 0xa010031, 0x795417, 0xa010032, 0x79558c, 0xa010033, 0x795721,
0xa010034, 0x7958a7, 0xa010035, 0x796616, 0xa010036, 0x7966ea, 0xa010037, 0x796f0e,
0xa010038, 0x79728d, 0xa010039, 0x7975e0, 0xa01003a, 0x797620, 0xa01003b, 0x797a50,
0xa01003c, 0x7988fa, 0xa01003d, 0x799ac0, 0xa01003e, 0x79b78c, 0xa01003f, 0x79c924,
0xa010040, 0x79cbb3, 0xa010041, 0x79da68, 0xa010042, 0x79deeb, 0xa010043, 0x79ea97,
0xa010044, 0x79eea4, 0xa010045, 0x7a2cdf, 0xa010046, 0x7a2e2b, 0xa010047, 0x7a2eef,
0xa010048, 0x7a2f6f, 0xa010049, 0x7a306b, 0xa01004a, 0x7a3772, 0xa01004b, 0x7a3a3d,
0xa01004c, 0x7a3aaf, 0xa01004d, 0x7a3b93, 0xa01004e, 0x7a3bfb, 0xa01004f, 0x7a3cbc,
0xa010050, 0x7a3d20, 0xa010051, 0x7a3df5, 0xa010052, 0x7a3e9d, 0xa010053, 0x7a5018,
0xa010054, 0x7a51d6, 0xa010055, 0x7a52c8, 0xa010056, 0x7a548e, 0xa010057, 0x7a5bd3,
0xa010058, 0x7a5d74, 0xa010059, 0x7a5f0c, 0xa01005a, 0x7a605c, 0xa01005b, 0x7a60fa,
0xa01005c, 0x7a627f, 0xa01005d, 0x7a636f, 0xa01005e, 0x7a6953, 0xa01005f, 0x7a6a8d,
0xa010060, 0x7a6bc0, 0xa010061, 0x7a6c6f, 0xa010062, 0x7a6ccb, 0xa010063, 0x7a6ee6,
0xa010064, 0x7a7086, 0xa010065, 0x7a72ea, 0xa010066, 0x7a74fa, 0xa010067, 0x7a76fc,
0xa010068, 0x7a784c, 0xa010069, 0x7a7a60, 0xa01006a, 0x7a7baa, 0xa01006b, 0x7a7c20,
0xa01006c, 0x7a7c94, 0xa01006d, 0x7a7db5, 0xa01006e, 0x7a7df9, 0xa01006f, 0x7a7e43,
0xa010070, 0x7a7f1c, 0xa010071, 0x7a887c, 0xa010072, 0x7aa2b1, 0xa010073, 0x7aa401,
0xa010074, 0x7aa7e8, 0xa010075, 0x7aa961, 0xa010076, 0x7aaa3c, 0xa010077, 0x7aade0,
0xa010078, 0x7aae1a, 0xa010079, 0x7ab0ab, 0xa01007a, 0x7b8bc2, 0xa01007b, 0x7b8c75,
0xa01007c, 0x7bb79e]
vmp_fun_idtomethod_id = [0xA020000,0x567960,0xA020001,0x56BB4C,0xA020002,0x56C039,0xA020003,0x57FC9F,0xA020004,0x57FD18,0xA020005,0x581D21]
"""
由于APP加固把vmp的dex code作为附加数据段附加值dex文件的尾部,不能被正常加载,且vmp的附加数据中dex code header被修改,code部分也没有对齐,需要恢复时我们需要把code恢复到code段,并且
每段code要对齐,然后需要把MAP段重新放到增加了code的code段后面,就涉及到MAP段在header中的offset修正,以及MAP段中MAP段中的定义。由于增加了code段数据,所以header中uint data_size 需要把
新增加的code长度加上,header中的文件大小也需要修正,最好包括check值。
Name Start End R W X D L Align Base Type Class AD ds
HEADER 00000000 00000070 ? ? ? . L byte 0002 public DATA 32 0002
STR_IDS 00000070 00034670 ? ? ? . L byte 0003 public DATA 32 0003
TYPES 00034670 0003D030 ? ? ? . L byte 0004 public DATA 32 0004
PROTO 0003D030 0005E780 ? ? ? . L byte 0005 public DATA 32 0005
FIELDS 0005E780 000DE760 ? ? ? . L byte 0006 public DATA 32 0006
METHODS 000DE760 00151000 ? ? ? . L byte 0007 public DATA 32 0007
CLASS_DEF 00151000 001842A0 ? ? ? . L byte 0008 public DATA 32 0008
STRINGS 001842A0 002EAE18 ? ? ? . L byte 000A public DATA 32 000A
CODE 002EAE18 00769088 ? ? ? . L byte 0001 public CODE 32 0001
MAP 00769088 00769164 ? ? ? . L byte 0009 public DATA 32 0009
"""
vmp_dex_filename = r"AndroidNativeEm/samples/appjiagu/data/classes_vmp.dex"
vmp_dex1_filename = r"AndroidNativeEm/samples/appjiagu/data/classes1_vmp.dex"
vmp_dex1_filename = r"AndroidNativeEm/samples/appjiagu/data/classes2_vmp.dex"
vm_data = codecs.open(vmp_dex1_filename, "rb")
vmp_data_buff = vm_data.read()
"""
这段代码是vmp的opcode与原始opcode的对应关系映射表的构造算法,我们利用这段代码直接构造出一个vmp opcode与原始opcode对应的映射表
.text:CBFE9CE2 ; ---------------------------------------------------------------------------
.text:CBFE9CE2
.text:CBFE9CE2 loc_CBFE9CE2 ; CODE XREF: sub_CBFE96A8+62E↑j
.text:CBFE9CE2 ; sub_CBFE96A8+634↑j ...
.text:CBFE9CE2 28 68 LDR R0, [R5] ; 原始opcode
.text:CBFE9CE4 19 68 LDR R1, [R3] ; vmp 执行代码表基地址
.text:CBFE9CE6 80 00 LSLS R0, R0, #2
.text:CBFE9CE8 09 18 ADDS R1, R1, R0
.text:CBFE9CEA 09 68 LDR R1, [R1] ; 获取vmp执行代码地址值
.text:CBFE9CEC 32 69 LDR R2, [R6,#0x10] ; 方法表基地址
.text:CBFE9CEE 10 18 ADDS R0, R2, R0
.text:CBFE9CF0 00 6B LDR R0, [R0,#0x30] ; method_ID
.text:CBFE9CF2 22 68 LDR R2, [R4] ; vmp opcode映射表基地址
.text:CBFE9CF4 80 00 LSLS R0, R0, #2
.text:CBFE9CF6 10 18 ADDS R0, R2, R0
.text:CBFE9CF8 01 60 STR R1, [R0] ; 写映射表
修改如下:
.text:CBFE9CEA 29 68 LDR R1, [R5] ;获取原始opcode 写入到表中,后面查询到的就是原始opcode了
获得的数据如下:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 AA 00 00 00 C9 00 00 00 09 00 00 00 6C 00 00 00 ª É l
00000010 E5 00 00 00 11 00 00 00 9C 00 00 00 77 00 00 00 å œ w
00000020 C3 00 00 00 07 00 00 00 56 00 00 00 5D 00 00 00 Ã V ]
00000030 81 00 00 00 04 00 00 00 59 00 00 00 B0 00 00 00 Y °
00000040 3D 00 00 00 DF 00 00 00 60 00 00 00 2C 00 00 00 = ß ` ,
00000050 67 00 00 00 E0 00 00 00 44 00 00 00 19 00 00 00 g à D
00000060 E7 00 00 00 A2 00 00 00 B7 00 00 00 52 00 00 00 ç ¢ · R
00000070 12 00 00 00 2B 00 00 00 7D 00 00 00 3A 00 00 00 + } :
00000080 E9 00 00 00 05 00 00 00 F5 00 00 00 10 00 00 00 é õ
00000090 7C 00 00 00 FF 00 00 00 42 00 00 00 01 00 00 00 | ÿ B
000000A0 16 00 00 00 46 00 00 00 B8 00 00 00 1D 00 00 00 F ¸
000000B0 AB 00 00 00 8F 00 00 00 0B 00 00 00 32 00 00 00 « 2
000000C0 D2 00 00 00 8E 00 00 00 A4 00 00 00 53 00 00 00 Ò Ž ¤ S
000000D0 87 00 00 00 4F 00 00 00 25 00 00 00 DB 00 00 00 ‡ O % Û
000000E0 9E 00 00 00 EA 00 00 00 F1 00 00 00 57 00 00 00 ž ê ñ W
000000F0 90 00 00 00 E8 00 00 00 D3 00 00 00 6D 00 00 00 è Ó m
00000100 68 00 00 00 99 00 00 00 0C 00 00 00 C5 00 00 00 h ™ Å
00000110 79 00 00 00 CF 00 00 00 6A 00 00 00 70 00 00 00 y Ï j p
00000120 C7 00 00 00 B1 00 00 00 D8 00 00 00 BD 00 00 00 Ç ± Ø ½
00000130 FB 00 00 00 A5 00 00 00 9D 00 00 00 41 00 00 00 û ¥ A
00000140 B4 00 00 00 AE 00 00 00 3C 00 00 00 82 00 00 00 ´ ® < ‚
00000150 6E 00 00 00 A3 00 00 00 6F 00 00 00 00 00 00 00 n £ o
00000160 E6 00 00 00 47 00 00 00 E4 00 00 00 BE 00 00 00 æ G ä ¾
00000170 02 00 00 00 E1 00 00 00 9B 00 00 00 5F 00 00 00 á › _
00000180 B9 00 00 00 0D 00 00 00 17 00 00 00 48 00 00 00 ¹ H
00000190 D5 00 00 00 9F 00 00 00 0A 00 00 00 AC 00 00 00 Õ Ÿ ¬
000001A0 76 00 00 00 1E 00 00 00 72 00 00 00 4A 00 00 00 v r J
000001B0 C1 00 00 00 F2 00 00 00 CB 00 00 00 1A 00 00 00 Á ò Ë
000001C0 23 00 00 00 7A 00 00 00 DE 00 00 00 F0 00 00 00 # z Þ ð
000001D0 85 00 00 00 89 00 00 00 28 00 00 00 71 00 00 00 … ‰ ( q
000001E0 5B 00 00 00 97 00 00 00 26 00 00 00 B3 00 00 00 [ — & ³
000001F0 30 00 00 00 92 00 00 00 4D 00 00 00 C4 00 00 00 0 ’ M Ä
00000200 F9 00 00 00 65 00 00 00 98 00 00 00 73 00 00 00 ù e ˜ s
00000210 DC 00 00 00 5A 00 00 00 14 00 00 00 7B 00 00 00 Ü Z {
00000220 40 00 00 00 3E 00 00 00 C6 00 00 00 22 00 00 00 @ > Æ "
00000230 29 00 00 00 BC 00 00 00 FC 00 00 00 49 00 00 00 ) ¼ ü I
00000240 F8 00 00 00 83 00 00 00 EC 00 00 00 21 00 00 00 ø ƒ ì !
00000250 FA 00 00 00 B2 00 00 00 BB 00 00 00 36 00 00 00 ú ² » 6
00000260 94 00 00 00 1F 00 00 00 7F 00 00 00 A8 00 00 00 ” ¨
00000270 50 00 00 00 91 00 00 00 5C 00 00 00 3B 00 00 00 P ‘ ;
00000280 DA 00 00 00 C8 00 00 00 18 00 00 00 08 00 00 00 Ú È
00000290 AF 00 00 00 2F 00 00 00 1C 00 00 00 55 00 00 00 ¯ / U
000002A0 62 00 00 00 35 00 00 00 63 00 00 00 33 00 00 00 b 5 c 3
000002B0 E3 00 00 00 64 00 00 00 EE 00 00 00 CE 00 00 00 ã d î Î
000002C0 0E 00 00 00 2D 00 00 00 8A 00 00 00 88 00 00 00 - Š ˆ
000002D0 A7 00 00 00 95 00 00 00 B5 00 00 00 38 00 00 00 § • µ 8
000002E0 4C 00 00 00 69 00 00 00 5E 00 00 00 54 00 00 00 L i ^ T
000002F0 34 00 00 00 6B 00 00 00 43 00 00 00 75 00 00 00 4 k C u
00000300 B6 00 00 00 2A 00 00 00 F6 00 00 00 93 00 00 00 ¶ * ö “
00000310 66 00 00 00 3F 00 00 00 8C 00 00 00 A0 00 00 00 f ? Œ
00000320 D6 00 00 00 D9 00 00 00 96 00 00 00 D0 00 00 00 Ö Ù – Ð
00000330 20 00 00 00 ED 00 00 00 EB 00 00 00 CA 00 00 00 í ë Ê
00000340 A1 00 00 00 BA 00 00 00 61 00 00 00 45 00 00 00 ¡ º a E
00000350 39 00 00 00 78 00 00 00 74 00 00 00 37 00 00 00 9 x t 7
00000360 FD 00 00 00 F7 00 00 00 CD 00 00 00 F3 00 00 00 ý ÷ Í ó
00000370 24 00 00 00 0F 00 00 00 4E 00 00 00 FE 00 00 00 $ N þ
00000380 AD 00 00 00 CC 00 00 00 C2 00 00 00 1B 00 00 00 Ì Â
00000390 E2 00 00 00 F4 00 00 00 84 00 00 00 80 00 00 00 â ô „ €
000003A0 27 00 00 00 58 00 00 00 06 00 00 00 EF 00 00 00 ' X ï
000003B0 13 00 00 00 7E 00 00 00 2E 00 00 00 15 00 00 00 ~ .
000003C0 03 00 00 00 8B 00 00 00 A6 00 00 00 8D 00 00 00 ‹ ¦
000003D0 9A 00 00 00 D4 00 00 00 D7 00 00 00 4B 00 00 00 š Ô × K
000003E0 A9 00 00 00 BF 00 00 00 D1 00 00 00 51 00 00 00 © ¿ Ñ Q
000003F0 31 00 00 00 C0 00 00 00 86 00 00 00 DD 00 00 00 1 À † Ý
"""
# opcode 映射表
opcode_v_opcode_table = codecs.open(r"AndroidNativeEm/samples/appjiagu/data/vmp_opcode_table", "rb")
# 把MAP段前的数据都读进来
# uint map_off 8138768 34h 4h Fg: Bg: File offset of map list map address
data_ptr = ReadFile(vm_data,0x34,4)
map_list_size = ReadFile(vm_data,data_ptr,4)
code_ptr = data_ptr
magic_begin = data_ptr + (map_list_size * 0xC) +4
# dex_data = list(vm_data.read(data_ptr))
dex_data = list(ReadFile(vm_data,0,data_ptr,1))
# vmp 数据开始地址
# magic = int.from_bytes((vmp_data_buff[magic_begin:(magic_begin+4)]), byteorder="little", signed=False)
magic_data =bytearray.fromhex("42443035323726")
magic = vmp_data_buff[magic_begin:(magic_begin+7)]
while magic != magic_data:
magic_begin += 1
magic = vmp_data_buff[magic_begin:(magic_begin+7)]
begin_addr = magic_begin + 0x2C
# 由于附加数据里面的vmp没有对齐,所以长度不正确,所以需要查询这个索引,才能确保正确的vmp dex数据
# vmp_methon_id = 0xA000000
vmp_fun_id = ReadFile(vm_data, begin_addr, 4)
vmp_len = ReadFile(vm_data,(magic_begin + 0x1A),2)
for i in range(vmp_len):
# 先读取vmp dex code 长度
code_len = ReadFile(vm_data, (begin_addr + 0x14), 2)
if code_len > 0x13:
# 如果code 长度大于 vmp代理入口函数长度就在code段后面增加这个Method code,恢复代码后需要修正Method 索引中的offset
for j in range(2):
# 先读取vmp dex Method 头的前2个字节
data_head = ReadFile(vm_data,(begin_addr + 6 + j),1)
dex_data.append(data_head)
# 由于APP加固把Method 的header 进行了重新拼装,所以需要重新修正
for j in range(6):
# 先读取vmp dex Method 头的前6个字节
data_head = ReadFile(vm_data,(begin_addr + 0xE + j),1)
dex_data.append(data_head)
index_fun = vmp_fun_idtomethod_id.index(vmp_fun_id) + 1
method_fun = vmp_fun_idtomethod_id[index_fun]
print(hex(method_fun))
vmp_fun_ep = ReadFile(vm_data, method_fun, 4, 1)
# 修正Method fun offset
new_offset = Get_uleb128(code_ptr,1)
for j in range(4):
dex_data[method_fun + j] = new_offset[j]
# 获取vmp 代理入口函数地址
ep_addr = Get_uleb128(vmp_fun_ep, 2)
# 获取debug info address 写入到新的code中
for j in range(4):
debug_info = ReadFile(vm_data, (ep_addr + 8 + j), 1)
dex_data.append(debug_info)
# 把vmp Method header 中code length写入新code中
for j in range(2):
len_dat = ReadFile(vm_data, (begin_addr + 0x14 + j), 1)
dex_data.append(len_dat)
# 四个字节对齐
for j in range(2):
dex_data.append(0)
vmp_code_addr = begin_addr + 0x16 # code 地址
# Method header 中的code length 是按双字节计算的,所以需要乘以2
code_len = code_len * 2
code_ptr += code_len +0x10
while code_len > 0:
vmp_opcode = ReadFile(vm_data, vmp_code_addr, 1)
index_opcode = vmp_opcode * 4
opcode = ReadFile(opcode_v_opcode_table, index_opcode, 1)
# 写入新的code中
dex_data.append(opcode)
# 获取这个opcode 的指令长度,然后减去opcode一个字节
opcode_len = opcode_Length[opcode] - 1
code_length = opcode_Length[opcode]
# 把code 指令写到新的code中
for k in range(opcode_len):
data_code = ReadFile(vm_data, (vmp_code_addr + 1 + k), 1)
dex_data.append(data_code)
vmp_code_addr += code_length
code_len -= code_length
print("vmp_opcode:", hex(vmp_opcode))
print("opcode:", hex(opcode))
# 写两个字节0结束符,防止小于vmp 代理入口函数时没有结束标记问题
for k in range(2):
dex_data.append(0)
code_ptr += 2
begin_addr = vmp_code_addr + code_length
else:
# 如果小于等于vmp代理入口长度,就写回到这个代理入口地址,且不需要修正Method 索引的offset
index_fun = vmp_fun_idtomethod_id.index(vmp_fun_id) + 1
method_fun = vmp_fun_idtomethod_id[index_fun]
vmp_fun_ep =ReadFile(vm_data, method_fun, 4,1)
# 获取vmp 代理入口函数地址
ep_addr = Get_uleb128(vmp_fun_ep, 2)
for j in range(2):
# 先读取vmp dex Method 头的前2个字节
data_head = ReadFile(vm_data,(begin_addr + 6 + j),1)
dex_data[ep_addr+j] = data_head
# 由于APP加固把Method 的header 进行了重新拼装,所以需要重新修正
for j in range(6):
# 先读取vmp dex Method 头的前6个字节
data_head = ReadFile(vm_data, (begin_addr + 0xE + j), 1)
dex_data[ep_addr + j + 2] = data_head
# 保存原debug info
# 写入code 长度
for j in range(2):
data_head = ReadFile(vm_data, (begin_addr + 0x14 + j), 1)
dex_data[ep_addr + 0x12 +j] = data_head
code_addr = begin_addr + 0x16 # code 地址
code_old_addr = ep_addr + 0x10
# Method header 中的code length 是按双字节计算的,所以需要乘以2
code_len = code_len * 2
while code_len > 0:
vmp_opcode = ReadFile(vm_data, code_addr, 1)
index_opcode = vmp_opcode * 4
opcode = ReadFile(opcode_v_opcode_table, index_opcode, 1)
dex_data[code_old_addr] = opcode
# 获取这个opcode 的指令长度,然后减去opcode一个字节
opcode_len = opcode_Length[opcode] - 1
code_length = opcode_Length[opcode]
# 把code 指令写到原始的地方
for k in range(opcode_len):
data_code = ReadFile(vm_data, (code_addr + 1 + k), 1)
dex_data[code_old_addr+ 1 + k] = data_code
code_old_addr = code_old_addr + code_length
code_addr += code_length
code_len -= code_length
print("vmp_opcode:", hex(vmp_opcode))
print("opcode:", hex(opcode))
# 写两个字节0结束符,防止小于vmp 代理入口函数时没有结束标记问题
for k in range(2):
dex_data[code_old_addr] = 0
begin_addr = code_addr + code_length
vmp_fun_id_n = vmp_fun_id + 1
vmp_fun_id = ReadFile(vm_data, begin_addr, 4)
vmp_fun_end = vmp_fun_id_n % 0x100
if vmp_fun_end > (vmp_len-1):
break
while vmp_fun_id != vmp_fun_id_n:
begin_addr += 1
vmp_fun_id = ReadFile(vm_data, begin_addr, 4)
# data = bytearray(dex_data)
map_data = list(ReadFile(vm_data,data_ptr,0xd8,1))
for i in range(len(map_data)):
dex_data.append(map_data[i])
# dex_data.append(map_data)
# 修正MAP段属性
# 修正header中MAP段offset
new_code_len = code_ptr - data_ptr
data_size = ReadFile(vm_data,0x68,4) + new_code_len
data_size_new = data_size.to_bytes(4, byteorder="little", signed=False)
for i in range(4):
dex_data[0x68 + i] = data_size_new[i]
map_offset = code_ptr.to_bytes(4, byteorder="little", signed=False)
for i in range(4):
dex_data.append(map_offset[i])
dex_data[0x34 + i] = map_offset[i]
# 修正header 中文件大小
file_size = len(dex_data)
file_size_new = file_size.to_bytes(4,byteorder="little", signed=False)
for i in range(4):
dex_data[0x20 + i] = file_size_new[i]
data = bytearray(dex_data)
bak_filename = r"AndroidNativeEm/samples/appjiagu/data/classes2_vmp_new.dex"
f = open(bak_filename,"wb")
if f:
f.write(data)
f.close()
if __name__ == '__main__':
main()
看雪ID:fxyang
https://bbs.kanxue.com/user-home-981.htm
# 往期推荐
3、阿里云CTF2024-暴力ENOTYOURWORLD题解
球分享
球点赞
球在看
点击阅读原文查看更多
原文始发于微信公众号(看雪学苑):APP加固系统分析心得