• LyScript 批量搜索反汇编特征


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

    得到汇编指令机器码: 该功能主要实现,得到用户传入汇编指令所对应的机器码,这段代码你可以这样来实现。

    1. from LyScript32 import MyDebug
    2. if __name__ == "__main__":
    3. dbg = MyDebug()
    4. connect_flag = dbg.connect()
    5. print("连接状态: {}".format(connect_flag))
    6. addr = dbg.create_alloc(1024)
    7. print("堆空间: {}".format(hex(addr)))
    8. asm_size = dbg.assemble_code_size("mov eax,1")
    9. print("汇编代码占用字节: {}".format(asm_size))
    10. write = dbg.assemble_write_memory(addr,"mov eax,1")
    11. byte_code = bytearray()
    12. for index in range(0,asm_size):
    13. read = dbg.read_memory_byte(addr + index)
    14. print("{:02x} ".format(read),end="")
    15. dbg.delete_alloc(addr)

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

    1. from LyScript32 import MyDebug
    2. # 传入汇编代码,得到对应机器码
    3. def get_opcode_from_assemble(dbg_ptr,asm):
    4. byte_code = bytearray()
    5. addr = dbg_ptr.create_alloc(1024)
    6. if addr != 0:
    7. asm_size = dbg_ptr.assemble_code_size(asm)
    8. # print("汇编代码占用字节: {}".format(asm_size))
    9. write = dbg_ptr.assemble_write_memory(addr,asm)
    10. if write == True:
    11. for index in range(0,asm_size):
    12. read = dbg_ptr.read_memory_byte(addr + index)
    13. # print("{:02x} ".format(read),end="")
    14. byte_code.append(read)
    15. dbg_ptr.delete_alloc(addr)
    16. return byte_code
    17. else:
    18. return bytearray(0)
    19. if __name__ == "__main__":
    20. dbg = MyDebug()
    21. connect_flag = dbg.connect()
    22. print("连接状态: {}".format(connect_flag))
    23. # 获取汇编代码
    24. byte_array = get_opcode_from_assemble(dbg,"xor eax,eax")
    25. for index in byte_array:
    26. print(hex(index),end="")
    27. print()
    28. # 汇编一个序列
    29. asm_list = ["xor eax,eax", "xor ebx,ebx", "mov eax,1"]
    30. for index in asm_list:
    31. byte_array = get_opcode_from_assemble(dbg, index)
    32. for index in byte_array:
    33. print(hex(index),end="")
    34. print()
    35. dbg.close()

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

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

    1. from LyScript32 import MyDebug
    2. if __name__ == "__main__":
    3. dbg = MyDebug()
    4. dbg.connect()
    5. local_base_start = dbg.get_local_base()
    6. local_base_end = local_base_start + dbg.get_local_size()
    7. print("开始地址: {} --> 结束地址: {}".format(hex(local_base_start),hex(local_base_end)))
    8. search_asm = ['test eax,eax', 'cmp esi, edi', 'pop edi', 'cmp esi,edi', 'jmp esp']
    9. while local_base_start <= local_base_end:
    10. disasm = dbg.get_disasm_one_code(local_base_start)
    11. print("地址: 0x{:08x} --> 反汇编: {}".format(local_base_start,disasm))
    12. # 寻找指令
    13. for index in range(0, len(search_asm)):
    14. if disasm == search_asm[index]:
    15. print("地址: {} --> 反汇编: {}".format(hex(local_base_start), disasm))
    16. # 递增计数器
    17. local_base_start = local_base_start + dbg.get_disasm_operand_size(local_base_start)
    18. dbg.close()

    搜索反汇编列表特征: 使用python实现方法,通过特定方法扫描内存范围,如果出现我们所需要的指令集序列,则输出该指令的具体内存地址。

    1. from LyScript32 import MyDebug
    2. # 传入汇编代码,得到对应机器码
    3. def get_opcode_from_assemble(dbg_ptr,asm):
    4. byte_code = bytearray()
    5. addr = dbg_ptr.create_alloc(1024)
    6. if addr != 0:
    7. asm_size = dbg_ptr.assemble_code_size(asm)
    8. # print("汇编代码占用字节: {}".format(asm_size))
    9. write = dbg_ptr.assemble_write_memory(addr,asm)
    10. if write == True:
    11. for index in range(0,asm_size):
    12. read = dbg_ptr.read_memory_byte(addr + index)
    13. # print("{:02x} ".format(read),end="")
    14. byte_code.append(read)
    15. dbg_ptr.delete_alloc(addr)
    16. return byte_code
    17. else:
    18. return bytearray(0)
    19. # 搜索机器码,如果存在则返回
    20. def SearchOpCode(dbg_ptr, Search):
    21. # 搜索机器码并转换为列表
    22. op_code = []
    23. for index in Search:
    24. byte_array = get_opcode_from_assemble(dbg, index)
    25. for index in byte_array:
    26. op_code.append(hex(index))
    27. # print("机器码列表: {}".format(op_code))
    28. # 将机器码列表转换为字符串
    29. # 1.先转成字符串列表
    30. x = [str(i) for i in op_code]
    31. # 2.将字符串列表转为字符串
    32. # search_code = ' '.join(x).replace("0x","")
    33. search_code = []
    34. # 增加小于三位前面的0
    35. for l in range(0,len(x)):
    36. if len(x[l]) <= 3:
    37. # 如果是小于3位数则在前面增加0
    38. # print(''.join(x[l]).replace("0x","").zfill(2))
    39. search_code.append(''.join(x[l]).replace("0x","").zfill(2))
    40. else:
    41. search_code.append(''.join(x[l]).replace("0x", ""))
    42. # 3.变成字符串
    43. search_code = ' '.join(search_code).replace("0x", "")
    44. print("被搜索字符串: {}".format(search_code))
    45. # 调用搜索命令
    46. ref = dbg.scan_memory_one(search_code)
    47. if ref != None or ref != 0:
    48. return ref
    49. else:
    50. return 0
    51. return 0
    52. if __name__ == "__main__":
    53. dbg = MyDebug()
    54. connect_flag = dbg.connect()
    55. print("连接状态: {}".format(connect_flag))
    56. # 搜索一个指令序列,用于快速查找构建漏洞利用代码
    57. SearchCode = [
    58. ["pop ecx", "pop ebp", "ret", "push ebp"],
    59. ["push ebp", "mov ebp,esp"],
    60. ["mov ecx, dword ptr ds:[eax+0x3C]", "add ecx, eax"]
    61. ]
    62. # 检索内存指令集
    63. for item in range(0, len(SearchCode)):
    64. Search = SearchCode[item]
    65. ret = SearchOpCode(dbg, Search)
    66. print("所搜指令所在内存: {}".format(hex(ret)))
    67. dbg.close()

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

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

    1. op_code = []
    2. for index in Search:
    3. byte_array = get_opcode_from_assemble(dbg, index)
    4. for index in byte_array:
    5. op_code.append(hex(index))

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

    1. # 将机器码列表转换为字符串
    2. # 1.先转成字符串列表
    3. x = [str(i) for i in op_code]
    4. # 2.将字符串列表转为字符串
    5. # search_code = ' '.join(x).replace("0x","")
    6. search_code = []
    7. # 增加小于三位前面的0
    8. for l in range(0,len(x)):
    9. if len(x[l]) <= 3:
    10. # 如果是小于3位数则在前面增加0
    11. # print(''.join(x[l]).replace("0x","").zfill(2))
    12. search_code.append(''.join(x[l]).replace("0x","").zfill(2))
    13. else:
    14. search_code.append(''.join(x[l]).replace("0x", ""))

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

    1. search_code = ' '.join(search_code).replace("0x", "")
    2. print("被搜索字符串: {}".format(search_code))
    3. # 调用搜索命令
    4. ref = dbg.scan_memory_one(search_code)
    5. if ref != None or ref != 0:
    6. return ref
    7. else:
    8. return 0
    9. return 0

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

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

  • 相关阅读:
    RabbitMQ实战
    java计算机毕业设计知道特产网源代码+系统+数据库+lw文档
    东南亚电商指南,卖家如何布局东南亚市场?
    Python实战项目-10文件存储/支付宝支付/支付成功回调接口
    SwiftUI 2.0 课程笔记 Chapter 6
    企业知识库有什么价值?
    2017年网易校招Java面试题
    YARN的产生背景和架构剖析
    设计模式使用场景实现示例及优缺点(结构型模式——代理模式、外观模式)
    rust特性
  • 原文地址:https://blog.csdn.net/lyshark_csdn/article/details/126345542