逆向抓包大神

0x01 前言

抓包应该是我们逆向的第一步,只有先抓到包,才能决定我们是否要进行脱壳、逆向。万一他没有加密、万一数据不是我们想要的那岂不是白忙活了。但是目前很APP都设置了门槛,比如新版的抖音、淘宝、天眼查等挂上代理就直接无数据或者就显示不出你想要的数据。还没有开始就直接结束了,让人懊恼不已。没办法只能上科技与狠活了。(感谢r0ysue肉师傅,以下很多素材都来源于他)

0x02 普通验证型

这个一般我们设置好IP和端口,导入证书不出意外是没问题。常见的抓包工具fiddler、charles、Burpsuite、httpcanary

0x03 双向验证型

针对双向证书绑定的APP,打印和保存证书,再导入到抓包工具中。

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

function hook_KeyStore_load() {

    Java.perform(function () {

        var ByteString = Java.use("com.android.okhttp.okio.ByteString");

        var myArray = new Array(1024);

        var i = 0

        for (i = 0; i < myArray.length; i++) {

            myArray[i] = 0x0;

        }

        var buffer = Java.array('byte', myArray);

        var StringClass = Java.use("java.lang.String");

        var KeyStore = Java.use("java.security.KeyStore");

        KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (arg0) {

            //可以在此打印调用栈观察信息

            console.log("KeyStore.load1:", arg0);

            this.load(arg0);

        };

        KeyStore.load.overload('java.io.InputStream''[C').implementation = function (arg0, arg1) {

            //可以在此打印调用栈观察信息

            console.log("KeyStore.load2:", arg0, arg1 ? StringClass.$new(arg1) : null);

            if (arg0) {

                var file = Java.use("java.io.File").$new("/sdcard/Download/" + String(arg0) + ".p12");

                var out = Java.use("java.io.FileOutputStream").$new(file);

                var r;

                while ((r = arg0.read(buffer)) > 0) {

                    out.write(buffer0, r)

                }

                console.log("save success!")

                out.close()

            }

            this.load(arg0, arg1);

        };

        console.log("hook_KeyStore_load...");

    });

}

将证书导出后,charles进行证书配置。

图片描述

ssl pinning 证书在代码中的额外校验:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

function hook_ssl() {

    Java.perform(function () {

        var ClassName = "com.android.org.conscrypt.Platform";

        var Platform = Java.use(ClassName);

        var targetMethod = "checkServerTrusted";

        var len = Platform[targetMethod].overloads.length;

        console.log(len);

        for (var i = 0; i < len++i) {

            Platform[targetMethod].overloads[i].implementation = function () {

                console.log("class:", ClassName, "target:", targetMethod, " i:", i, arguments);

            }

        }

    });

}

objection SSL

objection 中的 Bypass SSL pinning 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

sslContextEmptyTrustManager

    const x509TrustManager: X509TrustManager = Java.use("javax.net.ssl.X509TrustManager");

    const sSLContext: SSLContext = Java.use("javax.net.ssl.SSLContext");

okHttp3CertificatePinnerCheck

    const certificatePinner: CertificatePinner = Java.use("okhttp3.CertificatePinner");

okHttp3CertificatePinnerCheckOkHttp

    const certificatePinner: CertificatePinner = Java.use("okhttp3.CertificatePinner");

appceleratorTitaniumPinningTrustManager

   const pinningTrustManager: PinningTrustManager = Java.use("appcelerator.https.PinningTrustManager");

//Android 7+ TrustManagerImpl.verifyChain()

trustManagerImplVerifyChainCheck

    const trustManagerImpl: TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");

    const TrustManagerImplverifyChain = trustManagerImpl.verifyChain;

// Android 7+ TrustManagerImpl.checkTrustedRecursive()

trustManagerImplCheckTrustedRecursiveCheck

    const trustManagerImpl: TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");

    const TrustManagerImplcheckTrustedRecursive = trustManagerImpl.checkTrustedRecursive;

phoneGapSSLCertificateChecker

    const sslCertificateChecker: SSLCertificateChecker = Java.use("nl.xservices.plugins.SSLCertificateChecker");

DroidSSLUnpinning

DroidSSLUnpinning 这个工具是WooyunDota瘦蛟舞大佬总结的,github上有源码,以下我也贴出来了,他总结了一些常见的证书过检测的方法。

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

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

345

346

347

348

349

350

Java.perform(function() {

/*

hook list:

1.SSLcontext

2.okhttp

3.webview

4.XUtils

5.httpclientandroidlib

6.JSSE

7.network\_security\_config (android 7.0+)

8.Apache Http client (support partly)

9.OpenSSLSocketImpl

10.TrustKit

11.Cronet

*/

    // Attempts to bypass SSL pinning implementations in a number of

    // ways. These include implementing a new TrustManager that will

    // accept any SSL certificate, overriding OkHTTP v3 check()

    // method etc.

    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');

    var HostnameVerifier = Java.use('javax.net.ssl.HostnameVerifier');

    var SSLContext = Java.use('javax.net.ssl.SSLContext');

    var quiet_output = false;

    // Helper method to honor the quiet flag.

    function quiet_send(data) {

        if (quiet_output) {

            return;

        }

        send(data)

    }

    // Implement a new TrustManager

    // ref: https://gist.github.com/oleavr/3ca67a173ff7d207c6b8c3b0ca65a9d8

    // Java.registerClass() is only supported on ART for now(201803). 所以android 4.4以下不兼容,4.4要切换成ART使用.

    var X509Certificate = Java.use("java.security.cert.X509Certificate");

    var TrustManager;

    try {

        TrustManager = Java.registerClass({

            name: 'org.wooyun.TrustManager',

            implements: [X509TrustManager],

            methods: {

                checkClientTrusted: function(chain, authType) {},

                checkServerTrusted: function(chain, authType) {},

                getAcceptedIssuers: function() {

                    // var certs = [X509Certificate.$new()];

                    // return certs;

                    return [];

                }

            }

        });

    } catch (e) {

        quiet_send("registerClass from X509TrustManager >>>>>>>> " + e.message);

    }

    // Prepare the TrustManagers array to pass to SSLContext.init()

    var TrustManagers = [TrustManager.$new()];

    try {

        // Prepare a Empty SSLFactory

        var TLS_SSLContext = SSLContext.getInstance("TLS");

        TLS_SSLContext.init(null, TrustManagers, null);

        var EmptySSLFactory = TLS_SSLContext.getSocketFactory();

    } catch (e) {

        quiet_send(e.message);

    }

    send('Custom, Empty TrustManager ready');

    // Get a handle on the init() on the SSLContext class

    var SSLContext_init = SSLContext.init.overload(

        '[Ljavax.net.ssl.KeyManager;''[Ljavax.net.ssl.TrustManager;''java.security.SecureRandom');

    // Override the init method, specifying our new TrustManager

    SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {

        quiet_send('Overriding SSLContext.init() with the custom TrustManager');

        SSLContext_init.call(this, null, TrustManagers, null);

    };

    /*** okhttp3.x unpinning ***/

    // Wrap the logic in try/catch as not all applications will have

    // okhttp as part of the app.

    try {

        var CertificatePinner = Java.use('okhttp3.CertificatePinner');

        quiet_send('OkHTTP 3.x Found');

        CertificatePinner.check.overload('java.lang.String''java.util.List').implementation = function() {

            quiet_send('OkHTTP 3.x check() called. Not throwing an exception.');

        }

    } catch (err) {

        // If we dont have a ClassNotFoundException exception, raise the

        // problem encountered.

        if (err.message.indexOf('ClassNotFoundException'=== 0) {

            throw new Error(err);

        }

    }

    // Appcelerator Titanium PinningTrustManager

    // Wrap the logic in try/catch as not all applications will have

    // appcelerator as part of the app.

    try {

        var PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');

        send('Appcelerator Titanium Found');

        PinningTrustManager.checkServerTrusted.implementation = function() {

            quiet_send('Appcelerator checkServerTrusted() called. Not throwing an exception.');

        }

    } catch (err) {

        // If we dont have a ClassNotFoundException exception, raise the

        // problem encountered.

        if (err.message.indexOf('ClassNotFoundException'=== 0) {

            throw new Error(err);

        }

    }

    /*** okhttp unpinning ***/

    try {

        var OkHttpClient = Java.use("com.squareup.okhttp.OkHttpClient");

        OkHttpClient.setCertificatePinner.implementation = function(certificatePinner) {

            // do nothing

            quiet_send("OkHttpClient.setCertificatePinner Called!");

            return this;

        };

        // Invalidate the certificate pinnet checks (if "setCertificatePinner" was called before the previous invalidation)

        var CertificatePinner = Java.use("com.squareup.okhttp.CertificatePinner");

        CertificatePinner.check.overload('java.lang.String''[Ljava.security.cert.Certificate;').implementation = function(p0, p1) {

            // do nothing

            quiet_send("okhttp Called! [Certificate]");

            return;

        };

        CertificatePinner.check.overload('java.lang.String''java.util.List').implementation = function(p0, p1) {

            // do nothing

            quiet_send("okhttp Called! [List]");

            return;

        };

    } catch (e) {

        quiet_send("com.squareup.okhttp not found");

    }

    /*** WebView Hooks ***/

    /* frameworks/base/core/java/android/webkit/WebViewClient.java */

    /* public void onReceivedSslError(Webview, SslErrorHandler, SslError) */

    var WebViewClient = Java.use("android.webkit.WebViewClient");

    WebViewClient.onReceivedSslError.implementation = function(webView, sslErrorHandler, sslError) {

        quiet_send("WebViewClient onReceivedSslError invoke");

        //执行proceed方法

        sslErrorHandler.proceed();

        return;

    };

    WebViewClient.onReceivedError.overload('android.webkit.WebView''int''java.lang.String''java.lang.String').implementation = function(a, b, c, d) {

        quiet_send("WebViewClient onReceivedError invoked");

        return;

    };

    WebViewClient.onReceivedError.overload('android.webkit.WebView''android.webkit.WebResourceRequest''android.webkit.WebResourceError').implementation = function() {

        quiet_send("WebViewClient onReceivedError invoked");

        return;

    };

    /*** JSSE Hooks ***/

    /* libcore/luni/src/main/java/javax/net/ssl/TrustManagerFactory.java */

    /* public final TrustManager[] getTrustManager() */

    /* TrustManagerFactory.getTrustManagers maybe cause X509TrustManagerExtensions error  */

    // var TrustManagerFactory = Java.use("javax.net.ssl.TrustManagerFactory");

    // TrustManagerFactory.getTrustManagers.implementation = function(){

    //     quiet_send("TrustManagerFactory getTrustManagers invoked");

    //     return TrustManagers;

    // }

    var HttpsURLConnection = Java.use("javax.net.ssl.HttpsURLConnection");

    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */

    /* public void setDefaultHostnameVerifier(HostnameVerifier) */

    HttpsURLConnection.setDefaultHostnameVerifier.implementation = function(hostnameVerifier) {

        quiet_send("HttpsURLConnection.setDefaultHostnameVerifier invoked");

        return null;

    };

    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */

    /* public void setSSLSocketFactory(SSLSocketFactory) */

    HttpsURLConnection.setSSLSocketFactory.implementation = function(SSLSocketFactory) {

        quiet_send("HttpsURLConnection.setSSLSocketFactory invoked");

        return null;

    };

    /* libcore/luni/src/main/java/javax/net/ssl/HttpsURLConnection.java */

    /* public void setHostnameVerifier(HostnameVerifier) */

    HttpsURLConnection.setHostnameVerifier.implementation = function(hostnameVerifier) {

        quiet_send("HttpsURLConnection.setHostnameVerifier invoked");

        return null;

    };

    /*** Xutils3.x hooks ***/

    //Implement a new HostnameVerifier

    var TrustHostnameVerifier;

    try {

        TrustHostnameVerifier = Java.registerClass({

            name: 'org.wooyun.TrustHostnameVerifier',

            implements: [HostnameVerifier],

            method: {

                verify: function(hostname, session) {

                    return true;

                }

            }

        });

    } catch (e) {

        //java.lang.ClassNotFoundException: Didn't find class "org.wooyun.TrustHostnameVerifier"

        quiet_send("registerClass from hostnameVerifier >>>>>>>> " + e.message);

    }

    try {

        var RequestParams = Java.use('org.xutils.http.RequestParams');

        RequestParams.setSslSocketFactory.implementation = function(sslSocketFactory) {

            sslSocketFactory = EmptySSLFactory;

            return null;

        }

        RequestParams.setHostnameVerifier.implementation = function(hostnameVerifier) {

            hostnameVerifier = TrustHostnameVerifier.$new();

            return null;

        }

    } catch (e) {

        quiet_send("Xutils hooks not Found");

    }

    /*** httpclientandroidlib Hooks ***/

    try {

        var AbstractVerifier = Java.use("ch.boye.httpclientandroidlib.conn.ssl.AbstractVerifier");

        AbstractVerifier.verify.overload('java.lang.String''[Ljava.lang.String''[Ljava.lang.String''boolean').implementation = function() {

            quiet_send("httpclientandroidlib Hooks");

            return null;

        }

    } catch (e) {

        quiet_send("httpclientandroidlib Hooks not found");

    }

    /***

android 7.0+ network_security_config TrustManagerImpl hook

apache httpclient partly

***/

    var TrustManagerImpl = Java.use("com.android.org.conscrypt.TrustManagerImpl");

    // try {

    //     var Arrays = Java.use("java.util.Arrays");

    //     //apache http client pinning maybe baypass

    //     //https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#471

    //     TrustManagerImpl.checkTrusted.implementation = function (chain, authType, session, parameters, authType) {

    //         quiet_send("TrustManagerImpl checkTrusted called");

    //         //Generics currently result in java.lang.Object

    //         return Arrays.asList(chain);

    //     }

    //

    // } catch (e) {

    //     quiet_send("TrustManagerImpl checkTrusted nout found");

    // }

    try {

        // Android 7+ TrustManagerImpl

        TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {

            quiet_send("TrustManagerImpl verifyChain called");

            // Skip all the logic and just return the chain again :P

            //https://www.nccgroup.trust/uk/about-us/newsroom-and-events/blogs/2017/november/bypassing-androids-network-security-configuration/

            // https://github.com/google/conscrypt/blob/c88f9f55a523f128f0e4dace76a34724bfa1e88c/platform/src/main/java/org/conscrypt/TrustManagerImpl.java#L650

            return untrustedChain;

        }

    } catch (e) {

        quiet_send("TrustManagerImpl verifyChain nout found below 7.0");

    }

    // OpenSSLSocketImpl

    try {

        var OpenSSLSocketImpl = Java.use('com.android.org.conscrypt.OpenSSLSocketImpl');

        OpenSSLSocketImpl.verifyCertificateChain.implementation = function(certRefs, authMethod) {

            quiet_send('OpenSSLSocketImpl.verifyCertificateChain');

        }

        quiet_send('OpenSSLSocketImpl pinning')

    } catch (err) {

        quiet_send('OpenSSLSocketImpl pinner not found');

    }

    // Trustkit

    try {

        var Activity = Java.use("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");

        Activity.verify.overload('java.lang.String''javax.net.ssl.SSLSession').implementation = function(str) {

            quiet_send('Trustkit.verify1: ' + str);

            return true;

        };

        Activity.verify.overload('java.lang.String''java.security.cert.X509Certificate').implementation = function(str) {

            quiet_send('Trustkit.verify2: ' + str);

            return true;

        };

        quiet_send('Trustkit pinning')

    } catch (err) {

        quiet_send('Trustkit pinner not found')

    }

    try {

        //cronet pinner hook

        //weibo don't invoke

        var netBuilder = Java.use("org.chromium.net.CronetEngine$Builder");

        //https://developer.android.com/guide/topics/connectivity/cronet/reference/org/chromium/net/CronetEngine.Builder.html#enablePublicKeyPinningBypassForLocalTrustAnchors(boolean)

        netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.implementation = function(arg) {

            //weibo not invoke

            console.log("Enables or disables public key pinning bypass for local trust anchors = " + arg);

            //true to enable the bypass, false to disable.

            var ret = netBuilder.enablePublicKeyPinningBypassForLocalTrustAnchors.call(this, true);

            return ret;

        };

        netBuilder.addPublicKeyPins.implementation = function(hostName, pinsSha256, includeSubdomains, expirationDate) {

            console.log("cronet addPublicKeyPins hostName = " + hostName);

            //var ret = netBuilder.addPublicKeyPins.call(this,hostName, pinsSha256,includeSubdomains, expirationDate);

            //this 是调用 addPublicKeyPins 前的对象吗? Yes,CronetEngine.Builder

            return this;

        };

    } catch (err) {

        console.log('[-] Cronet pinner not found')

    }

});

使用方法:
1 attach : frida -U com.example.mennomorsink.webviewtest2 --no-pause -l hooks.js
2 spawn : frida -U -f com.example.mennomorsink.webviewtest2 -l hooks.js --no-pause

混淆

如果APP出现了混淆,使用 objection、DroidSSLUnpinning都无法成功hook住,首先不要慌,我们的目标还是先搞清楚他用的是什么框架。可以hook java.io.File类,因为校验证书的过程中,必然要打开它,通过打印的调栈再结合源码可以分析出到底使用了什么框架。

1

android hooking watch class_method  java.io.File.$init --dump-args --dump-backtrace --dump-return

0x04 r0capture

r0capture安卓应用层抓包通杀脚本这个工具比较厉害,无视所有证书校验或绑定,不用考虑任何证书的事情。
Spawn 模式:
python3 r0capture.py -U -f com.coolapk.market -v

Attach 模式,抓包内容保存成pcap文件供后续分析:
python3 r0capture.py -U 酷安 -v -p iqiyi.pcap

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Skywalking Kafka Tracing实现

背景 Skywalking默认场景下&#xff0c;Tracing对于消息队列的发送场景&#xff0c;无法将TraceId传递到下游消费者&#xff0c;但对于微服务场景下&#xff0c;是有大量消息队列的业务场景的&#xff0c;这显然无法满足业务预期。 解决方案 Skywalking的官方社区中&#xf…

企业展示小程序的制作流程及关键步骤详解

在移动互联网时代&#xff0c;企业展示小程序已成为各个行业推广和展示的重要工具。搭建一个企业展示小程序不仅能够提高企业形象&#xff0c;还能够增加用户粘性和提升用户体验。下面我们来看一下如何从零基础搭建一个企业展示小程序&#xff0c;并顺利上线。 第一步&#xff…

R package org.Hs.eg.db to convert gene id

文章目录 install使用org.Hs.egENSEMBL将Ensembl id convert to gene idorg.Hs.egGENENAME 将Ensembl id convert to gene nameorg.Hs.egSYMBOL 将 gene symbol convert to gene id我现在有一些ensembl id 如何转为 gene name注意你会遇到一些record不全的情况&#xff0c;gtf文…

【Go Web 篇】从零开始:构建最简单的 Go 语言 Web 服务器

随着互联网的迅速发展&#xff0c;Web 服务器成为了连接世界的关键组件之一。而在现代编程语言中&#xff0c;Go 语言因其卓越的性能和并发能力而备受青睐。本篇博客将带你从零开始&#xff0c;一步步构建最简单的 Go 语言 Web 服务器&#xff0c;让你对 Go 语言的 Web 开发能力…

C++多线程编程——线程同步(保姆级-1.4W字)

目录 C线程同步 引入 互斥锁 std::mutex std::lock_guard类模板 unique_lock 成员方法 应用举例 std::lock()函数模板 std::call_once(flag、function) 懒汉式单例模式实例 unique_lock互斥锁方式 ​编辑 call_once方式 条件变量 std::condition 条件变量使…

【网络】IP网络层和数据链路层

IP协议详解 1.概念 1.1 四层模型 应用层&#xff1a;解决如何传输数据&#xff08;依照什么格式/协议处理数据&#xff09;的问题传输层&#xff1a;解决可靠性问题网络层&#xff1a;数据往哪里传&#xff0c;怎么找到目标主机数据链路层&#xff08;物理层&#xff09;&…

Windows商店引入SUSE Linux Enterprise Server和openSUSE Leap

在上个月的Build 2017开发者大会上&#xff0c;微软宣布将SUSE&#xff0c;Ubuntu和Fedora引入Windows 商店&#xff0c;反应出微软对开放源码社区的更多承诺。 该公司去年以铂金会员身份加入Linux基金会。现在&#xff0c;微软针对内测者的Windows商店已经开始提供 部分Linux发…

react +Antd Cascader级联选择使用接口数据渲染

1获取接口数据并将数据转换成树形数组 useEffect(() > {axios.get(/接口数据, {params: {“请求参数”},}).then((res) > {console.log(res);const getTreeData (treeData, pid) > {// 把数据转化为树型结构let tree [];let currentParentId pid || 0;for (let i …

大数据扫盲(2): 数据分析BI与ETL的紧密关系——ETL是成功BI的先决条件

着业务的发展每个企业都将产生越来越多的数据&#xff0c;然后这些数据本身并不能直接带来洞察力并产生业务价值。为了释放数据的潜力&#xff0c;数据分析BI&#xff08;商业智能&#xff09;成为了现代企业不可或缺的一部分。然而&#xff0c;在数据分析的背后&#xff0c;有…

VUE笔记(九)vuex

一、vuex的简介 1、回顾组件之间的通讯 父组件向子组件通讯&#xff1a;通过props实现 子组件向父组件通讯&#xff1a;通过自定义事件($emit)方式来实现 兄弟组件之间的通讯&#xff1a;事件总线&#xff08;$eventBus&#xff09;、订阅与发布方式来实现 跨级组件的通讯…

word如何调整页码

文章目录 如何调整页码 如何调整页码 用 word 写报告的时候&#xff0c;经常遇到要求说是要从正文开始才显示页码&#xff0c;那如何实现呢 把鼠标放在我们正文的那一页的顶部&#xff0c;点击 布局 ,再点击分隔符&#xff0c;再点击连续 再点击编译页脚 选择你想要的页脚格式…

MySQL数据库基本操作

目录 一、数据库中常用的数据类型 二、常用命令与操作 1.DDL数据库定义语言 1、登录用户的数据库 2、查看当前服务器中的数据库 3、切换/进入数据库 并 查看数据库中包含的表 4、查看数据库中表的结构 5、创建数据库 7、展示创建数据表时的结构 8、创建表&#xff0c…

UML建模以及几种类图的理解

文章目录 前言1.用例与用例图1.1 参与者1.2 用例之间的关系1.3 用例图1.4 用例的描述 2.交互图2.1 顺序图2.2 协作图 3.类图和对象图3.1 关联关系3.2 聚合和组合3.3 泛化关系3.4 依赖关系 4.状态图与活动图4.1 状态图4.2 活动图 5.构件图 前言 UML通过图形化的表示机制从多个侧…

大语言模型之六- LLM之企业私有化部署

数据安全是每个公司不得不慎重对待的&#xff0c;为了提高生产力&#xff0c;降本增效又不得不接受新技术带来的工具&#xff0c;私有化部署对于公司还是非常有吸引力的。大语言模型这一工具结合公司的数据可以大大提高公司生产率。 私有化LLM需要处理的问题 企业内私有化LLM…

langchain ChatGPT AI私有知识库

企业知识库 原理就是把文档变为向量数据库&#xff0c;然后搜索向量数据库&#xff0c;把相似的数据和问题作为prompt&#xff0c; 输入到大模型&#xff0c;再利用GPT强大的自然语言处理、推理和分析等方面的能力将答案返回给用户 什么是langchain? langchain是一个强大的…

VScode代码自动补全提示

VScode代码自动补全提示 打开设置 搜索 Suggest:Snippets Prevent Quick Suggestions &#xff0c;去掉勾选 CtrlShiftP打开setting.json文件&#xff0c;添加以下代码 "editor.suggest.snippetsPreventQuickSuggestions": false,"editor.quickSuggestions…

机器学习概述

文章目录 机器学习应用背景数据挖掘个性化定制替代人力的软件应用 什么是机器学习示例 机器学习系统举例IBM Watson DeepQAIBM Watson技术需求相关技术 -- DeepQA 通用机器学习系统设计设计一个学习系统 1系统设计1 —— 用于训练的经验 设计学习系统 2系统设计2 —— 到底应该…

Spring Boot多环境指定yml或者properties

Spring Boot多环境指定yml或者properties 文章目录 Spring Boot多环境指定yml或者properties加载顺序配置指定某个yml 加载顺序 ● application-local.properties ● application.properties ● application-local.yml ● application.yml application.propertes server.port…

Tcp 协议的接口测试

首先明确 Tcp 的概念&#xff0c;针对 Tcp 协议进行接口测试&#xff0c;是指基于 Tcp 协议的上层协议比如 Http &#xff0c;串口&#xff0c;网口&#xff0c; Socket 等。这些协议与 Http 测试方法类似&#xff08;具体查看接口自动化测试章节&#xff09;&#xff0c;但在测…