浅谈淘四神的坑点

前言:

众所周知的,想要搞淘系的业务,那肯定得先解决掉这四个神,分别是

1
2
3
4
x-sign
x-umt
x-mini-wua
x-sgext

大厂的App那肯定少不了坑点,这里我浅浅的说一下,我遇到的一些坑点吧.

抓包问题:

有一部分淘系的App是可以直接抓到包的,而有一部分淘系的App是无法抓到包的,需要做一些处理.
这里我们来聊一下后者.针对这种抓不到包的App,目前是有大佬开源过解决方案的,就是去hook下面这个方法,改返回值为false,就能抓到包了.

1
mtopsdk.mtop.global.SwitchConfig.isGlobalSpdySwitchOpen

定位问题:

这里有三种方法:
第一种是通过关键字搜索一步一步去跟进定位.
第二种是hook一些常用的方法,如hashmap,okhttp3的addHeaders方法间接跟进定位.
第二种是hook NewStringUTF方法定位.
这里的话,我选择的是用第三种方法,因为是比较快的.
hook脚本如下:

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
function hookNewStringCreation() {
const nativeSymbols = Module.enumerateSymbolsSync("libart.so");
let newStringUTFAddress = null;

for (let i = 0; i < nativeSymbols.length; i++) {
const currentSymbol = nativeSymbols[i];

if (currentSymbol.name.includes("NewStringUTF") &&
!currentSymbol.name.includes("CheckJNI")) {
newStringUTFAddress = currentSymbol.address;
}
}

if (newStringUTFAddress) {
Interceptor.attach(newStringUTFAddress, {
onEnter: function (args) {
const nativeStringPtr = args[1];
const javaStringContent = nativeStringPtr.readCString();

//x-sgext
if (javaStringContent && javaStringContent.includes("JB")) {
console.log("Intercepted string:", javaStringContent);
//打印调用堆栈
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}

//x-sign
if (javaStringContent && javaStringContent.includes("azU")) {
console.log("Intercepted string:", javaStringContent);
//打印调用堆栈
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}

//x-umt
if (javaStringContent && javaStringContent.includes("/rA")) {
console.log("Intercepted string:", javaStringContent);
//打印调用堆栈
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}

//x-mini-mua
if (javaStringContent && javaStringContent.includes("==")) {
console.log("Intercepted string:", javaStringContent);
//打印调用堆栈
console.log(Thread.backtrace(this.context, Backtracer.ACCURATE).map(DebugSymbol.fromAddress).join('\n') + '\n');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
}
}
});
}
}

注意判断的条件需要根据实际的App来,这个不一定能够适配所有App,条件需要改改,根据实际App的四神结构进行修改即可.
hook日志如下:

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
x-sign:
azU7Bc002xAAIyNGn9YpMn/BdUhwUyNDIr1MxaTh2e/awto54GQc3cAJn96InpdNDQyNDIwMjQy
0x7933421704 libsgmiddletierso-6.6.231201.33656539.so!0x4d704
0x7933424630 libsgmiddletierso-6.6.231201.33656539.so!0x50630
0x79333df554 libsgmiddletierso-6.6.231201.33656539.so!0xb554
0x79a1568f4c libsgmainso-6.6.231201.33656539.so!0x25f4c
0x79a156b200 libsgmainso-6.6.231201.33656539.so!0x28200
0xa01f6f48
0xa01f6f48

java.lang.Throwable:
at com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative(Native Method)
at com.alibaba.wireless.security.mainplugin.doCommand(Unknown Source:0)
at com.alibaba.wireless.security.middletierplugin.d.d.a.a(Unknown Source:370)
at com.alibaba.wireless.security.middletierplugin.d.d.a$a.invoke(Unknown Source:56)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy27.getSecurityFactors(Unknown Source)
at mtopsdk.security.InnerSignImpl.getUnifiedSign(InnerSignImpl.java:299)
at mtopsdk.mtop.protocol.builder.impl.InnerProtocolParamBuilderImpl.buildParams(InnerProtocolParamBuilderImpl.java:853)
at mtopsdk.framework.filter.before.ProtocolParamBuilderBeforeFilter.doBefore(ProtocolParamBuilderBeforeFilter.java:6)
at mtopsdk.framework.manager.impl.AbstractFilterManager.start(AbstractFilterManager.java:62)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:39)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:44)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:21)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:1)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.originReq(MtopExtSDKHandler.java:75)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.process(MtopExtSDKHandler.java:502)
at com.taobao.android.remoteobject.core.BaseHandler.request(BaseHandler.java:57)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:3)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:1)
at com.taobao.android.remoteobject.easy.MtopSend.execute(MtopSend.java:332)
at com.taobao.android.remoteobject.easy.MtopSend$2.run(MtopSend.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)

x-sgext:
JBIjQbC0iwplXdc5Rhf42kEScRF5E2IRdhRzG2IWdwBiEnYVcBJ1EXcWcQBxEXVCcRNxEnIQcxR5F3FAYhZ0AHEAcRNiE3ETdgByAHAAcABwAHAAcABwAHEAdwByAHEAcQBxAHEAcQBxAHEAYkZiE2ITYkcnFngTdABxE3ETcQBxAHNHIABxAGIQYhJiE2hBnE2cTZxByBXMFcQVxBXMFcxFzEXIXZ0QVeh4WHhNnE2cVeUV5RnhAdgVxBXEFcQVxBXEFcXwgfHMFcgVxfHATHnEQZhtwD2ImaA5lAGYCcHlHAAh3QHVqA2YTDCZFA2omcXN5JnMDTQBnKXEMTRhqIFA2ZW5oBEQEYAtJJGkuaAB8
0x7933421704 libsgmiddletierso-6.6.231201.33656539.so!0x4d704
0x7933424630 libsgmiddletierso-6.6.231201.33656539.so!0x50630
0x79333df554 libsgmiddletierso-6.6.231201.33656539.so!0xb554
0x79a1568f4c libsgmainso-6.6.231201.33656539.so!0x25f4c
0x79a156b200 libsgmainso-6.6.231201.33656539.so!0x28200
0xa01f6f48
0xa01f6f48

java.lang.Throwable:
at com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative(Native Method)
at com.alibaba.wireless.security.mainplugin.doCommand(Unknown Source:0)
at com.alibaba.wireless.security.middletierplugin.d.d.a.a(Unknown Source:370)
at com.alibaba.wireless.security.middletierplugin.d.d.a$a.invoke(Unknown Source:56)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy27.getSecurityFactors(Unknown Source)
at mtopsdk.security.InnerSignImpl.getUnifiedSign(InnerSignImpl.java:299)
at mtopsdk.mtop.protocol.builder.impl.InnerProtocolParamBuilderImpl.buildParams(InnerProtocolParamBuilderImpl.java:853)
at mtopsdk.framework.filter.before.ProtocolParamBuilderBeforeFilter.doBefore(ProtocolParamBuilderBeforeFilter.java:6)
at mtopsdk.framework.manager.impl.AbstractFilterManager.start(AbstractFilterManager.java:62)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:39)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:44)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:21)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:1)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.originReq(MtopExtSDKHandler.java:75)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.process(MtopExtSDKHandler.java:502)
at com.taobao.android.remoteobject.core.BaseHandler.request(BaseHandler.java:57)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:3)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:1)
at com.taobao.android.remoteobject.easy.MtopSend.execute(MtopSend.java:332)
at com.taobao.android.remoteobject.easy.MtopSend$2.run(MtopSend.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)

x-mini-wua:
avQQ3JWQqnFmE5m2gFdc5x9QTxrpzaMcYtdXkDPamSPPAlPSPD9aA2Z+s4UtIIuuaw3TOJLAEvnxT0UOa7YOBLR3B3/Zz4bXtYnKW+9j/DBb+I/rK1eZhol187ozurOvKQq08Xvl7f+6XA1R3EHuQ==
0x7933421704 libsgmiddletierso-6.6.231201.33656539.so!0x4d704
0x7933424630 libsgmiddletierso-6.6.231201.33656539.so!0x50630
0x79333df554 libsgmiddletierso-6.6.231201.33656539.so!0xb554
0x79a1568f4c libsgmainso-6.6.231201.33656539.so!0x25f4c
0x79a156b200 libsgmainso-6.6.231201.33656539.so!0x28200
0xa01f6f48
0xa01f6f48

java.lang.Throwable:
at com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative(Native Method)
at com.alibaba.wireless.security.mainplugin.doCommand(Unknown Source:0)
at com.alibaba.wireless.security.middletierplugin.d.d.a.a(Unknown Source:370)
at com.alibaba.wireless.security.middletierplugin.d.d.a$a.invoke(Unknown Source:56)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy27.getSecurityFactors(Unknown Source)
at mtopsdk.security.InnerSignImpl.getUnifiedSign(InnerSignImpl.java:299)
at mtopsdk.mtop.protocol.builder.impl.InnerProtocolParamBuilderImpl.buildParams(InnerProtocolParamBuilderImpl.java:853)
at mtopsdk.framework.filter.before.ProtocolParamBuilderBeforeFilter.doBefore(ProtocolParamBuilderBeforeFilter.java:6)
at mtopsdk.framework.manager.impl.AbstractFilterManager.start(AbstractFilterManager.java:62)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:39)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:44)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:21)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:1)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.originReq(MtopExtSDKHandler.java:75)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.process(MtopExtSDKHandler.java:502)
at com.taobao.android.remoteobject.core.BaseHandler.request(BaseHandler.java:57)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:3)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:1)
at com.taobao.android.remoteobject.easy.MtopSend.execute(MtopSend.java:332)
at com.taobao.android.remoteobject.easy.MtopSend$2.run(MtopSend.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)

x-umt:
/rABZtxLPBiNv0aQ41fOVzV
0x7933421704 libsgmiddletierso-6.6.231201.33656539.so!0x4d704
0x7933424630 libsgmiddletierso-6.6.231201.33656539.so!0x50630
0x79333df554 libsgmiddletierso-6.6.231201.33656539.so!0xb554
0x79a1568f4c libsgmainso-6.6.231201.33656539.so!0x25f4c
0x79a156b200 libsgmainso-6.6.231201.33656539.so!0x28200
0xa01f6f48
0xa01f6f48

java.lang.Throwable:
at com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative(Native Method)
at com.alibaba.wireless.security.mainplugin.doCommand(Unknown Source:0)
at com.alibaba.wireless.security.middletierplugin.d.d.a.a(Unknown Source:370)
at com.alibaba.wireless.security.middletierplugin.d.d.a$a.invoke(Unknown Source:56)
at java.lang.reflect.Proxy.invoke(Proxy.java:1006)
at $Proxy27.getSecurityFactors(Unknown Source)
at mtopsdk.security.InnerSignImpl.getUnifiedSign(InnerSignImpl.java:299)
at mtopsdk.mtop.protocol.builder.impl.InnerProtocolParamBuilderImpl.buildParams(InnerProtocolParamBuilderImpl.java:853)
at mtopsdk.framework.filter.before.ProtocolParamBuilderBeforeFilter.doBefore(ProtocolParamBuilderBeforeFilter.java:6)
at mtopsdk.framework.manager.impl.AbstractFilterManager.start(AbstractFilterManager.java:62)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:39)
at mtopsdk.mtop.intf.MtopBuilder.asyncRequest(MtopBuilder.java:44)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:21)
at com.taobao.tao.remotebusiness.MtopBusiness.startRequest(MtopBusiness.java:1)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.originReq(MtopExtSDKHandler.java:75)
at com.taobao.android.remoteobject.mtopsdk.ext.MtopExtSDKHandler.process(MtopExtSDKHandler.java:502)
at com.taobao.android.remoteobject.core.BaseHandler.request(BaseHandler.java:57)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:3)
at com.taobao.android.remoteobject.mtopsdk.EasyMtopSDK$Context.execute(EasyMtopSDK.java:1)
at com.taobao.android.remoteobject.easy.MtopSend.execute(MtopSend.java:332)
at com.taobao.android.remoteobject.easy.MtopSend$2.run(MtopSend.java:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)

不管你用那种方法,最终的入口都能定位到这个方法

1
com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative

最终的So是

1
libsgmainso-6.6.231201.33656539.so

动态加载类问题:

当你用Frida hook com.taobao.wireless.security.adapter.JNICLibrary.doCommandNative此方法时,
会有以下的错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Error: java.lang.ClassNotFoundException: Didn't find class "com.taobao.wireless.security.adapter.JNICLibrary" on path: DexPathList[[zip file "/data/app/com.taobao.idlefish-p3-t2sVJ9mEECUcuGKPjAg==/base.apk"],nativeLibraryDirectories=[/data/user/0/com.taobao.idlefish/app_native_libs/lib/arm64-v8a, /data/app/com.taobao.idlefish-p3-t2sVJ9mEECUcuGKPjAg==/lib/arm64, /data/app/com.taobao.idlefish-p3-t2sVJ9mEECUcuGKPjAg==/base.apk!/lib/arm64-v8a, /system/lib64, /system/product/lib64]]
at <anonymous> (frida/node_modules/frida-java-bridge/lib/env.js:124)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/class-factory.js:443)
at value (frida/node_modules/frida-java-bridge/lib/class-factory.js:812)
at _make (frida/node_modules/frida-java-bridge/lib/class-factory.js:112)
at use (frida/node_modules/frida-java-bridge/lib/class-factory.js:63)
at use (frida/node_modules/frida-java-bridge/index.js:246)
at <anonymous> (/hooks.js:193)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:11)
at _performPendingVmOps (frida/node_modules/frida-java-bridge/index.js:238)
at <anonymous> (frida/node_modules/frida-java-bridge/index.js:213)
at <anonymous> (frida/node_modules/frida-java-bridge/lib/vm.js:11)
at _performPendingVmOpsWhenReady (frida/node_modules/frida-java-bridge/index.js:232)
at perform (frida/node_modules/frida-java-bridge/index.js:192)
at <eval> (/hooks.js:200)

说是找不到这个类,然后你反编译apk,去找这个类的时候,你会发现确实找不到.
这是为啥呢,他时动态加载的,磁盘上的dex和内存种的dex是显然不相同的,跟加固的原理差不多,但是又没加固那么高大尚.
这里我不卖关子了,直接说真相了.
淘子他把这个类独立的转成dex了,并且他确实就在磁盘上面,在lib/libsgmain.so,这个.so后缀的文件就是这个dex的压缩包,为啥那么肯定他说压缩包呢,可以通过mt管理器的十六进制功能查看这个文件,也可以通过010editor.查看后,你会发现他前4字节是50 4b 03 04,而一个正常的so的前4字节是7f 45 4c 46.
libsgmain.so
直接将后缀改成zip,或者通过mt管理器的浏览压缩包功能查看.
浏览压缩包
发现有个dex,反编译一下即可找到这个类.
反编译
如果是想frida hook的话,要枚举一遍所有的类.
hook脚本如下

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
Java.perform(function() {
// 遍历所有类加载器
Java.enumerateClassLoaders({
onMatch: function(loader) {
try {
// 尝试设置当前类加载器
Java.classFactory.loader = loader;
// 尝试使用目标类
const JNICLibrary = Java.use("com.taobao.wireless.security.adapter.JNICLibrary");
// 保存可用的类加载器供后续使用
Java.classFactory.loader = loader;
return "stop"; // 找到后停止遍历
} catch (e) {
// 当前加载器没有该类,继续尝试
}
},
onComplete: function() {
console.log("类加载器遍历完成");
}
});
});

Java.perform(function () {
let JNICLibrary = Java.use("com.taobao.wireless.security.adapter.JNICLibrary");
JNICLibrary["doCommandNative"].implementation = function (i, objArr) {
console.log(`JNICLibrary.doCommandNative is called: i=${i}, objArr=${log_ObjArr(objArr)}`);
let result = this["doCommandNative"](i, objArr);
console.log(`JNICLibrary.doCommandNative result=${result}`);
return result;
};
})

这篇就先讲那么多,后面我们讲讲unidbg补环境的坑点以及初始化问题.

📖 原贴链接https://bbs.kanxue.com/thread-288889.htm


浅谈淘四神的坑点
https://miku2024.top/posts/浅谈淘四神的坑点/
作者
KB
发布于
2026年4月16日
许可协议