LyScript 插件實現UPX脫殼

LyScript 插件可實現對壓縮殼的快速脫殼操作,目前支持兩種脫殼方式,一種是運用API接口自己編寫脫殼過程,另一種是直接加載現有的脫殼腳本運行脫殼。

LyScript項目地址: https://github.com/lyshark/LyScript

首先準備一個加了UPX壓縮殼的程序,然後我們通過自己編寫腳本完成脫殼任務。 我們將當前EIP停留在UPX殼的首地址處,執行如下腳本,將可以自動尋找到當前EIP的具體位置。

from LyScript32 import MyDebug

if __name__ == "__main__":
    # 初始化
    dbg = MyDebug()

    # 連接到調試器
    connect_flag = dbg.connect()
    print("連接狀態: {}".format(connect_flag))

    # 檢測套接字是否還在
    ref = dbg.is_connect()
    print("是否在連接: ", ref)

    is_64 = False

    # 判斷是否時64位數
    if is_64 == False:
        currentIP = dbg.get_register("eip")

        if dbg.read_memory_word(currentIP) != int(0xBE60):
            print("[-] 可能不是UPX")
            dbg.close()

        patternAddr = dbg.scan_memory_one("83 EC ?? E9 ?? ?? ?? ?? 00")
        print("匹配到的地址: {}".format(hex(patternAddr)))

        dbg.set_breakpoint(patternAddr)
        dbg.set_debug("Run")
        dbg.set_debug("Wait")
        dbg.delete_breakpoint(patternAddr)

        dbg.set_debug("StepOver")
        dbg.set_debug("StepOver")
        print("[+] 程序OEP = 0x{:x}".format(dbg.get_register("eip")))

    else:
        currentIP = dbg.get_register("rip")

        if dbg.read_memory_dword(currentIP) != int(0x55575653):
            print("[-] 可能不是UPX")
            dbg.close()

        patternAddr = dbg.scan_memory_one("48 83 EC ?? E9")
        print("匹配到的地址: {}".format(hex(patternAddr)))

        dbg.set_breakpoint(patternAddr)
        dbg.set_debug("Run")
        dbg.set_debug("Wait")
        dbg.delete_breakpoint(patternAddr)

        dbg.set_debug("StepOver")
        dbg.set_debug("StepOver")
        print("[+] 程序OEP = 0x{:x}".format(dbg.get_register("eip")))

    dbg.close()

運行如上代碼,將通過特徵碼快速定位並尋找到程序加殼前的OEP位置。

另一種方式是直接尋找原生脫殼腳本,並使用LyScript加載執行脫殼,如下是一段原生脫殼腳本,我們保存在磁盤中。

bphc                        //清除所有硬件斷點
sti                         //執行一次F8(步過)
bph esp,r,1                 //對當前Esp棧頂下 硬件讀取斷點,設置一個字節 r代表讀取 
erun                        //執行一次F9也就是運行起來,erun就是中間出異常了交給調試器執行
find eip,e9,1000            //利用Find功能在EIP位置尋找 jmp,搜索的內存大小爲1000
bphc                        

bph $result                 //搜尋的結果會放到 $result變量中
erun                        //執行
bphc       
sto 2                       //執行一下F7
cmt eip,"Current Eip is Oep Please Dump Entry" //在EIP位置填寫註釋
ret

接着通過LyScript插件,將其加載到x64dbg腳本引擎中,並直接運行。

from LyScript32 import MyDebug

if __name__ == "__main__":
    # 初始化
    dbg = MyDebug()

    # 連接到調試器
    connect_flag = dbg.connect()
    print("連接狀態: {}".format(connect_flag))

    # 檢測套接字是否還在
    ref = dbg.is_connect()
    print("是否在連接: ", ref)
    
    # 加載並運行腳本
    dbg.script_loader("d://script.txt")
    dbg.script_run()

    dbg.close()

同樣可以尋找到正確的OEP位置。

此時直接在OEP位置執行轉存內存即可完成脫殼。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章