逆向抓包大神

news2024/11/15 15:41:41

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.coloradmin.cn/o/934463.html

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

相关文章

Day45|leetcode 70. 爬楼梯、322. 零钱兑换、279.完全平方数

leetcode 70. 爬楼梯 题目链接&#xff1a;70. 爬楼梯 - 力扣&#xff08;LeetCode&#xff09; 本题可以用背包问题来解决&#xff0c;就相当于楼顶是背包&#xff0c;台阶是物品&#xff0c;相当于之前写法的进阶版。 代码实现 class Solution { public:int climbStairs(in…

ModaHub魔搭社区:WinPlan经营大脑API查询业务表单列表

查询业务表单模板列表 用户通过此接口查看生效的维度表单和业务表单的基础信息 ●URL:open.shulead.com/api/schema/getList ●Method:POST ●需要登录:否 ●需要鉴权:是 请求示例 可以仅传递部分请求参数。 成功响应 条件:请求参数合法,并且租户身份校验通过。 状态码:…

RedisDesktopManager(redis客户端,可输入用户名密码)

RedisDesktopManager&#xff08;redis客户端&#xff0c;可输入用户名密码&#xff09; Redis桌面管理器&#xff08;又名RDM&#xff09; - 是一个用于Windows&#xff0c;Linux和MacOS的快速开源Redis数据库管理应用程序。可以使用url连接或账号密码。 redis设置账号密码后…

电商数据接口API:品牌价格监控与数据分析的重要工具

一、引言 随着电子商务的快速发展&#xff0c;传统品牌企业越来越重视在线销售市场。为了在竞争激烈的市场环境中取得成功&#xff0c;企业需要实时掌握市场动态&#xff0c;了解自身产品的销售情况、价格趋势以及竞品信息。为了实现这一目标&#xff0c;各大电商平台&#xf…

机器视觉-外观缺陷检测已成笑话

外观检测盛行几年,只要做机器视觉工程师,每个人都好奇都想做做。不做不知道,一做吓一跳。我将从各大家一线公司掌握的信息来具体分析外观缺陷检测埋了多少坑: 明显的现象,公司摆了很多设备,都在公司,都没有出售。我从业15年,从来没有经历过有这么多设备待在公司。从来…

Python 潮流周刊#17:Excel 终于支持 Python 了、Meta 重磅开源新项目、Mojo 新得 1 亿美元融资

你好&#xff0c;我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容&#xff0c;大部分为英文。标题取自其中两则分享&#xff0c;不代表全部内容都是该主题&#xff0c;特此声明。 本周刊由 Python猫 出品&#xff0c;精心筛选国内外的 250 信息源&#xff0c;为你挑选…

软考:中级软件设计师:数据库恢复与备份,故障与恢复,反规范化

软考&#xff1a;中级软件设计师:数据库恢复与备份 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备…

第 7 章 排序算法(6)(快速排序)

7.9快速排序 7.9.1快速排序法介绍: 快速排序&#xff08;Quicksort&#xff09;是对冒泡排序的一种改进。基本思想是&#xff1a;通过一趟排序将要排序的数据分割成独立的两部分&#xff0c;其中一部分的所有数据都比另外一部分的所有数据都要小&#xff0c;然后再按此方法对…

idea2023项目上传到gitee

1、按照gitee插件 File——>Settings plugins——>Marketplace下面搜索gitee,然后按照gitee插件 2、上传项目 VCS_——>Share Project on Gitee 如果第一次没登录的需要先登录&#xff0c;登录完后就可以上传了

【Python】文件拖放(drag and drop)并获取文件信息

QWidget 对象支持拖放&#xff0c;拖拽文件到窗口时触发拖拽事件&#xff0c;拖拽时触发的几个事件函数&#xff1a; dragEnterEvent&#xff1a;当拖动动作进入窗口时触发该事件 dragLeaveEvent&#xff1a;当拖动动作离开窗口时触发该事件&#xff0c;离开窗口时没有mimeDa…

Matlab 使用经验分享(常用函数介绍;矩阵常见计算)

Matlab 使用经验分享 大家好&#xff01;最近有很多朋友询问我关于 Matlab 的使用&#xff0c;于是我决定写一篇博客来分享一下我的经验。对于数学和编程爱好者来说&#xff0c;Matlab 是一个非常有用的工具。我自己在数学实验和数学建模竞赛中也经常使用它。那么&#xff0c;…

数据结构算法--5 归并排序

归并排序 我们先看一下归并排序是怎么归并的 两个有序列表&#xff0c;有low指针指向2&#xff0c;high指针指向6&#xff0c;mid指针指向9 再建一个新列表&#xff0c;1<2&#xff0c;所以1放到列表&#xff0c;右指针右移一位&#xff0c;再比较2和3&#xff0c;2放入列…

【KMP算法-代码随想录】

目录 1.什么是KMP2.什么是next数组3.什么是前缀表&#xff08;1&#xff09;前后缀含义&#xff08;2&#xff09;最长公共前后缀&#xff08;3&#xff09;前缀表的必要性 4.计算前缀表5.前缀表与next数组&#xff08;1&#xff09;使用next数组来匹配 6.构造next数组&#xf…

微信小程序的社区老年人 高校大学生体检信息管理系统

社区老年人体检信息管理系统的系统项目的概述设计分析&#xff0c;主要内容有平台的具体分析&#xff0c;进行数据库的是设计&#xff0c;数据采用mysql数据库&#xff0c;并且对于系统的设计采用比较人性化的操作设计&#xff0c;对于系统出现的错误信息可以及时做出处理及反馈…

成都国际车展来袭:有颜值有实力 大运新能源两款车型备受关注

今年成都国际车展现场最大看点是什么&#xff1f;诸多实力车企汇聚一堂各显神通&#xff0c;形式各样的新能源车型更是吸晴无数&#xff0c;成为消费者的购车首选。老品牌、新势力的大运新能源独具匠心设计特色展台&#xff0c;旗下两款车型悦虎和远志M1重磅登场。两款车型既有…

直击成都国际车展:远航汽车多款车型登陆车展,打造完美驾乘体验

随着市场渗透率日益高涨&#xff0c;新能源汽车成为今年成都国际车展的关注焦点。在本届车展上&#xff0c;新能源品牌占比再创新高&#xff0c;覆盖两个展馆&#xff0c;印证了当下新能源汽车市场的火爆。作为大运集团重磅打造的高端品牌&#xff0c;远航汽车深度洞察高端智能…

记录一个问题~beego中的配置文件autorender

事情的经过是这样的: 在学习beego框架时,遇到了一个问题: tpl模板文件不显示内容; 原因所在: beego配置文件: appname hello httpport 8080 runmode dev world world dataSourceInfo root:955945tcp(localhost:3306)/gmusic?charsetutf8 #自动渲染 这里关闭后就关闭了自…

LeetCode 热题 100(六):25. K 个一组翻转链表、230. 二叉搜索树中第K小的元素、199. 二叉树的右视图

题目一&#xff1a; 25. K 个一组翻转链表https://leetcode.cn/problems/reverse-nodes-in-k-group/题目要求&#xff1a; 思路&#xff1a;建立虚拟头结点&#xff0c;并采用头尾节点&#xff0c;使用常规翻转的函数进行翻转。 具体见代码逻辑。 注意&#xff1a;一定注意好…

咸虾米中关于触发事件的运用

实验效果&#xff1a; 1.点击方块&#xff0c;方块中的随机数发生改变 2.点击方块&#xff0c;方块的背景颜色发生改变 3.点击方块&#xff0c;方块的大小任意改变 4.对上面的三种情况合并&#xff0c;随机数&#xff0c;大小&#xff0c;颜色都发生改变&#xff01; 输入以…

Redis持久化之RDB解读

目录 什么是RDB 配置位置参数解读 如何使用 自动触发 手动触发 save bgsave RDBRDB持久化文件的恢复 正常恢复 恢复失败处理方法 RDB优势 RDB 缺点 redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘…