大众点评请求解密

大众点评请求解密

逆向分析

API响应内容被AES加密,密钥固定。解密后是GZIP压缩内容。

解压缩后是某种序列化的结果,调用DPObject.nativeSeekMember获取想要字段的偏移,再根据偏移处的对象长度获取对应数据。

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
package com.dianping.dataservice.mapi.impl;

public final class d implements b {
@Override // com.dianping.nvnetwork.x
public final void onRequestFinish(Request request0, Response response0) {
Object[] arr_object = {request0, response0};
ChangeQuickRedirect changeQuickRedirect0 = d.changeQuickRedirect;
if(PatchProxy.isSupport(arr_object, this, changeQuickRedirect0, 0xE16E2)) {
PatchProxy.accessDispatch(arr_object, this, changeQuickRedirect0, 0xE16E2);
return;
}

long v = SystemClock.elapsedRealtimeNanos();
if(response0.statusCode() != 401) {
if(this.a == null) {
StringBuilder stringBuilder0 = a.o("mapi handler is null --> url: ");
stringBuilder0.append(this.b.url());
Logan.w(stringBuilder0.toString(), 3);
}
else {
com.dianping.dataservice.mapi.g g0 = com.dianping.dataservice.mapi.utils.e.b(response0); //<----------------
if(g.f().A) {
com.dianping.dataservice.mapi.utils.d.d("成功结果完成转换", request0, SystemClock.elapsedRealtimeNanos() - v);
}

this.a.onRequestFinish(this.b, g0);
}
}

this.d.remove(this.b);
if(g.f().A) {
com.dianping.dataservice.mapi.utils.d.b("Success", request0);
}
}
}


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
package com.dianping.dataservice.mapi.utils;

public final class e {
public static g b(Response response0) {
Object[] arr_object = {response0};
ChangeQuickRedirect changeQuickRedirect0 = e.changeQuickRedirect;
Object object0 = null;
if(PatchProxy.isSupport(arr_object, null, changeQuickRedirect0, 13093640)) {
return (g)PatchProxy.accessDispatch(arr_object, null, changeQuickRedirect0, 13093640);
}

ArrayList arrayList0 = new ArrayList();
if(response0.headers() != null) {
for(Object object1: response0.headers().entrySet()) {
arrayList0.add(new com.dianping.apache.http.message.a(((String)((Map.Entry)object1).getKey()), ((String)((Map.Entry)object1).getValue())));
}
}

if(response0.result() != null) {
object0 = com.dianping.dataservice.mapi.impl.f.d(response0.result());
}

return new com.dianping.dataservice.mapi.impl.a(response0.statusCode(), object0, arrayList0, response0.rawData(), response0.error(), response0.isCache(), response0.lastCacheTime()); //<----------------
}
}


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
package com.dianping.dataservice.mapi.impl;

public final class a extends com.dianping.dataservice.http.impl.a implements g {
public a(int v, Object object0, List list0, byte[] arr_b, Object object1) {
this(v, object0, list0, arr_b, object1, false, 0L);
Object[] arr_object = {new Integer(v), object0, list0, arr_b, object1};
ChangeQuickRedirect changeQuickRedirect0 = a.changeQuickRedirect;
if(PatchProxy.isSupport(arr_object, this, changeQuickRedirect0, 0x627CB7)) {
PatchProxy.accessDispatch(arr_object, this, changeQuickRedirect0, 0x627CB7);
}
}

public a(int v, Object object0, List list0, byte[] raw_data, Object object1, boolean z, long v1) {
super(v, object0, list0, object1);
Object[] arr_object = {new Integer(v), object0, list0, raw_data, object1, new Byte(((byte)z)), new Long(v1)};
ChangeQuickRedirect changeQuickRedirect0 = a.changeQuickRedirect;
if(PatchProxy.isSupport(arr_object, this, changeQuickRedirect0, 1070426)) {
PatchProxy.accessDispatch(arr_object, this, changeQuickRedirect0, 1070426);
return;
}

this.raw_data = raw_data; //<----------------
this.e = z;
this.f = v1;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
a->c (retType: [B): -5,-1,1,6,-86,112,117,-94,71,63,26,-83,-63,-8,-43,100,-62,-72,-79,120,40,-62,33,114,-13,66,41,49,70,-10,100,3,116,-33,11,-111,-31,90,-102,-126,99,115,-98,-82,83,-39,-69,-106,91,-74,-40,41,34,41,-112,33,-99,-87,-78,-57,-44,-68,119,-19,-29,-76,-88,99,82,-103,-22,9,74,28,-88,73,66,-54,-100,-95,104,-121,68,11,80,-115,86,19,87,-89,-107,-21,-106,70,97,-25,-52,-122,38,16,-24,2,-50,-111,-65,-77,41,57,17,54,-43,-75,103,-46,6,52,-74,66,-70,39,52,107,-99,-88,24,67,-127,50,-124,54,-25,-83,17,93,-105,67,32,115,31,127,-88,119,38,-8,41,54,67,41,-97,35,96,-114,-11,-108,24,58,119,114,-110,11,22,-128,-95,55,-75,-60,-32,-94,0,-12,64,39,25,16,65,-117,125,106,-107,122,-92,-83,94,2,-117,-102,-6,28,107,-75,62,-42,105,11,-122,100,-37,-74,-106,-128,122,19,20,-36,-35,23,-29,-103,67,-31,99,-30,23,77,-73,82,-94,67,-51,126,4,-42,2,22,-123,118,-19,41,-91,113,-122,60,-101,101,32,50,-92,98,10,-100,54,-54,102,47,23,-95,-76,-2,27,-25,-75,78,125,-10,-106,-2,-38,-104,34,-114,-6,95,-100,116,127,-91,-10,-58,-73,-60,39,91,46,-116,72,37,-72,102,-100,98,-4,62,112,28,-20,66,-104,-36,22,5,40,67,93,-126,96,-46,6,89,81,32,0,59,-42,110,-47,100,-77,-126,64,103,-45,-11,-121,121,-121,-71,121,-81,5,16,-60,94,-82,-116,17,-93,-8,89,-11,-56,-84,-38,0,-53,-107,-7,38,119,81,-107,88,78,-56,80,-110,5,-94,85,-88,-93,-112,85,-7,41,107,34,51,31,86,-74,-40,-61,-41,-30,-95,125,-19,126,23,21,34,42,67,63,58,125,-60,122,-38,-17,17,55,78,13,34,-28,-79,-126,19,34,-89,-109,82,-61,-106,-28,-104,-77,-39,97,85,38,34,-6,3,52,-120,-67,4,-80,-124,-32,-35,-64,100,-9,-12,-62,-54,-108,-52,-11,-46,-94,-40,-4,-11,-67,-124,-45,-84,-40,28,-5,-75,38,122,57,0,85,78,80,99,-2,-11,-56,124,96
java.lang.Exception
at com.dianping.dataservice.mapi.impl.a.c(Native Method)
at com.dianping.picassoclient.network.e.onRequestFinish(MApiDownloader.java:4)
at com.dianping.dataservice.mapi.impl.d.onRequestFinish(InnerMapiRequestHandlerWrapper.java:7)
at com.dianping.nvnetwork.NVDefaultNetworkService$MySubscriber.onNext(NVDefaultNetworkService.java:4)
at com.dianping.nvnetwork.NVDefaultNetworkService$MySubscriber.onNext(NVDefaultNetworkService.java:1)
at rx.observers.SafeSubscriber.onNext(SafeSubscriber.java:2)
at rx.internal.operators.OperatorSubscribeOn$1$1.onNext(Unknown Source:4)
at rx.internal.operators.OperatorObserveOn$ObserveOnSubscriber.call(OperatorObserveOn.java:9)
at rx.android.schedulers.LooperScheduler$ScheduledAction.run(LooperScheduler.java:1)
at android.os.Handler.handleCallback(Handler.java:958)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:224)
at android.os.Looper.loop(Looper.java:318)
at android.app.ActivityThread.main(ActivityThread.java:8777)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:561)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1013)
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
package com.dianping.picassoclient.network;

final class e implements f {
@Override // com.dianping.dataservice.f
public final void onRequestFinish(com.dianping.dataservice.e e0, g g0) {
d d0;
com.dianping.dataservice.mapi.f f0 = (com.dianping.dataservice.mapi.f)e0;
Subscriber subscriber0 = this.a;
com.dianping.picassoclient.network.f f1 = this.b.b;
Objects.requireNonNull(f1);
Object[] arr_object = {((com.dianping.dataservice.mapi.g)g0)};
ChangeQuickRedirect changeQuickRedirect0 = com.dianping.picassoclient.network.f.changeQuickRedirect;
if(PatchProxy.isSupport(arr_object, f1, changeQuickRedirect0, 4075730)) {
d0 = (d)PatchProxy.accessDispatch(arr_object, f1, changeQuickRedirect0, 4075730);
}
else {
byte[] raw_data = new byte[0];
if(((com.dianping.dataservice.mapi.g)g0) != null) {
raw_data = ((com.dianping.dataservice.mapi.g)g0).c();//<----------------
if(((com.dianping.dataservice.mapi.g)g0).message() != null) {
new String("{\"statusCode\":0,\"title\":\"\",\"content\":\"\",\"icon\":0,\"flag\":0,\"data\":\"\",\"errorMsg\":\"\",\"errorCode\":0,\"returnID\":0,\"yodaRequestCode\":\"\"}");
}
}

d0 = new d();
d0.raw_data = raw_data;
}

subscriber0.onNext(d0);
this.a.onCompleted();
}
}


image-20250315234606975

image-20250315234645195

NativeHelper.ndug实际上也是AES解密,此处为了native层解密失败,还用java实现了一遍解密,因此不用分析native函数。

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
package com.dianping.dataservice.mapi.impl;

public final class f {
public static byte[] a(byte[] arr_b) throws Exception {
ByteArrayOutputStream byteArrayOutputStream0;
GZIPInputStream gZIPInputStream0;
Object[] arr_object = {arr_b};
ChangeQuickRedirect changeQuickRedirect0 = f.changeQuickRedirect;
byte[] arr_b1 = null;
if(PatchProxy.isSupport(arr_object, null, changeQuickRedirect0, 0x9371A6)) {
return (byte[])PatchProxy.accessDispatch(arr_object, null, changeQuickRedirect0, 0x9371A6);
}

if(arr_b.length % 16 == 0 && (NativeHelper.a)) {
arr_b1 = NativeHelper.ndug(arr_b, f.b, f.c);
}

if(arr_b1 == null) {
Cipher cipher0 = Cipher.getInstance("AES/CBC/NoPadding");
IvParameterSpec ivParameterSpec0 = new IvParameterSpec(f.c);
cipher0.init(2, new SecretKeySpec(f.b, "AES"), ivParameterSpec0);
ByteArrayInputStream byteArrayInputStream0 = new ByteArrayInputStream(cipher0.doFinal(arr_b));
try {
gZIPInputStream0 = new GZIPInputStream(byteArrayInputStream0);
}
catch(Throwable throwable0) {
throw throwable0;
}

try {
byteArrayOutputStream0 = new ByteArrayOutputStream(0x4000);
}
catch(Throwable throwable1) {
throw throwable1;
}

try {
byte[] arr_b2 = new byte[0x1000];
while(true) {
int v = gZIPInputStream0.read(arr_b2);
if(v <= 0) {
break;
}

byteArrayOutputStream0.write(arr_b2, 0, v);
}

arr_b1 = byteArrayOutputStream0.toByteArray();
goto label_31;
}
catch(Throwable throwable2) {
}

try {
throw throwable2;
}
catch(Throwable throwable3) {
}

try {
byteArrayOutputStream0.close();
throw throwable3;
}
catch(Throwable throwable4) {
try {
throwable2.addSuppressed(throwable4);
throw throwable3;
label_31:
byteArrayOutputStream0.close();
goto label_43;
}
catch(Throwable throwable1) {
try {
throw throwable1;
}
catch(Throwable throwable5) {
try {
gZIPInputStream0.close();
throw throwable5;
}
catch(Throwable throwable6) {
}

try {
throwable1.addSuppressed(throwable6);
throw throwable5;
label_43:
gZIPInputStream0.close();
goto label_55;
}
catch(Throwable throwable0) {
}
}
}
}

try {
throw throwable0;
}
catch(Throwable throwable7) {
}

try {
byteArrayInputStream0.close();
}
catch(Throwable throwable8) {
throwable0.addSuppressed(throwable8);
}

throw throwable7;
label_55:
byteArrayInputStream0.close();
return arr_b1;
}

return arr_b1;
}
}
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
package com.dianping.archive;

public class DPObject implements Parcelable, Iterable {

public final DPObject E(String s) {
return this.C(DPObject.L(s));
}

public final String F(int hash) {
if(DPObject.d) {
int found_index = DPObject.nativeSeekMember(this.arr, this.b, this.length, hash);
if(found_index > 0) {
int v2 = this.length;
if(found_index < v2) {
int v3 = this.b + found_index;
byte[] arr_b = this.arr;
int v4 = arr_b[v3];
if(v4 == 0x53 && found_index + 2 < v2) {
int v5 = (arr_b[v3 + 1] & 0xFF) << 8 | arr_b[v3 + 2] & 0xFF;
if(v5 == 0) {
return "";
}

if(found_index + 2 + v5 < v2) {
try {
return new String(arr_b, v3 + 3, v5, "UTF-8");
}
catch(UnsupportedEncodingException unused_ex) {
}
}
}
else {
if(v4 != 'B' || found_index + 4 >= v2) {
return null;
}

int v6 = (arr_b[v3 + 1] & 0xFF) << 24 | (arr_b[v3 + 2] & 0xFF) << 16 | (arr_b[v3 + 3] & 0xFF) << 8 | arr_b[v3 + 4] & 0xFF;
if(v6 == 0) {
return "";
}

if(found_index + 4 + v6 < v2) {
try {
return new String(arr_b, v3 + 5, v6, "UTF-8");
}
catch(UnsupportedEncodingException unused_ex) {
return null;
}

return null;
}
}
}
}
}
else {
ByteBuffer byteBuffer0 = ByteBuffer.wrap(this.arr, this.b, this.length);
byteBuffer0.order(ByteOrder.BIG_ENDIAN);
if(DPObject.O(byteBuffer0, hash) == 0 && byteBuffer0.remaining() > 0) {
int v7 = byteBuffer0.get();
if(v7 == 0x53 && byteBuffer0.remaining() > 1) {
int v8 = byteBuffer0.getShort() & 0xFFFF;
if(v8 == 0) {
return "";
}

if(byteBuffer0.remaining() >= v8) {
try {
return new String(this.arr, byteBuffer0.position(), v8, "UTF-8");
}
catch(UnsupportedEncodingException unsupportedEncodingException0) {
Log.e("dpobj", "unable to decode string", unsupportedEncodingException0);
return null;
}
}
}
else if(v7 == 'B' && byteBuffer0.remaining() > 3) {
int v9 = byteBuffer0.getInt();
if(v9 == 0) {
return "";
}

if(byteBuffer0.remaining() >= v9) {
try {
return new String(this.arr, byteBuffer0.position(), v9, "UTF-8");
}
catch(UnsupportedEncodingException unsupportedEncodingException1) {
}

Log.e("dpobj", "unable to decode string", unsupportedEncodingException1);
}
}
}
}

return null;
}

private static native int nativeSeekMember(byte[] arg0, int arg1, int arg2, int arg3) {
}


}

抓包

Android抓包,我使用frida修改https请求为http,再用proxydroid转发http请求数据到burpsuite。

1
2
iptables -t nat -F
iptables -t nat -A OUTPUT -p tcp --dport 80 -j REDIRECT --to 8123
1
2
3
4
5
6
7
8
9
10
11
var Request = Java.use("com.dianping.nvnetwork.Request");
Request.url.overload().implementation = function() {
var retval = this.url()
console.log("Request->url (retType: java.lang.String): " + retval)
if(retval.indexOf('https://m.dianping.com') > -1){
console.log('replace...')
var new_url = retval.replaceAll('https://','http://')
return new_url
}
return retval;
}

image-20250316104525913

解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from Crypto.Cipher import AES
import binascii
import gzip
import struct


key = binascii.unhexlify('44374336463731413132313533454535')
iv = binascii.unhexlify('35354339333044383237424441424644')
response_hex_str = 'F8 FD 5C 64 B9 6C 04 F2 65 34 FF 95 7B E8 50 61 CF A4 B5 A9 30 64 DC 61 E6 1E 5D 77 CE 7D BE F9 99 16 FA 04 E4 D6 A8 64 12 CA 85 9B 74 7E D0 FD 86 5A FB 3F 17 91 B6 28 34 89 6B 49 3F 48 02 FB 7F 13 1B 14 9D 7E 91 0D 5D E8 39 30 3D CA 59 01 62 58 10 2D EE E4 22 8D 16 D9 26 B8 33 87 F9 48 96 C8 4A A9 E3 60 00 16 BB 21 22 1D F7 64 77 16 4A BF B4 47 25 9D B1 94 33 79 05 CB 37 E5 A6 AF 1C FD 12 68 27 28 CE B4 65 1A D9 B1 BA 25 4D 4C 8A 88 0C 4D 54 7E 6A EC 87 DA 01 B6 0A D2 97 5F 1F D5 3D AA F3 7D 10 EA BE 7B C9 3E F4 36 A8 31 BC F7 89 C0 D3 62 9A FF 23 02 27 22 BF EB 86 CD D2 D5 57 7B 8F D3 B7 9F 9F 65 55 0F 1D 02 EC 20 94 FF 0C 86 A4 B6 0E 08 52 DD 55 AD 61 46 F0 E2 AE DF 41 05 E3 A3 61 38 E3 C7 43 64 6F 6E 26 40 23 68 6E 31 E7 A2 DA 78 D7 D0 D4 D9 53 7D 05 56 A7 A5 A0 44 19 9A 49 1A 28 2A C3 75 42 8E AD 4B F2 2D 22 B9 4A 86 09 CC CB DB 93 C4 0A B0 81 40 C4 F4 67 14 39 FC A4 26 CD 31 0D CA A7 70 B9 C3 7C 55 D4 79 22 61 64 E0 5E 10 B2 CC C4 44 BE A4 11 FB 2E FD A9 3B A5 70 35 34 72 56 1B EE 9A EF D3 FF 44 30 A5 1C 9F AB 6C D8 7D 4C 56 A8 CF 3B 28 11 3B DB 35 4D 54 D3 52 BA 5F 22 1B 2C 89 66 CC D8 62 05 D0 A9 73 79 0D 55 91 76 D8 2F 8F 91 EA 01 47 2A 8B 2C 8A 56 91 A9 33 87 7D 9A 5B 82 7F E0 46 B4 BF F7 FF EA A1 7A BD B9 6D 54 BE E7 AB 41 B0 29 7B D4 C2 87 0D 80 A6 FB 99 0B 9E ED 30 CB 50 14 E7 28 61 C9 63 10 67 BB E5 50 E8 16 91 30 3E AB 4A 31 FB CE 83 1D 15 B7 5C BC D8 39 9B 61 B2 C8 ED E7 E4 04 34 6E 22 6E A0 A3 A8 A8 5F 6C 4C 25 2F B1 53 46 93 54 6C 25 AB 44 3A 48 C6 DC 0C 34 47 D8 A8 69 14 2C B1 E4 EA BC 48 1E 8E 20 DB 96 FC 39 F4 07 A8 69 20 B8 B2 23 21 DA 8E 69 48 75 29 41 E6 18 5C 6E 79 7E 3B 6B 67 01'
response_data = binascii.unhexlify(response_hex_str.replace(' ', ''))
crypto = AES.new(key, mode=AES.MODE_CBC, iv=iv)
gzip_data = crypto.decrypt(response_data)
decrypt_data = gzip.decompress(gzip_data)
buf = decrypt_data[7:11]
string_length = struct.unpack('>I', buf)[0]
str_buf = decrypt_data[6 + 5:6 + 5 + string_length]
print(str_buf.decode('utf8'))

1
{"data":{"totalPowerCoinNum":20345,"toExpirePowerCoinNum":0,"generalPassCardModule":{"passCardTitle":"变美玩乐PASS卡","passCardSubTitle":"可五折兑换","redeemablePassCardList":[{"redeemablePassCardId":11000000,"cost":50,"allRedeemed":false,"passCardRemainCount":"剩48张","powerCoinNum":2500},{"redeemablePassCardId":11000001,"cost":100,"allRedeemed":false,"passCardRemainCount":"剩1987张","powerCoinNum":5000},{"redeemablePassCardId":11000002,"cost":200,"allRedeemed":false,"passCardRemainCount":"剩1989张","powerCoinNum":10000},{"redeemablePassCardId":11000003,"cost":300,"allRedeemed":false,"passCardRemainCount":"剩1188张","powerCoinNum":15000},{"redeemablePassCardId":11000004,"cost":400,"allRedeemed":false,"passCardRemainCount":"剩992张","powerCoinNum":20000},{"redeemablePassCardId":11000005,"cost":500,"allRedeemed":false,"passCardRemainCount":"剩396张","powerCoinNum":25000},{"redeemablePassCardId":11000006,"cost":800,"allRedeemed":false,"passCardRemainCount":"剩19张","powerCoinNum":40000},{"redeemablePassCardId":11000007,"cost":1000,"allRedeemed":false,"passCardRemainCount":"剩10张","powerCoinNum":50000},{"redeemablePassCardId":11000008,"cost":1500,"allRedeemed":false,"passCardRemainCount":"剩5张","powerCoinNum":75000}]},"foodPassCardModule":{"passCardTitle":"美食PASS卡","passCardSubTitle":null,"redeemablePassCardList":[{"redeemablePassCardId":10000000,"cost":50,"allRedeemed":false,"passCardRemainCount":"剩682张","powerCoinNum":5000},{"redeemablePassCardId":10000001,"cost":100,"allRedeemed":false,"passCardRemainCount":"剩327张","powerCoinNum":10000},{"redeemablePassCardId":10000002,"cost":200,"allRedeemed":false,"passCardRemainCount":"剩347张","powerCoinNum":20000},{"redeemablePassCardId":10000003,"cost":300,"allRedeemed":false,"passCardRemainCount":"剩199张","powerCoinNum":30000},{"redeemablePassCardId":10000004,"cost":400,"allRedeemed":false,"passCardRemainCount":"剩335张","powerCoinNum":40000},{"redeemablePassCardId":10000005,"cost":500,"allRedeemed":false,"passCardRemainCount":"剩54张","powerCoinNum":50000},{"redeemablePassCardId":10000006,"cost":800,"allRedeemed":false,"passCardRemainCount":"剩100张","powerCoinNum":80000},{"redeemablePassCardId":10000007,"cost":1000,"allRedeemed":false,"passCardRemainCount":"剩15张","powerCoinNum":100000},{"redeemablePassCardId":10000008,"cost":1500,"allRedeemed":false,"passCardRemainCount":"剩10张","powerCoinNum":150000}]}},"status":true,"msg":"请求成功","code":200}