接上文:
四、设备指纹在业务中的应用
1. 初始化准备
0x001. 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:参数
- 系统环境检测
0x001.调用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
0x002.检测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 //字符串的编号
0x003.检测XPOSED、代理、ROM是否为自己编译的:
//检测
de.robv.android.xposed.XposedBridge
//检测代理
http.proxyHost
https.proxyHost
getProperty
0x004.检测关键方法是否被hook:
//检测方法是否被hook
传入方法首地址进行对比 0x780x5F 0xF8DF
//如果检测到第一个方法被hook,结果如下
1|
如果检测到第2个方法被hook,结果如下
1|2|
如果检测到第3个方法被hook,结果如下
1|2|3|
0x005.其它检测,代码如下:
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);
- 读取资源文件并解密
.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]
0x002.读取的数据与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.
0x003.检测是否为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}
0x004.计算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];
}
0x005.计算后的值为,该值会作为解密资源密钥的一部分:
638C81261479C2104EDE3F2518E91725
0x006.解密assets/ms_com.sankuai.meituan 组合密钥:包名+常量字符(WU@TEN)+META-INF/SANKUAI.RSA(md5):
com.sankuai.meituanWU@TEN638C81261479C2104EDE3F2518E91725
0x007.将组合后的字符串加密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
0x008.加密后的值为:
//该值为解密assets/ms_com.sankuai.meituan的密钥
69fe5963f3b95d9718c8d3e4f924ad9379500e9b51d80686e65347890e1748fe
0x009.读取资源文件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;
}
0x010.读取后内容(部分):
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 .........$@$....
各位读者如有新的看法,可以私聊联系昵称。