Tampermonkey快速查找JavaScript加密入口的方法

這篇文章將為大家詳細(xì)講解有關(guān)Tampermonkey快速查找JavaScript加密入口的方法,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。

創(chuàng)新互聯(lián)企業(yè)建站,十余年網(wǎng)站建設(shè)經(jīng)驗(yàn),專注于網(wǎng)站建設(shè)技術(shù),精于網(wǎng)頁設(shè)計(jì),有多年建站和網(wǎng)站代運(yùn)營(yíng)經(jīng)驗(yàn),設(shè)計(jì)師為客戶打造網(wǎng)絡(luò)企業(yè)風(fēng)格,提供周到的建站售前咨詢和貼心的售后服務(wù)。對(duì)于成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)中不同領(lǐng)域進(jìn)行深入了解和探索,創(chuàng)新互聯(lián)在網(wǎng)站建設(shè)中充分了解客戶行業(yè)的需求,以靈動(dòng)的思維在網(wǎng)頁中充分展現(xiàn),通過對(duì)客戶行業(yè)精準(zhǔn)市場(chǎng)調(diào)研,為客戶提供的解決方案。

在很多情況下,我們可能想要在網(wǎng)頁中自動(dòng)執(zhí)行某些代碼,幫助我們完成一些操作。如自動(dòng)搶票、自動(dòng)刷單、自動(dòng)爬蟲等等,這些操作絕大部分都是借助 JavaScript 來實(shí)現(xiàn)的。那么問題來了?在瀏覽器里面怎樣才能方便地執(zhí)行我們所期望執(zhí)行的 JavaScript 代碼呢?在這里推薦一個(gè)插件,叫做 Tampermonkey。這個(gè)插件的功能非常強(qiáng)大,利用它我們幾乎可以在網(wǎng)頁中執(zhí)行任何 JavaScript 代碼,實(shí)現(xiàn)我們想要的功能。

當(dāng)然不僅僅是自動(dòng)搶票、自動(dòng)刷單、自動(dòng)爬蟲,Tampermonkey 的用途遠(yuǎn)遠(yuǎn)不止這些,只要我們想要的功能能用 JavaScript 實(shí)現(xiàn),Tampermonkey 就可以幫我們做到。比如我們可以將 Tampermonkey 應(yīng)用到 JavaScript 逆向分析中,去幫助我們更方便地分析一些 JavaScript 加密和混淆代碼。

本節(jié)我們就來介紹一下這個(gè)插件的使用方法,并結(jié)合一個(gè)實(shí)際案例,介紹下這個(gè)插件在 JavaScript 逆向分析中的用途。

Tampermonkey

Tampermonkey,中文也叫作「油猴」,它是一款瀏覽器插件,支持 Chrome。利用它我們可以在瀏覽器加載頁面時(shí)自動(dòng)執(zhí)行某些 JavaScript 腳本。由于執(zhí)行的是 JavaScript,所以我們幾乎可以在網(wǎng)頁中完成任何我們想實(shí)現(xiàn)的效果,如自動(dòng)爬蟲、自動(dòng)修改頁面、自動(dòng)響應(yīng)事件等等。

安裝

首先我們需要安裝 Tampermonkey,這里我們使用的瀏覽器是 Chrome。直接在 Chrome 應(yīng)用商店或者在 Tampermonkey 的官網(wǎng) https://www.tampermonkey.net/ 下載安裝即可。

安裝完成之后,在 Chrome 瀏覽器的右上角會(huì)出現(xiàn) Tampermonkey 的圖標(biāo),這就代表安裝成功了。

Tampermonkey快速查找JavaScript加密入口的方法
獲取腳本

Tampermonkey 運(yùn)行的是 JavaScript 腳本,每個(gè)網(wǎng)站都能有對(duì)應(yīng)的腳本運(yùn)行,不同的腳本能完成不同的功能。這些腳本我們可以自定義,同樣也可以用已經(jīng)寫好的很多腳本,畢竟有些輪子有了,我們就不需要再去造了。

我們可以在 https://greasyfork.org/zh-CN/scripts 這個(gè)網(wǎng)站找到一些非常實(shí)用的腳本,如全網(wǎng)視頻去廣告、百度云全網(wǎng)搜索等等,大家可以體驗(yàn)一下。

腳本編寫

除了使用別人已經(jīng)寫好的腳本,我們也可以自己編寫腳本來實(shí)現(xiàn)想要的功能。編寫腳本難不難呢?其實(shí)就是寫 JavaScript 代碼,只要懂一些 JavaScript 的語法就好了。另外除了懂 JavaScript 語法,我們還需要遵循腳本的一些寫作規(guī)范,這其中就包括一些參數(shù)的設(shè)置。

下面我們就簡(jiǎn)單實(shí)現(xiàn)一個(gè)小的腳本,實(shí)現(xiàn)某個(gè)功能。

首先我們可以點(diǎn)擊 Tampermonkey 插件圖標(biāo),點(diǎn)擊「管理面板」按鈕,打開腳本管理頁面。

Tampermonkey快速查找JavaScript加密入口的方法

界面類似顯示如下圖所示。

Tampermonkey快速查找JavaScript加密入口的方法

在這里顯示了我們已經(jīng)有的一些 Tampermonkey 腳本,包括我們自行創(chuàng)建的,也包括從第三方網(wǎng)站下載安裝的。

另外這里也提供了編輯、調(diào)試、刪除等管理功能,我們可以方便地對(duì)腳本進(jìn)行管理。

接下來我們來創(chuàng)建一個(gè)新的腳本來試試,點(diǎn)擊左側(cè)的「+」號(hào),會(huì)顯示如圖所示的頁面。

Tampermonkey快速查找JavaScript加密入口的方法

初始化的代碼如下:

// ==UserScript==// @name         New Userscript// @namespace    http://tampermonkey.net/// @version      0.1// @description  try to take over the world!// @author       You// @match        https://www.tampermonkey.net/documentation.php?ext=dhdg// @grant        none// ==/UserScript==(function() {    'use strict';    // Your code here...})();


這里最上面是一些注釋,但這些注釋是非常有用的,這部分內(nèi)容叫做 UserScript Header ,我們可以在里面配置一些腳本的信息,如名稱、版本、描述、生效站點(diǎn)等等。

下面簡(jiǎn)單介紹下 UserScript Header 的一些參數(shù)定義。

?@name:腳本的名稱,就是在控制面板顯示的腳本名稱。?@namespace:腳本的命名空間。?@version:腳本的版本,主要是做版本更新時(shí)用。?@author:作者。?@description:腳本描述。?@homepage, @homepageURL, @website,@source:作者主頁,用于在Tampermonkey選項(xiàng)頁面上從腳本名稱點(diǎn)擊跳轉(zhuǎn)。請(qǐng)注意,如果 @namespace 標(biāo)記以 http://開頭,此處也要一樣。?@icon, @iconURL and @defaulticon:低分辨率圖標(biāo)。?@icon64 and @icon64URL:64x64 高分辨率圖標(biāo)。?@updateURL:檢查更新的網(wǎng)址,需要定義 @version。?@downloadURL:更新下載腳本的網(wǎng)址,如果定義成 none 就不會(huì)檢查更新。?@supportURL:報(bào)告問題的網(wǎng)址。?@include:生效頁面,可以配置多個(gè),但注意這里并不支持 URL Hash。例如:

// @include http://www.tampermonkey.net/*
// @include http://*
// @include https://*
// @include *

?@exclude:不生效頁面,可配置多個(gè),優(yōu)先級(jí)高于 @include 和 @match。?@require:附加腳本網(wǎng)址,相當(dāng)于引入外部的腳本,這些腳本會(huì)在自定義腳本執(zhí)行之前執(zhí)行,比如引入一些必須的庫,如 jQuery 等,這里可以支持配置多個(gè) @require 參數(shù)。例如:

// @require https://code.jquery.com/jquery-2.1.4.min.js
// @require https://code.jquery.com/jquery-2.1.3.min.js#sha256=23456...
// @require https://code.jquery.com/jquery-2.1.2.min.js#md5=34567...,sha256=6789...

?@resource:預(yù)加載資源,可通過 GM_getResourceURL 和 GM_getResourceText 讀取。?@connect:允許被 GM_xmlhttpRequest 訪問的域名,每行一個(gè)。?@run-at:腳本注入的時(shí)刻,如頁面剛加載時(shí),某個(gè)事件發(fā)生后等等。例如:?document-start:盡可能地早執(zhí)行此腳本。?document-body:DOM 的 body 出現(xiàn)時(shí)執(zhí)行。?document-end:DOMContentLoaded 事件發(fā)生時(shí)或發(fā)生后后執(zhí)行。?document-idle:DOMContentLoaded 事件發(fā)生后執(zhí)行,即 DOM 加載完成之后執(zhí)行,這是默認(rèn)的選項(xiàng)。?context-menu:如果在瀏覽器上下文菜單(僅限桌面 Chrome 瀏覽器)中點(diǎn)擊該腳本,則會(huì)注入該腳本。注意:如果使用此值,則將忽略所有 @include 和 @exclude 語句。?@grant:用于添加 GM 函數(shù)到白名單,相當(dāng)于授權(quán)某些 GM 函數(shù)的使用權(quán)限。例如:

// @grant GM_setValue
// @grant GM_getValue
// @grant GM_setClipboard
// @grant unsafeWindow
// @grant window.close
// @grant window.focus

如果沒有定義過 @grant 選項(xiàng),Tampermonkey 會(huì)猜測(cè)所需要的函數(shù)使用情況。

?@noframes:此標(biāo)記使腳本在主頁面上運(yùn)行,但不會(huì)在 iframe 上運(yùn)行。?@nocompat:由于部分代碼可能是專門為專門的瀏覽器所寫,通過此標(biāo)記,Tampermonkey 會(huì)知道腳本可以運(yùn)行的瀏覽器。例如:

// @nocompat Chrome

這樣就指定了腳本只在 Chrome 瀏覽器中運(yùn)行。

除此之外,Tampermonkey 還定義了一些 API,使得我們可以方便地完成某個(gè)操作,如:

?GM_log:將日志輸出到控制臺(tái)。?GM_setValue:將參數(shù)內(nèi)容保存到 Storage 中。?GM_addValueChangeListener:為某個(gè)變量添加監(jiān)聽,當(dāng)這個(gè)變量的值改變時(shí),就會(huì)觸發(fā)回調(diào)。?GM_xmlhttpRequest:發(fā)起 Ajax 請(qǐng)求。?GM_download:下載某個(gè)文件到磁盤。?GM_setClipboard:將某個(gè)內(nèi)容保存到粘貼板。

還有很多其他的 API,大家可以到 https://www.tampermonkey.net/documentation.php 來查看更多的內(nèi)容。

在 UserScript Header 下方是 JavaScript 函數(shù)和調(diào)用的代碼,其中 'use strict' 標(biāo)明代碼使用 JavaScript 的嚴(yán)格模式,在嚴(yán)格模式下可以消除 Javascript 語法的一些不合理、不嚴(yán)謹(jǐn)之處,減少一些怪異行為,如不能直接使用未聲明的變量,這樣可以保證代碼的運(yùn)行安全,同時(shí)提高編譯器的效率,提高運(yùn)行速度。在下方 // Your code here... 這里我們就可以編寫自己的代碼了。

實(shí)戰(zhàn) JavaScript 逆向

下面我們來通過一個(gè)簡(jiǎn)單的 JavaScript 逆向案例來演示一下 Tampermonkey 的作用。

在 JavaScript 逆向的時(shí)候,我們經(jīng)常會(huì)需要追蹤某些方法的堆棧調(diào)用情況,但很多情況下,一些 JavaScript 的變量或者方法名經(jīng)過混淆之后是非常難以捕捉的。

但如果我們能掌握一定的門路或規(guī)律,輔助以 Tampermonkey,就可以更輕松地找出一些 JavaScript 方法的斷點(diǎn)位置,從而加速逆向過程。

在逆向過程中,一個(gè)非常典型的技術(shù)就是 Hook 技術(shù)。Hook 技術(shù)中文又叫做鉤子技術(shù),它就是在程序運(yùn)行的過程中,對(duì)其中的某個(gè)方法進(jìn)行重寫,在原先的方法前后加入我們自定義的代碼。相當(dāng)于在系統(tǒng)沒有調(diào)用該函數(shù)之前,鉤子程序就先捕獲該消息,鉤子函數(shù)先得到控制權(quán),這時(shí)鉤子函數(shù)既可以加工處理(改變)該函數(shù)的執(zhí)行行為,還可以強(qiáng)制結(jié)束消息的傳遞。

如果覺得比較抽象,看完下面的 Hook 案例就懂了。

例如,我們接下來使用 Tampermonkey 實(shí)現(xiàn)對(duì)某個(gè) JavaScript 方法的 Hook,輕松找到某個(gè)方法執(zhí)行的位置,從而快速定位到逆向入口。

接下來我們來這么一個(gè)簡(jiǎn)單的網(wǎng)站:https://scrape.cuiqingcai.com/login1,這個(gè)網(wǎng)站結(jié)構(gòu)非常簡(jiǎn)單,就是一個(gè)用戶名密碼登錄,但是不同的是,點(diǎn)擊 Submit 的時(shí)候,表單提交 POST 的內(nèi)容并不是單純的用戶名和密碼,而是一個(gè)加密后的 Token。

頁面長(zhǎng)這樣:

Tampermonkey快速查找JavaScript加密入口的方法

我們隨便輸入用戶名密碼,點(diǎn)擊登錄按鈕,觀察一下網(wǎng)絡(luò)請(qǐng)求的變化。

可以看到如下結(jié)果:

Tampermonkey快速查找JavaScript加密入口的方法

看到實(shí)際上控制臺(tái)提交了一個(gè) POST 請(qǐng)求,內(nèi)容為:

{"token":"eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJhZG1pbiJ9"}

嗯,確實(shí),沒有諸如 username 和 password 的內(nèi)容了,那這究竟是個(gè)啥?我要是做爬蟲的話?怎么模擬登錄呢?

模擬登錄的前提當(dāng)然就是找到當(dāng)前 token 生成的邏輯了,那么問題來了,到底這個(gè) token 和用戶名、密碼什么關(guān)系呢?我們?cè)趺磥碚覍て渲械闹虢z馬跡呢?

這里我們就可能思考了,本身輸入的是用戶名和密碼,但是提交的時(shí)候卻變成了一個(gè) token,經(jīng)過觀察 token 的內(nèi)容還很像 Base64 編碼。這就代表,網(wǎng)站可能首先將用戶名密碼混為了一個(gè)新的字符串,然后最后經(jīng)過了一次 Base64 編碼,最后將其賦值為 token 來提交了。所以,初步觀察我們可以得出這么多信息。

好,那就來驗(yàn)證下吧,看看網(wǎng)站 JavaScript 代碼里面是咋實(shí)現(xiàn)的。

接下來我們看看網(wǎng)站的源碼,打開 Sources 面板,好家伙,看起來都是 Webpack 打包之后的內(nèi)容,經(jīng)過了一些混淆,類似結(jié)果如下:

Tampermonkey快速查找JavaScript加密入口的方法

這么多混淆代碼,總不能一點(diǎn)點(diǎn)扒著看吧?這得找到猴年馬月?那么遇到這種情形,這怎么去找 token 的生成位置呢?

解決方法其實(shí)有兩種。

Ajax 斷點(diǎn)

由于這個(gè)請(qǐng)求正好是一個(gè) Ajax 請(qǐng)求,所以我們可以添加一個(gè) XHR 斷點(diǎn)監(jiān)聽,把 POST 的網(wǎng)址加到斷點(diǎn)監(jiān)聽上面去,在 Sources 面板右側(cè)添加這么一個(gè) XHR 斷點(diǎn),如圖所示:

Tampermonkey快速查找JavaScript加密入口的方法

這時(shí)候如果我們?cè)俅吸c(diǎn)擊登錄按鈕的時(shí)候,正好發(fā)起一次 Ajax 請(qǐng)求,就進(jìn)入到斷點(diǎn)了,然后再看堆棧信息就可以一步步找到編碼的入口了。

點(diǎn)擊 Submit 之后,頁面就進(jìn)入了 Debug 狀態(tài)停下來了,結(jié)果如下:

Tampermonkey快速查找JavaScript加密入口的方法

一步步找,我們最后其實(shí)可以找到入口其實(shí)是在 onSubmit 方法這里。但實(shí)際上,我們觀察到,這里的斷點(diǎn)的棧頂還會(huì)包括了一些 async Promise 等無關(guān)的內(nèi)容,而我們真正想找的是用戶名和密碼經(jīng)過處理,再進(jìn)行 Base64 編碼的地方,這些請(qǐng)求的調(diào)用實(shí)際上和我們找尋的入口是沒有很大的關(guān)系的。

另外,如果我們想找的入口位置并不伴隨這一次 Ajax 請(qǐng)求,這個(gè)方法就沒法用了。

這個(gè)方法是奏效的,但是我們先不講 onSubmit 方法里面究竟是什么邏輯,下一個(gè)方法再來講。

Hook Function

所以,這里介紹第二種可以快速定位入口的方法,那就是使用 Tampermonkey 自定義 JavaScript 實(shí)現(xiàn)某個(gè) JavaScript 方法的 Hook。Hook 哪里呢?最明顯的,Hook Base64 編碼的位置就好了。

那么這里就涉及到一個(gè)小知識(shí)點(diǎn),JavaScript 里面的 Base64 編碼是怎么實(shí)現(xiàn)的。沒錯(cuò)就是 btoa 方法,所以說,我們來 Hook btoa 方法就好了。

好,這里我們新建一個(gè) Tampermonkey 腳本,內(nèi)容如下:

// ==UserScript==
// @name         HookBase64
// @namespace    https://scrape.cuiqingcai.com/
// @version      0.1
// @description  Hook Base64 encode function
// @author       Germey
// @match       https://scrape.cuiqingcai.com/login1
// @grant        none
// ==/UserScript==
(function () {
    'use strict'
    function hook(object, attr) {
        var func = object[attr]
        object[attr] = function () {
            console.log('hooked', object, attr)
            var ret = func.apply(object, arguments)
            debugger
            return ret
        }
    }
    hook(window, 'btoa')
})()

首先我們定義了一些 UserScript Header,包括 @name、@match 等等,這里比較重要的就是 @name,表示腳本名稱;另外一個(gè)就是 @match,代表腳本生效的網(wǎng)址。

腳本的內(nèi)容如上所示。我們定義了一個(gè) hook 方法,傳入 object 和 attr 參數(shù),意思就是 Hook object 對(duì)象的 attr 參數(shù)。例如我們?nèi)绻?Hook 一個(gè) alert 方法,那就把 object 設(shè)置為 window,把 attr 設(shè)置為 alert 字符串。這里我們想要 Hook Base64 的編碼方法,在 JavaScript 中,Based64 編碼是用 btoa 方法實(shí)現(xiàn)的,那么這里我們就只需要 Hook window 對(duì)象的 btoa 方法就好了。

那么 Hook 是怎么實(shí)現(xiàn)的呢?我們來看下,首先一句 var func = object[attr],相當(dāng)于我們先把它賦值為一個(gè)變量,我們調(diào)用 func 方法就可以實(shí)現(xiàn)和原來相同的功能。接著,我們?cè)僦苯痈膶戇@個(gè)方法的定義,直接改寫 object[attr],將其改寫成一個(gè)新的方法,在新的方法中,通過 func.apply 方法又重新調(diào)用了原來的方法。這樣我們就可以保證,前后方法的執(zhí)行效果是不受什么影響的,之前這個(gè)方法該干啥就還是干啥的。但是和之前不同的是,我們自定義方法之后,現(xiàn)在可以在 func 方法執(zhí)行的前后,再加入自己的代碼,如 console.log 將信息輸出到控制臺(tái),如 debugger 進(jìn)入斷點(diǎn)等等。這個(gè)過程中,我們先臨時(shí)保存下來了 func 方法,然后定義一個(gè)新的方法,接管程序控制權(quán),在其中自定義我們想要的實(shí)現(xiàn),同時(shí)在新的方法里面再重新調(diào)回 func 方法,保證前后結(jié)果是不受影響的。所以,我們達(dá)到了在不影響原有方法效果的前提下,可以實(shí)現(xiàn)在方法的前后實(shí)現(xiàn)自定義的功能,就是 Hook 的過程。

最后,我們調(diào)用 hook 方法,傳入 window 對(duì)象和 btoa 字符串,保存。

接下來刷新下頁面,這時(shí)候我們就可以看到這個(gè)腳本就在當(dāng)前頁面生效了,如圖所示。

Tampermonkey快速查找JavaScript加密入口的方法

接下來,打開控制臺(tái),切換到 Sources 面板,這時(shí)候我們可以看到站點(diǎn)下面的資源多了一個(gè)叫做 Tampermonkey 的目錄,展開之后,發(fā)現(xiàn)就是我們剛剛自定義的腳本。

Tampermonkey快速查找JavaScript加密入口的方法

然后輸入用戶名、密碼,點(diǎn)擊提交。發(fā)現(xiàn)成功進(jìn)入了斷點(diǎn)模式停下來了,代碼就卡在了我們自定義的 debugger 這一行代碼的位置,如下圖所示。

Tampermonkey快速查找JavaScript加密入口的方法

成功 Hook 住了,這說明 JavaScript 代碼在執(zhí)行過程中調(diào)用到了 btoa 方法。

看下控制臺(tái),如下圖所示。

Tampermonkey快速查找JavaScript加密入口的方法

這里也輸出了 window 對(duì)象和 btoa 方法,驗(yàn)證正確。

這樣,我們就順利找到了 Base64 編碼操作這個(gè)路口,然后看看堆棧信息,也已經(jīng)不會(huì)出現(xiàn) async、Promise 這樣的調(diào)用,很清晰地呈現(xiàn)了 btoa 方法逐層調(diào)用的過程,非常清晰明了了,如圖所示。

Tampermonkey快速查找JavaScript加密入口的方法

各個(gè)底層的 encode 方法略過,這樣我們也非常順利地找到了 onSubmit 方法里面的處理邏輯:

onSubmit: function() {
  var e = c.encode(JSON.stringify(this.form));
  this.$http.post(a["a"].state.url.root, {
    token: e
  }).then((function(e) {
      console.log("data", e)
  }))
}

仔細(xì)看看,encode 方法其實(shí)就是調(diào)用了一下 btoa 方法,就是一個(gè) Base64 編碼的過程。

另外堆棧信息中可以清晰地看到 Hook 的方法在執(zhí)行前傳入的參數(shù)值,即 arguments。另外執(zhí)行的之后的結(jié)果 ret 也可以輕松地找到了,如圖所示:

Tampermonkey快速查找JavaScript加密入口的方法

所以,現(xiàn)在我們知道了 token 和用戶名、密碼是什么關(guān)系了吧。

這里一目了然了,就是對(duì)表單進(jìn)行了 JSON 序列化,然后調(diào)用了 encode 也就是 btoa 方法,并賦值為了 token,入口順利解開。后面,我們只需要模擬這個(gè)過程就 OK 了。

所以,我們通過 Tampermonkey 自定義 JavaScript 腳本的方式實(shí)現(xiàn)了某個(gè)方法調(diào)用的 Hook,使得我們快速能定位到加密入口的位置,非常方便。

以后如果觀察出來了一些門道,可以多使用這種方法來嘗試,如 Hook encode 方法、decode 方法、stringify 方法、log 方法、alert 方法等等,簡(jiǎn)單而又高效。

以上便是通過 Tampermonkey 實(shí)現(xiàn)簡(jiǎn)單 Hook 的基礎(chǔ)操作,當(dāng)然這個(gè)僅僅是一個(gè)常見的基礎(chǔ)案例,不過從中我們也可以總結(jié)出一些 Hook 的基本門道。

后面我們會(huì)繼續(xù)介紹更多相關(guān)內(nèi)容。

如果想了解更多內(nèi)容,也可以關(guān)注下「夜幕團(tuán)隊(duì)」所開的 JavaScript 逆向課系列,文章:

嗯,我們出了一套做爬蟲必備的 JS 逆向課程

JavaScript 逆向高階課助你沖破爬蟲瓶頸!

關(guān)于Tampermonkey快速查找JavaScript加密入口的方法就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,可以學(xué)到更多知識(shí)。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。

名稱欄目:Tampermonkey快速查找JavaScript加密入口的方法
本文網(wǎng)址:http://bm7419.com/article26/psspcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、靜態(tài)網(wǎng)站、品牌網(wǎng)站制作、品牌網(wǎng)站建設(shè)、微信公眾號(hào)、營(yíng)銷型網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都定制網(wǎng)站網(wǎng)頁設(shè)計(jì)