i茅台自动申购算法协议分析

news2025/2/26 14:19:00

首发地址:http://zhuoyue360.com/crack/104.html

一、引言

今日看到有人分享了i茅台自动申购的文章。但是它酷似引流文章,全文一张图,呜呜呜。无法白嫖。太可恶了,因此,我来啦~ 我来整一整,我也要抢茅子!

二、开战

开发者详情:贵州茅台酒销售有限公司

版本信息:1.4.5

更新时间:2023/07/25 19:07

(一) 启动闪退

由于我们的环境特别的异常 Root,Xposed,Fridd,抓包的啥都有。

管他啥检测,先上个Shamiko配置排除列表. 就可以正常打开了~

img

(二) 抓包分析

本次使用的抓包手段是 Postern + Charles的抓包方案。

当我们点击登录以后,应用提示未检测到网络信号。它一定是有抓包检测的。

img

作为资深的脚本小子,我们再次借用大佬们做好的工具JustMePlus,提示验证码过期,我们也抓到了包数据。

img

看一下提交的数据。有几个不知道含义的字段MT-V、MT-Device-ID、MT-Request-ID、MT-R、MT-SN和BS-DVID参数。找到了未知的参数,我们的目标也就明确了。

POST /xhr/front/user/register/login HTTP/1.1
MT-K: 1690425040309
MT-V: 33212ce8f99d64231e221a5ec9y
MT-Token: 
User-Agent: android;29;google;sailfish
MT-Device-ID: clips_Kxx/RnJBdEYlFyZEJRx6QycQI0V2FydBcxd0FXZH
MT-APP-Version: 1.4.5
MT-Request-ID: 3b2b66c3-747d-4ce7-ba28-a3066594247e
MT-Network-Type: WIFI
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
MT-Bundle-ID: com.moutai.mall
MT-USER-TAG: 0
MT-SN: clips_ehwpSC0fLBggRnJAdxYgFiAYLxl9Si5PfEl/TC0afkw=
MT-DTIME: Wed Aug 14 09:25:50 GMT+08:00 2019
MT-RS: 1080*1794
MT-Lng: 
MT-Lat: 
BS-DVID: tDkAoOWWVDbDFNobZRf1eMcF364bZwAjmM87iuSKpikmnWOBRbaGo1ZQOYt0lu5NQDNwm1S-hrcW4Falp_9YIdg
MT-DOUBLE: 0
MT-SIM: 0
MT-ACBE: 0
MT-ACB: 0
MT-ACBM: 0
Content-Type: application/json; charset=UTF-8
Content-Length: 67
Host: app.moutai519.com.cn
Connection: Keep-Alive
Accept-Encoding: gzip

{"vCode":"111111","mobile":"13544711111","ydToken":"","ydLogId":""}

(三) 脱壳

看到libbaiduprotect.so文件,它使用了百度加固。接下来,脚本小子继续上!我使用的是FunDex

img

(四) 分析

使用的是Frida16大版本.

1. MT-K、MT-V (非必须)

随便跟踪一下。

img

img

Pair<String, String> b10 = 
  new RandK().b(
    n.n("", qm.b.e(System.currentTimeMillis())), 
    wf.a.c(), 
    ""
  );

一、qm.b.e(System.currentTimeMillis())

它其实就等于 new Long(System.currentTimeMillis())

public final class b {
    public static final Boolean a(boolean z10) {
        return Boolean.valueOf(z10);
    }

    public static final Double b(double d10) {
        return new Double(d10);
    }

    public static final Float c(float f10) {
        return new Float(f10);
    }

    public static final Integer d(int i10) {
        return new Integer(i10);
    }

    public static final Long e(long j10) {
        return new Long(j10);
    }
}

二、wf.a.c()

这里我把关键的函数给提取出来,先从部分一开始分析。因为它已经涉及到SO了。脚本小子继续上,这里使用yang神的HookRegisterNative的脚本。

//   部分一
public static final String DEVICE_ID = "device_id";

static {
    EnumMap<MMKVRecoverStrategic, Integer> enumMap = new EnumMap<>(MMKVRecoverStrategic.class);
    recoverIndex = enumMap;
    enumMap.put((EnumMap<MMKVRecoverStrategic, Integer>) MMKVRecoverStrategic.OnErrorDiscard, (MMKVRecoverStrategic) 0);
    recoverIndex.put((EnumMap<MMKVRecoverStrategic, Integer>) MMKVRecoverStrategic.OnErrorRecover, (MMKVRecoverStrategic) 1);
    System.loadLibrary("c++_shared");
    System.loadLibrary("mmkv");
    rootDir = null;
    mCreators = new HashMap<>();
}

private MMKV(long j10) {
    this.nativeHandle = j10;
}


private static native long getMMKVWithID(String str, int i10, String str2);

public static MMKV mmkvWithID(String str, int i10) {
    if (rootDir != null) {
        return new MMKV(getMMKVWithID(str, i10, null));
    }
    throw new IllegalStateException("You should Call MMKV.initialize() first.");
}


public static MMKV d(Context context, String str, boolean z10) {
    if (TextUtils.isEmpty(str)) {
        return null;
    }
    MMKV mmkv = a.get(str);
    if (mmkv == null && z10) {
        MMKV mmkvWithID = MMKV.mmkvWithID(str, 2);
        a.put(str, mmkvWithID);
        return mmkvWithID;
    }
    return mmkv;
}

public static String e(Context context, String str, String str2, String str3) {
    MMKV d10 = d(context, str, true);
    return d10 != null ? d10.getString(str2, str3) : str3;
}

public static Application a() {
    if (a == null) {
        a = a.e();
    }
    return a;
}


public static String k(String str, String str2, String str3) {
    return sj.a.e(b.a(), str, str2, str3);
}

public static String e(String str, String str2) {
    return k("YanXuan", str, str2);
}

public static String j() {
    return jk.a.e(PushConstants.DEVICE_ID, null);
}


public static synchronized String c() {
        synchronized (a.class) {
            if (TextUtils.isEmpty(a)) {
                String j10 = j();
                a = j10;
                if (!TextUtils.isEmpty(j10)) {
                    return a;
                }
                String a10 = a();
                a = a10;
                p(a10);
            }
            return a;
        }
    }

开始Hook看看函数的注册地址,再去用IDA分析,必须要偷懒~

frida -U -f com.moutai.mall -l .\hook_registerNative.js

很遗憾,但是又是在意料之中的事,应用存在Frida检测。看着日志信息,该反调试应该是由百度加固提供的.所以去看看它的so

[RegisterNatives] java_class: com.example.vmp.Hook.LHook name: getDexSizeForDexFile sig: (Ljava/lang/Object;)[I fnPtr: 0x72955fa5b0  fnOffset: 0x72955fa5b0 libLVmp.so!0x355b0  callee: 0x72955fb694 libLVmp.so!0x36694
[RegisterNatives] method_count: 0x1
[RegisterNatives] java_class: com.sagittarius.v6.D name: n0 sig: (I)I fnPtr: 0x728aecec64  fnOffset: 0x728aecec64 libbaiduprotect.so!0x32c64  callee: 0x728aeceae4 libbaiduprotect.so!0x32ae4
[RegisterNatives] method_count: 0x3
[RegisterNatives] java_class: com.sagittarius.v6.A name: n1 sig: (Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I)V fnPtr: 0x728aeb00f4  fnOffset: 0x728aeb00f4 libbaiduprotect.so!0x140f4 
 callee: 0x728aeb0090 libbaiduprotect.so!0x14090
[RegisterNatives] java_class: com.sagittarius.v6.A name: n2 sig: (Landroid/content/Context;)V fnPtr: 0x728aeb02b4  fnOffset: 0x728aeb02b4 libbaiduprotect.so!0x142b4  callee: 0x728aeb0090 libbaiduprotect.so!0x14090
[RegisterNatives] java_class: com.sagittarius.v6.A name: n3 sig: (Landroid/content/Context;)V fnPtr: 0x728aeb039c  fnOffset: 0x728aeb039c libbaiduprotect.so!0x1439c  callee: 0x728aeb0090 libbaiduprotect.so!0x14090
Process crashed: Bad access due to protection failure

***
*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Build fingerprint: 'google/sailfish/sailfish:10/QP1A.190711.020/5800535:user/release-keys'
Revision: '0'
ABI: 'arm64'
Timestamp: 2023-07-27 10:58:52+0800
pid: 19932, tid: 19974, name: com.moutai.mall  >>> com.moutai.mall <<<
uid: 10234
signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0x73883f4b20
Abort message: 'state=545'
    x0  0000007388402a68  x1  0000000000001000  x2  0000000000000001  x3  0000000000000000
    x4  00000072f11f4120  x5  00000072f11f4140  x6  0000007388548280  x7  00000073885482c0
    x8  0000000000000000  x9  0000000000000002  x10 0000000000000001  x11 0000000000000000
    x12 0000007388548240  x13 0000007388548200  x14 0000000000000000  x15 00000072f11acd40
    x16 0000007386ac6888  x17 0000007386ab969c  x18 0000000000000077  x19 0000000000000000
    x20 000000000000000c  x21 000000738994f000  x22 0000000000001000  x23 0000007386ac82e0
    x24 0000007388402a68  x25 00000073883f4b20  x26 000000738994f118  x27 0000007386ac8000
    x28 0000000000000018  x29 0000007289bea7b0
    sp  0000007289bea750  lr  0000007386abb5a8  pc  00000073883f4b20

backtrace:
      #00 pc 0000000000001b20  [anon:thread signal stack]
      #01 pc 00000000000e65a4  /apex/com.android.runtime/lib64/bionic/libc.so!libc.so (offset 0xe6000) (__cxa_finalize+212) (BuildId: 5812256023147338b8a9538321d4c456)
      #02 pc 00000000000e1ea8  /apex/com.android.runtime/lib64/bionic/libc.so!libc.so (offset 0xe1000) (exit+24) (BuildId: 5812256023147338b8a9538321d4c456)
      #03 pc 0000000000000008  <anonymous:72fb904000>
***

当我们使用IDA打开以后,发现它非常的苦恼,没法F5,那 我们还咋分析!这回没法借助脚本了。问了个好朋友,好朋友喊我DumpSo,我使用了FunELF工具,这效果也是嗷嗷好!

img

img

还记得以前在霜哥课程里面学的frida反调试,把检测线程直接干掉,这个也嗷嗷好用。在这里反调试我选择了霜哥的方法。

frida -U -f com.moutai.mall -l .\hook_anti-thread.js

干掉线程的脚本

function replace_thread() {
  var pthread_create_addr = Module.findExportByName(null, "pthread_create");
  var pthread_create = new NativeFunction(pthread_create_addr, "int", ["pointer", "pointer", "pointer", "pointer"]);
  Interceptor.replace(pthread_create_addr, new NativeCallback((parg0, parg1, parg2, parg3) => {
    var so_name = Process.findModuleByAddress(parg2).name;
    var so_base = Module.getBaseAddress(so_name);
    var offset = (parg2 - so_base);
    var PC = 0;
    console.log("normal find thread func offset", so_name, parg2,offset, offset.toString(16));
    // if ((so_name.indexOf("libmsaoaidsec.so") > -1)) {
    //     if (offset === 123) {
    //     } else if (offset === 95736) {
    //     } else if (offset === 93488) {
    //     }
    //     else {
    //         console.log("normal find thread func offset", so_name, offset, offset.toString(16));
    //         PC = pthread_create(parg0, parg1, parg2, parg3);
    //     }
    // } else {
    //     PC = pthread_create(parg0, parg1, parg2, parg3);
    // }

    if ((so_name.indexOf("libbaiduprotect.so") > -1)) {
      if (offset === 178752) {
      } 
      else {
        console.log("normal find thread func offset", so_name, offset, offset.toString(16));
        PC = pthread_create(parg0, parg1, parg2, parg3);
      }
    } else {
      PC = pthread_create(parg0, parg1, parg2, parg3);
    }
    return PC;
  }, "int", ["pointer", "pointer", "pointer", "pointer"]));
}

setImmediate(replace_thread)

于是乎,我们就把i茅台的反调试给过掉了,虽然不知道怎么检测了啥。脚本小子,不需要知道那么多! 继续RUN,RUN,RUN

我们继续回到wf.a.c

2. MT-Device-ID

let b = Java.use("ic.b");
b["a"].implementation = function (str) {
    console.log(`b.a is called: str=${str}`);
    let result = this["a"](str);
    console.log(`b.a result=${result}`);
    return result;
};
b.a is called: str=d127e6d9172a92a949532d2b6edd8b4e
b.a result=clips_LB0vGH1LLxYnECJDekgpECQdKBspTX8dK04qTnYUIEU=

再把堆栈打出来,发现d127e6d9172a92a949532d2b6edd8b4e是来自于wf.a.c(),这个方法在MT-V、MT-K中也用到了。这里就不多说了.

public static String j() {
    return jk.a.e(PushConstants.DEVICE_ID, null);
}


public static String a() {
        String d10 = d();
        String e10 = e();
        String i10 = i();
        String b10 = b();
        if (!TextUtils.isEmpty(d10) && n(d10) && !TextUtils.isEmpty(e10) && m(e10)) {
            d10 = d10 + "@" + e10;
        } else if (!TextUtils.isEmpty(e10) && m(e10)) {
            d10 = e10;
        } else if (TextUtils.isEmpty(d10) || !n(d10)) {
            if (TextUtils.isEmpty(i10) || !o(i10)) {
                d10 = !TextUtils.isEmpty(b10) ? b10 : "";
            } else {
                d10 = i10;
            }
        }
        if (TextUtils.isEmpty(d10)) {
            try {
                d10 = UUID.randomUUID().toString();
            } catch (Exception unused) {
            }
        }
        String a10 = b.a(d10, "UTF-8");
        return !TextUtils.isEmpty(a10) ? a10.trim() : d10;
    }


public static synchronized String c() {
    synchronized (a.class) {
        if (TextUtils.isEmpty(a)) {
            String j10 = j();
            a = j10;
            if (!TextUtils.isEmpty(j10)) {
                return a;
            }
            String a10 = a();
            a = a10;
            p(a10);
        }
        return a;
    }
}


wf.a.c()
public class a {
    public static String a(byte[] bArr) {
        return Base64.encodeToString(bArr, 2);
    }

    public static String b(String str) {
        try {
            return a(str.getBytes("UTF-8"));
        } catch (UnsupportedEncodingException e10) {
            e10.printStackTrace();
            return null;
        }
    }
}

public static String a(String str) {  // str = deviceId_md5
    if (TextUtils.isBlank(str)) {
        return str;
    }
    String b10 = a.b(b(str, 72));
    return "clips_" + b10;
}

public static String b(String str, int i10) {
    if (TextUtils.isBlank(str)) {
        return str;
    }
    StringBuilder sb2 = new StringBuilder();
    for (char c10 : str.toCharArray()) {
        i10 ^= c10;
        sb2.append((char) i10);
    }
    return sb2.toString();
}

总的来说逻辑如下:

  1. deviceID = 获取设备号deviceId
  2. deviceId_md5 = MD5(deviceID)
  3. mt_device_id = base64(xor(deviceId_md5))
import base64
import hashlib
import uuid


def getDeviceId():
    # UUID
    return uuid.uuid4()

def md5(deviceId):
    if not str:
        return None
    if not deviceId:
        str2 = "UTF-8"
    try:
        message_digest = hashlib.md5()
        message_digest.update(str.encode(deviceId))
        digest = message_digest.digest()
        string_buffer = ""
        for b10 in digest:
            string_buffer += format(b10, 'x')
        return string_buffer
    except Exception as e:
        return None
def getMTDeviceId(deviceId):
    ret = []
    i10 = 72
    for char in deviceId:
        i10 ^= ord(char)
        ret.append(chr(i10))
    ret = ''.join(ret)
    return base64.b64encode(ret.encode()).decode()

if __name__ == '__main__':
    deviceidMd5 = md5('d38d477f-9804-4667-822f-750d15e10915')
    mt_device_id = getMTDeviceId(deviceidMd5)
    print(mt_device_id)

在发送验证码的时候,有一个参数md5。这个就比较简单了。

str = 手机号;
String l10 = j10.l("2af72f100c356273d46284f6fd1dfc08" + str + currentTimeMillis);

然后其他就没什么难得东西了。

{'code': 2000}
验证码:271744
{'code': 2000, 'data': {'userId': 1127142557, 'userName': '用户1127142557', 'mobile': '135****9983', 'verifyStatus': 0, 'token': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY5MzAzNzU4MSwidXNlcklkIjoxMTI3MTQyNTU3LCJkZXZpY2VJZCI6ImNsaXBzX0xCb2pFSE5ISlJZaUczNVBmVVVrRVNaRkp4RW5GbmRESWhCeEZDWVMiLCJpYXQiOjE2OTA0NDU1ODF9.V_hJSKm3D6I56-6u9TkON4ZzFK6vkzey4wo9miSOAb4', 'userTag': 0, 'cookie': 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY5MzAzNzU4MSwidXNlcklkIjoxMTI3MTQyNTU3LCJkZXZpY2VJZCI6ImNsaXBzX0xCb2pFSE5ISlJZaUczNVBmVVVrRVNaRkp4RW5GbmRESWhCeEZDWVMiLCJpYXQiOjE2OTA0NDU1ODF9.fRFdAM_cVjsTSRtLIP5tl9zHLxs_-sW2L_9wJkHeZQQ'}}

(五) 登录代码

import base64
import hashlib
import time
import uuid

import requests


def getDeviceId():
    # UUID
    return str(uuid.uuid4())


def md5(deviceId):
    if not str:
        return None
    if not deviceId:
        str2 = "UTF-8"
    try:
        message_digest = hashlib.md5()
        message_digest.update(str.encode(deviceId))
        digest = message_digest.digest()
        string_buffer = ""
        for b10 in digest:
            string_buffer += format(b10, 'x')
        return string_buffer
    except Exception as e:
        return None


def getMTDeviceId(deviceId):
    ret = []
    i10 = 72
    for char in deviceId:
        i10 ^= ord(char)
        ret.append(chr(i10))
    ret = ''.join(ret)
    return 'clips_' + base64.b64encode(ret.encode()).decode()

def sendCode(phone,mt_device_id):
    timestamp =str(int(time.time() * 1000))
    url = 'https://app.moutai519.com.cn/xhr/front/user/register/vcode'
    md5_str = '2af72f100c356273d46284f6fd1dfc08' + phone + timestamp
    md5_str = hashlib.md5(md5_str.encode()).hexdigest()
    data = {
        "md5":md5_str,
        "mobile":phone,
        "timestamp":timestamp
    }
    headers = {
        "MT-Token": "",
        "User-Agent": "android;29;google;sailfish",
        "MT-Device-ID": mt_device_id,
        "MT-APP-Version": "1.4.5",
        "MT-Request-ID": str(uuid.uuid4()),
        "MT-Network-Type": "WIFI",
        "MT-Bundle-ID": "com.moutai.mall",
        "MT-USER-TAG": "0",
        "MT-RS": "1080*1794",
        "Content-Type": "application/json; charset=UTF-8",
        "Host": "app.moutai519.com.cn"
    }
    return requests.post(url=url, json=data, headers=headers).json()


def login(phone,code,mt_device_id):
    url = 'https://app.moutai519.com.cn/xhr/front/user/register/login'

    data = {
        "vCode":code,
        "mobile":phone,
        "ydToken":"",
        "ydLogId":""
    }
    headers = {
        "MT-Token": "",
        "User-Agent": "android;29;google;sailfish",
        "MT-Device-ID": mt_device_id,
        "MT-APP-Version": "1.4.5",
        "MT-Request-ID": str(uuid.uuid4()),
        "MT-Network-Type": "WIFI",
        "MT-Bundle-ID": "com.moutai.mall",
        "MT-USER-TAG": "0",
        "MT-RS": "1080*1794",
        "Content-Type": "application/json; charset=UTF-8",
        "Host": "app.moutai519.com.cn"
    }
    return requests.post(url=url, json=data, headers=headers).json()
def go():
    deviceId = getDeviceId()
    deviceidMd5 = md5(deviceId)
    mt_device_id = getMTDeviceId(deviceidMd5)
    print(mt_device_id)
    phone = "135********"
    data = sendCode(phone,mt_device_id)
    print(data)
    if data['code'] != 2000:
        print('异常')
        return
    code = input('验证码:')
    print(login(phone, code, mt_device_id))
if __name__ == '__main__':
    go()
请输入手机号:13544779983
{'code': 2000}
验证码:271744
{'code': 2000, 'data': {'userId': 123123, 'userName': '123123', 'mobile': '135********', 'verifyStatus': 0, 'token': '****.****.V_hJSKm3D6I56-****', 'userTag': 0, 'cookie': '***.eyJpc3MiOiJtdCIsImV**.*-*'}}

(六) 申购分析(actParam)

在申购得时候,发现一个关键参数也要搞.

{
	"sessionId": 700,
	"shopId": "144440300003",
	"itemInfoList": [{
		"itemId": "10213",
		"count": 1
	}],
	"actParam": "oUxr9vtC5s6wgqbkfHZkFAudq+iTYalbyD2cl2/oYIq44OE879P2dJcuXYNHvwht79rANbLKxdxL\n3hg7WmB2upL/xILVsuZ5TMg1A3Lma5dcdficheXbgZc2QmuIs0kJcVaseBdhtrvFiMrfEHCO0g==\n"
}

此处应该上RPC.

img

(七) 其他包

实名包

POST /xhr/front/user/realNameAuth HTTP/1.1
MT-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY5MzAzNzcyNCwidXNlcklkIjoxMTI3MTQyNTU3LCJkZXZpY2VJZCI6ImNsaXBzX0xCc3RUSGdlZTBvdlRpeE5LUjBzVFM4YUtSOTdHSDVKY0VRaVFIRkMiLCJpYXQiOjE2OTA0NDU3MjR9.NvaXbgWMOUEqtkyq15zDP8SQqKaGnQxUgoYMdl_aQkk
User-Agent: android;29;google;sailfish
MT-Device-ID: clips_LBstTHgee0ovTixNKR0sTS8aKR97GH5JcEQiQHFC
MT-APP-Version: 1.4.5
MT-Request-ID: e24eb535-daa3-45fd-a7f4-9f5e833d559d
MT-Network-Type: WIFI
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
MT-Bundle-ID: com.moutai.mall
MT-USER-TAG: 0
MT-SN: clips_ehwpSC0fLBggRnJAdxYgFiAYLxl9Si5PfEl/TC0afkw=
MT-DTIME: Wed Aug 14 09:25:50 GMT+08:00 2019
MT-RS: 1080*1794
MT-Lng: 
MT-Lat: 
BS-DVID: hWr62Q591-OLfaOq1ge1xkVW4OZfwq8jzbHpK2tx-B0Mhg0ZB8SVmhl0MzjFvXjHo7cnRUKQz5p9ChG1rFMxykw
MT-DOUBLE: 0
MT-SIM: 0
MT-ACBE: 0
MT-ACB: 0
MT-ACBM: 0
Content-Type: application/json; charset=UTF-8
Content-Length: 65
Host: app.moutai519.com.cn
Connection: Keep-Alive
Accept-Encoding: gzip

{"cardType":0,"idCardName":"ddd","idCardNo":"440582199811054333"}
curl -H "MT-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY5MzAzNzcyNCwidXNlcklkIjoxMTI3MTQyNTU3LCJkZXZpY2VJZCI6ImNsaXBzX0xCc3RUSGdlZTBvdlRpeE5LUjBzVFM4YUtSOTdHSDVKY0VRaVFIRkMiLCJpYXQiOjE2OTA0NDU3MjR9.NvaXbgWMOUEqtkyq15zDP8SQqKaGnQxUgoYMdl_aQkk" -H "User-Agent: android;29;google;sailfish" -H "MT-Device-ID: clips_LBstTHgee0ovTixNKR0sTS8aKR97GH5JcEQiQHFC" -H "MT-APP-Version: 1.4.5" -H "MT-Request-ID: e24eb535-daa3-45fd-a7f4-9f5e833d559d" -H "MT-Network-Type: WIFI" -H "MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==" -H "MT-Bundle-ID: com.moutai.mall" -H "MT-USER-TAG: 0" -H "MT-SN: clips_ehwpSC0fLBggRnJAdxYgFiAYLxl9Si5PfEl/TC0afkw=" -H "MT-DTIME: Wed Aug 14 09:25:50 GMT+08:00 2019" -H "MT-RS: 1080*1794" -H "MT-Lng: " -H "MT-Lat: " -H "BS-DVID: hWr62Q591-OLfaOq1ge1xkVW4OZfwq8jzbHpK2tx-B0Mhg0ZB8SVmhl0MzjFvXjHo7cnRUKQz5p9ChG1rFMxykw" -H "MT-DOUBLE: 0" -H "MT-SIM: 0" -H "MT-ACBE: 0" -H "MT-ACB: 0" -H "MT-ACBM: 0" -H "Content-Type: application/json; charset=UTF-8" -H "Host: app.moutai519.com.cn" --data-binary "{\"cardType\":0,\"idCardName\":\"ddd\",\"idCardNo\":\"440582199811054333\"}" --compressed "https://app.moutai519.com.cn/xhr/front/user/realNameAuth"

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/862833.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第二章:CSS基础进阶-part3:弹性例子布局

文章目录 Flex盒模型二、常见属性2.1 flex属性2.2 justify-content2.3 flex-wrap2.4 flex-flow2.5 align-items2.6 父容器-align-content Flex盒模型 1、普通盒模型 2、弹性盒布局 使用弹性盒布局能让容器的宽度跟随浏览器窗口的变化而变换 二、常见属性 2.1 flex属性 2.2 …

玩机搞机---安卓全机型各种玩机 搞机工具 推荐 一

安卓机型有很多大佬开发的工具箱可以让你在玩机搞机中达到事半功倍的效果。虽然都是adb指令操作。但图形化直观界面一目了然。下面为感兴趣的友友推荐一些工具。 任何的联机操作都有可能导致手机系统崩溃 严重会不开机。请理解工具箱中各个选项操作原理。谨慎操作 &#x1f4…

API接口站点(淘宝1688京东商品详情)实时数据参考示例返回

现如今&#xff0c;随着互联网的发展&#xff0c;商品价格监控已经成为电商行业中的一项重要工具。具体而言&#xff0c;商品价格监控通常包括以下几个方面&#xff1a; 1.数据采集&#xff1a;商品价格监控需要从各个电商平台或者其他相关网站上采集商品的价格数据。这一步骤…

FPGA应用学习笔记----定点除法的实现

除以2可以这样移位 迭代除法&#xff0c;就是直接除 迭代除法&#xff0c;就是直接除 除数左移&#xff0c;被除数减去除数&#xff0c;余数大于0则商数置1然后左移&#xff0c;余数作为被减数左移&#xff0c;再减除数&#xff0c;再看余数是否大于0&#xff0c;若大于0&…

QT--崩溃原因分析

本文为学习记录&#xff0c;若有错误&#xff0c;请联系作者&#xff0c;谦虚受教。 文章目录 前言一、目的二、实现步骤1 add2line.exe2 分析文件3 crash文件 三、相关代码1 pro文件2.ccrashstack.h3.ccrashstack.cpp4.main.cpp 总结 前言 你从来来去自由&#xff0c;若你不想…

【前端】WeUI DatePicker时间组件绑定方法以及chatGPT回答

2023年&#xff0c;第33周&#xff0c;第1篇文章。给自己一个目标&#xff0c;然后坚持总会有收货&#xff0c;不信你试试&#xff01; WeUI DatePicker&#xff0c;这个组件在纯html静态文件js里用的比较少&#xff0c;也忘记默认绑定值怎么设置&#xff0c;就用chatGPT来找答…

flutter相关URL schemes

先看效果 使用 url_launcher库 做唤起其他app操作 url_launcher | Flutter Package 配置 安卓 flutter 项目目录下的 android\app\src\main\AndroidManifest.xml 如果不配置的话 有些手机就打不开app 微信有两个 一个是weixin 一个是wechat <queries><!-- If you…

积木报表集成前端加载js文件404

项目场景&#xff1a; 在集成积木报表和shiro时候&#xff1a; 集成积木报表&#xff0c;shrio&#xff0c;shrio是定义在另一个模块下的&#xff0c;供另一个启动类使用&#xff0c;积木报表集成shrio的时候&#xff0c;需要依赖存放shrio的核心包&#xff0c;该核心包除了存…

异步编排CompletableFuture

文章目录 一.简介二.并行加载1.为何需要并行加载2.并行加载的实现方式 三.CompletableFuture使用与原理1.背景和定义2.常用方法3.CompletableFuture的使用3.CompletableFuture原理4.实践总结 一.简介 CompletableFuture由Java 8提供&#xff0c;是实现异步化的工具类&#xff…

JVM—内存管理(运行时数据区)

背景介绍 当JVM类加载器加载完字节码文件之后&#xff0c;会交给执行引擎执行&#xff0c;在执行的过程中会有一块JVM内存区域来存放程序运行过程中的数据&#xff0c;也就是我们图中放的运行时数据区&#xff0c;那这一块运行时数据区究竟帮我们做了哪些工作&#xff1f;我们…

rancher + k3s + docker私有仓库搭建K8环境(百分之百成功)

1.环境准备&#xff08;4台机器&#xff09; 文档准备了4台虚拟机&#xff0c;系统是ubuntu server: ubuntu-22.04.1-live-server-amd64.iso 然后进行安装4台虚拟机&#xff0c;如图&#xff1a; 其中一台用于rancher、其余三台跑K8&#xff0c;一台master&#xff0c;两台工作…

写测试用例、重构函数、生成SQL查询……原来CodeGeeX还能做这些!

CodeGeeX中的智能问答功能“Ask CodeGeeX”可以帮助程序员解答开发过程中遇到的问题。但是“Ask CodeGeeX”的能力不止于此&#xff0c;用它还能帮助程序员高效编写测试用例&#xff0c;添加代码调试信息&#xff0c;实现SQL语句等等。 如果你还不知道如何实现&#xff0c;下面…

途乐证券-新股行情持续火爆,哪些因素影响首日表现?

全面注册制以来&#xff0c;参加打新的投资者数量全体呈现下降。打新收益下降&#xff0c;破发频出的布景下&#xff0c;投资者打新策略从逢新必打逐步向优选个股改变。 经过很多历史数据&#xff0c;从商场定价、参加者热度以及机构重视度维度揭秘了上市后股价体现优秀的个股具…

启动springboot,出现Unable to start embedded Tomcat

报错信息 org.apache.catalina.core.ContainerBase : A child container failed during startjava.util.concurrent.ExecutionException: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Tomcat].StandardHost[localhost].TomcatEmbedd…

AMEYA:ROHM新增5款100V耐压双MOSFET,实现业界超低导通电阻

全球知名半导体制造商ROHM(总部位于日本京都市)面向通信基站和工业设备等的风扇电机驱动应 用&#xff0c;开发出将两枚100V耐压MOSFET* 1一体化封装的双MOSFET新产品。新产品分“HP8KEx/HT8KEx (NchNch)系列”和“HP8MEx(NchPch*2)系列”两个系列&#xff0c;共5款新机型。 近…

知了汇智携手20余所高校开展实习实训,助力数字化人才培养

随着数字化转型推进的深入&#xff0c;企业对数字化人才的需求量大幅增长&#xff0c;人才需求结构也发生显著变化。知了汇智作为一家以就业为导向的产教融合服务机构&#xff0c;始终活跃于“育人”与“用人”的生态圈&#xff0c;通过与高校进行产业学院建设、共建实验室、共…

东南亚海外跨境物流管理,移动支付、数据处理程序开发

境外虚拟物流跨境支付平台快速搭建、集成后台采集功能的步骤如下&#xff1a; 一、项目规划与需求分析 在开始搭建境外虚拟物流跨境支付平台之前&#xff0c;需要进行详细的规划和分析。这包括确定项目的目标、了解客户需求、分析市场环境、确定系统架构和技术选型等。通过深…

一文带你快速了解和入门 Apinto 网关!

Apinto 网关快速入门 是 Eolink 旗下一款专门为微服务架构设计的开源 API 网关&#xff0c;完全由 Go 语言开发&#xff0c; 本文主要带大家认识 Apinto 网关以及如何实现快速入门操作。 首先&#xff0c;让我们一起了解 API 网关的概念。它类似于一个门户&#xff0c;用于管理…

finfet grid

我正在「拾陆楼」和朋友们讨论有趣的话题&#xff0c;你⼀起来吧&#xff1f; 拾陆楼知识星球入口 90nm 及以下的工艺都要求储存器&#xff0c;IP&#xff0c;IO 的多晶硅方向必须和标准单元的多晶 硅方向保持一致&#xff0c;无法像过去工艺一样随意旋转方向。在 22nm 及以下…

shopee虾皮电商十个选品渠道!Get到了!

今天给大家分享虾皮的十个选品渠道&#xff0c;让选品不是难题&#xff01;话不多都说&#xff0c;往下看&#xff01; 1.搜索栏去搜索 拿台湾站来说&#xff0c;在shopee后台&#xff0c;我们搜索商品衬衫&#xff0c;在商品展示页面点击热销&#xff0c;除去第一排的广告商品…