乐趣区

关于python:LyScript-批量搜索反汇编特征

LyScript 插件实现对特定汇编指令片段的批量搜寻性能,用户传入一个汇编指令列表,而后循环搜寻该列表内的所有指令特色,如果找到了,则返回该指令的内存地址。

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

失去汇编指令机器码: 该性能次要实现,失去用户传入汇编指令所对应的机器码,这段代码你能够这样来实现。

from LyScript32 import MyDebug

if __name__ == "__main__":
    dbg = MyDebug()
    connect_flag = dbg.connect()
    print("连贯状态: {}".format(connect_flag))

    addr = dbg.create_alloc(1024)

    print("堆空间: {}".format(hex(addr)))

    asm_size = dbg.assemble_code_size("mov eax,1")
    print("汇编代码占用字节: {}".format(asm_size))

    write = dbg.assemble_write_memory(addr,"mov eax,1")

    byte_code = bytearray()

    for index in range(0,asm_size):
        read = dbg.read_memory_byte(addr + index)
        print("{:02x}".format(read),end="")

    dbg.delete_alloc(addr)

封装如上代码接口,实现 get_opcode_from_assemble() 用户传入汇编指令,失去该指令对应机器码。

from LyScript32 import MyDebug

# 传入汇编代码, 失去对应机器码
def get_opcode_from_assemble(dbg_ptr,asm):
    byte_code = bytearray()

    addr = dbg_ptr.create_alloc(1024)
    if addr != 0:
        asm_size = dbg_ptr.assemble_code_size(asm)
        # print("汇编代码占用字节: {}".format(asm_size))

        write = dbg_ptr.assemble_write_memory(addr,asm)
        if write == True:
            for index in range(0,asm_size):
                read = dbg_ptr.read_memory_byte(addr + index)
                # print("{:02x}".format(read),end="")
                byte_code.append(read)
        dbg_ptr.delete_alloc(addr)
        return byte_code
    else:
        return bytearray(0)

if __name__ == "__main__":
    dbg = MyDebug()
    connect_flag = dbg.connect()
    print("连贯状态: {}".format(connect_flag))

    # 获取汇编代码
    byte_array = get_opcode_from_assemble(dbg,"xor eax,eax")
    for index in byte_array:
        print(hex(index),end="")
    print()

    # 汇编一个序列
    asm_list = ["xor eax,eax", "xor ebx,ebx", "mov eax,1"]
    for index in asm_list:
        byte_array = get_opcode_from_assemble(dbg, index)
        for index in byte_array:
            print(hex(index),end="")
        print()

    dbg.close()

运行如上代码,可找出符合条件的内存地址。

批量搜寻反汇编代码: 与搜寻机器码相似,此性能实现了搜寻代码段中所有指令集,匹配列表中是否存在,存在则返回地址。

from LyScript32 import MyDebug

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

    local_base_start = dbg.get_local_base()
    local_base_end = local_base_start + dbg.get_local_size()
    print("开始地址: {} --> 完结地址: {}".format(hex(local_base_start),hex(local_base_end)))

    search_asm = ['test eax,eax', 'cmp esi, edi', 'pop edi', 'cmp esi,edi', 'jmp esp']

    while local_base_start <= local_base_end:
        disasm = dbg.get_disasm_one_code(local_base_start)
        print("地址: 0x{:08x} --> 反汇编: {}".format(local_base_start,disasm))

        # 寻找指令
        for index in range(0, len(search_asm)):
            if disasm == search_asm[index]:
                print("地址: {} --> 反汇编: {}".format(hex(local_base_start), disasm))

        # 递增计数器
        local_base_start = local_base_start + dbg.get_disasm_operand_size(local_base_start)

    dbg.close()

搜寻反汇编列表特色: 应用 python 实现办法,通过特定办法扫描内存范畴,如果呈现咱们所须要的指令集序列,则输入该指令的具体内存地址。

from LyScript32 import MyDebug

# 传入汇编代码, 失去对应机器码
def get_opcode_from_assemble(dbg_ptr,asm):
    byte_code = bytearray()

    addr = dbg_ptr.create_alloc(1024)
    if addr != 0:
        asm_size = dbg_ptr.assemble_code_size(asm)
        # print("汇编代码占用字节: {}".format(asm_size))

        write = dbg_ptr.assemble_write_memory(addr,asm)
        if write == True:
            for index in range(0,asm_size):
                read = dbg_ptr.read_memory_byte(addr + index)
                # print("{:02x}".format(read),end="")
                byte_code.append(read)
        dbg_ptr.delete_alloc(addr)
        return byte_code
    else:
        return bytearray(0)

# 搜寻机器码, 如果存在则返回
def SearchOpCode(dbg_ptr, Search):

    # 搜寻机器码并转换为列表
    op_code = []
    for index in Search:
        byte_array = get_opcode_from_assemble(dbg, index)
        for index in byte_array:
            op_code.append(hex(index))

    # print("机器码列表: {}".format(op_code))

    # 将机器码列表转换为字符串
    # 1. 先转成字符串列表
    x = [str(i) for i in op_code]

    # 2. 将字符串列表转为字符串
    # search_code = ''.join(x).replace("0x","")
    search_code = []

    # 减少小于三位后面的 0
    for l in range(0,len(x)):
        if len(x[l]) <= 3:
            # 如果是小于 3 位数则在后面减少 0
            # print(''.join(x[l]).replace("0x","").zfill(2))
            search_code.append(''.join(x[l]).replace("0x","").zfill(2))
        else:
            search_code.append(''.join(x[l]).replace("0x",""))

    # 3. 变成字符串
    search_code = ''.join(search_code).replace("0x","")
    print("被搜寻字符串: {}".format(search_code))

    # 调用搜寻命令
    ref = dbg.scan_memory_one(search_code)
    if ref != None or ref != 0:
        return ref
    else:
        return 0
    return 0

if __name__ == "__main__":
    dbg = MyDebug()
    connect_flag = dbg.connect()
    print("连贯状态: {}".format(connect_flag))

    # 搜寻一个指令序列, 用于疾速查找构建破绽利用代码
    SearchCode = [["pop ecx", "pop ebp", "ret", "push ebp"],
        ["push ebp", "mov ebp,esp"],
        ["mov ecx, dword ptr ds:[eax+0x3C]", "add ecx, eax"]
    ]

    # 检索内存指令集
    for item in range(0, len(SearchCode)):
        Search = SearchCode[item]
        ret = SearchOpCode(dbg, Search)
        print("所搜指令所在内存: {}".format(hex(ret)))

    dbg.close()

如上代码中,第一个函数 get_opcode_from_assemble(dbg_ptr,asm) 用于将用户传入的汇编指令失去机器码,函数 SearchOpCode(dbg_ptr, Search) 用于将用户传入的汇编列表转换成一个间断的字符串。

1. 片段 1 实现了将机器码转为一个十六进制数组

    op_code = []
    for index in Search:
        byte_array = get_opcode_from_assemble(dbg, index)
        for index in byte_array:
            op_code.append(hex(index))

2. 片段 2 将十六进制机器码去除 0x 前缀,并判断十六进制是否小于等于 3 位,如果是则输入前缀减少 0 补齐,否则间接输入到 search_code 变量内。

    # 将机器码列表转换为字符串
    # 1. 先转成字符串列表
    x = [str(i) for i in op_code]

    # 2. 将字符串列表转为字符串
    # search_code = ''.join(x).replace("0x","")
    search_code = []

    # 减少小于三位后面的 0
    for l in range(0,len(x)):
        if len(x[l]) <= 3:
            # 如果是小于 3 位数则在后面减少 0
            # print(''.join(x[l]).replace("0x","").zfill(2))
            search_code.append(''.join(x[l]).replace("0x","").zfill(2))
        else:
            search_code.append(''.join(x[l]).replace("0x",""))

3. 片段 3,最终调用搜寻机器码命令,首先将字符串列表转换为字符串,而后调用 dbg.scan_memory_one(search_code) 实现整个搜寻过程。

    search_code = ''.join(search_code).replace("0x","")
    print("被搜寻字符串: {}".format(search_code))

    # 调用搜寻命令
    ref = dbg.scan_memory_one(search_code)
    if ref != None or ref != 0:
        return ref
    else:
        return 0
    return 0

最终调用,用户传入一个二维列表,即可顺次搜寻该列表内所有符合条件的内存地址。

退出移动版