国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

4.10 x64dbg 反匯編功能的封裝

這篇具有很好參考價(jià)值的文章主要介紹了4.10 x64dbg 反匯編功能的封裝。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

LyScript 插件提供的反匯編系列函數(shù)雖然能夠?qū)崿F(xiàn)基本的反匯編功能,但在實(shí)際使用中,可能會(huì)遇到一些更為復(fù)雜的需求,此時(shí)就需要根據(jù)自身需要進(jìn)行二次開發(fā),以實(shí)現(xiàn)更加高級(jí)的功能。本章將繼續(xù)深入探索反匯編功能,并將介紹如何實(shí)現(xiàn)反匯編代碼的檢索、獲取上下一條代碼等功能。這些功能對(duì)于分析和調(diào)試代碼都非常有用,因此是書中重要的內(nèi)容之一。在本章的學(xué)習(xí)過程中,讀者不僅可以掌握反匯編的基礎(chǔ)知識(shí)和技巧,還能夠了解如何進(jìn)行插件的開發(fā)和調(diào)試,這對(duì)于提高讀者的技能和能力也非常有幫助。

4.10.1 搜索內(nèi)存機(jī)器碼特征

首先我們來實(shí)現(xiàn)第一種需求,通過LyScript插件實(shí)現(xiàn)搜索內(nèi)存中的特定機(jī)器碼,此功能當(dāng)然可通過scan_memory_all()系列函數(shù)實(shí)現(xiàn),但讀者希望你能通過自己的理解調(diào)用原生API接口實(shí)現(xiàn)這個(gè)需求,要實(shí)現(xiàn)該功能第一步則是需要封裝一個(gè)GetCode()函數(shù),該函數(shù)的作用是讀取進(jìn)程數(shù)據(jù)到內(nèi)存中。

其中dbg.get_local_base()用于獲取當(dāng)前進(jìn)程內(nèi)的首地址,而通過start_address + dbg.get_local_size()的方式則可獲取到該程序的結(jié)束地址,當(dāng)確定了讀取范圍后再通過dbg.read_memory_byte(index)循環(huán)即可將程序的內(nèi)存數(shù)據(jù)讀入,而ReadHexCode()僅僅只是一個(gè)格式化函數(shù),這段程序的核心代碼可以總結(jié)為如下樣子;

# 將可執(zhí)行文件中的單數(shù)轉(zhuǎn)換為 0x00 格式
def ReadHexCode(code):
    hex_code = []

    for index in code:
        if index >= 0 and index <= 15:
            #print("0" + str(hex(index).replace("0x","")))
            hex_code.append("0" + str(hex(index).replace("0x","")))
        else:
            hex_code.append(hex(index).replace("0x",""))
            #print(hex(index).replace("0x",""))

    return hex_code

# 獲取到內(nèi)存中的機(jī)器碼
def GetCode():
    try:
        ref_code = []
        dbg = MyDebug()
        connect_flag = dbg.connect()
        if connect_flag != 1:
            return None

        start_address = dbg.get_local_base()
        end_address = start_address + dbg.get_local_size()

        # 循環(huán)得到機(jī)器碼
        for index in range(start_address,end_address):
            read_bytes = dbg.read_memory_byte(index)
            ref_code.append(read_bytes)

        dbg.close()
        return ref_code
    except Exception:
        return False

接著則需要讀者封裝實(shí)現(xiàn)一個(gè)SearchHexCode()搜索函數(shù),如下這段代碼實(shí)現(xiàn)了在給定的字節(jié)數(shù)組中搜索特定的十六進(jìn)制特征碼的功能。

具體而言,函數(shù)接受三個(gè)參數(shù):Code表示要搜索的字節(jié)數(shù)組,SearchCode表示要匹配的特征碼,ReadByte表示要搜索的字節(jié)數(shù)。

函數(shù)首先獲取特征碼的長(zhǎng)度,并通過一個(gè)for循環(huán)遍歷給定字節(jié)數(shù)組中的所有可能匹配的位置。對(duì)于每個(gè)位置,函數(shù)獲取該位置及其后面SearchCount個(gè)字節(jié)的十六進(jìn)制表示形式,并將其與給定的特征碼進(jìn)行比較。如果有一位不匹配,則計(jì)數(shù)器重置為0,否則計(jì)數(shù)器加1。如果計(jì)數(shù)器最終等于特征碼長(zhǎng)度,則說明已找到完全匹配的特征碼,函數(shù)返回True。如果遍歷完整個(gè)數(shù)組都沒有找到匹配的特征碼,則函數(shù)返回False。

# 在字節(jié)數(shù)組中匹配是否與特征碼一致
def SearchHexCode(Code,SearchCode,ReadByte):
    SearchCount = len(SearchCode)
    #print("特征碼總長(zhǎng)度: {}".format(SearchCount))
    for item in range(0,ReadByte):
        count = 0
        # 對(duì)十六進(jìn)制數(shù)切片,每次向后遍歷SearchCount
        OpCode = Code[ 0+item :SearchCount+item ]
        #print("切割數(shù)組: {} --> 對(duì)比: {}".format(OpCode,SearchCode))
        try:
            for x in range(0,SearchCount):
                if OpCode[x] == SearchCode[x]:
                    count = count + 1
                    #print("尋找特征碼計(jì)數(shù): {} {} {}".format(count,OpCode[x],SearchCode[x]))
                    if count == SearchCount:
                        # 如果找到了,就返回True,否則返回False
                        return True
                        exit(0)
        except Exception:
            pass
    return False

有了這兩段程序的實(shí)現(xiàn)流程,那么完成特征碼搜索功能將變得很容易實(shí)現(xiàn),如下主函數(shù)中運(yùn)行后則可搜索進(jìn)程內(nèi)search中所涉及到的機(jī)器碼,當(dāng)搜索到后則返回一個(gè)狀態(tài)。

if __name__ == "__main__":
    # 讀取到內(nèi)存機(jī)器碼
    ref_code = GetCode()
    if ref_code != False:
        # 轉(zhuǎn)為十六進(jìn)制
        hex_code = ReadHexCode(ref_code)
        code_size = len(hex_code)

        # 指定要搜索的特征碼序列
        search = ['c0', '74', '0d', '66', '3b', 'c6', '77', '08']

        # 搜索特征: hex_code = exe的字節(jié)碼,search=搜索特征碼,code_size = 搜索大小
        ret = SearchHexCode(hex_code, search, code_size)
        if ret == True:
            print("特征碼 {} 存在".format(search))
        else:
            print("特征碼 {} 不存在".format(search))
    else:
        print("讀入失敗")

由于此類搜索屬于枚舉類,所以搜索效率會(huì)明顯變低,搜索結(jié)束后則會(huì)返回該特征值是否存在的一個(gè)標(biāo)志;

4.10 x64dbg 反匯編功能的封裝

4.10.2 搜索內(nèi)存反匯編特征

而與之對(duì)應(yīng)的,當(dāng)讀者搜索反匯編代碼時(shí)則無需自行實(shí)現(xiàn)內(nèi)存讀入功能,LyScript插件內(nèi)提供了dbg.get_disasm_code(eip,1000)函數(shù),可以讓我們很容易的實(shí)現(xiàn)讀取內(nèi)存的功能,如下案例中,搜索特定反匯編指令集,當(dāng)找到后返回其內(nèi)存地址;

from LyScript32 import MyDebug

# 檢索指定序列中是否存在一段特定的指令集
def SearchOpCode(OpCodeList,SearchCode,ReadByte):
    SearchCount = len(SearchCode)
    for item in range(0,ReadByte):
        count = 0
        OpCode_Dic = OpCodeList[ 0 + item : SearchCount + item ]
        # print("切割字典: {}".format(OpCode_Dic))
        try:
            for x in range(0,SearchCount):
                if OpCode_Dic[x].get("opcode") == SearchCode[x]:
                    #print(OpCode_Dic[x].get("addr"),OpCode_Dic[x].get("opcode"))
                    count = count + 1
                    if count == SearchCount:
                        #print(OpCode_Dic[0].get("addr"))
                        return OpCode_Dic[0].get("addr")
                        exit(0)
        except Exception:
            pass

if __name__ == "__main__":
    dbg = MyDebug()
    connect_flag = dbg.connect()
    print("連接狀態(tài): {}".format(connect_flag))

    # 得到EIP位置
    eip = dbg.get_register("eip")

    # 反匯編前1000行
    disasm_dict = dbg.get_disasm_code(eip,1000)

    # 搜索一個(gè)指令序列,用于快速查找構(gòu)建漏洞利用代碼
    SearchCode = [
        ["ret", "push ebp", "mov ebp,esp"],
        ["push ecx", "push ebx"]
    ]

    # 檢索內(nèi)存指令集
    for item in range(0,len(SearchCode)):
        Search = SearchCode[item]
        # disasm_dict = 返回匯編指令 Search = 尋找指令集 1000 = 向下檢索長(zhǎng)度
        ret = SearchOpCode(disasm_dict,Search,1000)
        if ret != None:
            print("指令集: {} --> 首次出現(xiàn)地址: {}".format(SearchCode[item],hex(ret)))

    dbg.close()

如上代碼當(dāng)搜尋到SearchCode內(nèi)的指令序列時(shí)則自動(dòng)輸出內(nèi)存地址,輸出效果圖如下所示;

4.10 x64dbg 反匯編功能的封裝

4.10.3 獲取上下一條匯編指令

LyScript 插件默認(rèn)并沒有提供上一條與下一條匯編指令的獲取功能,筆者認(rèn)為通過親自動(dòng)手封裝實(shí)現(xiàn)功能能夠讓讀者更好的理解內(nèi)存斷點(diǎn)的工作原理,則本次我們將親自動(dòng)手實(shí)現(xiàn)這兩個(gè)功能。

在x64dbg中,軟件斷點(diǎn)的實(shí)現(xiàn)原理與通用的軟件斷點(diǎn)實(shí)現(xiàn)原理類似。具體來說,x64dbg會(huì)在程序的指令地址處插入一個(gè)中斷指令,一般是int3指令。這個(gè)指令會(huì)觸發(fā)一個(gè)軟件中斷,從而讓程序停止執(zhí)行,等待調(diào)試器處理。在插入中斷指令之前,x64dbg會(huì)先將這個(gè)地址處的原始指令保存下來。這樣,當(dāng)程序被調(diào)試器停止時(shí),調(diào)試器就可以將中斷指令替換成原始指令,讓程序恢復(fù)執(zhí)行。

為了實(shí)現(xiàn)軟件斷點(diǎn),x64dbg需要修改程序的可執(zhí)行代碼。具體來說,它會(huì)將指令的第一個(gè)字節(jié)替換成中斷指令的操作碼,這樣當(dāng)程序執(zhí)行到這個(gè)指令時(shí)就會(huì)觸發(fā)中斷。如果指令長(zhǎng)度不足一個(gè)字節(jié),x64dbg會(huì)將這個(gè)指令轉(zhuǎn)換成跳轉(zhuǎn)指令,跳轉(zhuǎn)到另一個(gè)地址,然后在這個(gè)地址處插入中斷指令。

此外在調(diào)試器中設(shè)置軟件斷點(diǎn)時(shí),x64dbg會(huì)根據(jù)指令地址的特性來判斷是否可以設(shè)置斷點(diǎn)。如果指令地址不可執(zhí)行,x64dbg就無法在這個(gè)地址處設(shè)置斷點(diǎn)。另外,由于軟件斷點(diǎn)會(huì)修改程序的可執(zhí)行代碼,因此在某些情況下,設(shè)置過多的軟件斷點(diǎn)可能會(huì)影響程序的性能。

讀者注意:實(shí)現(xiàn)獲取下一條匯編指令的獲取,需要注意如果是被命中的指令,則此處應(yīng)該是CC斷點(diǎn)占用一個(gè)字節(jié),如果不是則正常獲取到當(dāng)前指令即可。

  • 1.我們需要檢查當(dāng)前內(nèi)存斷點(diǎn)是否被命中,如果沒有命中則說明,此處需要獲取到原始的匯編指令長(zhǎng)度,然后與當(dāng)前eip地址相加獲得。
  • 2.如果命中了斷點(diǎn),則此處又會(huì)兩種情況,如果是用戶下的斷點(diǎn),則此處調(diào)試器會(huì)在指令位置替換為CC斷點(diǎn),也就是匯編中的init停機(jī)指令,該指令占用1個(gè)字節(jié),需要eip+1得到。而如果是系統(tǒng)斷點(diǎn),EIP所停留的位置,則我們需要正常獲取當(dāng)前指令地址,此處調(diào)試器沒有改動(dòng)匯編指令,僅僅只下了異常斷點(diǎn)。
from LyScript32 import MyDebug

# 獲取當(dāng)前EIP指令的下一條指令
def get_disasm_next(dbg,eip):
    next = 0

    # 檢查當(dāng)前內(nèi)存地址是否被下了絆子
    check_breakpoint = dbg.check_breakpoint(eip)

    # 說明存在斷點(diǎn),如果存在則這里就是一個(gè)字節(jié)了
    if check_breakpoint == True:

        # 接著判斷當(dāng)前是否是EIP,如果是EIP則需要使用原來的字節(jié)
        local_eip = dbg.get_register("eip")

        # 說明是EIP并且命中了斷點(diǎn)
        if local_eip == eip:
            dis_size = dbg.get_disasm_operand_size(eip)
            next = eip + dis_size
            next_asm = dbg.get_disasm_one_code(next)
            return next_asm
        else:
            next = eip + 1
            next_asm = dbg.get_disasm_one_code(next)
            return next_asm
        return None

    # 不是則需要獲取到原始匯編代碼的長(zhǎng)度
    elif check_breakpoint == False:
        # 得到當(dāng)前指令長(zhǎng)度
        dis_size = dbg.get_disasm_operand_size(eip)
        next = eip + dis_size
        next_asm = dbg.get_disasm_one_code(next)
        return next_asm
    else:
        return None

if __name__ == "__main__":
    dbg = MyDebug()
    dbg.connect()

    eip = dbg.get_register("eip")

    next = get_disasm_next(dbg,eip)
    print("下一條指令: {}".format(next))

    prev = get_disasm_next(dbg,4584103)
    print("下一條指令: {}".format(prev))

    dbg.close()

如上代碼則是顯現(xiàn)設(shè)置斷點(diǎn)的核心指令集,讀者可自行測(cè)試是否可讀取到當(dāng)前指令的下一條指令,其輸出效果如下圖所示;

4.10 x64dbg 反匯編功能的封裝

讀者注意:獲取上一條匯編指令時(shí),由于上一條指令的獲取難點(diǎn)就在于,我們無法確定當(dāng)前指令的上一條指令到底有多長(zhǎng),所以只能用笨辦法,逐行掃描對(duì)比匯編指令,如果找到則取出其上一條指令即可。

from LyScript32 import MyDebug

# 獲取當(dāng)前EIP指令的上一條指令
def get_disasm_prev(dbg,eip):
    prev_dasm = None
    # 得到當(dāng)前匯編指令
    local_disasm = dbg.get_disasm_one_code(eip)

    # 只能向上掃描10行
    eip = eip - 10
    disasm = dbg.get_disasm_code(eip,10)

    # 循環(huán)掃描匯編代碼
    for index in range(0,len(disasm)):
        # 如果找到了,就取出他的上一個(gè)匯編代碼
        if disasm[index].get("opcode") == local_disasm:
            prev_dasm = disasm[index-1].get("opcode")
            break

    return prev_dasm

if __name__ == "__main__":
    dbg = MyDebug()
    dbg.connect()

    eip = dbg.get_register("eip")

    next = get_disasm_prev(dbg,eip)
    print("上一條指令: {}".format(next))

    dbg.close()

運(yùn)行后即可讀入當(dāng)前EIP的上一條指令位置處的反匯編指令,輸出效果如下圖所示;

4.10 x64dbg 反匯編功能的封裝文章來源地址http://www.zghlxwxcb.cn/news/detail-544156.html

到了這里,關(guān)于4.10 x64dbg 反匯編功能的封裝的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 4.9 x64dbg 內(nèi)存處理與差異對(duì)比

    4.9 x64dbg 內(nèi)存處理與差異對(duì)比

    LyScript 插件中針對(duì)內(nèi)存讀寫函數(shù)的封裝功能并不多,只提供了最基本的 內(nèi)存讀取 和 內(nèi)存寫入 系列函數(shù)的封裝,本章將繼續(xù)對(duì)API接口進(jìn)行封裝,實(shí)現(xiàn)一些在軟件逆向分析中非常實(shí)用的功能,例如ShellCode代碼寫出與置入,內(nèi)存交換,內(nèi)存區(qū)域?qū)Ρ?,磁盤與內(nèi)存鏡像比較,內(nèi)存特

    2024年02月16日
    瀏覽(25)
  • 4.3 x64dbg 搜索內(nèi)存可利用指令

    4.3 x64dbg 搜索內(nèi)存可利用指令

    發(fā)現(xiàn)漏洞的第一步則是需要尋找到可利用的反匯編指令片段,在某些時(shí)候遠(yuǎn)程緩沖區(qū)溢出需要通過類似于 jmp esp 等特定的反匯編指令實(shí)現(xiàn)跳轉(zhuǎn)功能,并以此來執(zhí)行布置好的 ShellCode 惡意代碼片段, LyScript 插件則可以很好的完成對(duì)當(dāng)前進(jìn)程內(nèi)存中特定函數(shù)的檢索工作。 一般而言

    2024年02月12日
    瀏覽(16)
  • 4.4 x64dbg 繞過反調(diào)試保護(hù)機(jī)制

    4.4 x64dbg 繞過反調(diào)試保護(hù)機(jī)制

    在Windows平臺(tái)下,應(yīng)用程序?yàn)榱吮Wo(hù)自己不被調(diào)試器調(diào)試會(huì)通過各種方法限制進(jìn)程調(diào)試自身,通常此類反調(diào)試技術(shù)會(huì)限制我們對(duì)其進(jìn)行軟件逆向與漏洞分析,下面是一些常見的反調(diào)試保護(hù)方法: IsDebuggerPresent:檢查當(dāng)前程序是否在調(diào)試器環(huán)境下運(yùn)行。 OutputDebugString:向調(diào)試器發(fā)

    2024年02月12日
    瀏覽(16)
  • 4.2 x64dbg 針對(duì)PE文件的掃描

    4.2 x64dbg 針對(duì)PE文件的掃描

    通過運(yùn)用 LyScript 插件并配合 pefile 模塊,即可實(shí)現(xiàn)對(duì)特定PE文件的掃描功能,例如載入PE程序到內(nèi)存,驗(yàn)證PE啟用的保護(hù)方式,計(jì)算PE節(jié)區(qū)內(nèi)存特征,文件FOA與內(nèi)存VA轉(zhuǎn)換等功能的實(shí)現(xiàn),首先簡(jiǎn)單介紹一下 pefile 模塊。 pefile模塊是一個(gè)用于解析Windows可執(zhí)行文件(PE文件)的Pytho

    2024年02月12日
    瀏覽(42)
  • 4.7 x64dbg 應(yīng)用層的鉤子掃描

    4.7 x64dbg 應(yīng)用層的鉤子掃描

    所謂的應(yīng)用層鉤子(Application-level hooks)是一種編程技術(shù),它允許應(yīng)用程序通過在特定事件發(fā)生時(shí)執(zhí)行特定代碼來自定義或擴(kuò)展其行為。這些事件可以是用戶交互,系統(tǒng)事件,或者其他應(yīng)用程序內(nèi)部的事件。應(yīng)用層鉤子是在應(yīng)用程序中添加自定義代碼的一種靈活的方式。它們

    2024年02月13日
    瀏覽(16)
  • 4.6 x64dbg 內(nèi)存掃描與查殼實(shí)現(xiàn)

    4.6 x64dbg 內(nèi)存掃描與查殼實(shí)現(xiàn)

    LyScript 插件中默認(rèn)提供了多種內(nèi)存特征掃描函數(shù),每一種掃描函數(shù)用法各不相同,在使用掃描函數(shù)時(shí)應(yīng)首先搞清楚不同函數(shù)之間的差異,本章內(nèi)容將分別詳細(xì)介紹每一種內(nèi)存掃描函數(shù)是如何靈活運(yùn)用,并實(shí)現(xiàn)一種內(nèi)存查殼腳本,可快速定位目標(biāo)程序加了什么殼以及尋找被加殼

    2024年02月13日
    瀏覽(18)
  • OllyDbg 與 x64Dbg 與 Windbg 與 IDA 區(qū)別是什么?

    OllyDbg 與 x64Dbg 與 Windbg 與 IDA 區(qū)別是什么?

    OllyDbg 和 x64Dbg 大致屬于同一類別。它們的主要優(yōu)勢(shì)是在沒有符號(hào)信息的情況下進(jìn)行調(diào)試(盡管它們也可以使用符號(hào)信息進(jìn)行調(diào)試)。OllyDbg(封閉源代碼)已經(jīng)很久沒有維護(hù)了,并且僅限于 x86 32 位。另一方面,x64Dbg 被積極維護(hù),開源并且可以處理 x86 和 x64。兩者都支持插件

    2024年02月08日
    瀏覽(19)
  • C++64位游戲軟件安全匯編與反匯編反調(diào)試 x64驅(qū)動(dòng)開發(fā)進(jìn)程保護(hù)進(jìn)程隱藏驅(qū)動(dòng)讀寫過保護(hù) 視頻教程

    ├─課程1 x32dbgx64dbg驅(qū)動(dòng)調(diào)試器反反調(diào)試器驅(qū)動(dòng)調(diào)試環(huán)境搭載 │ 1.為什么要搭載驅(qū)動(dòng)調(diào)試環(huán)境.mp4 │ 2.驅(qū)動(dòng)調(diào)試環(huán)境搭載1.mp4 │ 3.三種過PG的方法.mp4 │ 4.驅(qū)動(dòng)調(diào)試環(huán)境搭載2.mp4 │ 5.驅(qū)動(dòng)調(diào)試與驅(qū)動(dòng)進(jìn)程保護(hù)對(duì)抗.mp4 │ ├─課程2 C++64位游戲軟件安全匯編與反匯編反調(diào)試2021年新

    2024年02月02日
    瀏覽(24)
  • Visual Studio 2022 MASM x64匯編hello world以及調(diào)試(Console版 + Windows版)

    本文介紹使用Visual Studio 2022的MASM開發(fā)x64匯編程序hello world的環(huán)境配置和匯編代碼,作為學(xué)習(xí)CPU指令的起點(diǎn)。分兩個(gè)版本的hello world, 一個(gè)是console版本,另一個(gè)是windows版本。 首先安裝visual studio community 2022,下載地址 https://visualstudio.microsoft.com/,安裝時(shí)選擇C++開發(fā)模塊 安裝好以

    2024年02月05日
    瀏覽(31)
  • Windows 10 X64 內(nèi)核對(duì)象句柄表解析

    Windows 10 X64 內(nèi)核對(duì)象句柄表解析

    fweWindows 很多API函數(shù)都會(huì)創(chuàng)建和使用句柄(傳入?yún)?shù)),句柄代表一個(gè)內(nèi)核對(duì)象的內(nèi)存地址,每個(gè)進(jìn)程都有一個(gè)句柄表,它保存著進(jìn)程擁有的句柄,內(nèi)核也有一個(gè)句柄表 PspCidTable,它保存著整個(gè)系統(tǒng)的句柄。 ExpLookupHandleTableEntry windows內(nèi)核句柄表結(jié)構(gòu)解析 句柄表結(jié)構(gòu) 進(jìn)程句柄表位

    2024年02月06日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包