某商店JS混淆補環境與純算逆向分析

文章目錄

  • 1. 寫在前面
  • 2. 接口分析
  • 3. 補環境分析
  • 4. 純算法還原

【🏠作者主頁】:吳秋霖
【💼作者介紹】:擅長爬蟲與JS加密逆向分析!Python領域優質創作者、CSDN博客專家、阿里云博客專家、華為云享專家。一路走來長期堅守并致力于Python與爬蟲領域研究與開發工作!
【🌟作者推薦】:對爬蟲領域以及JS逆向分析感興趣的朋友可以關注《爬蟲JS逆向實戰》《深耕爬蟲領域》
未來作者會持續更新所用到、學到、看到的技術知識!包括但不限于:各類驗證碼突防、爬蟲APP與JS逆向分析、RPA自動化、分布式爬蟲、Python領域等相關文章

作者聲明:文章僅供學習交流與參考!嚴禁用于任何商業與非法用途!否則由此產生的一切后果均與作者無關!如有侵權,請聯系作者本人進行刪除!

1. 寫在前面

??這個站搜索請求必須攜帶一個Token,生成的話是在它自己sec接口請求生成的(無感驗證生成),請求生成Token的參數中有驗簽需要處理,源碼套了混淆。有概率會出現二次驗證(極驗),總得來說比較簡單,之前一個小伙伴找到咨詢補環境的時候出現異常時因為反調試的問題,整個只需要處理一下格式化檢測跟那個內存溢出無限循行的問題就可以

在這里插入圖片描述


分析網站

aHR0cHM6Ly9tLmFwcC5taS5jb20v

2. 接口分析

這里隨便搜索一個關鍵詞,可以看到提交的請求參數中有一個Token,這個參數的值在上一個請求觸發并在接口響應數據中返回,這個有效性僅一次,不能夠固定。如下所示:

{"msg":"非正常請求","code":403001,"data":null,"logId":"MO-29s4w-elibom-3c-noitcudorp-noitargetni-bew-erotsppa_0825121058059_33aa"}

在這里插入圖片描述
在這里插入圖片描述

生成Token參數的接口請求參數有兩個動態參數(s、d)需要處理,根據堆棧進入到m.js混淆過的JS文件,找到發包的位置跟一下可以看到最終參數生成的位置,如下所示:

在這里插入圖片描述

3. 補環境分析

混淆的JS代碼中實現了一些普遍的反調試手段,包括不限于環境檢測,Function.prototype.toString檢測以及一些自動化工具的檢測。混淆源代碼的控制流扁平化跟字符串的加密(所有的字符都放在_0x3fb6數組中)運行時動態去還原,如下所示:

// Function.prototype.toString檢測??
var _0x4ef304 = function() {var _0x5ca3e4 = new RegExp('\x5c\x77\x2b\x20\x2a\x5c\x28\x5c\x29\x20\x2a\x7b\x5c\x77\x2b\x20\x2a\x5b\x27\x7c\x22\x5d\x2e\x2b\x5b\x27\x7c\x22\x5d\x3b\x3f\x20\x2a\x7d');return !_0x5ca3e4['\x74\x65\x73\x74'](_0x20e69d['\x74\x6f\x53\x74\x72\x69\x6e\x67']());
};// 瀏覽器指紋檢測
function _0x836b91() {/Android ((\d).\d+)/['test'](navigator['userAgent']);return parseInt(RegExp['$2']) < 6;
}// WebGL檢測??
var _0x5c8ed2 = document.createElement('canvas');
var _0x510957 = _0x5c8ed2.getContext('webgl') || _0x5c8ed2.getContext('experimental-webgl');// 無限遞歸(導致崩潰)
function _0x3fa0e2(_0x16d6fa) {if (_0x16d6fa['indexOf']('\x69' === -1)) {_0x3f7dc2(_0x16d6fa);}
}// 內存占用??
var _0x2e4c9a = [];
for (var i = 0; i < 1000000; i++) {_0x2e4c9a.push(Math.random());
}

在這里插入圖片描述

可以看到上圖中_0x27edce就是入口的加密函數了,兩個參數一個是env的結構化數據,還有一個固定的字符串search傳不傳都可以,如下圖所示:

在這里插入圖片描述

如果是選擇補環境的方案,不想去分析整個JS的混淆加密邏輯,只需要把m.js整個源碼拿出來即可,補環境這里作者使用jsdom快速實現的(大家也可以自己手補或者用其他的框架都行),環境頭如下所示:

const { JSDOM } = require("jsdom");const baseUrl = "https://m.app.mi.com/";const dom = new JSDOM("", {url: baseUrl,referrer: baseUrl,userAgent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",runScripts: "dangerously"
});window = dom.window;document = window.document;window.HTMLCanvasElement.prototype.getContext = function() {return {fillRect: function() {},clearRect: function() {},getImageData: function(x, y, w, h) {return {data: new Uint8ClampedArray(w * h * 4)};},putImageData: function() {},createImageData: function() {return [];},setTransform: function() {},drawImage: function() {},save: function() {},fillText: function() {},restore: function() {},beginPath: function() {},moveTo: function() {},lineTo: function() {},closePath: function() {},stroke: function() {},translate: function() {},scale: function() {},rotate: function() {},arc: function() {},fill: function() {},measureText: function() {return { width: 0 };},transform: function() {},rect: function() {},clip: function() {},};
};window.HTMLCanvasElement.prototype.toDataURL = function() {return "";
};navigator = {appVersion:"5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36",platform:'MacIntel',appCodeName:'Mozilla',appName:'Netscape',language:'en-US',product:'Gecko',vendorSub:'',vendor:'Google Inc.',userAgent:'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36'
}

然后使用window導出_0x27edce到全局使用即可,有兩個地方的小細節需要處理一下。就是上面檢測點里面的一個無限遞歸導致內存滿溢出的問題還有一個就是格式化檢測,處理一下注釋或者修改一下就可以,如下所示:

在這里插入圖片描述

4. 純算法還原

function _0x27edce(_0xd7d75d, _0x264211) {var _0x4874ab = function(_0xd7d75d) {for (var _0x264211 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '-', '=', '_', '+', '~', '`', '{', '}', '[', ']', '|', ':', '<', '>', '?', '/', '.'], _0x4874ab = [], _0xb6b2f = 0x0; _0xb6b2f < _0xd7d75d; _0xb6b2f += 0x1)_0x4874ab[_0x5ebc('0x17')](_0x264211[parseInt(0x59 * Math['random'](), 0xa)]);return _0x4874ab[_0x5ebc('0x19')]('');}(0x10), _0xb6b2f = _0x25aa39[_0x5ebc('0x261')][_0x5ebc('0x262')][_0x5ebc('0x263')](_0x5ebc('0x264')), _0xd88633 = _0x25aa39[_0x5ebc('0x265')]['pkcs7'][_0x5ebc('0x266')](_0x25aa39[_0x5ebc('0x261')][_0x5ebc('0x262')][_0x5ebc('0x263')](JSON['stringify'](_0xd7d75d))), _0xd88633 = new _0x25aa39[(_0x5ebc('0x267'))][(_0x5ebc('0x12f'))](_0x25aa39['utils']['utf8'][_0x5ebc('0x263')](_0x4874ab),_0xb6b2f)[_0x5ebc('0x12b')](_0xd88633), _0xd88633 = _0x5aeeb2['encode'](_0x3969ee[_0x5ebc('0x268')](_0x25aa39['utils'][_0x5ebc('0x11d')][_0x5ebc('0x269')](_0xd88633))), _0x4874ab = _0x3250e2[_0x5ebc('0x12b')](_0x5aeeb2[_0x5ebc('0x117')](_0x4874ab), _0x3250e2[_0x5ebc('0x26a')](_0x5ebc('0x26b'))), _0xd7d75d = _0x5aeeb2[_0x5ebc('0x117')](JSON[_0x5ebc('0x26c')](_0xd7d75d)), _0x264211 = (_0x264211 = _0x264211 + _0xd7d75d,_0x379e77[_0x5ebc('0x143')](_0x264211));return Object(_0x1c50fb['i'])() ? {'s': _0x264211,'d': _0xd7d75d} : {'s': _0x4874ab,'d': _0xd88633};
}

這里從上面這段核心的混淆代碼開始進行分析,還原純算加密的流程,_0xd7d75d的原始對象是env的一個大串,_0x264211是一個可選參數,_0x4874ab這里從隨機字符表中獲取到了一個16位的隨機字符(AES的密鑰),_0x264211是密鑰的字符集,實現如下:

import randomdef generate_aes_key():charset = list("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890!@#$%^&*()-=_+~`{}[]|:<>?/.")return "".join(random.choice(charset) for _ in range(16)).encode("utf-8")

這里我們得到了AES的密鑰,也拿到env的結構化數據,往下繼續看d參數對應的_0xd88633怎么來的,混淆JS中特征也很明顯,其中有pkcs7,跳轉到如下代碼處:

var _0x25aa39 = {'AES': _0x4cca13,'ModeOfOperation': {'cbc': _0x35f959},'utils': {'hex': _0x264211,'utf8': _0x51dd15},'padding': {'pkcs7': {'pad': function(_0xd7d75d) {var _0x264211 = 0x10 - (_0xd7d75d = _0x300d04(_0xd7d75d, !0x0))['length'] % 0x10, _0x4874ab = _0x2d1977(_0xd7d75d[_0x5ebc('0x51')] + _0x264211);_0x294129(_0xd7d75d, _0x4874ab);for (var _0xb6b2f = _0xd7d75d[_0x5ebc('0x51')]; _0xb6b2f < _0x4874ab[_0x5ebc('0x51')]; _0xb6b2f++)_0x4874ab[_0xb6b2f] = _0x264211;return _0x4874ab;}}}
}

_0x5ebc('0x264')這個是AES加密的IV_0x5ebc('0x12f')是AES加密使用的模式,然后_0x5aeeb2調用的如下:

var _0x5aeeb2 = {'base64': _0x5ebc('0x119'),'encode': function(_0xd7d75d) {if (!_0xd7d75d)return !0x1;for (var _0x264211, _0x4874ab, _0xb6b2f, _0xd88633, _0x49094b, _0x3aca4c, _0x253b33 = '', _0x2f77ed = 0x0; _0xb6b2f = (_0x3aca4c = _0xd7d75d[_0x5ebc('0xec')](_0x2f77ed++)) >> 0x2,_0xd88633 = (0x3 & _0x3aca4c) << 0x4 | (_0x264211 = _0xd7d75d[_0x5ebc('0xec')](_0x2f77ed++)) >> 0x4,_0x49094b = (0xf & _0x264211) << 0x2 | (_0x4874ab = _0xd7d75d[_0x5ebc('0xec')](_0x2f77ed++)) >> 0x6,_0x3aca4c = 0x3f & _0x4874ab,isNaN(_0x264211) ? _0x49094b = _0x3aca4c = 0x40 : isNaN(_0x4874ab) && (_0x3aca4c = 0x40),_0x253b33 += this[_0x5ebc('0x11a')][_0x5ebc('0x8b')](_0xb6b2f) + this[_0x5ebc('0x11a')][_0x5ebc('0x8b')](_0xd88633) + this[_0x5ebc('0x11a')][_0x5ebc('0x8b')](_0x49094b) + this[_0x5ebc('0x11a')][_0x5ebc('0x8b')](_0x3aca4c),_0x2f77ed < _0xd7d75d[_0x5ebc('0x51')]; );return _0x253b33;},'decode': function(_0xd7d75d) {if (!_0xd7d75d)return !0x1;_0xd7d75d = _0xd7d75d[_0x5ebc('0x43')](/[^A-Za-z0-9\+\/\=]/g, '');for (var _0x264211, _0x4874ab, _0xb6b2f, _0xd88633, _0x49094b = '', _0x3aca4c = 0x0; _0x264211 = this[_0x5ebc('0x11a')][_0x5ebc('0x1b')](_0xd7d75d[_0x5ebc('0x8b')](_0x3aca4c++)),_0x4874ab = this['base64'][_0x5ebc('0x1b')](_0xd7d75d[_0x5ebc('0x8b')](_0x3aca4c++)),_0xb6b2f = this[_0x5ebc('0x11a')][_0x5ebc('0x1b')](_0xd7d75d[_0x5ebc('0x8b')](_0x3aca4c++)),_0xd88633 = this['base64'][_0x5ebc('0x1b')](_0xd7d75d[_0x5ebc('0x8b')](_0x3aca4c++)),_0x49094b += String[_0x5ebc('0x11b')](_0x264211 << 0x2 | _0x4874ab >> 0x4),0x40 != _0xb6b2f && (_0x49094b += String[_0x5ebc('0x11b')]((0xf & _0x4874ab) << 0x4 | _0xb6b2f >> 0x2)),0x40 != _0xd88633 && (_0x49094b += String['fromCharCode']((0x3 & _0xb6b2f) << 0x6 | _0xd88633)),_0x3aca4c < _0xd7d75d[_0x5ebc('0x51')]; );return _0x49094b;}
}

現在上面的分析,可以知道參數d的實現先是對env_data數據進行了一個JSON序列化,如下所示:

在這里插入圖片描述

然后生成AES的密鑰,根據調試信息中獲取到的CBC、IV等信息對參數d加密并編碼,還原算法實現如下所示:

import json
import base64
from Crypto.Util.Padding import pad
from Crypto.Cipher import AES, PKCS1_v1_5def aes_cbc_encrypt_fixed_iv(key: bytes, data: bytes) -> bytes:iv = b"0102030405060708"cipher = AES.new(key, AES.MODE_CBC, iv)return cipher.encrypt(pad(data, AES.block_size))def sign(env_data: dict) -> dict:json_data = json.dumps(env_data, separators=(',', ':'), ensure_ascii=False).encode('utf-8')# 隨機16位密鑰aes_key = generate_aes_key()encrypted_data = aes_cbc_encrypt_fixed_iv(aes_key, json_data)aes_key_b64 = base64.b64encode(aes_key).decode()d = base64.b64encode(encrypted_data).decode()return d

接下來看參數s是如何加密生成的,_0x4874ab這個地方獲取了一個getPublicKey,然后公鑰在_0x5ebc('0x26b')進行了一個RSA的加密,在最初的大數組中也能看到相關的特征,如下所示:

在這里插入圖片描述

_0x3250e2 = {'getPublicKey': function(_0xd7d75d) {return !(_0xd7d75d[_0x5ebc('0x51')] < 0x32) && (_0x5ebc('0x11e') == _0xd7d75d['substr'](0x0, 0x1a) && ('-----END\x20PUBLIC\x20KEY-----' == (_0xd7d75d = _0xd7d75d[_0x5ebc('0x115')](0x1a))[_0x5ebc('0x115')](_0xd7d75d[_0x5ebc('0x51')] - 0x18) && (_0xd7d75d = _0xd7d75d['substr'](0x0, _0xd7d75d['length'] - 0x18),!(_0xd7d75d = new _0x56ab29(_0x5aeeb2['decode'](_0xd7d75d)))[_0x5ebc('0x42')] && (_0x5ebc('0x11f') === (_0xd7d75d = _0xd7d75d[_0x5ebc('0x11')])[0x0][0x0][0x0] && new _0x8f65e0(_0xd7d75d[0x0][0x1][0x0][0x0],_0xd7d75d[0x0][0x1][0x0][0x1])))));},'encrypt': function(_0xd7d75d, _0x264211) {if (!_0x264211)return !0x1;var _0x4874ab = _0x264211[_0x5ebc('0x116')][_0x5ebc('0x10f')]() + 0x7 >> 0x3;if (!(_0xd7d75d = this[_0x5ebc('0x120')](_0xd7d75d, _0x4874ab)))return !0x1;if (!(_0xd7d75d = _0xd7d75d[_0x5ebc('0x121')](_0x264211[_0x5ebc('0x118')], _0x264211[_0x5ebc('0x116')])))return !0x1;for (_0xd7d75d = _0xd7d75d[_0x5ebc('0x54')](0x10); _0xd7d75d[_0x5ebc('0x51')] < 0x2 * _0x4874ab; )_0xd7d75d = '0'[_0x5ebc('0x18')](_0xd7d75d);return _0x5aeeb2[_0x5ebc('0x117')](_0x3969ee['decode'](_0xd7d75d));},'pkcs1pad2': function(_0xd7d75d, _0x264211) {if (_0x264211 < _0xd7d75d[_0x5ebc('0x51')] + 0xb)return null;for (var _0x4874ab = [], _0xb6b2f = _0xd7d75d[_0x5ebc('0x51')] - 0x1; 0x0 <= _0xb6b2f && 0x0 < _0x264211; )_0x4874ab[--_0x264211] = _0xd7d75d[_0x5ebc('0xec')](_0xb6b2f--);for (_0x4874ab[--_0x264211] = 0x0; 0x2 < _0x264211; )_0x4874ab[--_0x264211] = Math['floor'](0xfe * Math[_0x5ebc('0x3d')]()) + 0x1;return _0x4874ab[--_0x264211] = 0x2,_0x4874ab[--_0x264211] = 0x0,new _0x20635b(_0x4874ab);}

在這里插入圖片描述

綜上分析發現它這個參數s是對AES的密鑰進行了一層RSA后再編碼得到的,所以服務端那邊的校驗則是先對s參數的值進行一個B64的解碼,然后使用RSA私鑰進行解密得到AES的密鑰,服務端再拿著這個16字節的密鑰去解參數d加密后的業務數據,以此驗證本次請求的合法性,至此純算的加密流程圖及算法實現如下:

在這里插入圖片描述

from Crypto.PublicKey import RSA
def rsa_encrypt_pkcs1_v1_5(data: bytes, public_key_pem: str) -> bytes:rsa_key = RSA.import_key(public_key_pem)cipher = PKCS1_v1_5.new(rsa_key)return cipher.encrypt(data)aes_key = generate_aes_key()
aes_key_b64 = base64.b64encode(aes_key).decode()
s = rsa_encrypt_pkcs1_v1_5(aes_key_b64.encode())

不管是補環境還是純算,有一處小細節需要注意一下。在構建環境數據env_data的時候,涉及到時間戳的地方都需要動態生成傳遞,然后如果加密參數不對的話是通過不了接口驗簽的,會出現如下所示的情況:

{'msg': '參數錯誤', 'code': 400, 'data': {'message': 'invalid data', 'status': 463}}

文中之前開頭也提到了會有概率觸發一個極驗的二次行為驗證滑塊,這個感興趣的也可以去分析一下,觸發率極低,調試的時候就出現過一次,如下所示:

在這里插入圖片描述

在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/920495.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/920495.shtml
英文地址,請注明出處:http://en.pswp.cn/news/920495.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何安裝 mysql-installer-community-8.0.21.0.tar.gz(Linux 詳細教程附安裝包下載)?

這是一個 ?Linux 下 MySQL 8.0.21 的壓縮安裝包&#xff0c;雖然名字里有 installer&#xff0c;但它其實就是一個壓縮好的二進制安裝包&#xff0c;不是 Windows 那種圖形化安裝程序。 一、準備工作 確保你已經有&#xff1a; Linux 系統&#xff08;比如 Ubuntu、CentOS、…

IDEA-琴澳研究中心及學術聯盟啟動,產研協同賦能區域發展

8月30日&#xff0c;IDEA-琴澳中心主導研發的Smaray渲染引擎將發布可免費下載的Tech Preview&#xff08;技術預覽版&#xff09;。本次發布標志著粵港澳大灣區在政產研協同創新實現成果落地&#xff0c;也是產業“人工智能”的探索邁進。Smaray是國內首個公開服務的、AI驅動的…

如何備份 TECNO 手機上的短信

許多 TECNO 用戶都在尋找方法&#xff0c;以防止因手機損壞、被盜或恢復出廠設置而導致重要對話意外丟失&#xff0c;確保在需要時能夠訪問他們的數據。還有些人希望在釋放設備存儲空間的同時&#xff0c;仍然保留舊消息的副本以供日后參考。如果你一直在尋找“備份 TECNO 短信…

OpenAI Sora深度解析:AI視頻生成技術如何重塑廣告電商行業?影業合作已落地

最近刷到一條超震撼的視頻&#xff1a;咖啡杯從桌角滑落&#xff0c;在空中轉了半圈居然自己彈回桌面&#xff0c;牛奶一滴沒灑。你猜怎么著&#xff1f;這居然是AI生成的&#xff0c;就是OpenAI那個叫Sora的工具做的。是不是覺得有點不可思議&#xff1f;現在這技術已經能做到…

力扣p1011在D天送達包裹的能力 詳解

題目如下&#xff1a;代碼如下&#xff0c;先看代碼&#xff0c;再看思路&#xff1a;注意&#xff0c;從check函數下方的left處看&#xff0c;我認為難點在于以啥來二分&#xff0c;都說求啥拿啥分&#xff0c;但實際無從下手&#xff0c;關鍵在于如何尋找邊界&#xff0c;此處…

React Three Fiber

下面&#xff0c;我們來系統的梳理關于 React Three Fiber&#xff1a;WebGL 與 React 的基本知識點&#xff1a; 一、React Three Fiber 核心概念 1.1 什么是 React Three Fiber&#xff1f; React Three Fiber&#xff08;R3F&#xff09;是一個用于 Three.js 的 React 渲染…

YARN架構解析:深入理解Hadoop資源管理核心

YARN架構解析&#xff1a;深入理解Hadoop資源管理核心 &#x1f31f; 你好&#xff0c;我是 勵志成為糕手 &#xff01; &#x1f30c; 在代碼的宇宙中&#xff0c;我是那個追逐優雅與性能的星際旅人。 ? 每一行代碼都是我種下的星光&#xff0c;在邏輯的土壤里生長成璀璨的銀…

爬蟲代理的核心作用、分類及使用要點

在數據采集場景中&#xff0c;爬蟲代理作為“中間傳輸節點”&#xff0c;通過轉發爬蟲請求、隱藏真實IP地址&#xff0c;解決傳統爬蟲面臨的諸多限制&#xff0c;其核心價值體現在三個方面&#xff1a;突破IP封鎖與訪問限制&#xff1a;多數網站會對高頻請求的IP進行封鎖&#…

EXCEL開發之路(三)sheets梯形樣式設計—仙盟創夢IDE

在蔬菜批發行業&#xff0c;高效的信息管理與操作便捷性對于業務的順暢開展至關重要。梯形 Nav&#xff08;導航欄&#xff09;切換這一設計&#xff0c;看似只是界面交互的小細節&#xff0c;實則在提升用戶體驗、優化業務流程等方面有著不可忽視的意義&#xff0c;對于初學者…

Unity游戲打包——iOS打包pod的重裝和使用

本文由 NRatel 歷史筆記整理而來&#xff0c;如有錯誤歡迎指正。 一、重裝 pod 和使用 1、下載安裝 rvm curl -L get.rvm.io | bash -s stable 2、使環境變量生效 (zsh) source ~/.zshrc source ~/.profile 3、查看rvm版本 rvm -v 4、重裝ruby 關閉mac sip&#xff08;可能需…

AWS OpenSearch 可觀測最佳實踐

AWS OpenSearch 介紹 OpenSearch 是一種全面開源搜索和分析引擎&#xff0c;使用案例包括日志分析、實時應用程序監控、點擊流分析等。Amazon OpenSearch Service 是一項托管服務&#xff0c;讓用戶能夠在 AWS 云中輕松部署、運行并擴展 OpenSearch 集群。 觀測云 觀測云是一…

HTML5七夕節網站源碼

一&#xff0c;網站概述 本七夕節主題網站采用HTML5、CSS3與JavaScript技術棧構建&#xff0c;響應式設計適配多終端設備&#xff0c;通過模塊化開發實現豐富交互體驗。以下從架構設計、功能實現和視覺效果三方面概述&#xff1a; 1.1、架構設計 采用單頁應用(SPA)架構&…

以技術賦能強化消費者信任,助推餐飲服務質量提質增效的明廚亮灶開源了

AI 視頻監控平臺簡介 AI 視頻監控平臺是一款兼具強大功能與便捷操作的實時算法視頻監控系統。其核心愿景在于打破各大芯片廠商間的技術壁壘&#xff0c;省去冗余重復的適配流程&#xff0c;構建 “芯片 - 算法 - 應用” 的全流程組合體系。這一體系可幫助企業級應用降低約 95%…

【NJU-OS-JYY筆記】操作系統:設計與實現

1. 緒論 1.1. 程序的執行與狀態機 在計算機科學中&#xff0c;任何程序都可以被抽象為一個狀態機&#xff0c;無論是我們熟知的日常工具&#xff08;LibreOffice&#xff0c;Chrome&#xff09;還是開發工具&#xff08;IDE&#xff0c;GCC&#xff0c;GDB&#xff09;&#…

GaussDB 修改schema屬主時報:must be member of role “dtest“

1 問題現象schema的屬主為root&#xff0c;客戶需要修改對應的業務用戶&#xff0c;在使用root用戶登入postgres庫時修改schema屬主時報&#xff1a;ERROR:dn_6007_6008_6009:must be member of role "dtest"執行命令為&#xff1a;alter schema dtest owner to dtes…

好?真題資源+專業練習平臺=高效備賽2025年初中古詩文大會(0829)

2025年初中生古詩文大會的初選11月2日-9日正式開賽&#xff0c;還有兩個多月。快來做真題&#xff0c;吃透題目背后的知識點&#xff0c;舉一反三不但對比賽有用&#xff0c;對于課內的語文學習也有很大促進。【好消息】2025年古詩文大會閱讀專輯的模擬題好真題獨家超詳細完整解…

Pointer--Learing MOOC-C語言第九周指針

2、指針運算1.指針運算&#xff08;本節內容詳細請登錄中國大學MOOC官網查詢&#xff09;指針是可計算的112&#xff1f;指針計算*p指針比較0地址指針的類型用指針來做什么2.動態內存分配輸入數據&#xff1a;1.如果輸入數據時候&#xff0c;先告訴你個數&#xff0c;然后再輸入…

升級DrRacket8.10到8.18版本@Ubuntu24.04

升級DrRacket8.10到8.18版本 安裝參考&#xff1a;在FreeBSD、Windows、Ubuntu24三種平臺下安裝Racket多范式編程語言_racket安裝-CSDN博客 Ubuntu24.04里面的版本是8.10,所以無法使用apt upgrade升級&#xff0c;最終是使用下載升級軟件&#xff0c;手工升級完成&#xff01…

亞馬遜季節性產品運營策略:從傳統到智能化的演進

"季節性產品如何在有限銷售窗口內實現收益最大化&#xff1f;" "面對劇烈波動的市場需求&#xff0c;廣告投放該如何靈活應對&#xff1f;" "如何避免旺季斷貨或淡季資源浪費的庫存難題&#xff1f;" "傳統人工運營方式能否跟上季節性產品的…

解析xml文件并錄入數據庫

主函數&#xff1a;參數處理、信號處理、打開日志、解析參數到結構體、添加進程心跳、處理業務函數業務處理函數&#xff1a;將規則xml加載到結構體&#xff08;xml文件名、對應表名、更新標志、預先執行語句&#xff09;、打開源文件夾并匹配10000個xml文件、判斷數據庫是否開…