Capstone是一个轻量级的多平台、多架构的反汇编框架。该模块支持目前所有的通用操作系统,几乎所有的反汇编架构都支持。本文将使用LyScript插件结合Capstone反汇编引擎实现一个钩子扫描器。插件地址:https://github.com/lyshark/Ly...实现应用层钩子扫描,需要获取程序内存文件的机器码和磁盘中的机器码,使用capstone,一个第三方反汇编引擎,将两者反汇编,最后将汇编指令一一对比,实现进程钩子扫描的效果。通过LyScript插件读取内存中的机器码,然后交给第三方反汇编库执行,并将结果输出成字典格式。#coding:utf-8importbinascii,os,sysimportpefilefromcapstoneimport*fromLyScript32importMyDebug#获取内存反汇编代码defget_memory_disassembly(address,offset,len):#反汇编列表dasm_memory_dict=[]#内存列表ref_memory_list=bytearray()#读取范围内索引的数据(offset,len):char=dbg.read_memory_byte(address+index)ref_memory_list.append(char)#执行反汇编md=Cs(CS_ARCH_X86,CS_MODE_32)foriteminmd.disasm(ref_memory_list,0x1):addr=int(pe_base)+item.addressdasm_memory_dict.append({"address":str(addr),"opcode":item.mnemonic+""+item.op_str})returndasm_memory_dictif__name__=="__main__":dbg=MyDebug()dbg.connect()pe_base=dbg.get_local_base()pe_size=dbg.get_local_size()print("模块基址:{}".format(hex(pe_base)))print("模块大小:{}".format(hex(pe_size)))#获取内存反汇编代码dasm_memory_list=get_memory_disassembly(pe_base,0,pe_size)print(dasm_memory_list)dbg.close()效果如下:我们也写了文件的反汇编,然后对比一下,这样可以扫描内存是否和汇编一致文件中的说明#coding:utf-8importbinascii,os,sysimportpefilefromcapstoneimport*fromLyScript32importMyDebug#获取内存反汇编代码defget_memory_disassembly(address,offset,len):#反汇编列表dasm_memory_dict=[]#内存列表ref_memory_list=bytearray()#读取范围内索引的数据(offset,len):char=dbg.read_memory_byte(address+index)ref_memory_list.append(char)#执行反汇编md=Cs(CS_ARCH_X86,CS_MODE_32)foriteminmd.disasm(ref_memory_list,0x1):addr=int(pe_base)+item.addressdic={"address":str(addr),"opcode":item.mnemonic+""+item.op_str}dasm_memory_dict.append(dic)returndasm_memory_dict#机器码在反汇编文件defget_file_disassembly(path):opcode_list=[]pe=pefile.PE(path)ImageBase=pe.OPTIONAL_HEADER.ImageBaseforiteminpe.sections:ifstr(item.Name.decode('UTF-8').strip(b'\x00'.decode()))==".text":#print("虚拟地址:0x%.8X虚拟大小:0x%.8X"%(item.VirtualAddress,item.Misc_VirtualSize))VirtualAddress=item.VirtualAddressVirtualSize=item.Misc_VirtualSizeActualOffset=item.PointerToRawDataStartVA=ImageBase+VirtualAddressStopVA=ImageBase+VirtualAddress+VirtualSizewith打开(路径,“rb”)作为fp:fp.seek(ActualOffset)HexCode=fp.read(VirtualSize)md=Cs(CS_ARCH_X86,CS_MODE_32)对于md.disasm(HexCode,0)中的项目:addr=hex(int(StartVA)+item.address)dic={"address":str(addr),"opcode":item.mnemonic+""+item.op_str}#print("{}".format(dic))opcode_list.append(dic)returnopcode_listif__name__=="__main__":dbg=MyDebug()dbg.connect()pe_base=dbg.get_local_base()pe_size=dbg.get_local_size()print("模块地址:{}".format(hex(pe_base)))print("模块大小:{}".format(hex(pe_size)))#获取内存反汇编代码dasm_memory_list=get_memory_disassembly(pe_base,0,pe_size)dasm_file_list=get_file_disassembly("d://win32project1.exe")#循环比较内存和机器中的范围内索引的文件代码(0,len(dasm_file_list)):ifdasm_memory_list[index]!=dasm_file_list[index]:print("address:{:8}-->memorydisassembly:{:32}-->磁盘反汇编:{:32}".format(dasm_memory_list[index].get("address"),dasm_memory_list[index].get("opcode"),dasm_file_list[index].get("opcode")))dbg.close()这里如果一致,说明没有hook。如果不一致,就会输出。这里的输出可能不准确。这只是抛砖引玉
