wyy音乐过签名校验

看了52pj正己的frida教程,想到通过frida-inlinehook来实现网易云音乐8.1版本的签名校验对抗

重签名后运行查看堆栈信息

1
2
3
4
5
6
7
8
9
10
11
backtrace:
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #00 pc 00004b2c [anon:libc_malloc]
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #01 pc 000b32cd /apex/com.android.runtime/lib/bionic/libc.so (__cxa_finalize+72) (BuildId: 3516bc395829323390a814b64aaaf5a1)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #02 pc 000ae7ed /apex/com.android.runtime/lib/bionic/libc.so (exit+10) (BuildId: 3516bc395829323390a814b64aaaf5a1)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #03 pc 0004365d /data/app/~~JfDcLN3ADNGo3jHH4eqcQw==/com.netease.cloudmusic-A9CfQ5-akXzh6poBdNDy2w==/lib/arm/libpoison.so
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #04 pc 00199511 /data/app/~~JfDcLN3ADNGo3jHH4eqcQw==/com.netease.cloudmusic-A9CfQ5-akXzh6poBdNDy2w==/oat/arm/base.odex (art_jni_trampoline+112)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #05 pc 000d3fd5 /apex/com.android.art/lib/libart.so (art_quick_invoke_stub_internal+68) (BuildId: ba7696c70b1fbab959c337cb708debe7)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #06 pc 004c4849 /apex/com.android.art/lib/libart.so (art_quick_invoke_static_stub+288) (BuildId: ba7696c70b1fbab959c337cb708debe7)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #07 pc 001230d3 /apex/com.android.art/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+158) (BuildId: ba7696c70b1fbab959c337cb708debe7)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #08 pc 00233877 /apex/com.android.art/lib/libart.so (art::interpreter::ArtInterpreterToCompiledCodeBridge(art::Thread*, art::ArtMethod*, art::ShadowFrame*, unsigned short, art::JValue*)+250) (BuildId: ba7696c70b1fbab959c337cb708debe7)
2024-06-28 18:44:58.463 11401-11401 DEBUG pid-11401 A #09 pc 0022f8fb /apex/com.android.art/lib/libart.so (bool art::interpreter::DoCall<false, false>(art::ArtMethod*, art::Thread*,

可以发现是libpoison.so出现了异常

ida分析,尝试搜索sign关键字,定位到sub_435a4

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
int __fastcall sub_435A4(int a1, int a2, int a3)
{
int v5; // r6
int v6; // r0
int v7; // r0
int v8; // r0
int v9; // r0
int v10; // r7
int v11; // r5
int v12; // r0
char *v13; // r5
int result; // r0
int v15; // [sp+Ch] [bp-34h]
int v16; // [sp+10h] [bp-30h]
int v17; // [sp+14h] [bp-2Ch]
int v18; // [sp+18h] [bp-28h]
int v19; // [sp+1Ch] [bp-24h]
int v20; // [sp+20h] [bp-20h]
int v21; // [sp+24h] [bp-1Ch]

v5 = sub_7F10(a1, "android/content/ContextWrapper");
v6 = sub_7F3E(a1, v5, "getPackageManager", "()Landroid/content/pm/PackageManager;");
v17 = sub_7F4A(a1, a3, v6);
v7 = sub_7F3E(a1, v5, "getPackageName", "()Ljava/lang/String;");
v18 = sub_7F4A(a1, a3, v7);
v19 = sub_7F10(a1, "android/content/pm/PackageManager");
v8 = sub_7F3E(a1, v19, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;");
v20 = sub_7F4A(a1, v17, v8);
v21 = sub_7F10(a1, "android/content/pm/PackageInfo");
v9 = (*(int (__fastcall **)(int, int, const char *, const char *))(*(_DWORD *)a1 + 376))(
a1,
v21,
"signatures",
"[Landroid/content/pm/Signature;");
v10 = (*(int (__fastcall **)(int, int, int))(*(_DWORD *)a1 + 380))(a1, v20, v9);
if ( !sub_7FCA(a1, v10) )
goto LABEL_2;
v15 = sub_7F10(a1, "android/content/pm/Signature");
v11 = sub_7F3E(a1, v15, "toByteArray", "()[B");
v12 = (*(int (__fastcall **)(int, int, _DWORD))(*(_DWORD *)a1 + 692))(a1, v10, 0);
v16 = sub_7F4A(a1, v12, v11);
v13 = (char *)sub_43464(a1, v16);
sub_24CE4((int)&dword_581A8, v13);
sub_7F1A(a1, v5);
sub_7F1A(a1, v17);
sub_7F1A(a1, v18);
sub_7F1A(a1, v19);
sub_7F1A(a1, v20);
sub_7F1A(a1, v21);
sub_7F1A(a1, v10);
sub_7F1A(a1, v15);
sub_7F1A(a1, v16);
if ( sub_44DC0(v13, "d65201860dfc37b60e245b772ee8b213") )
{
if ( sub_44DC0(v13, "da6b069da1e2982db3e386233f68d76d")
&& sub_44DC0(v13, "efba65f1032493581f79e1ecc35c496b")
&& sub_44DC0(v13, "67e142a5bbd766e57be8d0c9c2bee892") )
{
LABEL_2:
j_exit(0);
}
}
result = sub_44D90(v13);
byte_58004 = 1;
return result;
}

可以看到关键在于exit这里,可以通过修改第一个判断的返回值过掉这个退出

看看汇编

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 01 F0 5F FB                 BL      sub_44DC0
exterm:000436FE
exterm:00043702 00 28 CMP R0, #0
exterm:00043704 14 D0 BEQ loc_43730
exterm:00043704
exterm:00043706 1F 49 LDR R1, =(aDa6b069da1e298 - 0x4370E) ; "da6b069da1e2982db3e386233f68d76d"
exterm:00043708 28 1C MOVS R0, R5
exterm:0004370A 79 44 ADD R1, PC ; "da6b069da1e2982db3e386233f68d76d"
exterm:0004370C 01 F0 58 FB BL sub_44DC0
exterm:0004370C
exterm:00043710 00 28 CMP R0, #0
exterm:00043712 0D D0 BEQ loc_43730
exterm:00043712
exterm:00043714 1C 49 LDR R1, =(aEfba65f1032493 - 0x4371C) ; "efba65f1032493581f79e1ecc35c496b"
exterm:00043716 28 1C MOVS R0, R5
exterm:00043718 79 44 ADD R1, PC ; "efba65f1032493581f79e1ecc35c496b"

可以看到就是CMP R0,#0这条指令,可以通过修改寄存器的值或者直接修改汇编来实现,这里我选择通过修改寄存器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function inline_hook(){
var soAddr = Module.findBaseAddress("libpoison.so");
console.log("[*] soAddr: " + soAddr);
if(soAddr){
var func_addr = soAddr.add(0x43702+1);//偏移
console.log("[*] funcAddr: " + func_addr);
Java.perform(function(){
console.log("[*] funciton onLoad")
Interceptor.attach(func_addr,{
onEnter:function(args){
console.log("[*] onEnter");
console.log("[*] context: " + JSON.stringify(this.context));//打印加载了哪些寄存器
console.log("[*] r0 before : " + JSON.stringify(this.context.r0));
this.context.r0 = ptr(0);//修改寄存器值
console.log("[*] r0 after : " + JSON.stringify(this.context.r0));
},
onLeave:function(retval){
console.log("[*] onLeave")
}
});
});
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(frida) C:\Users\n1ng>frida -U -f com.netease.cloudmusic -l E:\Learn\签名校验\hook.js
____
/ _ | Frida 16.1.4 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to MI 9 (id=21ce24db)
Spawned `com.netease.cloudmusic`. Resuming main thread!
[MI 9::com.netease.cloudmusic ]-> [*] soAddr: null
Process crashed: Bad access due to protection failure

可以看到报错了,并且连so都没有加载

猜测可能是因为这个so加载的时机比较早,所以我想到尝试通过hook dlopen实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function inline_hook(){
var soAddr = Module.findBaseAddress("libpoison.so");
console.log("[*] soAddr: " + soAddr);
if(soAddr){
var func_addr = soAddr.add(0x43702+1);//偏移
console.log("[*] funcAddr: " + func_addr);
Java.perform(function(){
console.log("[*] funciton onLoad")
Interceptor.attach(func_addr,{
onEnter:function(args){
console.log("[*] onEnter");
console.log("[*] context: " + JSON.stringify(this.context));//打印加载了哪些寄存器
console.log("[*] r0 before : " + JSON.stringify(this.context.r0));
this.context.r0 = ptr(0);//修改寄存器值
console.log("[*] r0 after : " + JSON.stringify(this.context.r0));
},
onLeave:function(retval){
console.log("[*] onLeave")
}
});
});
}
}
function hook_dlopen() {
var dlopen = Module.findExportByName(null, "dlopen");
Interceptor.attach(dlopen, {
onEnter: function (args) {
var so_name = args[0].readCString();
if (so_name.indexOf("libpoison.so") >= 0) this.call_hook = true;
}, onLeave: function (retval) {
if (this.call_hook) hookTest2();
}
});
// 高版本Android系统使用android_dlopen_ext
var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");
Interceptor.attach(android_dlopen_ext, {
onEnter: function (args) {
var so_name = args[0].readCString();
if (so_name.indexOf("libpoison.so") >= 0) this.call_hook = true;
}, onLeave: function (retval) {
if (this.call_hook) inline_hook();
}
});
}

function main(){
Java.perform(function(){
hook_dlopen();
});
}
setImmediate(main);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(frida) C:\Users\n1ng>frida -U -f com.netease.cloudmusic -l E:\Learn\签名校验\hook.js
____
/ _ | Frida 16.1.4 - A world-class dynamic instrumentation toolkit
| (_| |
> _ | Commands:
/_/ |_| help -> Displays the help system
. . . . object? -> Display information about 'object'
. . . . exit/quit -> Exit
. . . .
. . . . More info at https://frida.re/docs/home/
. . . .
. . . . Connected to MI 9 (id=21ce24db)
Spawned `com.netease.cloudmusic`. Resuming main thread!
[MI 9::com.netease.cloudmusic ]-> [*] soAddr: 0xdae9e000
[*] funcAddr: 0xdaee1703
[*] funciton onLoad
[*] onEnter
[*] context: {"pc":"0xdaee1702","sp":"0xffa47e00","cpsr":537526272,"r0":"0x1","r1":"0xdaeebf2e","r2":"0x65","r3":"0x64","r4":"0xf2a195a0","r5":"0xf2af7e18","r6":"0x85","r7":"0xe5","r8":"0x0","r9":"0xf28cee00","r10":"0xffa47f08","r11":"0xffa47ecc","r12":"0xdaef5ee4","lr":"0xdaee1703","q0":{},"q1":{},"q2":{},"q3":{},"q4":{},"q5":{},"q6":{},"q7":{},"q8":{},"q9":{},"q10":{},"q11":{},"q12":{},"q13":{},"q14":{},"q15":{},"d0":0,"d1":0,"d2":0,"d3":0,"d4":0,"d5":0,"d6":0,"d7":0,"d8":0,"d9":0,"d10":0,"d11":0,"d12":0,"d13":0,"d14":0,"d15":0,"d16":0,"d17":0,"d18":0,"d19":0,"d20":0.1390649941707655e-308,"d21":0.1390649941707655e-308,"d22":0.0000000000098497e-308,"d23":null,"d24":0.1390649941707655e-308,"d25":1.4477527650248676e+235,"d26":1.4477527650248676e+235,"d27":1.4477527650248676e+235,"d28":1.4477527650248676e+235,"d29":1.4477527650248676e+235,"d30":0.00000000000002e-308,"d31":1.4477527650248676e+235,"s0":0,"s1":0,"s2":0,"s3":0,"s4":0,"s5":0,"s6":0,"s7":0,"s8":0,"s9":0,"s10":0,"s11":0,"s12":0,"s13":0,"s14":0,"s15":0,"s16":0,"s17":0,"s18":0,"s19":0,"s20":0,"s21":0,"s22":0,"s23":0,"s24":0,"s25":0,"s26":0,"s27":0,"s28":0,"s29":0,"s30":0,"s31":0}
[*] r0 before : "0x1"
[*] r0 after : "0x0"

可以看到现在打印出了寄存器信息并且成功的将r0寄存器的值修改,此时手机上的app也可以正常启动


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 3049155267@qq.com

💰

×

Help us with donation