目錄: 一、電商類APP業務風險類型 二、設備指紋在業務中的應用 三、整體框架 四、初始化流程分析 五、反爬蟲mtgsig簽名 六、設備指紋分析 七、設備指紋攻擊 八、黑產工具特征檢測 九、總結
一、電商類APP業務風險類型
電商行業的各個業務場景面臨不同的風險種類:客戶端漏洞利用、協議逆向、注冊小號、商品信息被抓取、推廣渠道作弊、營銷活動被薅羊毛、商品秒殺等。
大多的防御方案是通過端上安全、鏈路安全、接口和數據傳輸安全保護,再借助設備安全核驗技術、人機識別及時發現各種模擬行為和異操作風險、同時集合風控策略實現多節點防護。
二、設備指紋在業務中的應用
設備指紋技術是使用更多的信息來完成對終端設備的唯一性識別,在業務中可以有效辨別設備是真實用戶還是機器在注冊、登錄,及時檢測出單設備登入多帳號、防止批量注冊、登錄等操作行為。
三、整體框架
因為框架流程過於復雜,我將框架分為兩個部分,一是初始化,二是設備指紋,這樣會更清楚些,如圖3-1與3-2所示:
圖3-1
圖3-2
四、初始化流程分析
4.1、初始化准備
java層調用init()初始化,獲取Context,包名,AppInfo,XML配置信息等,然后加載so libmtguard.so 在so中注冊一個Native方法,該Native方法傳入不同的數字代表不同的功能,代碼如下所示:
Lcom/meituan/android/common/mtguard/MTGuard;->loadSo(Ljava/lang/String;)V System.loadLibrary("mtguard"); //注冊Native方法 private static native Object[] main(int arg0, Object[] arg1)//arg0:傳入不同的編號走不同的邏輯,arg1:參數
4.2、系統環境檢測
調用Native層Object[] v12_2 = NBridge.main3(1, new Object[1]),傳入參數為1,表示檢測環境, 檢測系統目錄中是否有ls文件且是否為elf格式:
.text:B1BF744E 01 26 MOVS R6, #1 .text:B1BF7450 2E 70 STRB R6, [R5] .text:B1BF7452 20 48 LDR R0, =(aSystemBinLs - 0xB1BF7458) ; "/system/bin/ls" .text:B1BF7454 78 44 ADD R0, PC ; "/system/bin/ls" ; file .text:B1BF7456 00 25 MOVS R5, #0 .text:B1BF7458 29 00 MOVS R1, R5 ; oflag .text:B1BF745A CF F7 A0 EC BLX open .text:B1BF745E 04 00 MOVS R4, R0 .text:B1BF7460 00 2C CMP R4, #0 .text:B1BF7462 25 DB BLT loc_B1BF74B0 .text:B1BF7464 01 AD ADD R5, SP, #0x28+buf .text:B1BF7466 14 22 MOVS R2, #0x14 ; nbytes .text:B1BF7468 20 00 MOVS R0, R4 ; fd .text:B1BF746A 29 00 MOVS R1, R5 ; buf .text:B1BF746C CF F7 10 EE BLX read .text:B1BF7470 14 28 CMP R0, #0x14 .text:B1BF7472 18 D1 BNE loc_B1BF74A6 .text:B1BF7474 28 78 LDRB R0, [R5] .text:B1BF7476 7F 28 CMP R0, #0x7F .text:B1BF7478 15 D1 BNE loc_B1BF74A6 .text:B1BF747A 01 A8 ADD R0, SP, #0x28+buf .text:B1BF747C 40 78 LDRB R0, [R0,#1] .text:B1BF747E 45 28 CMP R0, #0x45 ; 'E' .text:B1BF7480 11 D1 BNE loc_B1BF74A6 .text:B1BF7482 01 A8 ADD R0, SP, #0x28+buf .text:B1BF7484 80 78 LDRB R0, [R0,#2] .text:B1BF7486 4C 28 CMP R0, #0x4C ; 'L' .text:B1BF7488 0D D1 BNE loc_B1BF74A6 .text:B1BF748A 01 A8 ADD R0, SP, #0x28+buf .text:B1BF748C C0 78 LDRB R0, [R0,#3] .text:B1BF748E 46 28 CMP R0, #0x46 ; 'F' .text:B1BF7490 09 D1 BNE loc_B1BF74A6 .text:B1BF7492 01 A8 ADD R0, SP, #0x28+buf .text:B1BF7494 80 7C LDRB R0, [R0,#0x12] .text:B1BF7496 3E 28 CMP R0, #0x3E ; '>' .text:B1BF7498 01 D0 BEQ loc_B1BF749E .text:B1BF749A 03 28 CMP R0, #3 .text:B1BF749C 03 D1 BNE loc_B1BF74A6 .text:B1BF749E .text:B1BF749E loc_B1BF749E .text:B1BF749E 20 00 MOVS R0, R4 ; fd .text:B1BF74A0 CF F7 88 EC BLX close
檢測root:
//檢測root 直接用svc指令,防止hook .text:BB9F5444 ;faccessat .text:BB9F5444 F0 B5 PUSH {R4-R7,LR} .text:BB9F5446 03 AF ADD R7, SP, #0xC .text:BB9F5448 0B 00 MOVS R3, R1 .text:BB9F544A 04 00 MOVS R4, R0 .text:BB9F544C 63 20 MOVS R0, #0x63 ; 'c' .text:BB9F544E C5 43 MVNS R5, R0 .text:BB9F5450 A7 20 MOVS R0, #0xA7 .text:BB9F5452 46 00 LSLS R6, R0, #1 .text:BB9F5454 28 46 MOV R0, R5 .text:BB9F5456 21 46 MOV R1, R4 .text:BB9F5458 1A 46 MOV R2, R3 .text:BB9F545A 37 46 MOV R7, R6 .text:BB9F545C 00 DF SVC 0 .text:BB9F545E 03 46 MOV R3, R0 .text:BB9F5460 18 00 MOVS R0, R3 .text:BB9F5462 F0 BD POP {R4-R7,PC} //檢測文件特征 /system/bin/su /system/bin/360s /system/xbin/krdem /system/xbin/ku.sud /system/xbin/ksud /system/bin/.usr/.ku /system/xbin/ku.sud.tmp /system/bin/ddexe_real /system/bin/.krsh /system/bin/.suv /system/bin/debuggerd-ku.bak /system/xbin/kugote /system/xbin/kugote /system/usr/ikm/ikmsu /system/etc/kds /system/xbin/start_kusud.sh /system/bin/ddexe-tcs.bak //檢測結果 1|2|3|32 //字符串的編號
檢測XPOSED、代理、ROM是否為自己編譯的
//檢測
de.robv.android.xposed.XposedBridge
//檢測代理
http.proxyHost
https.proxyHost
getProperty
檢測關鍵方法是否被hook
//檢測方法是否被hook 傳入方法首地址進行對比 0x780x5F 0xF8DF //如果檢測到第一個方法被hook,結果如下 1| 如果檢測到第2個方法被hook,結果如下 1|2| 如果檢測到第3個方法被hook,結果如下 1|2|3|
其它檢測,代碼如下:
boolean v2 = MTGuard.isEmu(); boolean v3 = MTGuard.isRoot(); boolean v4 = MTGuard.hasMalware(); boolean v5 = MTGuard.isDarkSystem(); boolean v6 = MTGuard.isVirtualLocation(); boolean v7 = MTGuard.isRemoteCall(); boolean v8 = MTGuard.isSigCheckOK(); boolean v11 = MTGuard.inSandBox(); boolean v13 = MTGuard.isHook(); boolean v14 = MTGuard.isDebug(); boolean v15 = MTGuard.isProxy(); boolean v16 = MTGuard.isCameraHack(); 最終都會走到Native方法中去 private static native Object[] main(int arg0, Object[] arg1);
4.3、讀取資源文件並解密
4.3.1、讀文件META-INF/SANKUAI.RSA計算MD5
代碼如下:
.text:B65E1FE4 F0 B5 PUSH {R4-R7,LR} .text:B65E1FE6 03 AF ADD R7, SP, #0xC .text:B65E1FE8 8F B0 SUB SP, SP, #0x3C .text:B65E1FEA 0E 00 MOVS R6, R1 .text:B65E1FEC 2D 49 LDR R1, =(__stack_chk_guard_ptr - 0xB65E1FF2) .text:B65E1FEE 79 44 ADD R1, PC ; __stack_chk_guard_ptr .text:B65E1FF0 0C 68 LDR R4, [R1] ; __stack_chk_guard .text:B65E1FF2 21 68 LDR R1, [R4] .text:B65E1FF4 0E 91 STR R1, [SP,#0x48+var_10] .text:B65E1FF6 0A 21 MOVS R1, #0xA .text:B65E1FF8 CA 43 MVNS R2, R1 .text:B65E1FFA 01 68 LDR R1, [R0] ; file .text:B65E1FFC 48 1E SUBS R0, R1, #1 .text:B65E1FFE 82 58 LDR R2, [R0,R2] .text:B65E2000 00 25 MOVS R5, #0 .text:B65E2002 E8 43 MVNS R0, R5 .text:B65E2004 00 2A CMP R2, #0 .text:B65E2006 43 D0 BEQ loc_B65E2090 .text:B65E2008 00 25 MOVS R5, #0 .text:B65E200A 05 95 STR R5, [SP,#0x48+var_34] .text:B65E200C 04 90 STR R0, [SP,#0x48+var_38] .text:B65E200E 06 90 STR R0, [SP,#0x48+var_30] .text:B65E2010 07 95 STR R5, [SP,#0x48+var_2C] .text:B65E2012 08 90 STR R0, [SP,#0x48+var_28] .text:B65E2014 0C 90 STR R0, [SP,#0x48+var_18] .text:B65E2016 0D 95 STR R5, [SP,#0x48+var_14] .text:B65E2018 E8 43 MVNS R0, R5 .text:B65E201A 0B 90 STR R0, [SP,#0x48+var_1C] .text:B65E201C 0A 90 STR R0, [SP,#0x48+var_20] .text:B65E201E 04 A8 ADD R0, SP, #0x48+var_38 ; int .text:B65E2020 0D F0 40 FF BL openfile_sub_C6BADEA4 ; R3:要讀取的文件 .text:B65E2024 01 30 ADDS R0, #1 .text:B65E2026 30 D0 BEQ loc_B65E208A .text:B65E2028 02 96 STR R6, [SP,#0x48+var_40] .text:B65E202A 04 A8 ADD R0, SP, #0x48+var_38 .text:B65E202C 1E 49 LDR R1, =(sub_B65E20AC+1 - 0xB65E2032) .text:B65E202E 79 44 ADD R1, PC ; sub_B65E20AC .text:B65E2030 0E F0 C8 F9 BL size_sub_C6BAE3C4 .text:B65E2034 06 00 MOVS R6, R0 .text:B65E2036 00 2E CMP R6, #0 .text:B65E2038 27 D0 BEQ loc_B65E208A .text:B65E203A 00 25 MOVS R5, #0 .text:B65E203C 03 95 STR R5, [SP,#0x48+byte_count] .text:B65E203E 04 A8 ADD R0, SP, #0x48+var_38 .text:B65E2040 03 AA ADD R2, SP, #0x48+byte_count .text:B65E2042 31 00 MOVS R1, R6 .text:B65E2044 0E F0 2E FB BL read_sub_C6BAE6A4 .text:B65E2048 03 99 LDR R1, [SP,#0x48+byte_count] .text:B65E204A 00 29 CMP R1, #0 .text:B65E204C 1D D0 BEQ loc_B65E208A .text:B65E204E 00 28 CMP R0, #0 .text:B65E2050 1B D0 BEQ loc_B65E208A .text:B65E2052 08 00 MOVS R0, R1 ; byte_count .text:B65E2054 01 91 STR R1, [SP,#0x48+var_44] .text:B65E2056 EF F7 48 EE BLX malloc ; 分配存放空間 .text:B65E205A 02 00 MOVS R2, R0 .text:B65E205C 00 28 CMP R0, #0 .text:B65E205E 14 D0 BEQ loc_B65E208A .text:B65E2060 00 21 MOVS R1, #0 .text:B65E2062 15 00 MOVS R5, R2 .text:B65E2064 28 00 MOVS R0, R5 .text:B65E2066 01 9A LDR R2, [SP,#0x48+var_44] .text:B65E2068 16 F0 2A FA BL memset_sub_C6BB64C0 .text:B65E206C 04 A8 ADD R0, SP, #0x48+var_38 .text:B65E206E 31 00 MOVS R1, R6 .text:B65E2070 2A 00 MOVS R2, R5 .text:B65E2072 0E F0 6B FB BL ReadFile_unzip_sub_C6BAE74C ; 讀取並解壓 .text:B65E2076 00 28 CMP R0, #0 .text:B65E2078 03 D0 BEQ loc_B65E2082 .text:B65E207A 03 98 LDR R0, [SP,#0x48+byte_count] .text:B65E207C 02 99 LDR R1, [SP,#0x48+var_40] .text:B65E207E 08 60 STR R0, [R1]
讀取的數據與APk包中的內容是一樣的。
B3C7B000 30 82 03 F5 06 09 2A 86 48 86 F7 0D 01 07 02 A0 0.......H....... B3C7B010 82 03 E6 30 82 03 E2 02 01 01 31 0F 30 0D 06 09 ..........1.0... B3C7B020 60 86 48 01 65 03 04 02 01 05 00 30 0B 06 09 2A `.H.e......0...* B3C7B030 86 48 86 F7 0D 01 07 01 A0 82 02 83 30 82 02 7F .H..........0... B3C7B040 30 82 01 E8 A0 03 02 01 02 02 04 4D 69 1B B8 30 0..........Mi..0 B3C7B050 0D 06 09 2A 86 48 86 F7 0D 01 01 05 05 00 30 81 ...*.H........0. B3C7B060 82 31 0B 30 09 06 03 55 04 06 13 02 43 4E 31 10 .1.0...U....CN1. B3C7B070 30 0E 06 03 55 04 08 13 07 42 65 69 6A 69 6E 67 0...U....Beijing B3C7B080 31 10 30 0E 06 03 55 04 07 13 07 42 65 69 6A 69 1.0...U....Beiji B3C7B090 6E 67 31 24 30 22 06 03 55 04 0A 13 1B 53 61 6E ng1$0"..U....San B3C7B0A0 6B 75 61 69 20 54 65 63 68 6E 6F 6C 6F 67 79 20 kuai Technology B3C7B0B0 43 6F 2E 20 4C 74 64 2E 31 14 30 12 06 03 55 04 Co. Ltd.1.0...U. B3C7B0C0 0B 13 0B 6D 65 69 74 75 61 6E 2E 63 6F 6D 31 13 ...meituan.com1.
檢測是否為RSA文件:
.text:B65EFCBC isRSA_sub_CB471CBC .text:B65EFCBC ; __unwind { // FDA46000 .text:B65EFCBC D0 B5 PUSH {R4,R6,R7,LR} .text:B65EFCBE 02 AF ADD R7, SP, #8 .text:B65EFCC0 01 00 MOVS R1, R0 .text:B65EFCC2 00 20 MOVS R0, #0 .text:B65EFCC4 00 29 CMP R1, #0 .text:B65EFCC6 1B D0 BEQ locret_B65EFD00 .text:B65EFCC8 0A 78 LDRB R2, [R1] .text:B65EFCCA 30 2A CMP R2, #0x30 ; '0' .text:B65EFCCC 18 D1 BNE locret_B65EFD00 .text:B65EFCCE 01 22 MOVS R2, #1 .text:B65EFCD0 8C 56 LDRSB R4, [R1,R2] .text:B65EFCD2 7F 22 MOVS R2, #0x7F .text:B65EFCD4 22 40 ANDS R2, R4 .text:B65EFCD6 FF 23 MOVS R3, #0xFF .text:B65EFCD8 23 40 ANDS R3, R4 .text:B65EFCDA 00 2C CMP R4, #0 .text:B65EFCDC 00 DB BLT loc_B65EFCE0 .text:B65EFCDE 1A 00 MOVS R2, R3 .text:B65EFCE0 .text:B65EFCE0 loc_B65EFCE0 .text:B65EFCE0 04 2A CMP R2, #4 .text:B65EFCE2 0D D8 BHI locret_B65EFD00 .text:B65EFCE4 00 2A CMP R2, #0 .text:B65EFCE6 0B D0 BEQ locret_B65EFD00 .text:B65EFCE8 02 31 ADDS R1, #2 .text:B65EFCEA D3 00 LSLS R3, R2, #3 .text:B65EFCEC 08 3B SUBS R3, #8 .text:B65EFCEE 00 20 MOVS R0, #0 .text:B65EFCF0 .text:B65EFCF0 loc_B65EFCF0 .text:B65EFCF0 0C 78 LDRB R4, [R1] .text:B65EFCF2 9C 40 LSLS R4, R3 .text:B65EFCF4 20 43 ORRS R0, R4 .text:B65EFCF6 01 3A SUBS R2, #1 .text:B65EFCF8 08 3B SUBS R3, #8 .text:B65EFCFA 01 31 ADDS R1, #1 .text:B65EFCFC 00 2A CMP R2, #0 .text:B65EFCFE F7 D1 BNE loc_B65EFCF0 .text:B65EFD00 .text:B65EFD00 locret_B65EFD00 .text:B65EFD00 D0 BD POP {R4,R6,R7,PC}
計算MD5值
int __fastcall md5_sub_C6FEF398(int a1, int a2, int a3) { int i; // r0 int v8[26]; // [sp+10h] [bp-68h] BYREF memset_sub_C6BB64C0(v8, 0, 88); v8[0] = 0; v8[1] = 0; v8[2] = 1732584193; v8[3] = -271733879; v8[4] = -1732584194; v8[5] = 271733878; sub_B65F11F4(v8, a1, a2); sub_B65F1294(v8, a3); for ( i = 0; i != 88; ++i ) *((_BYTE *)v8 + i) = 0; return _stack_chk_guard - v8[22]; }
計算后的值為:
638C81261479C2104EDE3F2518E91725
該值會作為解密資源密鑰的一部分。
4.3.2、解密assets/ms_com.sankuai.meituan
組合密鑰:
包名+常量字符(WU@TEN)+META-INF/SANKUAI.RSA(md5)
com.sankuai.meituanWU@TEN638C81261479C2104EDE3F2518E91725
將組合后的字符串加密Sha1值
.text:C1D52AA4 F0 B5 PUSH {R4-R7,LR} .text:C1D52AA6 03 AF ADD R7, SP, #0xC .text:C1D52AA8 8F B0 SUB SP, SP, #0x3C .text:C1D52AAA 15 00 MOVS R5, R2 .text:C1D52AAC 0E 00 MOVS R6, R1 .text:C1D52AAE 02 90 STR R0, [SP,#0x48+var_40] .text:C1D52AB0 1A 48 LDR R0, =(__stack_chk_guard_ptr - 0xC1D52AB6) .text:C1D52AB2 78 44 ADD R0, PC ; __stack_chk_guard_ptr .text:C1D52AB4 04 68 LDR R4, [R0] ; __stack_chk_guard .text:C1D52AB6 20 68 LDR R0, [R4] .text:C1D52AB8 0E 90 STR R0, [SP,#0x48+var_10] .text:C1D52ABA 00 2E CMP R6, #0 .text:C1D52ABC 1F D0 BEQ loc_C1D52AFE .text:C1D52ABE 00 2D CMP R5, #0 .text:C1D52AC0 1D D0 BEQ loc_C1D52AFE .text:C1D52AC2 01 94 STR R4, [SP,#0x48+var_44] .text:C1D52AC4 05 AC ADD R4, SP, #0x48+var_34 .text:C1D52AC6 21 21 MOVS R1, #0x21 ; '!' .text:C1D52AC8 20 00 MOVS R0, R4 .text:C1D52ACA F2 F7 26 E9 BLX __aeabi_memclr4 .text:C1D52ACE 30 00 MOVS R0, R6 .text:C1D52AD0 29 00 MOVS R1, R5 .text:C1D52AD2 22 00 MOVS R2, R4 .text:C1D52AD4 12 F0 8E FB BL JMP_Sha1_256_sub_C6BB01F4 ; R0:原始值,R1:大小,R2:返回值 .text:C1D52AD8 03 A8 ADD R0, SP, #0x48+var_3C .text:C1D52ADA 20 22 MOVS R2, #0x20 ; ' ' .text:C1D52ADC 21 00 MOVS R1, R4 .text:C1D52ADE 01 9C LDR R4, [SP,#0x48+var_44] .text:C1D52AE0 FF F7 72 FF BL Hex2String_sub_C6B9D9C8 ; R1:返回值,R2:大小 .text:C1D52AE4 03 98 LDR R0, [SP,#0x48+var_3C] .text:C1D52AE6 02 99 LDR R1, [SP,#0x48+var_40] .text:C1D52AE8 08 60 STR R0, [R1] .text:C1D52AEA 0D 48 LDR R0, =(off_C1DD8C48 - 0xC1D52AF0) .text:C1D52AEC 78 44 ADD R0, PC ; off_C1DD8C48 .text:C1D52AEE 00 68 LDR R0, [R0] ; dword_C1DEAADC .text:C1D52AF0 01 00 MOVS R1, R0 .text:C1D52AF2 0C 31 ADDS R1, #0xC .text:C1D52AF4 03 91 STR R1, [SP,#0x48+var_3C] .text:C1D52AF6 04 A9 ADD R1, SP, #0x48+var_38 .text:C1D52AF8 6B F0 26 FE BL free_sub_B2943748
加密后的值為:
//該值為解密assets/ms_com.sankuai.meituan的密鑰
69fe5963f3b95d9718c8d3e4f924ad9379500e9b51d80686e65347890e1748fe
讀取資源文件assets/ms_com.sankuai.meituan
int __fastcall ReadFile_unzip_sub_C6BAE74C(int *a1, int a2, int a3) { int v5; // r0 int v6; // r5 int v7; // r0 int v8; // r6 int v9; // r5 int v10; // r0 __int64 v13; // [sp+24h] [bp-28h] BYREF unsigned int v14; // [sp+30h] [bp-1Ch] BYREF int v15; // [sp+34h] [bp-18h] BYREF int v16; // [sp+38h] [bp-14h] BYREF v5 = a2 - 10000; v6 = 0; if ( a2 >= 10000 && v5 < a1[8] ) { if ( *(_DWORD *)(a1[9] + 8 * v5) ) { v6 = 0; if ( read_sub_C6BAE448(a1, a2, &v16, &v15, (int *)&v14, &v13, 0, 0) ) { v7 = mapfile_sub_C6BAE6C0(a1, a2); v8 = v7; if ( v7 ) { v9 = *(_DWORD *)(v7 + 24); if ( v14 > 0x8000 ) sub_C1D62E3C(v7, 2); if ( v16 ) { v10 = unzip_sub_C6BAE820(a3, v9, v15, v14); v6 = 0; if ( !v10 ) { LABEL_15: free_sub_CA79DF8C(v8); return v6; } } else { getvalu_sub_C87B550A(a3, v9, v15); } if ( v14 > 0x8000 ) sub_C1D62E3C(v8, 0); v6 = 1; goto LABEL_15; } } } } return v6; }
讀取后內容(部分)
BCF4A000 89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52 .PNG........IHDR BCF4A010 00 00 00 3C 00 00 00 3C 08 06 00 00 00 3A FC D9 ...<...<.....:.. BCF4A020 72 00 00 13 56 49 44 41 54 78 DA ED 5A 79 70 55 r...VIDATx..ZypU BCF4A030 D7 79 BF 42 AC C6 80 09 5E 00 DB 98 5D E0 64 92 ...B.ƀ .^...]... BCF4A040 4E 92 76 6C 37 EE 4C 26 4D 5D A7 6E DA 74 49 26 N.vl7...M].n..I& BCF4A050 53 B7 C9 8C FF 68 DC 75 9C DA 1D D7 F5 C4 4E 13 S.Ɍ .h.......... BCF4A060 63 D7 98 C5 80 36 90 90 D0 CA 62 83 84 D9 F4 F4 cט ŀ 6....b..... BCF4A070 16 BD 4D CB D3 BE 20 24 10 9B 10 12 9B 04 48 08 ..M... $......H. BCF4A080 B4 DE 5F 7F E7 DC E5 9D FB 24 40 24 B6 EB E9 F4 .........$@$....
解析解密圖片得到PIC數據
int __fastcall ParsePng_sub_CB4C8858( int *a1, unsigned int *a2, unsigned int *a3, _DWORD *a4, unsigned int data, unsigned int a6) { int *v54; // r4 void *v55; // r0 int (__fastcall *v56)(void **, int *, unsigned __int8 *, unsigned int, _DWORD *); v7 = 0; *a1 = 0; *a3 = 0; *a2 = 0; result = CRC32_sub_CB4C7D08((int *)a2, (int *)a3, a4, (unsigned __int8 *)data, a6); a4[92] = result; if ( result ) return result; v110 = a4 + 92; v9 = a4[39]; v10 = a4[38]; v135 = a4 + 39; v104 = a4 + 38; v108 = a4; v131 = a4 + 35; v148 = (void *)*a3; v11 = *a2; v12 = 0; if ( v10 <= 6 ) v12 = dword_C1DD1C40[v10]; v13 = v12 * v9; v14 = v108[27]; v15 = v108[28]; if ( v14 <= 6 ) v7 = dword_C1DD1C40[v14]; if ( v13 <= v7 * v15 ) { v18 = 0; v17 = *a3; if ( v14 <= 6 ) v18 = dword_C1DD1C40[v14]; v143 = v15 * v18; } else { v16 = 0; v17 = *a3; if ( v10 <= 6 ) v16 = dword_C1DD1C40[v10]; v143 = v9 * v16; } v19 = v11 * v17; v20 = 0; if ( v11 ) { v21 = to1028_sub_CA812FD0(v11 * v17, v11); v20 = 0; v17 = (unsigned int)v148; if ( (void *)v21 != v148 ) goto LABEL_125; if ( v19 ) { v22 = to1028_sub_CA812FD0(8 * v19, v19); v20 = 0; v17 = (unsigned int)v148; if ( v22 != 8 ) goto LABEL_125; } if ( v11 >> 3 ) { v23 = to1028_sub_CA812FD0((v11 >> 3) * v143, v11 >> 3); v17 = (unsigned int)v148; v20 = (v11 >> 3) * v143; if ( v23 != v143 ) goto LABEL_125; } } v24 = v20 + (((v11 & 7) * v143 + 7) >> 3); if ( v24 < v20 || v24 > 0xFFFFFFFA || to1028_sub_CA812FD0(v17 * (v24 + 5), v24 + 5) != v17 ) { LABEL_125: result = 92; *v110 = 92; return result; } v25 = v108; v111 = v108 + 1; v26 = (unsigned __int8 *)(data + 33); pdata = 0; v129 = 0; v119 = 0; v116 = 1; while ( 1 ) { v27 = (unsigned int)&v26[-data + 12]; if ( (unsigned int)v26 < data || v27 > a6 ) { if ( v25[7] ) goto LABEL_136; v44 = 30; goto LABEL_132; } v144 = v26; v28 = v26; v29 = _byteswap_ulong(*(_DWORD *)v26); v30 = v110; if ( v29 < 0 ) { v25 = v108; if ( v108[7] ) goto LABEL_136; v44 = 63; goto LABEL_133; } if ( v29 + v27 > a6 || (unsigned int)&v26[v29 + 12] < data ) break; v31 = v26 + 8; if ( !byte_C1DEAAB4 ) { DecString((const char *)byte_C1DE8374, aXpvn, 17, 4); v28 = v144; byte_C1DE8378 = 0; } byte_C1DEAAB4 = 1; if ( getIHDR_sub_CCBFBBC8(v28, byte_C1DE8374) ) { v32 = v29 + v129; if ( v29 + v129 < v29 ) { v43 = 95; goto LABEL_134; } v122 = v29 + v129; if ( v119 >= v32 ) { v34 = (int)pdata; } else { v33 = v29 + v129; if ( v32 <= 2 * v119 ) v33 = (3 * v32) >> 1; v119 = v33; v34 = realloc(pdata); if ( !v34 ) { v43 = 83; goto LABEL_134; } } v35 = 0; v116 = 3; if ( v29 ) { v37 = v129; do { *(_BYTE *)(v34 + v37) = *v31++; --v29; ++v37; } while ( v29 ); } v129 = v122; pdata = (unsigned __int8 *)v34; goto LABEL_50; } if ( !byte_C1DEAAB5 ) { DecString((const char *)byte_C1DE8379, aPv, 18, 4); byte_C1DE837D = 0; } v35 = 1; byte_C1DEAAB5 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8379) ) goto LABEL_50; if ( !byte_C1DEAAA8 ) { DecString((const char *)byte_C1DE8338, aSjI, 3, 4); unk_C1DE833C = 0; } byte_C1DEAAA8 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8338) ) { v36 = dec_sub_CA801FF0(v104, v31, v29); *v110 = v36; v35 = 0; v116 = 2; LABEL_67: v25 = v108; v38 = (unsigned int *)v144; if ( v36 ) goto LABEL_136; LABEL_51: if ( !v25[5] ) { v39 = gencrc_sub_CA800C08(v38); v38 = (unsigned int *)v144; if ( v39 ) { v44 = 57; LABEL_132: v30 = v110; LABEL_133: *v30 = v44; goto LABEL_136; } } if ( v35 ) goto LABEL_136; LABEL_55: v40 = *v110; goto LABEL_56; } if ( !byte_C1DEAAA9 ) { DecString((const char *)byte_C1DE833D, aPud, 4, 4); byte_C1DE8341 = 0; } byte_C1DEAAA9 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE833D) ) { v36 = sub_C1DB9080(v104, v31, v29); LABEL_66: *v110 = v36; v35 = 0; goto LABEL_67; } if ( !byte_C1DEAAAA ) { DecString((const char *)byte_C1DE8342, aGclj, 5, 4); byte_C1DE8346 = 0; } byte_C1DEAAAA = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8342) ) { v36 = sub_C1DB9100(v131, v31, v29); goto LABEL_66; } if ( !byte_C1DEAAAB ) { DecString((const char *)byte_C1DE8347, aRlt, 6, 4); byte_C1DE834B = 0; } byte_C1DEAAAB = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8347) ) { v35 = 0; if ( v108[9] ) { v36 = sub_C1DB917C((int)v131, v31, v29); LABEL_79: *v110 = v36; goto LABEL_67; } goto LABEL_50; } if ( !byte_C1DEAAAC ) { DecString((const char *)byte_C1DE834C, aUd, 7, 4); byte_C1DE8350 = 0; } byte_C1DEAAAC = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE834C) ) { v35 = 0; if ( v108[9] ) { v36 = sub_C1DB923C(v131, v111, v31, v29); goto LABEL_79; } LABEL_50: v25 = v108; v38 = (unsigned int *)v144; goto LABEL_51; } if ( !byte_C1DEAAAD ) { DecString((const char *)byte_C1DE8351, aAVe, 8, 4); byte_C1DE8355 = 0; } byte_C1DEAAAD = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8351) ) { if ( v108[9] ) { v41 = sub_C1DB936C(v131, v111, v31, v29); *v110 = v41; v25 = v108; v38 = (unsigned int *)v144; v35 = 0; if ( v41 ) goto LABEL_136; } else { v25 = v108; v38 = (unsigned int *)v144; v35 = 0; } goto LABEL_51; } if ( !byte_C1DEAAAE ) { DecString((const char *)byte_C1DE8356, aEbw, 9, 4); unk_C1DE835A = 0; } byte_C1DEAAAE = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8356) ) { if ( v29 != 7 ) { v43 = 73; LABEL_134: v30 = v110; goto LABEL_135; } v108[58] = 1; v38 = (unsigned int *)v144; v108[59] = (v144[8] << 8) | v144[9]; v108[60] = v144[10]; v108[61] = v144[11]; v108[62] = v144[12]; v108[63] = v144[13]; v108[64] = v144[14]; LABEL_92: v35 = 0; *v110 = 0; v25 = v108; goto LABEL_51; } if ( !byte_C1DEAAAF ) { DecString((const char *)byte_C1DE835B, aZei, 10, 4); unk_C1DE835F = 0; } byte_C1DEAAAF = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE835B) ) { v36 = sub_C1DB95FC(v131, (int)v31, v29); goto LABEL_66; } if ( !byte_C1DEAAB0 ) { DecString((const char *)byte_C1DE8360, aLoU, 11, 4); unk_C1DE8364 = 0; } byte_C1DEAAB0 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8360) ) { if ( v29 != 4 ) { v43 = 96; goto LABEL_134; } v108[69] = 1; v38 = (unsigned int *)v144; v108[70] = _byteswap_ulong(*((_DWORD *)v144 + 2)); goto LABEL_92; } if ( !byte_C1DEAAB1 ) { DecString((const char *)byte_C1DE8365, aOgX, 12, 4); unk_C1DE8369 = 0; } byte_C1DEAAB1 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE8365) ) { v36 = sub_C1DB9640(v131, (unsigned int *)v31, v29); goto LABEL_66; } if ( !byte_C1DEAAB2 ) { DecString((const char *)byte_C1DE836A, aBtt, 13, 4); unk_C1DE836E = 0; } byte_C1DEAAB2 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE836A) ) { if ( v29 != 1 ) { v43 = 98; goto LABEL_134; } v108[80] = 1; v108[81] = *v31; v35 = 0; *v110 = 0; goto LABEL_50; } if ( !byte_C1DEAAB3 ) { DecString((const char *)byte_C1DE836F, aGrwg, 14, 4); unk_C1DE8373 = 0; } byte_C1DEAAB3 = 1; if ( getIHDR_sub_CCBFBBC8(v144, byte_C1DE836F) ) { v36 = sub_C1DB9714(v131, v111, v31, v29); goto LABEL_66; } if ( !v108[6] && (v144[4] & 0x20) == 0 ) { v43 = 69; goto LABEL_134; } if ( !v108[10] ) { v25 = v108; v38 = (unsigned int *)v144; goto LABEL_55; } v25 = v108; v42 = sub_C1DB7CCE(&v108[v116 + 85], &v108[v116 + 88], (unsigned int *)v144); v38 = (unsigned int *)v144; *v110 = v42; v40 = 0; if ( v42 ) goto LABEL_136; LABEL_56: v26 = isPng_sub_CA800C80((unsigned __int8 *)v38); if ( v40 ) goto LABEL_136; } v43 = 64; LABEL_135: *v30 = v43; v25 = v108; LABEL_136: v154 = 0; v152 = 0; v153 = 0; v45 = v25[37]; v123 = v25 + 37; v46 = *a2; if ( v45 ) { v145 = *a3; v47 = (*a3 + 7) >> 3; v140 = sub_C1DBAC4C((v46 + 7) >> 3, v47, (unsigned int *)v104); v48 = v46 + 3; if ( v46 >= 5 ) { v49 = sub_C1DBAC4C(v48 >> 3, v47, (unsigned int *)v104) + v140; v48 = v46 + 3; v140 = v49; } v50 = sub_C1DBAC4C(v48 >> 2, (v145 + 3) >> 3, (unsigned int *)v104) + v140; v51 = v46 + 1; if ( v46 >= 3 ) { v50 += sub_C1DBAC4C(v51 >> 2, (v145 + 3) >> 2, (unsigned int *)v104); v51 = v46 + 1; } v52 = sub_C1DBAC4C(v51 >> 1, (v145 + 1) >> 2, (unsigned int *)v104) + v50; if ( v46 >= 2 ) v52 += sub_C1DBAC4C(v46 >> 1, (v145 + 1) >> 1, (unsigned int *)v104); v53 = sub_C1DBAC4C(v46, v145 >> 1, (unsigned int *)v104) + v52; } else { v53 = sub_C1DBAC4C(*a2, *a3, (unsigned int *)v104); } v54 = v110; if ( !*v110 ) { if ( !v53 ) goto LABEL_149; v55 = (void *)realloc(0); if ( !v55 ) { v57 = 83; goto LABEL_157; } v152 = v55; v154 = v53; if ( !*v110 ) { LABEL_149: v56 = (int (__fastcall *)(void **, int *, unsigned __int8 *, unsigned int, _DWORD *))v108[2]; if ( v56 ) v57 = v56(&v152, &v153, pdata, v129, v111); else v57 = sub_C1DB7A98(&v152, &v153, pdata, v129, v111); v58 = v57; v54 = v110; if ( v153 != v53 ) v58 = 91; if ( !v57 ) v57 = v58; LABEL_157: *v54 = v57; } } free(pdata); if ( !*v54 ) { v59 = *v135; v107 = *a2; v132 = *a3; v146 = *v104; v60 = sub_C1DB7DA4(*a2, *a3, *v104, *v135); v61 = malloc(v60); *a1 = v61; v62 = 83; if ( v61 ) { if ( v60 ) { for ( i = 0; i != v60; ++i ) { *(_BYTE *)(v61 + i) = 0; v61 = *a1; } v64 = v108[38]; v59 = *v135; v132 = *a3; v107 = *a2; } else { v64 = v146; } v147 = (char *)v152; v65 = 0; if ( v64 <= 6 ) v65 = dword_C1DD1C40[v64]; v66 = v59 * v65; v62 = 31; if ( v66 ) { if ( *v123 ) { v139 = v61; sub_C1DBAF5C(v159, v158, v157, v156, v155, v107, v132, v66); v67 = 0; do { v68 = *(_DWORD *)&v158[v67]; v141 = v67; v136 = &v147[*(_DWORD *)&v156[v67]]; v69 = *(_DWORD *)&v159[v67]; v62 = sub_C1DBAC80(v136); if ( v62 ) { v80 = 0; v54 = v110; goto LABEL_206; } if ( v66 <= 7 ) sub_C1DBAECC(&v147[*(_DWORD *)&v155[v141]], v136, v69 * v66, (v69 * v66 + 7) & 0xFFFFFFF8, v68); v67 = v141 + 4; } while ( v141 != 24 ); sub_C1DBAF5C(v164, v163, v162, v161, v160, v107, v132, v66); if ( v66 <= 7 ) { v81 = 0; v118 = v66; do { v96 = v81; v82 = v81; v106 = v163[v82]; if ( v106 ) { v134 = v164[v82]; v103 = &dword_C1DD1BAC[v82]; v101 = (_DWORD *)((char *)&unk_C1DD1BC8 + v82 * 4); v99 = &dword_C1DD1BE4[v82]; v98 = &dword_C1DD1C00[v82]; v97 = &v160[v82 * 4]; for ( j = 0; j != v106; ++j ) { if ( v134 ) { pdatab = (void *)((*v99 * j + *v98) * v107 + *v101); v125 = *v103; v121 = 8 * *(_DWORD *)v97; v83 = 0; do { v84 = (v83 + v134 * j) * v66 + v121; v138 = v83; v85 = ((_DWORD)pdatab + v125 * v83) * v66; v86 = v66; do { v87 = ((unsigned __int8)v147[v84 >> 3] >> (~(_BYTE)v84 & 7)) & 1; ++v84; if ( v87 ) *(_BYTE *)(v139 + (v85 >> 3)) |= (_BYTE)v87 << (~(_BYTE)v85 & 7); --v86; ++v85; } while ( v86 ); v83 = v138 + 1; v66 = v118; } while ( v138 + 1 != v134 ); } } } v81 = v96 + 1; } while ( v96 != 6 ); } else { v70 = v66 >> 3; v71 = 0; v149 = v66 >> 3; do { v100 = v71; v72 = v71; pdataa = (void *)v163[v71]; if ( pdataa ) { v120 = &dword_C1DD1BAC[v72]; v117 = (_DWORD *)((char *)&unk_C1DD1BC8 + v72 * 4); v112 = &dword_C1DD1BE4[v72]; v105 = &dword_C1DD1C00[v72]; v102 = &v160[v72 * 4]; v142 = v164[v71]; v124 = v142 * v70; v133 = 0; v130 = v147; do { if ( v142 ) { v73 = &v130[*(_DWORD *)v102]; v137 = *v120 * v70; v74 = (_BYTE *)(v139 + (*v117 + (*v105 + *v112 * (_DWORD)v133) * v107) * v70); for ( k = 0; k != v142; ++k ) { if ( v70 ) { v76 = v73; v77 = (char *)v149; v78 = v74; do { *v78 = *v76++; --v77; ++v78; } while ( v77 ); } v70 = v149; v73 += v149; v74 += v137; } } v130 += v124; v133 = (char *)v133 + 1; } while ( v133 != pdataa ); } v71 = v100 + 1; } while ( v100 != 6 ); } v62 = 0; v54 = v110; v80 = 1; LABEL_206: if ( v80 ) LABEL_207: v62 = 0; } else if ( v66 > 7 || (v79 = v107 * v66, v107 * v66 == ((v107 * v66 + 7) & 0xFFFFFFF8)) ) { v62 = sub_C1DBAC80(v61); if ( !v62 ) goto LABEL_207; } else { v151 = (void *)((v107 * v66 + 7) & 0xFFFFFFF8); v95 = v61; v62 = sub_C1DBAC80(v152); if ( !v62 ) { sub_C1DBAECC(v95, v147, v79, v151, v132); goto LABEL_207; } } } } *v54 = v62; } v88 = 0; v153 = 0; v154 = 0; free(v152); result = *v54; if ( !*v54 ) { v89 = v108 + 27; if ( v108[8] ) { if ( !sub_C1DB8460(v108 + 27, v104) ) { if ( (*v89 | 4) != 6 ) { result = 56; if ( v108[28] != 8 ) return result; } v150 = (void *)*a1; v90 = *a3; v91 = *a2; v92 = sub_C1DB7DA4(*a2, *a3, *v89, v108[28]); v93 = malloc(v92); *a1 = v93; v94 = 83; if ( v93 ) v94 = sub_C1DB8064(v93, v150, v89, v104, v91, v90); *v110 = v94; free(v150); return *v110; } } else { result = sub_C1DB7D34(v108 + 27, v104); *v110 = result; if ( result ) return result; } return v88; } return result; }
得到PIC數據(部分)(這個數據是伴隨APP整個生命周期,主要用途是加解密密鑰)
BDC74300 2E 50 49 43 90 01 00 00 10 02 00 00 B0 02 00 00 .PIC............ BDC74310 82 1B 33 E3 4F 0C 49 C7 00 00 00 00 2D AA F5 F4 ..3...I.....-... BDC74320 52 22 D7 92 FB 3E EB AA 4A A2 74 C9 12 2D F9 92 R"ג .>....t..-.. BDC74330 F4 E7 CD 2C D8 33 1A B5 D4 8F F1 1E 11 6A 63 4D ........ԏ ....cM BDC74340 73 AC 1E 88 BB E5 A5 D2 19 F4 46 8A 7D 13 57 F8 s.............W. BDC74350 0C 14 F1 4C C7 E2 89 01 1A BD C8 72 66 3F F0 A9 ............f?.. BDC74360 C2 BA 6B 75 6D E3 03 FC 8F 61 20 96 6F 2C 44 2D º kum....a .o,D- BDC74370 D6 19 DE F4 74 8E 6F 01 6B 9D 5F BB 6D C4 6C CD ....t.o.k._.m... BDC74380 49 00 8F 36 F9 18 8E 50 2D 35 F3 6C F0 6C 75 84 I..6...P-5....u. BDC74390 2C 78 A0 D7 8E 64 A1 E9 CC 5C 1A 59 C3 78 E3 7A ,x...d.....Y....
4.4、采集系統環境信息加密
4.4.1、循環獲取信息 0x34次
.text:C1AF5224 02 98 LDR R0, [SP,#8] .text:C1AF5226 06 59 LDR R6, [R0,R4] .text:C1AF5228 D6 F7 46 F8 BL init_DecString_sub_C84582B8 .text:C1AF522C 06 90 STR R0, [SP,#0x18] .text:C1AF522E 0A AD ADD R5, SP, #0x28 ; '(' .text:C1AF5230 28 00 MOVS R0, R5 .text:C1AF5232 04 99 LDR R1, [SP,#0x10] .text:C1AF5234 05 9A LDR R2, [SP,#0x14] .text:C1AF5236 33 00 MOVS R3, R6 .text:C1AF5238 FB F7 AC FE BL GetDeviceInfo_dispatch_loop_sub_C89F8F94 ; 獲取設備信息1 .text:C1AF523C 06 98 LDR R0, [SP,#0x18] .text:C1AF523E 31 00 MOVS R1, R6 .text:C1AF5240 2A 00 MOVS R2, R5 .text:C1AF5242 03 9D LDR R5, [SP,#0xC] .text:C1AF5244 F9 F7 BE F9 BL jmp_checkField_sub_C89F65C4 ; 判斷采集的設備信息是否等於如下特殊字符[],{},mtg_block,mtg_unsupport .text:C1AF5248 0A 98 LDR R0, [SP,#0x28] .text:C1AF524A 40 19 ADDS R0, R0, R5 .text:C1AF524C 09 A9 ADD R1, SP, #0x24 ; '$' .text:C1AF524E 4C F0 7B FA BL free_sub_B2943748 .text:C1AF5252 04 34 ADDS R4, #4 .text:C1AF5254 34 2C CMP R4, #0x34 ; '4' ; 判斷是否結束 .text:C1AF5256 E5 D1 BNE loc_C1AF5224 .text:C1AF5258 03 B5 PUSH {R0,R1,LR} ; 獲取結束
在下面地方下是跳轉到每一個采集信息方法入口的地方,下好斷點:
.text:C207A134 80 00 LSLS R0, R0, #2 ; 跳到真實執行方法 .text:C207A136 02 A1 ADR R1, loc_C207A140 .text:C207A138 08 58 LDR R0, [R1,R0] ; 取方法表偏移 .text:C207A13A 08 18 ADDS R0, R1, R0 .text:C207A13C 87 46 MOV PC, R0
獲取的系統環境信息
{ "0": 2, "1": ["-", "-", "-", "-", "-", "-", "-", "-", "google", "user", "-", "PQ2A.190305.002", "-", "-", "-", "sailfish", "-", "-", "Pixel", "-", "-", "-", "-", "adb", "-", "-", "-", "-", "-", "{\"1\":\"-\",\"2\":\"-\",\"3\":\"-\",\"4\":\"\",\"5\":\"\",\"6\":\"-\",\"7\":\"-\",\"8\":\"\",\"9\":\"\",\"10\":\"-\",\"11\":\"-\",\"12\":\"32\",\"13\":\"\",\"14\":\"-\",\"15\":\"\",\"33\":{\"0\":0,\"1\":\"-\",\"2\":\"-\",\"3\":\"-\",\"4\":\"-\",\"5\":\"-\",\"6\":\"-\",\"7\":\"-\",\"8\":\"-\",\"9\":\"-\",\"10\":\"-\",\"11\":\"-\",\"12\":\"-\",\"13\":\"-\",\"14\":\"-\",\"15\":\"-\"}}", "midi,adb", "midi,adb", "release-keys", "-", "1", "1", "-", "9"], "2": ["-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-", "-"], "3": "{}" }
4.4.2、加密設備信息
壓縮信息
result = deflateInit_(&strm, -1, a128, 56); if ( !result ) { v6 = deflate(&strm, 4); if ( v6 == 1 ) { *a4 = strm.total_out; return deflateEnd(&strm); } deflateEnd(&strm); if ( v6 != 2 ) { if ( v6 != -5 ) return v6; result = -3; if ( strm.avail_in ) return v6; return result; } return -3; } return result;
壓縮后信息
C3904500 78 9C 9D 92 DB 0A C2 30 0C 86 DF 25 D7 CD E8 61 x............... C3904510 53 B7 3B DF 60 5E 5B 2F 26 AB 5A 9C 0C 56 04 65 S.;..^[/&.Z..V.e C3904520 F4 DD ED 0E B0 20 4E A6 17 81 2F E1 4F D2 9F B4 ..... N.../..... C3904530 05 0E 99 64 20 20 DB 03 02 FB 1A E7 BA 3E 57 26 ...d ........W& C3904540 C0 DD 99 66 AC E5 3B B9 8D 44 CA 15 4F 22 CE E5 ...f.....D..O".. C3904550 5B 87 2B 6C 75 B2 EE 42 4A B9 7D 98 EA C3 F0 A2 [.+lu.....}..... C3904560 3C CE AC 6D 35 08 0D 99 06 D4 C0 34 48 C2 8A 70 <ά m5......4H..p C3904570 DC 73 8F C9 84 2B A2 58 13 DE 4C 92 74 42 C1 89 ...Ʉ +.X....tB.. C3904580 44 D0 AD 62 58 AB E4 90 29 D2 13 53 19 59 AD 3A DЭ bX......S.Y.: C3904590 51 78 7C 37 93 B3 5F 4C 20 71 81 0B 6C 20 F1 81 Qx|7.._L q..l ..
解密PIC數據獲取加密key 上面計算得到的sha256值,(包名+固定字符+SANKUAI.RSA的MD5值)->轉換成hex 69fe5963f3b95d9718c8d3e4f924ad9379500e9b51d80686e65347890e1748fe
69 FE 59 63 F3 B9 5D 97 18 C8 D3 E4 F9 24 AD 93 79 50 0E 9B 51 D8 06 86 E6 53 47 89 0E 17 48 FE
取前0x10字節
69 FE 59 63 F3 B9 5D 97 18 C8 D3 E4 F9 24 AD 93
生成AES KEY
.text:C1AE9DA2 0A A8 ADD R0, SP, #0x28 ; '(' ; 生成AES key .text:C1AE9DA4 08 90 STR R0, [SP,#0x20] .text:C1AE9DA6 84 5D LDRB R4, [R0,R6] .text:C1AE9DA8 82 B0 SUB SP, SP, #8 .text:C1AE9DAA 03 B5 PUSH {R0,R1,LR} .text:C1AE9DAC DF F7 72 E9 BLX jmp_sub_B288C094 .text:C1AE9DB0 54 01 LSLS R4, R2, #5 .text:C1AE9DB2 00 00 MOVS R0, R0 .text:C1AE9DB4 01 BC POP {R0} .text:C1AE9DB6 20 18 ADDS R0, R4, R0 .text:C1AE9DB8 29 00 MOVS R1, R5 .text:C1AE9DBA 63 F0 49 F9 BL sub_C1B4D050 .text:C1AE9DBE 07 91 STR R1, [SP,#0x1C] .text:C1AE9DC0 82 B0 SUB SP, SP, #8 .text:C1AE9DC2 03 B5 PUSH {R0,R1,LR} .text:C1AE9DC4 DF F7 66 E9 BLX jmp_sub_B288C094 .text:C1AE9DC8 40 01 LSLS R0, R0, #5 .text:C1AE9DCA 00 00 MOVS R0, R0 .text:C1AE9DCC 01 BC POP {R0} .text:C1AE9DCE 20 18 ADDS R0, R4, R0 .text:C1AE9DD0 04 99 LDR R1, [SP,#0x10] .text:C1AE9DD2 63 F0 3D F9 BL sub_C1B4D050 .text:C1AE9DD6 69 43 MULS R1, R5 .text:C1AE9DD8 07 98 LDR R0, [SP,#0x1C] .text:C1AE9DDA 08 18 ADDS R0, R1, R0 ; 初始化密鑰 .text:C1AE9DDC 03 21 MOVS R1, #3 .text:C1AE9DDE 41 43 MULS R1, R0 .text:C1AE9DE0 06 98 LDR R0, [SP,#0x18] .text:C1AE9DE2 40 18 ADDS R0, R0, R1 .text:C1AE9DE4 80 78 LDRB R0, [R0,#2] .text:C1AE9DE6 20 40 ANDS R0, R4 .text:C1AE9DE8 FE 21 MOVS R1, #0xFE .text:C1AE9DEA 01 40 ANDS R1, R0 .text:C1AE9DEC 08 98 LDR R0, [SP,#0x20] .text:C1AE9DEE 81 55 STRB R1, [R0,R6] ; 存儲密鑰 .text:C1AE9DF0 01 36 ADDS R6, #1 .text:C1AE9DF2 10 2E CMP R6, #0x10 ; 判斷是否結束 .text:C1AE9DF4 D5 D1 BNE loc_C1AE9DA2 ; 生成AES key
生成最終的AES KEY
68 98 08 02 F2 80 1C 94 08 C8 90 E4 A0 04 AC 82
AES 解密pic
//IV 0102030405060708 .text:C1AE7598 57 F0 7A F8 BL AES_set_decrypt_key_sub_CB601690 ; R0:key,R1:大小,R2:初始AES_KEY返回結構 .text:C1AE759C 00 20 MOVS R0, #0 .text:C1AE759E 69 46 MOV R1, SP .text:C1AE75A0 06 9A LDR R2, [SP,#0x128+var_110] .text:C1AE75A2 0A 60 STR R2, [R1,#0x128+var_128] .text:C1AE75A4 48 60 STR R0, [R1,#0x128+var_124] .text:C1AE75A6 08 98 LDR R0, [SP,#0x128+var_108] .text:C1AE75A8 04 9E LDR R6, [SP,#0x128+var_118] .text:C1AE75AA 31 00 MOVS R1, R6 .text:C1AE75AC 07 9C LDR R4, [SP,#0x128+var_10C] .text:C1AE75AE 22 00 MOVS R2, R4 .text:C1AE75B0 03 9B LDR R3, [SP,#0x128+var_11C] .text:C1AE75B2 57 F0 35 FD BL AES_cbc_Dncrypt_sub_CB602020 .text:C1AE75B6 30 00 MOVS R0, R6
解密解壓后PIC數據
{"a1":0,"a10":400,"a2":"com.sankuai.meituan","a11":"c1ee9178c95d9ec75f0f076a374df94a032d54c8576298d4f75e653de3705449","a3":"0a16ecd60eb56a6a3349f66cdcf7f7bf5190e5a42d6280d8dc0ee3be228398ec","a4":1100030200,"k0":{"k1":"meituan1sankuai0","k2":"meituan0sankuai1","k3":"$MXMYBS@HelloPay","k4":"Maoyan010iauknaS","k5":"34281a9dw2i701d4","k6":"X%rj@KiuU+|xY}?f"},"a5":"11.3.200","a0":"pw/LhTdeoTTyaxPHcHMy+/ssGNS1ihNkrJ+uBI74FIfd90KlTil1m0i7FF/n0bhY","a6":"/HntC9XIfdUyII/UiVfx020EQPpHz2XZY3qzM2aiNmM0i0pB1yeSO689TY9SBB3s","a7":"QsHnU6kFjTYR8Z6tHEvkGMO2Hrt+NRnVQhmxg6EtVBzuzQcBpma3AdhTWNMpesFT","c0":{"c1":true,"c2":false},"a9":"SDEzWXi5LHL/cuMCZ1zYyv+0hIViqWWf+ShbUYILWf4=","a8":1603800117167}
解析json獲取key k6
X%rj@KiuU+|xY}?f
計算壓縮后信息的CRC值
.text:C1B2C832 crc32_loc_CCBA9832 .text:C1B2C848↓j .text:C1B2C832 FF 25 MOVS R5, #0xFF .text:C1B2C834 05 40 ANDS R5, R0 .text:C1B2C836 16 78 LDRB R6, [R2] .text:C1B2C838 6E 40 EORS R6, R5 .text:C1B2C83A B5 00 LSLS R5, R6, #2 .text:C1B2C83C 65 59 LDR R5, [R4,R5] .text:C1B2C83E 00 0A LSRS R0, R0, #8 .text:C1B2C840 68 40 EORS R0, R5 .text:C1B2C842 01 39 SUBS R1, #1 .text:C1B2C844 01 32 ADDS R2, #1 .text:C1B2C846 00 29 CMP R1, #0 .text:C1B2C848 F3 D1 BNE crc32_loc_CCBA9832
計算后的CRC值為 744d7275 組合加密壓縮后設備環境信息的key
744d7275X%rj@Kiu //crc32+k6前8字節
AES加密壓縮后數據
.text:C1AE750E 32 00 MOVS R2, R6 .text:C1AE7510 56 F0 30 FF BL AES_set_Encrypt_key_sub_CB601374 ; R0:key,R1:長度,R2:返回值 .text:C1AE7514 06 9A LDR R2, [SP,#0x120+byte_count] .text:C1AE7516 01 20 MOVS R0, #1 .text:C1AE7518 69 46 MOV R1, SP .text:C1AE751A 04 9B LDR R3, [SP,#0x120+var_110] .text:C1AE751C 0B 60 STR R3, [R1,#0x120+var_120] .text:C1AE751E 48 60 STR R0, [R1,#0x120+var_11C] .text:C1AE7520 05 98 LDR R0, [SP,#0x120+p] .text:C1AE7522 02 9C LDR R4, [SP,#0x120+var_118] .text:C1AE7524 21 00 MOVS R1, R4 .text:C1AE7526 33 00 MOVS R3, R6 .text:C1AE7528 57 F0 7A FD BL AES_cbc_Encrypt_sub_CB602020 ; R0:原始數據,R1:返回,R2:大小,R3:key .text:C1AE752C 06 98 LDR R0, [SP,#0x120+byte_count] .text:C1AE752E 03 99 LDR R1, [SP,#0x120+var_114]
加密后數據(部分)
C37514E0 2E 5D 33 AF C8 C3 6B 6A 7F C2 9F F6 39 16 52 57 .]3...kj.......W C37514F0 1D CB 01 FF A2 FA 48 0B 2D 2B 7E 39 73 EB 65 E7 ......H.-+~9s... C3751500 14 93 59 D9 15 F2 D7 CB C7 40 DC B5 9D 0D 34 16 ..Y......@....4. C3751510 9C BF 69 C6 54 97 81 C8 69 7A 26 03 BF FA F3 D9 ..i......z&..... C3751520 A3 D2 BE 38 B0 99 48 4A 5E 56 F0 C6 88 54 79 BD .Ҿ 8..HJ^V....y. C3751530 56 86 96 A7 40 D4 61 32 6D A4 07 55 F1 46 46 EF V...@..2m..U.... C3751540 4E A1 CA 86 F8 1E 69 09 0B CF 6D 05 3B D3 0F B4 N.ʆ ..i.....;... C3751550 63 78 65 6D AD F7 B2 C4 75 86 C5 35 B5 6F 42 BA cxem.........oB. C3751560 FA AF E7 4C 56 41 CF 36 46 86 3E E0 11 A3 35 9E .....A..F.>...5.
base64加密
text:C1ACFE62 27 DB BLT loc_C1ACFEB4 .text:C1ACFE64 00 25 MOVS R5, #0 .text:C1ACFE66 3A 4A LDR R2, =(aAbcdefghijklmn - 0xC1ACFE6C) ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"... .text:C1ACFE68 7A 44 ADD R2, PC ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"... .text:C1ACFE6A 01 9E LDR R6, [SP,#0x28+var_24] .text:C1ACFE6C .text:C1ACFE6C loc_C1ACFE6C ; CODE XREF: base64_sub_C795AE10+A0↓j .text:C1ACFE6C 43 5D LDRB R3, [R0,R5] ; 加密后數據 .text:C1ACFE6E 9B 08 LSRS R3, R3, #2 .text:C1ACFE70 D3 5C LDRB R3, [R2,R3] ; base64 key .text:C1ACFE72 33 70 STRB R3, [R6] .text:C1ACFE74 43 5D LDRB R3, [R0,R5] .text:C1ACFE76 1B 01 LSLS R3, R3, #4 .text:C1ACFE78 30 24 MOVS R4, #0x30 ; '0' .text:C1ACFE7A 1C 40 ANDS R4, R3 .text:C1ACFE7C 43 19 ADDS R3, R0, R5 .text:C1ACFE7E 08 00 MOVS R0, R1 .text:C1ACFE80 59 78 LDRB R1, [R3,#1] .text:C1ACFE82 09 09 LSRS R1, R1, #4 .text:C1ACFE84 21 43 ORRS R1, R4 .text:C1ACFE86 51 5C LDRB R1, [R2,R1] .text:C1ACFE88 71 70 STRB R1, [R6,#1] .text:C1ACFE8A 59 78 LDRB R1, [R3,#1] .text:C1ACFE8C 89 00 LSLS R1, R1, #2 .text:C1ACFE8E 3C 24 MOVS R4, #0x3C ; '<' .text:C1ACFE90 0C 40 ANDS R4, R1 .text:C1ACFE92 99 78 LDRB R1, [R3,#2] .text:C1ACFE94 89 09 LSRS R1, R1, #6 .text:C1ACFE96 21 43 ORRS R1, R4 .text:C1ACFE98 51 5C LDRB R1, [R2,R1] .text:C1ACFE9A B1 70 STRB R1, [R6,#2] .text:C1ACFE9C 99 78 LDRB R1, [R3,#2] .text:C1ACFE9E 3F 23 MOVS R3, #0x3F ; '?' .text:C1ACFEA0 0B 40 ANDS R3, R1 .text:C1ACFEA2 D1 5C LDRB R1, [R2,R3] .text:C1ACFEA4 F1 70 STRB R1, [R6,#3] .text:C1ACFEA6 01 00 MOVS R1, R0 .text:C1ACFEA8 04 98 LDR R0, [SP,#0x28+var_18] .text:C1ACFEAA 04 36 ADDS R6, #4 .text:C1ACFEAC 03 35 ADDS R5, #3 .text:C1ACFEAE 8D 42 CMP R5, R1 .text:C1ACFEB0 DC DB BLT loc_C1ACFE6C ; 加密后數據 .text:C1ACFEB2 02 9A LDR R2, [SP,#0x28+var_20] .text:C1ACFEB4 .text:C1ACFEB4 loc_C1ACFEB4 ; CODE XREF: base64_sub_C795AE10+52↑j .text:C1ACFEB4 95 42 CMP R5, R2 .text:C1ACFEB6 1F DA BGE loc_C1ACFEF8 .text:C1ACFEB8 41 5D LDRB R1, [R0,R5] .text:C1ACFEBA 14 00 MOVS R4, R2 .text:C1ACFEBC 8A 08 LSRS R2, R1, #2 .text:C1ACFEBE 25 49 LDR R1, =(aAbcdefghijklmn - 0xC1ACFEC4) ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"... .text:C1ACFEC0 79 44 ADD R1, PC ; "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklm"... .text:C1ACFEC2 8A 5C LDRB R2, [R1,R2] .text:C1ACFEC4 32 70 STRB R2, [R6] .text:C1ACFEC6 42 5D LDRB R2, [R0,R5] .text:C1ACFEC8 13 01 LSLS R3, R2, #4 .text:C1ACFECA 30 22 MOVS R2, #0x30 ; '0' .text:C1ACFECC 1A 40 ANDS R2, R3 .text:C1ACFECE 63 1E SUBS R3, R4, #1 .text:C1ACFED0 9D 42 CMP R5, R3 .text:C1ACFED2 14 D1 BNE loc_C1ACFEFE .text:C1ACFED4 89 5C LDRB R1, [R1,R2] .text:C1ACFED6 71 70 STRB R1, [R6,#1] .text:C1ACFED8 3D 21 MOVS R1, #0x3D ; '=' .text:C1ACFEDA 1B E0 B loc_C1ACFF14
Base64加密后
Ll0zr8jDa2p/wp/2ORZSVx3LAf+i+kgLLSt+OXPrZecUk1nZFfLXy8dA3LWdDTQWnL9pxlSXgchpeiYDv/rz2aPSvjiwmUhKXlbwxohUeb1WhpanQNRhMm2kB1XxRkbvTqHKhvgeaQkLz20FO9MPtGN4ZW2t97LEdYbFNbVvQrr6r+dMVkHPNkaGPuARozWeaQGSSMkoMMJ+ve9rA1L+aQTgGSootSpmPnT3TPLrCPN0Z6HzPKtpxopqfsjfcIV7YcP7M8Wc847wXfhMA2hYTRO24or97heGubGuxo8hQyw=
將CRC值與Base64加密后值組合,(簽名時使用到)
744d7275Ll0zr8jDa2p/wp/2ORZSVx3LAf+i+kgLLSt+OXPrZecUk1nZFfLXy8dA3LWdDTQWnL9pxlSXgchpeiYDv/rz2aPSvjiwmUhKXlbwxohUeb1WhpanQNRhMm2kB1XxRkbvTqHKhvgeaQkLz20FO9MPtGN4ZW2t97LEdYbFNbVvQrr6r+dMVkHPNkaGPuARozWeaQGSSMkoMMJ+ve9rA1L+aQTgGSootSpmPnT3TPLrCPN0Z6HzPKtpxopqfsjfcIV7YcP7M8Wc847wXfhMA2hYTRO24or97heGubGuxo8hQyw=
4.5、第二次加密設備信息
設備信息數據
{"voltage":"1","type":"user","brand":"google","psuc":"adb","temp":"1","suc":"midi,adb","id":"PQ2A.190305.002","sus":"midi,adb","tags":"release-keys","timestamp":"1631688160837","hardware":"sailfish","version":"9","model":"Pixel"}
壓縮數據
C42FEF80 78 9C 55 8E 41 12 82 30 0C 45 EF D2 35 32 2D 8C x.U.A..0.E...2-. C42FEF90 08 EE BC 81 1E 21 D8 08 19 5B CA 34 80 32 8E 77 . .!...[...2.w C42FEFA0 37 15 37 AE 92 FF F2 93 FC 97 5A 82 9B A0 43 75 7.7.......Z...Cu C42FEFB0 54 46 65 6A 5A C7 D4 CE 8C 51 54 1B 61 B0 22 BB TFejZ..Ό QT.a.". C42FEFC0 10 3A 87 02 46 9E AF A2 C1 B6 C9 8B 7E FC AD 6D .:..F.....ɋ ~..m C42FEFD0 D8 93 A5 6C 9B 51 5A 3B 5F 8A 53 6E 1A 5D EA 7D ...l.QZ;_.Sn.].. C42FEFE0 AE 75 F1 F5 F1 BF 4F 5E 27 12 D1 21 30 EE EE B8 .u....O^'...0... C42FEFF0 72 A2 E4 91 27 D8 CE 57 A5 A9 EA DA 54 BA 2E 0F r......W........
解密PIC數據獲取key(k1),流程和上面一樣
解密后得到key meituan1sankuai0
AES 加密壓縮后數據
.text:C1AE7510 56 F0 30 FF BL AES_set_Encrypt_key_sub_CB601374 ; R0:key,R1:長度,R2:返回值 .text:C1AE7514 06 9A LDR R2, [SP,#0x120+byte_count] .text:C1AE7516 01 20 MOVS R0, #1 .text:C1AE7518 69 46 MOV R1, SP .text:C1AE751A 04 9B LDR R3, [SP,#0x120+var_110] .text:C1AE751C 0B 60 STR R3, [R1,#0x120+var_120] .text:C1AE751E 48 60 STR R0, [R1,#0x120+var_11C] .text:C1AE7520 05 98 LDR R0, [SP,#0x120+p] .text:C1AE7522 02 9C LDR R4, [SP,#0x120+var_118] .text:C1AE7524 21 00 MOVS R1, R4 .text:C1AE7526 33 00 MOVS R3, R6 .text:C1AE7528 57 F0 7A FD BL AES_cbc_Encrypt_sub_CB602020 ; R0:原始數據,R1:返回,R2:大小,R3:key .text:C1AE752C 06 98 LDR R0, [SP,#0x120+byte_count]
加密后數據(部分)
DEED6F00 2E 0F E3 72 62 1C 2B FB 35 B0 A9 CA E5 29 9F 79 ......+.5....).y DEED6F10 C6 37 F0 02 CB 17 12 AE 6E 3D 5E AC EB A6 B5 DD ........n=^.릵 . DEED6F20 33 B9 24 A9 F4 E0 6D 6C 64 D6 76 E4 65 88 6C 6F 3.$.....d.....lo DEED6F30 F3 53 20 FA B3 F8 02 6C 6D BC 75 C9 87 66 92 CE .......lm.uɇ f.. DEED6F40 51 7A BC 09 BF 69 5D C0 C3 0A 71 77 46 5B E0 81 Qz...i]...qwF[.. DEED6F50 E2 15 67 05 5B 87 48 2D 0D D4 FA 99 EF 1C AC BD ....[.H-........ DEED6F60 53 26 56 13 16 91 68 A8 EC 5B 1F D8 5F F4 61 BB S&V...h......... DEED6F70 FA 2A 2F 03 B5 3F 6E 02 6E 57 ED 46 8B A1 1A 0A .*/..?n.nW...... DEED6F80 F5 C5 E7 38 9F E5 8E 70 B1 8C D6 CF E8 D5 16 6F ...............o DEED6F90 F6 36 3B A5 D8 2B 3D D9 83 BD 17 C5 3F AA 3D 96 ......=ك .....=.
Base64加密后
Lg/jcmIcK/s1sKnK5SmfecY38ALLFxKubj1erOumtd0zuSSp9OBtbGTWduRliGxv81Mg+rP4AmxtvHXJh2aSzlF6vAm/aV3Awwpxd0Zb4IHiFWcFW4dILQ3U+pnvHKy9UyZWExaRaKjsWx/YX/Rhu/oqLwO1P24CblftRouhGgr1xec4n+WOcLGM1s/o1RZv9jY7pdgrPdmDvRfFP6o9liGe0rCXBoG85J1mm/6GmqQ=
4.6、代碼混淆
代碼邏輯跳轉動態計算:
模板1 .text:B845707C 01 10 CE E3 BIC R1, LR, #1 .text:B8457080 00 11 91 E7 LDR R1, [R1,R0,LSL#2] .text:B8457084 0E 10 81 E0 ADD R1, R1, LR .text:B8457088 08 E0 9D E5 LDR LR, [SP,#arg_8] .text:B845708C 08 10 8D E5 STR R1, [SP,#arg_8] .text:B8457090 03 80 BD E8 POP {R0,R1,PC} 模板2 .text:C18BDAC0 7F B5 PUSH {R0-R6,LR} .text:C18BDAC2 7F B5 PUSH {R0-R6,LR} .text:C18BDAC4 0D 26 MOVS R6, #0xD .text:C18BDAC6 63 21 MOVS R1, #0x63 ; 'c' .text:C18BDAC8 68 46 MOV R0, SP .text:C18BDACA 10 30 ADDS R0, #0x10 .text:C18BDACC 02 26 MOVS R6, #2 .text:C18BDACE 08 30 ADDS R0, #8 .text:C18BDAD0 01 1D ADDS R1, R0, #4 .text:C18BDAD2 8D 46 MOV SP, R1 .text:C18BDAD4 04 A6 05 36 ADRL R6, byte_C18BDAED .text:C18BDAD8 02 21 MOVS R1, #2 .text:C18BDADA 0A 36 ADDS R6, #0xA .text:C18BDADC 76 18 ADDS R6, R6, R1 .text:C18BDADE 46 62 STR R6, [R0,#0x24] .text:C18BDAE0 40 BC POP {R6} .text:C18BDAE2 01 E0 B loc_C18BDAE8 .text:C18BDAE4 ; .text:C18BDAE4 84 44 ADD R12, R0 .text:C18BDAE6 12 34 ADDS R4, #0x12 .text:C18BDAE8 .text:C18BDAE8 loc_C18BDAE8 .text:C18BDAE8 00 46 MOV R0, R0 .text:C18BDAEA 7F BD POP {R0-R6,PC}
字符串解密:
.text:C1D46060 DecString .text:C1D46060 ; __unwind { // 91B9000 .text:C1D46060 10 B5 PUSH {R4,LR} .text:C1D46062 01 2B CMP R3, #1 .text:C1D46064 08 DB BLT locret_C1D46078 .text:C1D46066 .text:C1D46066 loc_C1D46066 .text:C1D46066 0C 78 LDRB R4, [R1] .text:C1D46068 54 40 EORS R4, R2 .text:C1D4606A 04 70 STRB R4, [R0] .text:C1D4606C 01 3B SUBS R3, #1 .text:C1D4606E 01 30 ADDS R0, #1 .text:C1D46070 01 31 ADDS R1, #1 .text:C1D46072 03 32 ADDS R2, #3 .text:C1D46074 00 2B CMP R3, #0 .text:C1D46076 F6 D1 BNE loc_C1D46066 .text:C1D46078 .text:C1D46078 locret_C1D46078 .text:C1D46078 10 BD POP {R4,PC}
流程混淆:
.text:C1AF41F0 00 2C CMP R4, #0 .text:C1AF41F2 01 DA BGE loc_C1AF41F8 .text:C1AF41F4 FC F7 C8 FF BL loc_C1AF1188 .text:C1AF41F8 .text:C1AF41F8 loc_C1AF41F8 ; CODE XREF: .text:C1AF41F2↑j .text:C1AF41F8 03 B5 PUSH {R0,R1,LR} .text:C1AF41FA 01 48 LDR R0, =0x4A .text:C1AF41FC FC F7 F0 FE BL ret_sub_CA67BFE0 .text:C1AF0FE0 ret_sub_CA67BFE0 .text:C1AF0FE0 .text:C1AF0FE0 D8 F7 4C E8 BLX jmp_sub_B288C07C .text:C1AF0FE4 F0 1D ADDS R0, R6, #7
五、反爬蟲mtgsig簽名
5.1、基本流程
APP每一個業務網絡請求的請求頭中都有mtgsig參數,該參數是請求體與其它參數計算的簽名值。
java層代碼如下:
public static String makeHeader(byte[] arg13, MODE arg14) { Object[] v8 = new Object[]{arg13, arg14}; ChangeQuickRedirect v11 = WTSign.changeQuickRedirect; if(PatchProxy.isSupport(v8, null, v11, true, "4371e5fcb0c4ae2bd761bbf35c1a43bf", 0x6000000000000000L)) { return (String)PatchProxy.accessDispatch(v8, null, v11, true, "4371e5fcb0c4ae2bd761bbf35c1a43bf"); } if(arg13 == null) { return "-2003"; } Object[] v13 = NBridge.main3(2, new Object[]{MTGuard.sAppKey, arg13, ((int)arg14.mode)}); if(v13 == null) { return "-1001"; } return (v13[0] instanceof Integer) ? v13[0] : ((String)v13[0]); }
最終會走到Native層進行簽名計算
5.2、加密系統環境信息
// 是否root、ADB調試狀態、USB調試模式等 { "b1": "{\"1\":\"\",\"2\":\"1|2|3\",\"3\":\"\",\"4\":\"\",\"5\":\"\",\"6\":\"\",\"7\":\"2\",\"8\":\"\",\"9\":\"\",\"10\":\"\",\"11\":\"\",\"12\":\"32\",\"13\":\"\",\"14\":\"\",\"15\":\"\",\"33\":{\"0\":2,\"1\":\"\",\"2\":\"\",\"3\":\"\",\"4\":\"2|22\",\"5\":\"\",\"6\":\"\",\"7\":\"\",\"8\":\"\",\"9\":\"\",\"10\":\"\",\"11\":\"\",\"12\":\"\",\"13\":\"\",\"14\":\"2\",\"15\":\"\"}}", "b2": 35, "b3": 0, "b4": "com.sankuai.meituan", "b5": "11.12.204", "b6": "1100120204", "b7": 1631754559 }
壓縮信息
E53E7D80 78 9C 9D 91 C1 0E C2 20 10 44 FF 65 CF 0D 61 76 x........D.e..av E53E7D90 81 2A DF C2 A5 35 1E 1A D3 7A D0 9E DA FE BB 40 .*...5....О ...@ E53E7DA0 4D C0 A4 C6 C4 D3 3E 66 17 66 36 2C D4 83 3C 2D M......f.f6,ԃ <- E53E7DB0 81 10 C8 07 0A D4 04 E2 8C 58 79 95 7C 96 D2 32 ..........y.|... E53E7DC0 05 6D 41 57 B0 CD C8 99 4F 45 3E 17 84 AE B8 72 .mAW....OE>....r E53E7DD0 C5 6E 2B FB 5D 54 A6 A8 5C 51 D9 4A 9A 89 D1 D3 ..+.]T..\Q...... E53E7DE0 83 DC 1C AC 70 9C 9E 57 E6 9F 1B FC BF C0 B7 F8 ....p..W........ E53E7DF0 FC 99 7F DB A8 A1 9E C9 8B 8D 55 C8 EB 58 4C FC .......ɋ .U..XL. E53E7E00 8B CB 7D 54 8F 6E BA CD DD A0 C6 EB F0 9C BB 29 ...T.n.......... E53E7E10 4D DA D8 02 14 58 B1 36 49 70 59 D0 1A AC DF 4A M....X.6IpY.....
組合密鑰
1631754963 9b69f861-e054-4bc4-9daf-d36ae205ed3e //當前時間加APPkey
RC4加密壓縮后數據
.text:C881966C 11 99 LDR R1, [SP,#0x44] .text:C881966E 0E 9E LDR R6, [SP,#0x38] .text:C8819670 8A 59 LDR R2, [R1,R6] .text:C8819672 16 A8 ADD R0, SP, #0x58 ; 'X' .text:C8819674 1A F0 B0 FF BL initkey_sub_C79725D8 ; R1:key 15525971099b69f861-e054-4bc4-9daf-d36ae205ed3e R2:長度0x2E .text:C8819678 10 9B LDR R3, [SP,#0x40] .text:C881967A 29 00 MOVS R1, R5 .text:C881967C 2A 00 MOVS R2, R5 .text:C881967E 1A F0 B2 FF BL RC4_sub_C79725E6 ; R0:初始化的KEY,R1:壓縮后數據,R3:壓縮后大小 .text:C8819682 11 98 LDR R0, [SP,#0x44]
加密后
E53E7D80 62 16 1F 8D D5 8D AF 42 8B D2 2C 32 77 29 5A 5F b...Ս .B...2w)Z_ E53E7D90 1B ED 38 9E F7 85 82 50 E0 FA D1 0A CD C4 6F 29 ..............o) E53E7DA0 69 0C FA 10 AE 63 57 E1 11 EA A4 DF 12 36 B2 4D i....cW......6.M E53E7DB0 A0 A2 78 3B 5A 60 E6 AB E9 4C A1 13 CD DB EB F0 ..x;Z`...L...... E53E7DC0 1B FC 49 D2 6C CE 5A 96 C6 6B 71 45 80 8B 5D B7 ..I.......qE..]. E53E7DD0 97 54 D5 58 0F F8 5E 68 25 CE 31 58 2D 04 C0 F2 .T....^h%..X-... E53E7DE0 70 E7 D4 2E E7 C9 2C DD 07 F2 7A F4 CA 06 F3 CB p............... E53E7DF0 C3 CC 14 76 0A 44 2C 48 A2 35 6B 7D 0D 8C 51 60 ...v.D,H.5k}..Q` E53E7E00 3F A9 F8 C6 D1 02 04 2B A3 BF 86 3F 54 83 D4 43 ?......+...?T... E53E7E10 39 9C AB 66 0D DD 21 90 2B 73 B9 1F C3 C2 B8 86 9..f....+s......
Base64加密
An2sai6nXEuFYeKbDUk/qEo/7am8Jtn3O2Has5efofCux7iubGRCS8TKpjUgotJ6MGdQrBsvwh/peZwuikT+5rCr4RzN8SXXCeDOtZQ6sbo/snVdESSJweNqd6i/WbIwDOgv5eaWRQoISjdgNfW3hk7tf0QhsZFbOELcPxz5pRzo6d6EsBLFu5Mq8DbVNgsYF+6aqZ7302/G+Rr7MlUT2M9y3EjgjH01L39q/eRJ
5.3、獲取dfpid (設備指紋)
判斷本地是否有存儲,如果有優先讀取本地,如果無反謝java層從服務器端獲取,這部分詳細分析見后面設備指紋部分。
.text:C8A93C78 F0 B5 PUSH {R4-R7,LR} .text:C8A93C7A 03 AF ADD R7, SP, #0xC .text:C8A93C7C 91 B0 SUB SP, SP, #0x44 .text:C8A93C7E 09 92 STR R2, [SP,#0x50+var_2C] .text:C8A93C80 0A 91 STR R1, [SP,#0x50+var_28] .text:C8A93C82 01 B4 PUSH {R0} .text:C8A93C84 10 BC POP {R4} .text:C8A93C86 8E 48 LDR R0, =(__stack_chk_guard_ptr - 0xC8A93C8C) .text:C8A93C88 78 44 ADD R0, PC ; __stack_chk_guard_ptr .text:C8A93C8A 05 68 LDR R5, [R0] ; __stack_chk_guard .text:C8A93C8C 28 68 LDR R0, [R5] .text:C8A93C8E 10 90 STR R0, [SP,#0x50+var_10] .text:C8A93C90 20 00 MOVS R0, R4 .text:C8A93C92 00 F0 3F F9 BL getClassLoader_sub_C6FD9F14 .text:C8A93C96 00 26 MOVS R6, #0 .text:C8A93C98 00 28 CMP R0, #0 .text:C8A93C9A 00 D1 BNE loc_C8A93C9E .text:C8A93C9C 06 E1 B loc_C8A93EAC .text:C8A93C9E ; --------------------------------------------------------------------------- .text:C8A93C9E .text:C8A93C9E loc_C8A93C9E ; CODE XREF: main2_sub_B6891C78+22↑j .text:C8A93C9E 0B 90 STR R0, [SP,#0x50+var_24] .text:C8A93CA0 F6 F7 EE FC BL malloc_sub_C8BC6680 .text:C8A93CA4 9C 21 MOVS R1, #0x9C .text:C8A93CA6 41 58 LDR R1, [R0,R1] ; char * .text:C8A93CA8 0E AE ADD R6, SP, #0x50+var_18 .text:C8A93CAA 0D AA ADD R2, SP, #0x50+var_1C .text:C8A93CAC 30 00 MOVS R0, R6 ; int .text:C8A93CAE 6F F0 F7 FF BL basic_string_sub_B2943CA0 .text:C8A93CB2 20 00 MOVS R0, R4 .text:C8A93CB4 31 00 MOVS R1, R6 .text:C8A93CB6 03 F0 35 FF BL NewStringUTF_sub_C6B9DB24 .text:C8A93CBA 26 00 MOVS R6, R4 .text:C8A93CBC 04 00 MOVS R4, R0 .text:C8A93CBE 0E 98 LDR R0, [SP,#0x50+var_18] .text:C8A93CC0 0C 38 SUBS R0, #0xC .text:C8A93CC2 0F A9 ADD R1, SP, #0x50+var_14 .text:C8A93CC4 6F F0 40 FD BL free_sub_B2943748 .text:C8A93CC8 0C 96 STR R6, [SP,#0x50+var_20] .text:C8A93CCA 30 00 MOVS R0, R6 .text:C8A93CCC 07 F0 FC FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93CD0 00 26 MOVS R6, #0 .text:C8A93CD2 00 28 CMP R0, #0 .text:C8A93CD4 07 D0 BEQ loc_C8A93CE6 .text:C8A93CD6 00 2C CMP R4, #0 .text:C8A93CD8 00 D1 BNE loc_C8A93CDC .text:C8A93CDA E2 E0 B loc_C8A93EA2 .text:C8A93CDC ; --------------------------------------------------------------------------- .text:C8A93CDC .text:C8A93CDC loc_C8A93CDC ; CODE XREF: main2_sub_B6891C78+60↑j .text:C8A93CDC 08 94 STR R4, [SP,#0x50+var_30] .text:C8A93CDE 07 95 STR R5, [SP,#0x50+var_34] .text:C8A93CE0 00 26 MOVS R6, #0 .text:C8A93CE2 0C 9C LDR R4, [SP,#0x50+var_20] .text:C8A93CE4 D7 E0 B loc_C8A93E96 .text:C8A93CE6 ; --------------------------------------------------------------------------- .text:C8A93CE6 .text:C8A93CE6 loc_C8A93CE6 ; CODE XREF: main2_sub_B6891C78+5C↑j .text:C8A93CE6 00 2C CMP R4, #0 .text:C8A93CE8 00 D1 BNE loc_C8A93CEC .text:C8A93CEA DA E0 B loc_C8A93EA2 .text:C8A93CEC ; --------------------------------------------------------------------------- .text:C8A93CEC .text:C8A93CEC loc_C8A93CEC ; CODE XREF: main2_sub_B6891C78+70↑j .text:C8A93CEC 08 94 STR R4, [SP,#0x50+var_30] .text:C8A93CEE 07 95 STR R5, [SP,#0x50+var_34] .text:C8A93CF0 74 4E LDR R6, =(byte_C8B2D4E0 - 0xC8A93CF6) .text:C8A93CF2 7E 44 ADD R6, PC ; byte_C8B2D4E0 .text:C8A93CF4 30 78 LDRB R0, [R6] .text:C8A93CF6 00 28 CMP R0, #0 .text:C8A93CF8 0A D1 BNE loc_C8A93D10 .text:C8A93CFA 73 4C LDR R4, =(aJavaLangClassl - 0xC8A93D00) ; "java/lang/ClassLoader" .text:C8A93CFC 7C 44 ADD R4, PC ; "java/lang/ClassLoader" .text:C8A93CFE 73 49 LDR R1, =(unk_C8B1E8A0 - 0xC8A93D04) .text:C8A93D00 79 44 ADD R1, PC ; unk_C8B1E8A0 .text:C8A93D02 00 25 MOVS R5, #0 .text:C8A93D04 15 23 MOVS R3, #0x15 .text:C8A93D06 20 00 MOVS R0, R4 .text:C8A93D08 2A 00 MOVS R2, R5 .text:C8A93D0A F7 F7 A9 F9 BL DecString .text:C8A93D0E 65 75 STRB R5, [R4,#(aJavaLangClassl+0x15 - 0xC8B1E489)] ; "" .text:C8A93D10 .text:C8A93D10 loc_C8A93D10 ; CODE XREF: main2_sub_B6891C78+80↑j .text:C8A93D10 01 20 MOVS R0, #1 .text:C8A93D12 06 90 STR R0, [SP,#0x50+var_38] .text:C8A93D14 30 70 STRB R0, [R6] .text:C8A93D16 0C 9C LDR R4, [SP,#0x50+var_20] .text:C8A93D18 20 68 LDR R0, [R4] .text:C8A93D1A 82 69 LDR R2, [R0,#0x18] .text:C8A93D1C 6C 49 LDR R1, =(aJavaLangClassl - 0xC8A93D22) ; "java/lang/ClassLoader" .text:C8A93D1E 79 44 ADD R1, PC ; "java/lang/ClassLoader" .text:C8A93D20 20 00 MOVS R0, R4 .text:C8A93D22 90 47 BLX R2 .text:C8A93D24 05 00 MOVS R5, R0 .text:C8A93D26 20 00 MOVS R0, R4 .text:C8A93D28 07 F0 CE FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93D2C 00 26 MOVS R6, #0 .text:C8A93D2E 00 28 CMP R0, #0 .text:C8A93D30 05 D0 BEQ loc_C8A93D3E .text:C8A93D32 00 2D CMP R5, #0 .text:C8A93D34 20 B4 PUSH {R5} .text:C8A93D36 02 BC POP {R1} .text:C8A93D38 00 D0 BEQ loc_C8A93D3C .text:C8A93D3A A8 E0 B loc_C8A93E8E .text:C8A93D3C ; --------------------------------------------------------------------------- .text:C8A93D3C .text:C8A93D3C loc_C8A93D3C ; CODE XREF: main2_sub_B6891C78+C0↑j .text:C8A93D3C AB E0 B loc_C8A93E96 .text:C8A93D3E ; --------------------------------------------------------------------------- .text:C8A93D3E .text:C8A93D3E loc_C8A93D3E ; CODE XREF: main2_sub_B6891C78+B8↑j .text:C8A93D3E 00 2D CMP R5, #0 .text:C8A93D40 00 D1 BNE loc_C8A93D44 .text:C8A93D42 A8 E0 B loc_C8A93E96 .text:C8A93D44 ; --------------------------------------------------------------------------- .text:C8A93D44 .text:C8A93D44 loc_C8A93D44 ; CODE XREF: main2_sub_B6891C78+C8↑j .text:C8A93D44 05 95 STR R5, [SP,#0x50+var_3C] .text:C8A93D46 63 4E LDR R6, =(byte_C8B2D4E1 - 0xC8A93D4C) .text:C8A93D48 7E 44 ADD R6, PC ; byte_C8B2D4E1 .text:C8A93D4A 30 78 LDRB R0, [R6] .text:C8A93D4C 00 28 CMP R0, #0 .text:C8A93D4E 0A D1 BNE loc_C8A93D66 .text:C8A93D50 61 4D LDR R5, =(aLoadclass - 0xC8A93D56) ; "loadClass" .text:C8A93D52 7D 44 ADD R5, PC ; "loadClass" .text:C8A93D54 61 49 LDR R1, =(aMkfnnRej - 0xC8A93D5A) ; "mkfnN|rej" .text:C8A93D56 79 44 ADD R1, PC ; "mkfnN|rej" .text:C8A93D58 01 22 MOVS R2, #1 .text:C8A93D5A 09 23 MOVS R3, #9 .text:C8A93D5C 28 00 MOVS R0, R5 .text:C8A93D5E F7 F7 7F F9 BL DecString .text:C8A93D62 00 20 MOVS R0, #0 .text:C8A93D64 68 72 STRB R0, [R5,#(aLoadclass+9 - 0xC8B1E49F)] ; "" .text:C8A93D66 .text:C8A93D66 loc_C8A93D66 ; CODE XREF: main2_sub_B6891C78+D6↑j .text:C8A93D66 06 9D LDR R5, [SP,#0x50+var_38] .text:C8A93D68 35 70 STRB R5, [R6] .text:C8A93D6A 5D 4E LDR R6, =(byte_C8B2D4E2 - 0xC8A93D70) .text:C8A93D6C 7E 44 ADD R6, PC ; byte_C8B2D4E2 .text:C8A93D6E 30 78 LDRB R0, [R6] .text:C8A93D70 00 28 CMP R0, #0 .text:C8A93D72 0E D1 BNE loc_C8A93D92 .text:C8A93D74 5B 48 LDR R0, =(aLjavaLangStrin - 0xC8A93D7A) ; "(Ljava/lang/String;)Ljava/lang/Class;" .text:C8A93D76 78 44 ADD R0, PC ; "(Ljava/lang/String;)Ljava/lang/Class;" .text:C8A93D78 03 90 STR R0, [SP,#0x50+var_44] .text:C8A93D7A 5B 49 LDR R1, =(unk_C8B1E8C0 - 0xC8A93D80) .text:C8A93D7C 79 44 ADD R1, PC ; unk_C8B1E8C0 .text:C8A93D7E 02 22 MOVS R2, #2 .text:C8A93D80 25 23 MOVS R3, #0x25 ; '%' .text:C8A93D82 04 93 STR R3, [SP,#0x50+var_40] .text:C8A93D84 04 9B LDR R3, [SP,#0x50+var_40] .text:C8A93D86 F7 F7 6B F9 BL DecString .text:C8A93D8A 00 20 MOVS R0, #0 .text:C8A93D8C 04 99 LDR R1, [SP,#0x50+var_40] .text:C8A93D8E 03 9A LDR R2, [SP,#0x50+var_44] .text:C8A93D90 50 54 STRB R0, [R2,R1] .text:C8A93D92 .text:C8A93D92 loc_C8A93D92 ; CODE XREF: main2_sub_B6891C78+FA↑j .text:C8A93D92 35 70 STRB R5, [R6] .text:C8A93D94 20 68 LDR R0, [R4] .text:C8A93D96 84 21 MOVS R1, #0x84 .text:C8A93D98 46 58 LDR R6, [R0,R1] .text:C8A93D9A 54 4A LDR R2, =(aLoadclass - 0xC8A93DA0) ; "loadClass" .text:C8A93D9C 7A 44 ADD R2, PC ; "loadClass" .text:C8A93D9E 54 4B LDR R3, =(aLjavaLangStrin - 0xC8A93DA4) ; "(Ljava/lang/String;)Ljava/lang/Class;" .text:C8A93DA0 7B 44 ADD R3, PC ; "(Ljava/lang/String;)Ljava/lang/Class;" .text:C8A93DA2 20 00 MOVS R0, R4 .text:C8A93DA4 05 99 LDR R1, [SP,#0x50+var_3C] .text:C8A93DA6 B0 47 BLX R6 .text:C8A93DA8 05 00 MOVS R5, R0 .text:C8A93DAA 20 00 MOVS R0, R4 .text:C8A93DAC 07 F0 8C FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93DB0 00 26 MOVS R6, #0 .text:C8A93DB2 00 28 CMP R0, #0 .text:C8A93DB4 6A D1 BNE loc_C8A93E8C .text:C8A93DB6 00 2D CMP R5, #0 .text:C8A93DB8 68 D0 BEQ loc_C8A93E8C .text:C8A93DBA 20 00 MOVS R0, R4 .text:C8A93DBC 0B 99 LDR R1, [SP,#0x50+var_24] .text:C8A93DBE 2A 00 MOVS R2, R5 .text:C8A93DC0 08 9B LDR R3, [SP,#0x50+var_30] .text:C8A93DC2 00 F0 13 F9 BL CallObjectMethodV_sub_C6B99FEC .text:C8A93DC6 05 00 MOVS R5, R0 .text:C8A93DC8 20 00 MOVS R0, R4 .text:C8A93DCA 07 F0 7D FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93DCE 00 28 CMP R0, #0 .text:C8A93DD0 04 D0 BEQ loc_C8A93DDC .text:C8A93DD2 00 26 MOVS R6, #0 .text:C8A93DD4 00 2D CMP R5, #0 .text:C8A93DD6 05 99 LDR R1, [SP,#0x50+var_3C] .text:C8A93DD8 53 D1 BNE loc_C8A93E82 .text:C8A93DDA 58 E0 B loc_C8A93E8E .text:C8A93DDC ; --------------------------------------------------------------------------- .text:C8A93DDC .text:C8A93DDC loc_C8A93DDC ; CODE XREF: main2_sub_B6891C78+158↑j .text:C8A93DDC 00 2D CMP R5, #0 .text:C8A93DDE 05 99 LDR R1, [SP,#0x50+var_3C] .text:C8A93DE0 55 D0 BEQ loc_C8A93E8E .text:C8A93DE2 04 95 STR R5, [SP,#0x50+var_40] .text:C8A93DE4 43 4E LDR R6, =(byte_C8B2D4E3 - 0xC8A93DEA) .text:C8A93DE6 7E 44 ADD R6, PC ; byte_C8B2D4E3 .text:C8A93DE8 30 78 LDRB R0, [R6] .text:C8A93DEA 00 28 CMP R0, #0 .text:C8A93DEC 0A D1 BNE loc_C8A93E04 .text:C8A93DEE 42 4D LDR R5, =(aMain2 - 0xC8A93DF4) ; "main2" .text:C8A93DF0 7D 44 ADD R5, PC ; "main2" .text:C8A93DF2 42 49 LDR R1, =(aNgB - 0xC8A93DF8) ; "ng`b=" .text:C8A93DF4 79 44 ADD R1, PC ; "ng`b=" .text:C8A93DF6 03 22 MOVS R2, #3 .text:C8A93DF8 05 23 MOVS R3, #5 .text:C8A93DFA 28 00 MOVS R0, R5 .text:C8A93DFC F7 F7 30 F9 BL DecString .text:C8A93E00 00 20 MOVS R0, #0 .text:C8A93E02 68 71 STRB R0, [R5,#(aMain2+5 - 0xC8B1E4CF)] ; "" .text:C8A93E04 .text:C8A93E04 loc_C8A93E04 ; CODE XREF: main2_sub_B6891C78+174↑j .text:C8A93E04 06 9D LDR R5, [SP,#0x50+var_38] .text:C8A93E06 35 70 STRB R5, [R6] .text:C8A93E08 3D 4E LDR R6, =(byte_C8B2D4E4 - 0xC8A93E0E) .text:C8A93E0A 7E 44 ADD R6, PC ; byte_C8B2D4E4 .text:C8A93E0C 30 78 LDRB R0, [R6] .text:C8A93E0E 00 28 CMP R0, #0 .text:C8A93E10 0E D1 BNE loc_C8A93E30 .text:C8A93E12 3C 48 LDR R0, =(aILjavaLangObje_0 - 0xC8A93E18) ; "(I[Ljava/lang/Object;)Ljava/lang/Object"... .text:C8A93E14 78 44 ADD R0, PC ; "(I[Ljava/lang/Object;)Ljava/lang/Object"... .text:C8A93E16 02 90 STR R0, [SP,#0x50+var_48] .text:C8A93E18 3B 49 LDR R1, =(unk_C8B1E8F0 - 0xC8A93E1E) .text:C8A93E1A 79 44 ADD R1, PC ; unk_C8B1E8F0 .text:C8A93E1C 04 22 MOVS R2, #4 .text:C8A93E1E 28 23 MOVS R3, #0x28 ; '(' .text:C8A93E20 03 93 STR R3, [SP,#0x50+var_44] .text:C8A93E22 03 9B LDR R3, [SP,#0x50+var_44] .text:C8A93E24 F7 F7 1C F9 BL DecString .text:C8A93E28 00 20 MOVS R0, #0 .text:C8A93E2A 03 99 LDR R1, [SP,#0x50+var_44] .text:C8A93E2C 02 9A LDR R2, [SP,#0x50+var_48] .text:C8A93E2E 50 54 STRB R0, [R2,R1] .text:C8A93E30 .text:C8A93E30 loc_C8A93E30 ; CODE XREF: main2_sub_B6891C78+198↑j .text:C8A93E30 35 70 STRB R5, [R6] .text:C8A93E32 71 20 80 00 MOVS R0, #0x1C4 .text:C8A93E36 21 68 LDR R1, [R4] .text:C8A93E38 0D 58 LDR R5, [R1,R0] .text:C8A93E3A 34 4A LDR R2, =(aMain2 - 0xC8A93E40) ; "main2" .text:C8A93E3C 7A 44 ADD R2, PC ; "main2" .text:C8A93E3E 34 4B LDR R3, =(aILjavaLangObje_0 - 0xC8A93E44) ; "(I[Ljava/lang/Object;)Ljava/lang/Object"... .text:C8A93E40 7B 44 ADD R3, PC ; "(I[Ljava/lang/Object;)Ljava/lang/Object"... .text:C8A93E42 20 00 MOVS R0, R4 .text:C8A93E44 04 99 LDR R1, [SP,#0x50+var_40] .text:C8A93E46 A8 47 BLX R5 .text:C8A93E48 05 00 MOVS R5, R0 .text:C8A93E4A 20 00 MOVS R0, R4 .text:C8A93E4C 07 F0 3C FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93E50 00 26 MOVS R6, #0 .text:C8A93E52 00 28 CMP R0, #0 .text:C8A93E54 14 D1 BNE loc_C8A93E80 .text:C8A93E56 2A 00 MOVS R2, R5 .text:C8A93E58 00 2D CMP R5, #0 .text:C8A93E5A 04 9D LDR R5, [SP,#0x50+var_40] .text:C8A93E5C 11 D0 BEQ loc_C8A93E82 .text:C8A93E5E 68 46 MOV R0, SP .text:C8A93E60 09 99 LDR R1, [SP,#0x50+var_2C] .text:C8A93E62 01 60 STR R1, [R0,#0x50+var_50] .text:C8A93E64 20 00 MOVS R0, R4 .text:C8A93E66 29 00 MOVS R1, R5 .text:C8A93E68 0A 9B LDR R3, [SP,#0x50+var_28] .text:C8A93E6A 00 F0 DD F8 BL CallStaticObjectMethodV_sub_B6892028 .text:C8A93E6E 0A 90 STR R0, [SP,#0x50+var_28] .text:C8A93E70 20 00 MOVS R0, R4 .text:C8A93E72 07 F0 29 FD BL ExceptionCheck_sub_C6BA18C8 .text:C8A93E76 00 26 MOVS R6, #0 .text:C8A93E78 00 28 CMP R0, #0 .text:C8A93E7A 02 D1 BNE loc_C8A93E82 .text:C8A93E7C 0A 9E LDR R6, [SP,#0x50+var_28] .text:C8A93E7E 00 E0 B loc_C8A93E82 .text:C8A93E80 ; --------------------------------------------------------------------------- .text:C8A93E80 .text:C8A93E80 loc_C8A93E80 ; CODE XREF: main2_sub_B6891C78+1DC↑j .text:C8A93E80 04 9D LDR R5, [SP,#0x50+var_40] .text:C8A93E82 .text:C8A93E82 loc_C8A93E82 ; CODE XREF: main2_sub_B6891C78+160↑j .text:C8A93E82 ; main2_sub_B6891C78+1E4↑j ... .text:C8A93E82 20 68 LDR R0, [R4] .text:C8A93E84 C2 6D LDR R2, [R0,#0x5C] .text:C8A93E86 20 00 MOVS R0, R4 .text:C8A93E88 29 00 MOVS R1, R5 .text:C8A93E8A 90 47 BLX R2 .text:C8A93E8C .text:C8A93E8C loc_C8A93E8C ; CODE XREF: main2_sub_B6891C78+13C↑j .text:C8A93E8C ; main2_sub_B6891C78+140↑j .text:C8A93E8C 05 99 LDR R1, [SP,#0x50+var_3C]
獲取到的dfpid如下:
DAD796C46B5A6525F4B89DF661A97C7A218A219FC24B93F689DEBD92
5.4、獲取xid (設備指紋)
判斷本地是否有存儲,如果有優先讀取本地,如果無反謝java層從服務器端獲取,APP第一次運行進就用UUID與時間加密生成一個,這部分詳細分析見后面設備指紋部分。
.text:C8AEE3A4 F0 B5 PUSH {R4-R7,LR} .text:C8AEE3A6 03 AF ADD R7, SP, #0xC .text:C8AEE3A8 81 B0 SUB SP, SP, #4 .text:C8AEE3AA 0C 00 MOVS R4, R1 .text:C8AEE3AC 06 00 MOVS R6, R0 .text:C8AEE3AE 00 23 MOVS R3, #0 .text:C8AEE3B0 20 00 MOVS R0, R4 .text:C8AEE3B2 11 00 MOVS R1, R2 .text:C8AEE3B4 1A 00 MOVS R2, R3 .text:C8AEE3B6 A5 F7 5F FC BL main2_sub_B6891C78 ; 反射調用java層 .text:C8AEE3BA 05 00 MOVS R5, R0 .text:C8AEE3BC 20 00 MOVS R0, R4 .text:C8AEE3BE AD F7 83 FA BL ExceptionCheck_sub_C6BA18C8 .text:C8AEE3C2 00 28 CMP R0, #0 .text:C8AEE3C4 09 D0 BEQ loc_C8AEE3DA .text:C8AEE3C6 9C F7 5B F9 BL malloc_sub_C8BC6680 .text:C8AEE3CA 01 00 MOVS R1, R0 .text:C8AEE3CC 7C 31 ADDS R1, #0x7C ; '|' .text:C8AEE3CE 30 00 MOVS R0, R6 .text:C8AEE3D0 15 F0 30 FA BL empty_sub_C6C09834 .text:C8AEE3D4 00 2D CMP R5, #0 .text:C8AEE3D6 07 D1 BNE loc_C8AEE3E8 .text:C8AEE3D8 13 E0 B loc_C8AEE402 .text:C8AEE3DA ; --------------------------------------------------------------------------- .text:C8AEE3DA .text:C8AEE3DA loc_C8AEE3DA ; CODE XREF: main2_sub_B292E3A4+20↑j .text:C8AEE3DA 00 2D CMP R5, #0 .text:C8AEE3DC 0A D0 BEQ loc_C8AEE3F4 .text:C8AEE3DE 30 00 MOVS R0, R6 .text:C8AEE3E0 21 00 MOVS R1, R4 .text:C8AEE3E2 2A 00 MOVS R2, R5 .text:C8AEE3E4 A9 F7 CE FC BL String_sub_B28D7D84 ; 出現字符串
獲取到的xid如下:
Rs8NOy0BFS5JQxfdOoIxpMnKV3iqYWcblAjp0vpnWZyNzyF9rfsi3ekpm4ScaIZgeImizX/5AbS3e838Or4el4+PPPI2kD8XW+8vbvjDBSM=
組合json
{ "a0": "2.0", "a1": "9b69f861-e054-4bc4-9daf-d36ae205ed3e", "a3": 2, "a4": 1631754963, "a5": "An2sai6nXEuFYeKbDUk/qEo/7am8Jtn3O2Has5efofCux7iubGRCS8TKpjUgotJ6MGdQrBsvwh/peZwuikT+5rCr4RzN8SXXCeDOtZQ6sbo/snVdESSJweNqd6i/WbIwDOgv5eaWRQoISjdgNfW3hk7tf0QhsZFbOELcPxz5pRzo6d6EsBLFu5Mq8DbVNgsYF+6aqZ7302/G+Rr7MlUT2M9y3EjgjH01L39q/eRJ", "a6": 1025, "a7": "Rs8NOy0BFS5JQxfdOoIxpMnKV3iqYWcblAjp0vpnWZyNzyF9rfsi3ekpm4ScaIZgeImizX/5AbS3e838Or4el4+PPPI2kD8XW+8vbvjDBSM=", "a8": "DAD796C46B5A6525F4B89DF661A97C7A218A219FC24B93F689DEBD92", "a9": "f4ec12efNkQBqdtVlV78x1/Mln2Us/xw171NuJjdEXrGWsFDdMV5Te45wqjL0nPO8OFFKjvKthvva+lS9xqhMhSt1WZRjDYpsWc/eh3z4F2JTv3MOh8NEDmk7Frthx5/bczdDIKvRP0QneTfNKSm116fUjdLhOEYlNbym/xI+5jZAEJGfGjltFLEOmtOwgxasgHQh2woMl/vAyr7ePuoVC6wEcbv2+w6n/+Pl1U1KO2YcTw4peiZDqC7iHpTVQH4fWri9R5+Ev1zx/xObVqoxqe3TEW/t2EIRqQ4QoRZRix0xC6C280faz8U5vOqafUnm+qev7tjs7SOV4SNxBv+LEJTxr5IJU302FJEk/CqhKoz5eWRYtT5Z52kEanlfu4AGHcJLC343kpI3GxYw7uPeewA/Ye0qDgZUyfj0MPpaYMPj0UmtvnbXEU4+FaRaCb/LsQtWdOtEiEKveUQU9bTW4NfHch2+6gcHP2/E+UQSlREX67PPa9XN8tgL4H6qzghiE1NL3gYw0rrjzEXiO6jsjvIdzwDjeab9woJyr8W3xSACz3sezUS+AJAKohnJvlQkFM9cdG3lPYS7gByAK++K2/vI714kxJHqCZQQMbVNsoWj5w64YL+sE1A4byzOPgK71oPb9w6Cb+KwVlDtqH8F5vlVkO23Iq8E28BI2vQuq5TLRzMunjo45Ks2Py9ZZuHkGb+QIVpUz6ViB+JlUONKinIJF1p6g==", "a10": "{}", "x0": 1 }
每一個字段的解釋:
a0:版本,a1:appkey, a3:版本,a4:時間,a5:加密的設備環境,a6:固定數字,a7:xid,a8:dfpid,a9:初始化時加密的設備環境信息(前8字符中CRC:f4ec12ef)
5.5、計算請求體簽名值
獲取請求體數據
.text:C8A8FA4C 29 68 LDR R1, [R5] .text:C8A8FA4E 0A 58 LDR R2, [R1,R0] .text:C8A8FA50 28 00 MOVS R0, R5 .text:C8A8FA52 31 00 MOVS R1, R6 .text:C8A8FA54 90 47 BLX R2 ; 獲取body長度 .text:C8A8FA56 0A 90 STR R0, [SP,#0x28] .text:C8A8FA58 28 00 MOVS R0, R5 .text:C8A8FA5A 0B F0 35 FF BL ExceptionCheck_sub_C6BA18C8 .text:C8A8FA5E 00 28 CMP R0, #0 .text:C8A8FAF0 00 00 MOVS R0, R0 .text:C8A8FAF2 00 00 MOVS R0, R0 .text:C8A8FAF4 D8 74 STRB R0, [R3,#0x13] .text:C8A8FAF6 86 1B SUBS R6, R0, R6 .text:C8A8FAF8 10 99 LDR R1, [SP,#0xC+arg_34] ; 獲取body .text:C8A8FAFA 0B 20 MOVS R0, #0xB .text:C8A8FAFC C2 43 MVNS R2, R0 .text:C8A8FAFE 03 91 STR R1, [SP,#0xC+arg_0] .text:C8A8FB00 08 68 LDR R0, [R1] .text:C8A8FB02 02 92 STR R2, [SP,#0xC+var_4] .text:C8A8FB04 80 58 LDR R0, [R0,R2] .text:C8A8FB06 0A 9C LDR R4, [SP,#0xC+arg_1C] .text:C8A8FB08 00 19 ADDS R0, R0, R4 .text:C8A8FB0A 04 90 STR R0, [SP,#0xC+arg_4] .text:C8A8FB0C 46 1C ADDS R6, R0, #1 .text:C8A8FB0E 30 00 MOVS R0, R6 .text:C8A8FB10 FA F7 EA E8 BLX malloc ; 分配body存儲空間 .text:C8A8FB14 00 21 MOVS R1, #0 .text:C8A8FB16 06 91 STR R1, [SP,#0xC+arg_C] .text:C8A8FB18 32 00 MOVS R2, R6 .text:C8A8FB1A 06 00 MOVS R6, R0 .text:C8A8FB1C 20 F0 D0 FC BL memset_sub_C6BB64C0 .text:C8A8FB20 19 20 40 01 MOVS R0, #0x320 .text:C8A8FB24 29 68 LDR R1, [R5] .text:C8A8FB26 08 58 LDR R0, [R1,R0] .text:C8A8FB28 05 90 STR R0, [SP,#0xC+arg_8] .text:C8A8FB2A 68 46 MOV R0, SP .text:C8A8FB2C 06 60 STR R6, [R0,#0xC+var_C] .text:C8A8FB2E 28 00 MOVS R0, R5 .text:C8A8FB30 07 99 LDR R1, [SP,#0xC+arg_10] .text:C8A8FB32 06 9A LDR R2, [SP,#0xC+arg_C] .text:C8A8FB34 23 00 MOVS R3, R4 .text:C8A8FB36 05 9C LDR R4, [SP,#0xC+arg_8] .text:C8A8FB38 A0 47 BLX R4 ; GetByteArrayRegion .text:C8A8FB38 ; 獲取要計算簽名的body值 .text:C8A8FB3A 28 00 MOVS R0, R5 .text:C8A8FB3C 0B F0 C4 FE BL ExceptionCheck_sub_C6BA18C8 .text:C8A8FB40 00 28 CMP R0, #0
獲取的數據(部分)
CB092000 50 4F 53 54 20 2F 76 35 2F 73 69 67 6E 20 7B 22 POST /v5/sign {" CB092010 64 61 74 61 22 3A 22 62 4A 62 50 67 72 4B 49 42 data":"bJbPgrKIB CB092020 6A 6D 4E 4E 2B 6B 63 30 39 66 66 6F 54 70 67 48 jmNN+kc09ffoTpgH CB092030 57 39 57 46 7A 43 6B 67 75 4D 4E 71 50 52 57 68 W9WFzCkguMNqPRWh CB092040 6A 70 41 67 2B 4E 62 45 70 76 47 62 44 42 54 47 jpAg+NbEpvGbDBTG CB092050 6E 79 31 38 6C 6C 39 38 75 43 37 44 68 67 2B 33 ny18ll98uC7Dhg+3 CB092060 56 44 39 31 62 38 50 67 67 47 2F 47 56 61 52 59 VD91b8PggG/GVaRY CB092070 71 4D 4C 37 33 36 30 6E 63 71 41 59 57 37 68 4A qML7360ncqAYW7hJ CB092080 4A 52 69 34 44 59 73 50 31 66 73 59 35 38 4F 79 JRi4DYsP1fsY58Oy
解密PIC數據獲取key (a7),解密流程與初始化時一樣。解密后的值
{"a1":0,"a10":400,"a2":"com.sankuai.meituan","a11":"c1ee9178c95d9ec75f0f076a374df94a032d54c8576298d4f75e653de3705449","a3":"0a16ecd60eb56a6a3349f66cdcf7f7bf5190e5a42d6280d8dc0ee3be228398ec","a4":1100030200,"k0":{"k1":"meituan1sankuai0","k2":"meituan0sankuai1","k3":"$MXMYBS@HelloPay","k4":"Maoyan010iauknaS","k5":"34281a9dw2i701d4","k6":"X%rj@KiuU+|xY}?f"},"a5":"11.3.200","a0":"pw/LhTdeoTTyaxPHcHMy+/ssGNS1ihNkrJ+uBI74FIfd90KlTil1m0i7FF/n0bhY","a6":"/HntC9XIfdUyII/UiVfx020EQPpHz2XZY3qzM2aiNmM0i0pB1yeSO689TY9SBB3s","a7":"QsHnU6kFjTYR8Z6tHEvkGMO2Hrt+NRnVQhmxg6EtVBzuzQcBpma3AdhTWNMpesFT","c0":{"c1":true,"c2":false},"a9":"SDEzWXi5LHL/cuMCZ1zYyv+0hIViqWWf+ShbUYILWf4=","a8":1603800117167}
解析json獲取a7
QsHnU6kFjTYR8Z6tHEvkGMO2Hrt+NRnVQhmxg6EtVBzuzQcBpma3AdhTWNMpesFT
appkey與pic中的a7異或
.text:C8A90424 20 00 MOVS R0, R4 .text:C8A90426 02 99 LDR R1, [SP,#8] .text:C8A90428 7E F0 12 FE BL sub_C8B0F050 .text:C8A9042C 03 98 LDR R0, [SP,#0xC] .text:C8A9042E 00 5D LDRB R0, [R0,R4] ; 取a7 QsHnU6kFjTYR8Z6tHEvkGMO2Hrt+NRnVQhmxg6EtVBzuzQcBpma3AdhTWNMpesFT .text:C8A90430 72 5C LDRB R2, [R6,R1] ; appkey 9b69f861-e054-4bc4-9daf-d36ae205ed3e .text:C8A90432 42 40 EORS R2, R0 .text:C8A90434 6A 54 STRB R2, [R5,R1] .text:C8A90436 01 34 ADDS R4, #1 .text:C8A90438 04 98 LDR R0, [SP,#0x10] .text:C8A9043A A0 42 CMP R0, R4 ; 判斷是否結束 .text:C8A9043C F2 D1 BNE loc_C8A90424 .text:C8A9043E 03 B5 PUSH {R0,R1,LR} .text:C8A90440 01 48 LDR R0, =0 .text:C8A90442 FF F7 DB FF BL loc_C8A903FC
異或后的值
BC79D120 5E 54 73 4D 30 7A 4C 44 57 34 53 77 44 40 55 51 ^TsM0zLDW4SwD@UQ BC79D130 22 50 45 6D 33 2F 2B 5D 01 40 70 35 2B 60 5E 63 "PEm3/+].@p5+`^c BC79D140 34 0C 5E 1D
再次異或
.text:C8A91C00 loc_C8A91C00 ; CODE XREF: hmac_sha256_sub_BB754BAC+6C↓j .text:C8A91C00 43 A9 ADD R1, SP, #0x160+var_54 .text:C8A91C02 09 5C LDRB R1, [R1,R0] ; 取APPkey與a7加密后數據 .text:C8A91C04 5C 22 MOVS R2, #0x5C ; '\' .text:C8A91C06 4A 40 EORS R2, R1 .text:C8A91C08 32 AB ADD R3, SP, #0x160+var_98 .text:C8A91C0A 1A 54 STRB R2, [R3,R0] ; 存值 .text:C8A91C0C 36 22 MOVS R2, #0x36 ; '6' .text:C8A91C0E 4A 40 EORS R2, R1 .text:C8A91C10 21 A9 ADD R1, SP, #0x160+var_DC .text:C8A91C12 0A 54 STRB R2, [R1,R0] ; 存值 .text:C8A91C14 01 30 ADDS R0, #1 .text:C8A91C16 40 28 CMP R0, #0x40 ; '@' ; 判斷是否結束 .text:C8A91C18 F2 D1 BNE loc_C8A91C00
異或后的值
CB0D3000 68 62 45 7B 06 4C 7A 72 61 02 65 41 72 76 63 67 hbE{.Lzra.eArvcg CB0D3010 14 66 73 5B 05 19 1D 6B 37 76 46 03 1D 56 68 55 .fs[...k7vF..VhU CB0D3020 02 3A 68 2B 36 36 36 36 36 36 36 36 36 36 36 36 .:h+666666666666 CB0D3030 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666
將異或后的值與請求體組合
CB0D3000 68 62 45 7B 06 4C 7A 72 61 02 65 41 72 76 63 67 hbE{.Lzra.eArvcg CB0D3010 14 66 73 5B 05 19 1D 6B 37 76 46 03 1D 56 68 55 .fs[...k7vF..VhU CB0D3020 02 3A 68 2B 36 36 36 36 36 36 36 36 36 36 36 36 .:h+666666666666 CB0D3030 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 36 6666666666666666 CB0D3040 50 4F 53 54 20 2F 76 35 2F 73 69 67 6E 20 7B 22 POST /v5/sign {" CB0D3050 64 61 74 61 22 3A 22 62 4A 62 50 67 72 4B 49 42 data":"bJbPgrKIB CB0D3060 6A 6D 4E 4E 2B 6B 63 30 39 66 66 6F 54 70 67 48 jmNN+kc09ffoTpgH CB0D3070 57 39 57 46 7A 43 6B 67 75 4D 4E 71 50 52 57 68 W9WFzCkguMNqPRWh CB0D3080 6A 70 41 67 2B 4E 62 45 70 76 47 62 44 42 54 47 jpAg+NbEpvGbDBTG CB0D3090 6E 79 31 38 6C 6C 39 38 75 43 37 44 68 67 2B 33 ny18ll98uC7Dhg+3 CB0D30A0 56 44 39 31 62 38 50 67 67 47 2F 47 56 61 52 59 VD91b8PggG/GVaRY CB0D30B0 71 4D 4C 37 33 36 30 6E 63 71 41 59 57 37 68 4A qML7360ncqAYW7hJ
計算組合值的MD5
.text:C8A91C60 2A 00 MOVS R2, R5 .text:C8A91C62 00 F0 79 F9 BL md5_sub_BB7CFF58 ; R0:原始數后,R1:大小,R2:返回 .text:C8A91C66 05 AE ADD R6, SP, #0x160+var_14C .text:C8A91C68 55 21 MOVS R1, #0x55 ; 'U' .text:C8A91C6A 30 00 MOVS R0, R6 .text:C8A91C6C F8 F7 54 E8 BLX __aeabi_memclr4 .text:C8A91C70 32 A9 ADD R1, SP, #0x160+var_98 .text:C8A91C72 30 00 MOVS R0, R6 .text:C8A91C74 02 9A LDR R2, [SP,#0x160+var_158] .text:C8A91C76 1E F0 48 FC BL getvalu_sub_C87B550A .text:C8A91C7A 30 00 MOVS R0, R6 .text:C8A91C7C 40 30 ADDS R0, #0x40 ; '@' .text:C8A91C7E 14 22 MOVS R2, #0x14 .text:C8A91C80 29 00 MOVS R1, R5 .text:C8A91C82 1E F0 42 FC BL getvalu_sub_C87B550A .text:C8A91C86 54 21 MOVS R1, #0x54 ; 'T' .text:C8A91C88 30 00 MOVS R0, R6 .text:C8A91C8A 01 9A LDR R2, [SP,#0x160+var_15C] .text:C8A91C8C 00 F0 64 F9 BL md5_sub_BB7CFF58 ; R0:原始數后,R1:大小,R2:返回 .text:C8A91C90 20 00 MOVS R0, R4 ; p .text:C8A91C92 F8 F7 30 E8 BLX free
計算后得到的值
F0 EF 16 F8 BD C6 7B CC 8C B4 8F AC 4C EC 7A DB A8 A8 D1 05
解密PIC數據獲取KEY(a9)
解析json獲取a3:0a16ecd60eb56a6a3349f66cdcf7f7bf5190e5a42d6280d8dc0ee3be228398ec
a3為AES KEY解密a9解密后數據,該值作為加密body md5值的key
3ey2scPxek170m6K
AES加密Body計算得到的MD5值
IV 0102030405060708 key:3ey2scPxek170m6K .text:C8AA94F0 E0 F7 FA EB BLX malloc .text:C8AA94F4 00 26 MOVS R6, #0 .text:C8AA94F6 00 28 CMP R0, #0 .text:C8AA94F8 1C D0 BEQ loc_C8AA9534 .text:C8AA94FA 4A 99 LDR R1, [SP,#0x120+arg_0] .text:C8AA94FC 03 91 STR R1, [SP,#0x120+var_114] .text:C8AA94FE 07 AE ADD R6, SP, #0x120+var_104 .text:C8AA9500 F4 21 MOVS R1, #0xF4 .text:C8AA9502 02 90 STR R0, [SP,#0x120+var_118] .text:C8AA9504 30 00 MOVS R0, R6 .text:C8AA9506 E0 F7 08 EC BLX __aeabi_memclr4 .text:C8AA950A 80 21 MOVS R1, #0x80 .text:C8AA950C 20 00 MOVS R0, R4 .text:C8AA950E 32 00 MOVS R2, R6 .text:C8AA9510 56 F0 30 FF BL AES_set_Encrypt_key_sub_CB601374 ; R0:key,R1:長度,R2:返回值 .text:C8AA9514 06 9A LDR R2, [SP,#0x120+byte_count] .text:C8AA9516 01 20 MOVS R0, #1 .text:C8AA9518 69 46 MOV R1, SP .text:C8AA951A 04 9B LDR R3, [SP,#0x120+var_110] .text:C8AA951C 0B 60 STR R3, [R1,#0x120+var_120] .text:C8AA951E 48 60 STR R0, [R1,#0x120+var_11C] .text:C8AA9520 05 98 LDR R0, [SP,#0x120+p] .text:C8AA9522 02 9C LDR R4, [SP,#0x120+var_118] .text:C8AA9524 21 00 MOVS R1, R4 .text:C8AA9526 33 00 MOVS R3, R6 .text:C8AA9528 57 F0 7A FD BL AES_cbc_Encrypt_sub_CB602020 ; R0:原始數據,R1:返回,R2:大小,R3:key .text:C8AA952C 06 98 LDR R0, [SP,#0x120+byte_count] .text:C8AA952E 03 99 LDR R1, [SP,#0x120+var_114] .text:C8AA9530 08 60 STR R0, [R1] .text:C8AA9532 26 00 MOVS R6, R4 .text:C8AA9534 .text:C8AA9534 loc_C8AA9534 ; CODE XREF: Aes_sub_CB5AA4B8+40↑j .text:C8AA9534 05 98 LDR R0, [SP,#0x120+p] ; p .text:C8AA9536 E0 F7 DE EB BLX free
加密后數據
C7B9C460 06 34 4B B7 17 3B 29 9D FE B9 85 8D 24 6C 52 AE C7B9C470 BB AF 22 3F 8E 43 FB C5 66 2B 54 E2 C6 6A 54 EA
轉換成字符串
06344bb7173b299dfeb9858d246c52aebbaf223f8e43fbc5662b54e2c66a54ea
組合json,生成簽名
{ "a0": "2.0", "a1": "9b69f861-e054-4bc4-9daf-d36ae205ed3e", "a3": 2, "a4": 1631754963, "a5": "An2sai6nXEuFYeKbDUk/qEo/7am8Jtn3O2Has5efofCux7iubGRCS8TKpjUgotJ6MGdQrBsvwh/peZwuikT+5rCr4RzN8SXXCeDOtZQ6sbo/snVdESSJweNqd6i/WbIwDOgv5eaWRQoISjdgNfW3hk7tf0QhsZFbOELcPxz5pRzo6d6EsBLFu5Mq8DbVNgsYF+6aqZ7302/G+Rr7MlUT2M9y3EjgjH01L39q/eRJ", "a6": 1025, "a7": "Rs8NOy0BFS5JQxfdOoIxpMnKV3iqYWcblAjp0vpnWZyNzyF9rfsi3ekpm4ScaIZgeImizX/5AbS3e838Or4el4+PPPI2kD8XW+8vbvjDBSM=", "a8": "DAD796C46B5A6525F4B89DF661A97C7A218A219FC24B93F689DEBD92", "a9": "f4ec12efNkQBqdtVlV78x1/Mln2Us/xw171NuJjdEXrGWsFDdMV5Te45wqjL0nPO8OFFKjvKthvva+lS9xqhMhSt1WZRjDYpsWc/eh3z4F2JTv3MOh8NEDmk7Frthx5/bczdDIKvRP0QneTfNKSm116fUjdLhOEYlNbym/xI+5jZAEJGfGjltFLEOmtOwgxasgHQh2woMl/vAyr7ePuoVC6wEcbv2+w6n/+Pl1U1KO2YcTw4peiZDqC7iHpTVQH4fWri9R5+Ev1zx/xObVqoxqe3TEW/t2EIRqQ4QoRZRix0xC6C280faz8U5vOqafUnm+qev7tjs7SOV4SNxBv+LEJTxr5IJU302FJEk/CqhKoz5eWRYtT5Z52kEanlfu4AGHcJLC343kpI3GxYw7uPeewA/Ye0qDgZUyfj0MPpaYMPj0UmtvnbXEU4+FaRaCb/LsQtWdOtEiEKveUQU9bTW4NfHch2+6gcHP2/E+UQSlREX67PPa9XN8tgL4H6qzghiE1NL3gYw0rrjzEXiO6jsjvIdzwDjeab9woJyr8W3xSACz3sezUS+AJAKohnJvlQkFM9cdG3lPYS7gByAK++K2/vI714kxJHqCZQQMbVNsoWj5w64YL+sE1A4byzOPgK71oPb9w6Cb+KwVlDtqH8F5vlVkO23Iq8E28BI2vQuq5TLRzMunjo45Ks2Py9ZZuHkGb+QIVpUz6ViB+JlUONKinIJF1p6g==", "a10": "{}", "x0": 1, "a2": "06344bb7173b299dfeb9858d246c52aebbaf223f8e43fbc5662b54e2c66a54ea" }
a2:就是請求體簽名值,其它字段上面已經解釋過,然后將簽名值返回到java層,整個簽名流程就完成了。
六、設備指紋分析
6.1、dfpid基本流程
java層調用fetchDfpId()獲取dfpid
public boolean fetchDfpId(boolean arg13) { Object[] v8 = new Object[]{((byte)(((byte)arg13)))}; ChangeQuickRedirect v10 = DFPManager.changeQuickRedirect; if(PatchProxy.isSupport(v8, this, v10, false, "19489f6702cf81011acff69ff203e6a7", 0x4000000000000000L)) { return ((Boolean)PatchProxy.accessDispatch(v8, this, v10, false, "19489f6702cf81011acff69ff203e6a7")).booleanValue(); } try { if(this.isOutDate()) { label_49: if(!this.postDFPID(this.encDfpDataForId())) { // 服務器獲取 this.ensureLocalID(); // 讀取本地ID } } else { if(arg13) { goto label_49; } String v4 = this.idStore.getLocalDFPId(); if(!TextUtils.isEmpty(v4)) { goto label_38; } if(!this.postDFPID(this.encDfpDataForId())) { this.ensureLocalID(); return 1; label_38: this.idCallback.onSuccess(v4, ((long)DFPManager.ONE_HOUR) * ((long)this.idStore.getInterval()) + ((long)this.idStore.getLastUpdateTime()), "get dfp from local store"); long v7 = System.currentTimeMillis(); this.doPersistence(v4, this.idStore.getInterval().longValue(), v7); return 1; } } } catch(Throwable unused_ex) { } return 1; }
調用encDfpDataForId()方法走到Native層獲取請求體
public String encDfpDataForId() { Object[] v8 = new Object[0]; ChangeQuickRedirect v9 = DFPManager.changeQuickRedirect; if(PatchProxy.isSupport(v8, this, v9, false, "c899af894ac6d9a1a9df952ed8770d17", 0x4000000000000000L)) { return (String)PatchProxy.accessDispatch(v8, this, v9, false, "c899af894ac6d9a1a9df952ed8770d17"); } FamaCollector.hasCollected = true; return NBridge.main1(41, new Object[0]); // 請求體 }
調用postDFPID(String arg12)發送網絡請求獲取dfpid
url: https://appsec-mobile.meituan.com/v5/sign public boolean postDFPID(String arg12) { Object[] v0 = new Object[]{null}; v0[0] = arg12; ChangeQuickRedirect v9 = IDFPManager.changeQuickRedirect; if(PatchProxy.isSupport(v0, this, v9, false, "f625ba5594fc8256be5f644877e817ae", 0x4000000000000000L)) { return ((Boolean)PatchProxy.accessDispatch(v0, this, v9, false, "f625ba5594fc8256be5f644877e817ae")).booleanValue(); } Interceptor v0_1 = this.getInterceptor(); String v1 = this.getMtgVersion(); DFPReporter v0_2 = new Builder().addInterceptor(v0_1).addResponseParser(new IResponseParser() { public static ChangeQuickRedirect changeQuickRedirect; @Override // com.meituan.android.common.dfingerprint.network.IResponseParser public boolean onError(Call arg11, IOException arg12) { Object[] v0 = new Object[]{arg11, arg12}; ChangeQuickRedirect v12 = com.meituan.android.common.dfingerprint.interfaces.IDFPManager.1.changeQuickRedirect; if(PatchProxy.isSupport(v0, this, v12, false, "0231e3e90aba1d77b6009d4f4e808ce1", 0x4000000000000000L)) { return ((Boolean)PatchProxy.accessDispatch(v0, this, v12, false, "0231e3e90aba1d77b6009d4f4e808ce1")).booleanValue(); } Logger.logD("/v5/sign onError"); IDFPManager.this.ensureLocalID(); return 1; } @Override // com.meituan.android.common.dfingerprint.network.IResponseParser public boolean onResponse(Response arg23, long arg24, int arg26) { String v2_1; long interval; String dfpid; ResponseBody body; Object[] v11 = new Object[]{arg23, new Long(arg24), ((int)arg26)}; ChangeQuickRedirect v14 = com.meituan.android.common.dfingerprint.interfaces.IDFPManager.1.changeQuickRedirect; if(PatchProxy.isSupport(v11, this, v14, false, "cfa6814ee923204fe513080ced241785", 0x4000000000000000L)) { return ((Boolean)PatchProxy.accessDispatch(v11, this, v14, false, "cfa6814ee923204fe513080ced241785")).booleanValue(); } Logger.logD("/v5/sign onResponse $response"); if(arg23 == null) { return 0; } if(arg23.code() != 200) { MTGlibInterface.raptorAPI("v5_/v5/sign", arg23.code(), arg26, 0, System.currentTimeMillis() - arg24); return 0; } try { body = arg23.body(); if(body == null) { IDFPManager.this.idCallback.onFailed(-3, "request body is invalid"); return 0; } String v3 = new String(body.bytes()); MTGlibInterface.raptorAPI("v5_/v5/sign", arg23.code(), arg26, v3.length(), System.currentTimeMillis() - arg24); Logger.logD("RaptorMonitorService >> ${RaptorUtil.API_reportdfpidsync}"); Logger.logD("RaptorMonitorService result>> ${result}"); if(v3.isEmpty()) { IDFPManager.this.idCallback.onFailed(-3, "request body is invalid"); MTGlibInterface.raptorAPI("v5_/v5/sign", 9401, arg26, 0, System.currentTimeMillis() - arg24); return 0; } Logger.logD("/v5/sign response.body() >> $result"); DFPResponse body_json = (DFPResponse)new Gson().fromJson(v3, DFPResponse.class); if(body_json == null) { goto label_145; } if(body_json.code == 0xFFFFFF80) { goto label_145; } int v3_1 = body_json.code; if(v3_1 != 0) { IDFPManager.this.idCallback.onFailed(v3_1, body_json.message); MTGlibInterface.raptorAPI("v5_/v5/sign", 9402, arg26, 0, System.currentTimeMillis() - arg24); return 0; } dfpid = body_json.data.dataDfp; interval = body_json.data.dataInterval; v2_1 = body_json.message; } catch(Exception unused_ex) { IDFPManager.this.ensureLocalID(); MTGlibInterface.raptorAPI("v5_/v5/sign", 9405, arg26, 0, System.currentTimeMillis() - arg24); return 0; } try { Logger.logD("/v5/sign response, dataDecrypt > $dataDecrypt"); } catch(Exception unused_ex) { } try { // 如果等空讀取本地的 if(dfpid == "") { // 如果等空讀取本地的 IDFPManager.this.ensureLocalID(); } else { Logger.logD("/v5/sign 返回新的 local_dfp_id,需要保存它"); long currtime = System.currentTimeMillis(); if(DFPConfigs.isDfpidFirst) { MTGlibInterface.raptorFakeAPI("v5_dfpid_duration", 200, System.currentTimeMillis() - MTGuard.sFirstLaunchTime); DFPConfigs.isDfpidFirst = false; } IDFPManager.this.doPersistence(dfpid, interval, currtime); // 保存dfpid IDFPManager.this.idCallback.onSuccess(dfpid, interval * ((long)IDFPManager.ONE_HOUR) + currtime, v2_1); } body.close(); return 1; label_145: IDFPManager.this.idCallback.onFailed(-4, "body parse failed"); } catch(Exception unused_ex) { IDFPManager.this.ensureLocalID(); MTGlibInterface.raptorAPI("v5_/v5/sign", 9405, arg26, 0, System.currentTimeMillis() - arg24); } return 0; } }).build(); try { ReqeustBody v2 = new ReqeustBody(arg12, v1, null); Gson v12 = new GsonBuilder().disableHtmlEscaping().create(); if(v12 != null) { String v12_1 = v12.toJson(v2); Logger.logD("postDFPID body > $body"); return v0_2.reportDFPIDSync(v12_1, ContentType.application_json); // 網絡請求 } } catch(Exception unused_ex) { } return false; }
6.2、dfpid請求體分析
請求體調用Native層方法NBridge.main(41, new Object[0])在Native層計算得到
循環獲取設備信息
text:C8A8C684 09 98 LDR R0, [SP,#0x24] .text:C8A8C686 61 F0 CD FF BL getmContext_sub_CC9EF624 ; 獲取上下文件 .text:C8A8C68A 07 90 STR R0, [SP,#0x1C] .text:C8A8C68C 00 F0 14 FE BL init_DecString_sub_C84582B8 .text:C8A8C690 06 90 STR R0, [SP,#0x18] .text:C8A8C692 2B A8 ADD R0, SP, #0xAC .text:C8A8C694 05 90 STR R0, [SP,#0x14] .text:C8A8C696 09 99 LDR R1, [SP,#0x24] .text:C8A8C698 07 9A LDR R2, [SP,#0x1C] .text:C8A8C69A 2B 00 MOVS R3, R5 .text:C8A8C69C 26 F0 7A FC BL GetDeviceInfo_dispatch_loop_sub_C89F8F94 ; 獲取設備信息1 .text:C8A8C6A0 06 98 LDR R0, [SP,#0x18] .text:C8A8C6A2 29 00 MOVS R1, R5 .text:C8A8C6A4 05 9A LDR R2, [SP,#0x14] .text:C8A8C6A6 23 F0 8D FF BL jmp_checkField_sub_C89F65C4 ; 判斷獲取的內容是否為特殊字符mtg_unsupport,mtg_block,setup_empty .text:C8A8C6AA 2B 98 LDR R0, [SP,#0xAC] .text:C8A8C6AC 04 99 LDR R1, [SP,#0x10] .text:C8A8C6AE 40 18 ADDS R0, R0, R1 .text:C8A8C6B0 27 A9 ADD R1, SP, #0x9C .text:C8A8C6B2 77 F0 49 F8 BL free_sub_B2943748 .text:C8A8C6B6 07 99 LDR R1, [SP,#0x1C] .text:C8A8C6B8 00 29 CMP R1, #0 .text:C8A8C6BA 00 D1 BNE loc_C8A8C6BE .text:C8A8C6BC 4C E7 B loc_C8A8C558
在下面地方下好斷點跳到獲取設備信息的地方,可以繞過代碼流程混淆,快速定位到想要獲取設備信息的方法:
.text:C8AB5134 80 00 LSLS R0, R0, #2 ; 跳到真實執行方法 .text:C8AB5136 02 A1 ADR R1, loc_C8AB5140 .text:C8AB5138 08 58 LDR R0, [R1,R0] ; 取方法表偏移 .text:C8AB513A 08 18 ADDS R0, R1, R0 .text:C8AB513C 87 46 MOV PC, R0
獲取完設備信息后組合成json,主要獲取硬件類ID、imei、mac,系統屬性、CPU、內存、陀螺儀傳感器等
{ "m20": "3", "m22": "0", "m24": "-1", "m25": "0", "m26": "0", "m27": "DAD703FB1B789AFCFA0CAD4778CF9C8D0146219F941D41B66617A73F", "m28": "0", "m29": "28.5", "m30": "1", "m31": "0", "m32": "0", "m33": "1", "m34": "", "m35": "0", "m36": "0", "m37": "0", "m38": "1", "m39": "Google", "m40": "", "m41": "", "m42": "1", "m43": "23132356608", "m44": "1230796800000", "m45": "1", "m46": "", "m47": "android", "m48": "0", "m49": "nonetwork", "m50": "user", "m51": "1", "m52": "google", "m53": "unknown", "m54": "adb", "m55": "{\"data\":[36.107063],\"name\":\"TMD4903LightSensor\",\"vendor\":\"AMS\"}", "m56": "google/sailfish/sailfish:9/PQ2A.190305.002/5240760:user/release-keys", "m57": "[{\"ssid\":\"2F16C2\",\"bssid\":\"cc:ee:07:2f:16:c2\"},{\"ssid\":\"2F16C2\",\"bssid\":\"cc:ee:07:2f:16:c2\"},{\"ssid\":\"JinRong\",\"bssid\":\"cc:e9:e4:84:cc:76\"}]", "m58": "unknown", "m59": "0", "m60": "2283765760", "m61": "[1,BMI160accelerometer,1,Bosch,156,2500,0,0,4,BMI160gyroscope,1,Bosch,17,2500,0,0,2,AK09915magnetometer,1,AKM,1300,20000,0,0,6,BMP285pressure,1,Bosch,1100,100000,0,0,65536,BMP285temperature,1,Bosch,85,40000,0,0,8,TMD4903ProximitySensor,1,AMS,5,200000,0,1,5,TMD4903LightSensor,1,AMS,43000,200000,0,10,3,Orientation,1,Google,360,5000,0,1,18,BMI160Stepdetector,1,Bosch,1,0,0,1,17,Significantmotion,1,Google,1,-1,0,1,9,Gravity,1,Google,1000,5000,0,1,10,LinearAcceleration,1,Google,1000,5000,0,1,11,RotationVector,1,Google,1000,5000,0,1,20,GeomagneticRotationVector,1,Google,1000,5000,0,1,15,GameRotationVector,1,Google,1000,5000,0,1,25,PickupGesture,1,Google,1,-1,0,1,22,TiltDetector,1,Google,1,0,0,1,19,BMI160Stepcounter,1,Bosch,1,0,0,1,14,AK09915magnetometer(uncalibrated),1,AKM,1300,20000,0,0,16,BMI160gyroscope(uncalibrated),1,Bosch,17,2500,0,0,65537,SensorsSync,1,Google,1,0,0,1,65538,DoubleTwist,1,Google,1,0,0,1,65539,DoubleTap,1,Google,1,0,0,1,27,DeviceOrientation,1,Google,3,0,0,1,65540,DoubleTouch,1,Google,1,-1,0,1,35,BMI160accelerometer(uncalibrated),1,Bosch,156,2500,0,0,32,DynamicSensorManager,1,Google,1,1000,0,1]", "m62": "1", "m63": "0", "m64": "1", "m65": "1", "m66": "Bosch", "m67": "unknown", "m68": "", "m69": "352531086839980", "m70": "sailfish", "m71": "Gravity", "m72": "1", "m73": "com.qihoo.appstore-bin.mt.plus-cn.tongdun.sdkdemo-com.arcsoft.arcfacedemo-com.baidu.idl.face.demo-com.bjgas.shop-com.duapps.gif.emoji.gifmaker-com.mv.livebodyexample-com.sankuai.meituan-com.songheng.wubiime", "m74": "FA7740302912", "m75": "unknown", "m76": "QualcommRIL1.0", "m77": "BMI160accelerometer", "m78": "com.android.chrome-com.android.settings-com.android.vending-com.google.android.GoogleCamera-com.google.android.apps.docs-com.google.android.apps.maps-com.google.android.apps.messaging-com.google.android.apps.photos-com.google.android.calendar-com.google.android.contacts", "m79": "midi,adb", "m80": "", "m81": "8996-130181-1811270246", "m82": "32", "m83": "PQ2A.190305.002", "m84": "midi,adb", "m85": "", "m86": "PQ2A.190305.002", "m87": "lac:40980,cid:3909155,rssi:22|lac:-1,cid:-1,rssi:20", "m88": "cn", "m89": "release-keys", "m90": "1", "m91": "unknown", "m92": "", "m93": "{\"hashInfo\":[],\"number\":0}", "m94": "sailfish", "m95": "1", "m96": "8996-012001-1812132253", "m97": "", "m98": "Google", "m99": "", "m100": "0", "m101": "CN", "m102": "1", "m103": "26109874176", "m104": "1593600", "m105": "420", "m106": "0", "m107": "ac:37:43:df:02:7e", "m108": "android-build", "m111": "37cb81453cec878d", "m112": "unknown", "m116": "wlan0", "m117": "1631706064788", "m122": "AA==\n", "m123": "", "m125": "", "m126": "Dalvik/2.1.0(Linux;U;Android9;PixelBuild/PQ2A.190305.002)", "m127": "0.0000000000|0.0000000000", "m128": "unknown", "m129": "", "m130": "", "m131": "23132299264", "m132": "26109874176", "m133": "", "m134": "bus", "m135": "0.000000", "m136": "", "m137": "3.18.122-g665c9a1", "m138": "[2,95]", "m139": "4", "m140": "arm64-v8a,armeabi-v7a,armeabi", "m141": "0", "m142": "0.16470589", "m143": "0", "m144": "11.12.204", "m145": "mtguard", "m146": "1", "m147": "sailfish", "m148": "1631706140783", "m149": "1631706064", "m150": "1631754658276", "m151": "unknown", "m152": "5.1.7", "m153": "", "m154": "com.sankuai.meituan", "m155": "1629207179980", "m156": "", "m157": "3948302336", "m158": "sailfish", "m159": "abfarm722", "m160": "9", "m161": "0", "m162": "unknown", "m163": "0", "m164": "zh", "m165": "[GMT+08:00,Asia/Shanghai]", "m166": "Pixel", "m167": "1080*1794", "m253": "", "m254": "", "m255": "0", "m256": "", "m293": "DAD7A2870A2DAAA2F67190B216A34A886A9E219F941D662641A653D9", "m241": "", "m242": "", "m245": "{\"libc.so:\":\"E5592D3E966419A89DEF46F6BE029015\",\"libandroid.so:\":\"\",\"libandroid_runtime.so:\":\"2F4ADAB748DE1F97EACAC55B9584E504\",\"libandroid_servers.so:\":\"75AF8941A0B6C9A841C05442FE32CCFC\",\"framework.jar:\":\"\",\"services.jar:\":\"\",\"core.jar:\":\"\"}", "m246": "ae:37:43:df:02:7e", "m247": "35253108683998", "m289": "352531086839980", "m290": "352531086839980", "m294": "{\"1\":\"\",\"2\":\"1|2|3\",\"3\":\"\",\"4\":\"\",\"5\":\"\",\"6\":\"\",\"7\":\"2\",\"8\":\"\",\"9\":\"\",\"10\":\"\",\"11\":\"\",\"12\":\"32\",\"13\":\"\",\"14\":\"\",\"15\":\"\",\"33\":{\"0\":2,\"1\":\"\",\"2\":\"\",\"3\":\"\",\"4\":\"2|22\",\"5\":\"\",\"6\":\"\",\"7\":\"\",\"8\":\"\",\"9\":\"\",\"10\":\"\",\"11\":\"\",\"12\":\"\",\"13\":\"\",\"14\":\"2\",\"15\":\"\"}}", "m304": "-1", "m305": "1080*1920", "m217": "1631706064788185", "m243": "-1", "m244": "{\"DCIM\":\"00045F6737E705C00001C3B7F33CF3000005C810802CB9C0000083D1C295CA000005C810802CB9C0000083D1C295CA00\",\"Android\":\"00045F6737F648000002A40F89B18AC00005C5CB1C563D000000EE4ABA3499C00005C5CB1C563D000000EE4ABA3499C0\",\"misc\":\"0005BA6437AAF540000037EFB50958800005BDC662F5BF40000263501EE0BE000005BDC662F5BF40000263501EE0BE00\",\"settings\":\"00045F67360E000000005AF31103944000045F67360E000000005AF31103944000045F67360E000000005AF311039440\",\"saver\":\"0005BA6437AAF54000005F590941430000045F67377C360000014D7BCD19158000045F67377C360000014D7BCD191580\",\"mtp\":\"0005BA6437AAF5400000CC7CB757DE0000045F67360E00000001EB208F56774000045F67360E00000001EB208F567740\",\"calendar\":\"0005BA6437AAF54000008CD291CAAE4000045F6738AD630000019F5706658BC000045F6738AD630000019F5706658BC0\",\"media\":\"0005BA6437AAF5400000B7440023B8000000225E8BD0FF0000037B4E60CF5D000000225E8BD0FF0000037E567AF07C40\",\"misc_ce\":\"0005BA6437AAF540000062612371A48000045F6737D7C38000010AC9B10045C000057E646876D18000027F601A1B3540\",\"rollback\":\"\",\"system\":\"0005BA6437AAF54000005C50EF10E1800005CC17296EE1C0000373A4714044800005CC17296EE1C0000373A471404480\",\"data\":\"0005BA6437AAF5400000687157C325400005CC0732B344C000001BE686FAA0400005CC0732B344C000001BE686FAA040\",\"install_sessions\":\"0005BA6437AAF54000005F59094143000000225E8BD0FF00000329739E3E68C00000225E8BD0FF00000329739E3E68C0\",\"webview\":\"0005BA6437AAF54000008CD291CAAE4000045F6737C88140000104B976B8E40000045F6737C88140000107C190DA0340\"}", "m248": "", "m307": "{\"m34\":5,\"m40\":5,\"m41\":5,\"m46\":5,\"m58\":2,\"m67\":6,\"m68\":5,\"m75\":6,\"m80\":5,\"m85\":5,\"m91\":2,\"m92\":5,\"m97\":5,\"m99\":5,\"m112\":3,\"m123\":5,\"m125\":5,\"m128\":6,\"m129\":5,\"m130\":5,\"m133\":5,\"m136\":5,\"m151\":2,\"m153\":5,\"m156\":5,\"m162\":6,\"m253\":5,\"m254\":7,\"m256\":7,\"m241\":7,\"m242\":5,\"m248\":5}" }
6.3、加密設備數據
解密PIC數據獲取AES KEY, 解密后數據
{"a1":0,"a10":400,"a2":"com.sankuai.meituan","a11":"c1ee9178c95d9ec75f0f076a374df94a032d54c8576298d4f75e653de3705449","a3":"0a16ecd60eb56a6a3349f66cdcf7f7bf5190e5a42d6280d8dc0ee3be228398ec","a4":1100030200,"k0":{"k1":"meituan1sankuai0","k2":"meituan0sankuai1","k3":"$MXMYBS@HelloPay","k4":"Maoyan010iauknaS","k5":"34281a9dw2i701d4","k6":"X%rj@KiuU+|xY}?f"},"a5":"11.3.200","a0":"pw/LhTdeoTTyaxPHcHMy+/ssGNS1ihNkrJ+uBI74FIfd90KlTil1m0i7FF/n0bhY","a6":"/HntC9XIfdUyII/UiVfx020EQPpHz2XZY3qzM2aiNmM0i0pB1yeSO689TY9SBB3s","a7":"QsHnU6kFjTYR8Z6tHEvkGMO2Hrt+NRnVQhmxg6EtVBzuzQcBpma3AdhTWNMpesFT","c0":{"c1":true,"c2":false},"a9":"SDEzWXi5LHL/cuMCZ1zYyv+0hIViqWWf+ShbUYILWf4=","a8":1603800117167}
解析json得到 aes key:meituan1sankuai0
AES加密設備json數據
IV 0102030405060708 .text:C8AA94EE 06 98 LDR R0, [SP,#0x120+byte_count] ; byte_count .text:C8AA94F0 E0 F7 FA EB BLX malloc ; 存放加密后數據 .text:C8AA94F4 00 26 MOVS R6, #0 .text:C8AA94F6 00 28 CMP R0, #0 .text:C8AA94F8 1C D0 BEQ loc_C8AA9534 .text:C8AA94FA 4A 99 LDR R1, [SP,#0x120+arg_0] .text:C8AA94FC 03 91 STR R1, [SP,#0x120+var_114] .text:C8AA94FE 07 AE ADD R6, SP, #0x120+var_104 .text:C8AA9500 F4 21 MOVS R1, #0xF4 .text:C8AA9502 02 90 STR R0, [SP,#0x120+var_118] .text:C8AA9504 30 00 MOVS R0, R6 .text:C8AA9506 E0 F7 08 EC BLX __aeabi_memclr4 .text:C8AA950A 80 21 MOVS R1, #0x80 .text:C8AA950C 20 00 MOVS R0, R4 .text:C8AA950E 32 00 MOVS R2, R6 .text:C8AA9510 56 F0 30 FF BL AES_set_Encrypt_key_sub_CB601374 ; R0:key,R1:長度,R2:返回值 .text:C8AA9514 06 9A LDR R2, [SP,#0x120+byte_count] .text:C8AA9516 01 20 MOVS R0, #1 .text:C8AA9518 69 46 MOV R1, SP .text:C8AA951A 04 9B LDR R3, [SP,#0x120+var_110] .text:C8AA951C 0B 60 STR R3, [R1,#0x120+var_120] .text:C8AA951E 48 60 STR R0, [R1,#0x120+var_11C] .text:C8AA9520 05 98 LDR R0, [SP,#0x120+p] .text:C8AA9522 02 9C LDR R4, [SP,#0x120+var_118] .text:C8AA9524 21 00 MOVS R1, R4 .text:C8AA9526 33 00 MOVS R3, R6 .text:C8AA9528 57 F0 7A FD BL AES_cbc_Encrypt_sub_CB602020 ; R0:原始數據,R1:返回,R2:大小,R3:key .text:C8AA952C 06 98 LDR R0, [SP,#0x120+byte_count] .text:C8AA952E 03 99 LDR R1, [SP,#0x120+var_114] .text:C8AA9530 08 60 STR R0, [R1] .text:C8AA9532 26 00 MOVS R6, R4 .text:C8AA9534 .text:C8AA9534 loc_C8AA9534 ; CODE XREF: Aes_sub_CB5AA4B8+40↑j .text:C8AA9534 05 98 LDR R0, [SP,#0x120+p] ; p .text:C8AA9536 E0 F7 DE EB BLX free
加密后數據(部分)
C6A47000 6C 96 CF 82 B2 88 06 39 8D 37 E9 1C D3 D7 DF A1 l.ς ...9.7...... C6A47010 A1 D7 C5 C7 A2 1F 21 47 F4 8D F8 E3 59 55 68 87 ...Ǣ .!G....YUh. C6A47020 13 D2 C7 A5 AD 47 51 04 64 B2 86 3A 86 AA 47 36 .....GQ.d..:..G6 C6A47030 8A 26 F7 03 A0 42 3F 4E B7 43 53 F5 E8 DE 9A 48 .&....?N.CS....H C6A47040 FF 7D CC D3 30 91 1C 59 34 6C 3C D5 A4 45 AD 8A .}..0..Y4l<դ E.. C6A47050 69 06 49 EA 1B B5 95 7F 40 3F AF BE DB 18 CB CD i.I.....@?...... C6A47060 85 A9 05 0E 02 43 1C 10 2C 50 53 9F A0 A1 6D 14 .....C..,PS...m. C6A47070 DF F9 23 99 64 3C E4 D8 7C 56 58 C0 35 E6 81 34 ..#.d<...VX..... C6A47080 9B 9C 6D A3 92 5B 36 50 6E 85 79 6E 2A 6C EB BF ..m..[6Pn.yn*l.. C6A47090 59 F5 77 F3 C3 F8 3D 47 04 D4 55 FB C1 D6 8D 3A Y.....=G.......: C6A470A0 0F 4D EF 9E A2 C0 DF 93 58 B5 E1 79 22 EE 6A 65 .M ...X....... C6A470B0 A4 A8 47 7F 68 BA C1 C7 19 96 8A 9E 29 90 48 07 ..G.h.......).H.
base64加密(部分)
bJbPgrKIBjmNN+kc09ffoaHXxceiHyFH9I3441lVaIcT0selrUdRBGSyhjqGqkc2iib3A6BCP063Q1P16N6aSP99zNMwkRxZNGw81aRFrYppBknqG7WVf0A/r77bGMvNhakFDgJDHBAsUFOfoKFtFN/5I5lkPOTYfFZYwDXmgTSbnG2jkls2UG6FeW4qbOu/WfV388P4PUcE1FX7wdaNOg9N756iwN+TWLXheSLuamWkqEd/aLrBxxmWip4pkEgHlLK14AbB68tlUvIauN50i/KZVCun9lA13FmhY9t4JiZYMuQUiluXGtFLoVLUb3ybe9Uy156k8NFn8sZkCzx5I1nUFKEx2Mgb6Q+SDXY1r4TCh6jYCYd/Dfr+n1ccN+Z7M8oceexb3KD+yapCYKvhj2sm5/WptX+ncnTTalrLG8U53YZAJtwQ2NTZ/yuVJWNpnEjRE3EI
返回java層組合請求體,計算請求頭簽名發送給服務器獲取dfpid 請求體格式
{"data":"Native加密的設備數據","dfpVersion":"5.1.7","mtgVersion":"5.1.7","os":"Android","time":"2021-09-01 11:35:35"}
計算的請求頭簽名
{"a0":"2.0","a1":"9b69f861-e054-4bc4-9daf-d36ae205ed3e","a3":2,"a4":1631778284,"a5":"A18ywLdCS48BnwSLKup0wrjB+dsq4S6V+9BZPtgOWyf76KKpdYv8xejvBBC8HE6C4uRAl79/X7icd48pdktGG8B0+yAbMGtUl5Ri2kQc4/RgxjDiN64MjMvus7Aok+9LqzRZW1W9Qj2yJoMyK7h57/+amTSLDqyUzbat6zAgCAdeZ/vbKk+34+NVNwoz7fMLqvRlGbTVLZddTFIQvzbs1rNC3eV7mH9ORw==","a6":0,"a7":"lpArUzLcl+lgZ9YXlGR9nPVqJMM2UvrBYyFRM2UsDIidftxLwpEOzzcZ7NPmHxahYSpXrJr/eHv4y2FmjsLwnykKopieCU4Prh4FskqVsRg=","a8":"DAD796C46B5A6525F4B89DF661A97C7A218A219FC24B93F689DEBD92","a9":"97a62b63j1IexpGhrGBYdWqnstTXCpGUZncRa5MAcc5LtAO65uXQ/gPQuhqUcACAU5Cstbgs/wxZr8oFrMNqpSDo+Lt3QT7CenBY9BUnVn6bSHYNAaPhQ3WxYc1fpRi3+Lfpqz6/6CtwzNM113yKUoIgwMQZ2TTkRJ5S7JI0PztFc8u2I5ngz2thHx3rIXDjNXhmxoo7xH9rULUa65Y1zdPRx2xVNGDUJDFX78jvL39wIkvvnqBMK54GyQ8F8Vd/+lyPg1Wi3GoVUyFKrfw5RRDTElNyby2CvgQVKFRwHYbJu8OS3TjT6sW4uqmNxZQl4Zg4DBg/C6vlXAZISTCiCzC5yQ/xfqrQ5hNmKmsfHiVMduB7XYh9INAqceiTRlPV/ccY/JeGPRTbo52FoIHEponCLaToMU08uJVYC+hvT21OB/Wae2dr1l0vF4zDP+109YHgf7HbHg40TJW+UfIJdkAR0XHDINEqZIPmgE7jgon2B9KMXSyrWTg3OvOVA2USc7lBX9/8s1AXyI6MYgb7JwddM/cajZJle9ipMzJTmSZbJPw8o3bHGlt2pTtXzJb7mLgOxS1cwoc2kUTQYkRz5irPM1bhY4dT33d0tOr6C8IjROMgQMuIsVxKYCt88qo8ESk/nZEpVcWvBlsM+HWSwjHKtOJ8iPl3EqwSQiWRjVN6bOQyQIsPNVTfkZHSBqKnJ4dXcjXMTqcxGgxEzfD5sLfzXDz71A==","a10":"{}","x0":1,"a2":"0f4513356e64a6d70d962a764b1d68b8"}
發送給服務器后成功返回dfpid
{"code":0,"data":{"serverTimestamp":0,"clientIp":"218.xx.xx.xx","interval":24,"dfp":"8ecde1544fbe09ba3ec851e72fdd28c0803df1f83c5c0862c8ad571c"},"message":"ok"}
以上就是完整的dfpid設備指紋生成過程,xid生成也是類似的,也是在Native層獲取設備信息加密返回到java層組合請求體,計算請求頭簽名,發送給服務器計算ID返回ID的過程,我就不再重復分析了。
七、設備指紋攻擊
7.1、設備指紋原理
設備指紋是用來標識手機設備的唯一ID,能夠通過這個ID關聯到手機相關的全部數據,因此設備指紋是風控中最核心的數據之一,所以它需要具備以下幾個條件時ID不變:設備重置、設備更新、設備刷機。要同時具備這樣的條件,必須從多個維度采集不同的信息來生成ID,這些信息可以大致分為:軟件ID、軟件靜態特征、硬件靜態特征和硬件動態特征。采集完信息后如何基於這些信息計算出一個穩定的設備指紋ID,還是有比較大挑戰,再加上目前國家對公民隱私保護嚴格,用戶敏感信息不能采集,很多唯一性比較好的數據就失效,要做一穩定性高的ID就難上加難了。
7.2、設備指紋變與不變
既然設備指紋ID是根據手機設備的數據生成的,哪么我們的攻擊思路就是修改設備信息,同一台手機不斷變化設備信息讓生成設備指紋的服務返回新的ID就算攻擊成功了,因為它無法識別手機的唯一性。
實戰修改設備字段生成新的dfpid
測試過程就是在內存中將采集的某設備字段改掉就可以生成新的設備ID(該字段是軟件相關的ID,比較敏感就不說了,總共沒有多少字段,想玩的朋友可以自己調試測試)
修改前后對比圖7-1與7-2所示,返回新的ID:
圖7-1
圖7-2
八、黑產工具特征檢測
8.1、解密黑產工具特征
獲取密鑰,解密PIC數據獲取key(a9)
.text:C8571594 20 00 MOVS R0, R4 .text:C8571596 32 00 MOVS R2, R6 .text:C8571598 57 F0 7A F8 BL AES_set_decrypt_key_sub_CB601690 ; R0:key,R1:大小,R2:初始AES_KEY返回結構 .text:C857159C 00 20 MOVS R0, #0 .text:C857159E 69 46 MOV R1, SP .text:C85715A0 06 9A LDR R2, [SP,#0x128+var_110] .text:C85715A2 0A 60 STR R2, [R1,#0x128+var_128] .text:C85715A4 48 60 STR R0, [R1,#0x128+var_124] .text:C85715A6 08 98 LDR R0, [SP,#0x128+var_108] .text:C85715A8 04 9E LDR R6, [SP,#0x128+var_118] .text:C85715AA 31 00 MOVS R1, R6 .text:C85715AC 07 9C LDR R4, [SP,#0x128+var_10C] .text:C85715AE 22 00 MOVS R2, R4 .text:C85715B0 03 9B LDR R3, [SP,#0x128+var_11C] .text:C85715B2 57 F0 35 FD BL AES_cbc_Encrypt_sub_CB602020 .text:C85715B6 30 00 MOVS R0, R6
解密后特征
{ "0": 2, "1": "", "2": ["/sys/devices/virtual/misc/qemu_pipe", "/sys/module/vboxsf", "/system/droid4x", "/system/bin/droid4x-vbox-sf", "/system/lib/egl/libEGL_tiDetectanVM.so", "/system/bin/ttVM-vbox-sf", "/system/lib/libnox.so", "/system/bin/nox-vbox-sf", "/system/bin/androVM-vbox-sf", "/ueventd.vbox86.rc", "/sys/class/misc/qemu_pipe", "/sys/qemu_trace", "/dev/com.bluestacks.superuser.daemon", "/system/framework/libqemu_wl.txt", "/system/lib/libc_malloc_debug_qemu.so-arm", "/data/downloads/qemu_list.txt", "/system/bin/yiwan-prop", "/system/bin/yiwan-sf", "/system/bin/qemu_props", "/system/bin/androVM-prop", "/system/bin/microvirt-prop", "/system/lib/libdroid4x.so", "/system/bin/windroyed", "/system/bin/microvirtd", "/system/bin/nox-prop", "/system/bin/ttVM-prop", "/dev/qemu_pipe", "/vendor/bin/qemu-props", "/system/bin/droid4x-prop", "/data/.bluestacks.prop", "/system/app/com.mumu.launcher", "/system/lib/vboxguest.ko", "/system/lib/vboxsf.ko", "/sys/class/misc/vboxguest", "/sys/class/misc/vboxuser"], "3": ["de.robv.android.xposed.installer", "com.saurik.substrate", "com.soft.apk008v", "com.soft.apk008Tool", "com.mockgps.outside.ui", "com.tim.apps.mockgps", "com.huichongzi.locationmocke", "com.lxzs"], "4": ["XposedBridge.jar", "frida", "substrate", "libriru_edxp.so", "libsandhook.edxp.so", "libwhale.edxp.so", "libxposed_art.so", "edxp.jar", "fasthook", "libfakeloc_initzygote.so", "qssq666", "com.lxzs", "sandhook", "libsubstrate.so", "libiohook.so", "libepic.so", "libepic64.so", "libexp824.so", "libexp82464.so", "libexposed.so", "cydia", "/data/local/tmp"], "5": "", "6": ["de.robv.android.xposed.XposedBridge", "de.robv.android.xposed.XposedHelpers"], "7": ["/system/lib/lic", "/system/lib/ccc", "/system/lib/.aa"], "8": ["de.robv.android.xposed.XposedBridge", "xposed", "com.lxzs"], "9": ["dexguard_DGResourcesSuperClass.dex"], "10": ["VirtualBox"], "11": ["com.gsxz.location", "net.anylocation", "com.huichongzi.locationmocker", "top.a1024bytes.mockloc.ca.pro", "com.deniu.daniu"], "12": ["fridaserver", "magisk", "xposed"], "13": "", "14": ["charles", "fiddler"], "15": ["com.netease.nemu_vinput.nemu"] }
8.2、解析json檢測特征
//直接調用SVC指令,檢測特征是否存在系統中。 .text:C8571444 faccessat_sub_C8BE5444 .text:C8571444 .text:C8571444 F0 B5 PUSH {R4-R7,LR} .text:C8571446 03 AF ADD R7, SP, #0xC .text:C8571448 0B 00 MOVS R3, R1 .text:C857144A 04 00 MOVS R4, R0 .text:C857144C 63 20 MOVS R0, #0x63 ; 'c' .text:C857144E C5 43 MVNS R5, R0 .text:C8571450 A7 20 MOVS R0, #0xA7 .text:C8571452 46 00 LSLS R6, R0, #1 .text:C8571454 28 46 MOV R0, R5 .text:C8571456 21 46 MOV R1, R4 .text:C8571458 1A 46 MOV R2, R3 .text:C857145A 37 46 MOV R7, R6 .text:C857145C 00 DF SVC 0 .text:C857145E 03 46 MOV R3, R0 .text:C8571460 18 00 MOVS R0, R3 .text:C8571462 F0 BD POP {R4-R7,PC}
九、總結
9.1、安全點
代碼混淆,代碼塊間跳轉動態計算獲取,單步調試容易跑飛、流程混淆無法F5,字符串加密。采集設備信息都在Native層反射來獲取,
9.1、不足點
指紋穩定性比較差,在華為的機型上基本不行,防hook只是簡單做了前幾個字節判斷,檢測黑產工具的特征寫死的。
樣本獲取,關注公眾號,公眾號輸入框回復“MT”即可
作者簡介:
我是小三,目前從事軟件安全相關工作,雖己工作多年,但內心依然有着執着的追求,信奉終身成長,不定義自己,熱愛技術但不拘泥於技術,愛好分享,喜歡讀書和樂於結交朋友,歡迎加我微信與我交朋友(公眾號輸入框回復“wx”即可)