LyScript 实现应用层钩子扫描器

打印 上一主题 下一主题

主题 780|帖子 780|积分 2340

Capstone 是一个轻量级的多平台、多架构的反汇编框架,该模块支持目前所有通用操作系统,反汇编架构几乎全部支持,本篇文章将运用LyScript插件结合Capstone反汇编引擎实现一个钩子扫描器。
要实现应用层钩子扫描,我们需要得到程序内存文件的机器码以及磁盘中的机器码,并通过capstone这个第三方反汇编引擎,对两者进行反汇编,最后逐条对比汇编指令,实现进程钩子扫描的效果。
LyScript项目地址:https://github.com/lyshark/LyScript
通过LyScript插件读取出内存中的机器码,然后交给第三方反汇编库执行,并将结果输出成字典格式。
  1. #coding: utf-8
  2. import binascii,os,sys
  3. import pefile
  4. from capstone import *
  5. from LyScript32 import MyDebug
  6. # 得到内存反汇编代码
  7. def get_memory_disassembly(address,offset,len):
  8.     # 反汇编列表
  9.     dasm_memory_dict = []
  10.     # 内存列表
  11.     ref_memory_list = bytearray()
  12.     # 读取数据
  13.     for index in range(offset,len):
  14.         char = dbg.read_memory_byte(address + index)
  15.         ref_memory_list.append(char)
  16.     # 执行反汇编
  17.     md = Cs(CS_ARCH_X86,CS_MODE_32)
  18.     for item in md.disasm(ref_memory_list,0x1):
  19.         addr = int(pe_base) + item.address
  20.         dasm_memory_dict.append({"address": str(addr), "opcode": item.mnemonic + " " + item.op_str})
  21.     return dasm_memory_dict
  22. if __name__ == "__main__":
  23.     dbg = MyDebug()
  24.     dbg.connect()
  25.     pe_base = dbg.get_local_base()
  26.     pe_size = dbg.get_local_size()
  27.     print("模块基地址: {}".format(hex(pe_base)))
  28.     print("模块大小: {}".format(hex(pe_size)))
  29.     # 得到内存反汇编代码
  30.     dasm_memory_list = get_memory_disassembly(pe_base,0,pe_size)
  31.     print(dasm_memory_list)
  32.     dbg.close()
复制代码
效果如下:

我们将文件反汇编也写一下,然后让其对比,这样就可以实现扫描内存与文件中的汇编指令是否一致。
  1. #coding: utf-8
  2. import binascii,os,sys
  3. import pefile
  4. from capstone import *
  5. from LyScript32 import MyDebug
  6. # 得到内存反汇编代码
  7. def get_memory_disassembly(address,offset,len):
  8.     # 反汇编列表
  9.     dasm_memory_dict = []
  10.     # 内存列表
  11.     ref_memory_list = bytearray()
  12.     # 读取数据
  13.     for index in range(offset,len):
  14.         char = dbg.read_memory_byte(address + index)
  15.         ref_memory_list.append(char)
  16.     # 执行反汇编
  17.     md = Cs(CS_ARCH_X86,CS_MODE_32)
  18.     for item in md.disasm(ref_memory_list,0x1):
  19.         addr = int(pe_base) + item.address
  20.         dic = {"address": str(addr), "opcode": item.mnemonic + " " + item.op_str}
  21.         dasm_memory_dict.append(dic)
  22.     return dasm_memory_dict
  23. # 反汇编文件中的机器码
  24. def get_file_disassembly(path):
  25.     opcode_list = []
  26.     pe = pefile.PE(path)
  27.     ImageBase = pe.OPTIONAL_HEADER.ImageBase
  28.     for item in pe.sections:
  29.         if str(item.Name.decode('UTF-8').strip(b'\x00'.decode())) == ".text":
  30.             # print("虚拟地址: 0x%.8X 虚拟大小: 0x%.8X" %(item.VirtualAddress,item.Misc_VirtualSize))
  31.             VirtualAddress = item.VirtualAddress
  32.             VirtualSize = item.Misc_VirtualSize
  33.             ActualOffset = item.PointerToRawData
  34.     StartVA = ImageBase + VirtualAddress
  35.     StopVA = ImageBase + VirtualAddress + VirtualSize
  36.     with open(path,"rb") as fp:
  37.         fp.seek(ActualOffset)
  38.         HexCode = fp.read(VirtualSize)
  39.     md = Cs(CS_ARCH_X86, CS_MODE_32)
  40.     for item in md.disasm(HexCode, 0):
  41.         addr = hex(int(StartVA) + item.address)
  42.         dic = {"address": str(addr) , "opcode": item.mnemonic + " " + item.op_str}
  43.         # print("{}".format(dic))
  44.         opcode_list.append(dic)
  45.     return opcode_list
  46. if __name__ == "__main__":
  47.     dbg = MyDebug()
  48.     dbg.connect()
  49.     pe_base = dbg.get_local_base()
  50.     pe_size = dbg.get_local_size()
  51.     print("模块基地址: {}".format(hex(pe_base)))
  52.     print("模块大小: {}".format(hex(pe_size)))
  53.     # 得到内存反汇编代码
  54.     dasm_memory_list = get_memory_disassembly(pe_base,0,pe_size)
  55.     dasm_file_list = get_file_disassembly("d://win32project1.exe")
  56.     # 循环对比内存与文件中的机器码
  57.     for index in range(0,len(dasm_file_list)):
  58.         if dasm_memory_list[index] != dasm_file_list[index]:
  59.             print("地址: {:8} --> 内存反汇编: {:32} --> 磁盘反汇编: {:32}".
  60.                   format(dasm_memory_list[index].get("address"),dasm_memory_list[index].get("opcode"),dasm_file_list[index].get("opcode")))
  61.     dbg.close()
复制代码
此处如果一致,则说明没有钩子,如果不一致则输出,这里的输出结果不一定准确,此处只是抛砖引玉。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

去皮卡多

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表