关于python:LyScript-插件实现UPX寻找入口

53次阅读

共计 1957 个字符,预计需要花费 5 分钟才能阅读完成。

LyScript 插件可实现对压缩壳的疾速脱壳操作,目前反对两种脱壳形式,一种是使用 API 接口本人编写脱壳过程,另一种是间接加载现有的脱壳脚本运行脱壳。

  • 插件地址:https://github.com/lyshark/Ly…

首先筹备一个加了 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 地位执行转存内存即可实现脱壳。

正文完
 0