4.7 x64dbg 应用层的钩子扫描
所谓的应用层钩子(Application-level hooks)是一种编程技术,它允许应用程序通过在特定事件发生时执行特定代码来自定义或扩展其行为。这些事件可以是用户交互,系统事件,或者其他应用程序内部的事件。应用层钩子是在应用程序中添加自定义代码的一种灵活的方式。它们可以用于许多不同的用途,如安全审计、性能监视、访问控制和行为修改等。应用层钩子通常在应用程序的运行时被调用,可以执行一些预定义的操作或触发一些自定义代码。
通常情况下,第三方应用在需要扩展一个程序功能是都会采用挂钩子的方式实现,而由于内存数据被修改后磁盘数据依然是原始数据,这就给扫描这些钩子提供了便利,具体来说钩子扫描的原理是通过读取磁盘中的PE文件中的反汇编代码,并与内存中的代码作比较,当两者发生差异是则可以证明此处被挂了钩子。
本节内容中,笔者将通过一个案例并配合Capstone
引擎来实现这个功能,之所以选用该引擎是因为该引擎支持Python
包,可以非常容易的与LyScript
插件互动,此外Capstone
引擎在逆向工程、漏洞分析、恶意代码分析等领域有广泛的应用,著名反汇编调试器IDA
则是使用了该引擎工作的。
Capstone引擎的主要特点包括:
支持多种指令集:支持x86、ARM、MIPS、PowerPC等多种指令集,且能够在不同的平台上运行。
轻量级高效:采用C语言编写,代码简洁高效,反汇编速度快。
易于使用:提供了易于使用的API和文档,支持Python、Ruby、Java等多种编程语言。
可定制性:提供了多种可配置选项,能够满足不同用户的需求。
Capstone的安装非常容易,只需要执行pip install capstone
即可完成,使用Capstone反汇编时读者只需要传入一个PE文件路径,并通过md.disasm(HexCode, 0)
即可实现反汇编任务;
代码首先使用pefile
库读取PE文件,获取文件的ImageBase
,以及名为".text"
的节表的VirtualAddress、Misc_VirtualSize
和PointerToRawData
等信息。接下来,代码计算了".text"
节表的起始地址StartVA
和结束地址StopVA
,然后使用文件指针读取文件中".text"
节表的原始数据,并使用capstone
库进行反汇编。反汇编结果以字典形式存储,包括反汇编地址和反汇编指令。最后,函数返回了包含所有反汇编指令的opcode_list
列表。
from capstone import *
import pefiledef Disassembly(FilePath):opcode_list = []pe = pefile.PE(FilePath)ImageBase = pe.OPTIONAL_HEADER.ImageBasefor item in pe.sections:if str(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 open(FilePath,"rb") as fp:fp.seek(ActualOffset)HexCode = fp.read(VirtualSize)md = Cs(CS_ARCH_X86, CS_MODE_32)for item in md.disasm(HexCode, 0):addr = hex(int(StartVA) + item.address)dic = {"Addr": str(addr) , "OpCode": item.mnemonic + " " + item.op_str}print("[+] 反汇编地址: {} 参数: {}".format(addr,dic))opcode_list.append(dic)return opcode_listif __name__ == "__main__":Disassembly("d://lyshark.exe")
当读者运行上方代码片段时,则可输出lyshark.exe
程序内text
节所有反汇编代码片段,输出效果如下图所示;
接着我们需要读入内存中的PE文件机器码并通过Capstone
引擎反汇编为汇编指令集,如下get_memory_disassembly
函数则是实现内存反汇编的具体实现细节。
此案例中通过read_memory_byte
读入内存完整数据,并使用md.disasm
依次反汇编,并最终将结果存储到dasm_memory_dict
字典中保存。
import binascii,os,sys
import pefile
from capstone import *
from LyScript32 import MyDebug# 得到内存反汇编代码
def get_memory_disassembly(address,offset,len):# 反汇编列表dasm_memory_dict = []# 内存列表ref_memory_list = bytearray()# 读取数据for index in range(offset,len):char = dbg.read_memory_byte(address + index)ref_memory_list.append(char)# 执行反汇编md = Cs(CS_ARCH_X86,CS_MODE_32)for item in md.disasm(ref_memory_list,0x1):addr = int(pe_base) + item.addressdasm_memory_dict.append({"address": str(addr), "opcode": item.mnemonic + " " + item.op_str})return dasm_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()
执行如上所示代码,则可输出当前程序内存中的反汇编指令集,并以字典的方式输出,效果图如下所示;
这两项功能实现之后,那么实现内存与磁盘之间的比对工作将变得很容易实现,如下代码中首先通过get_memory_disassembly
获取到内存反汇编指令,然后通过get_file_disassembly
获取磁盘反汇编指令,并将两者dasm_memory_list[index] != dasm_file_list[index]
最比较,以此来判断特定内存是否被挂钩;
import binascii,os,sys
import pefile
from capstone import *
from LyScript32 import MyDebug# 得到内存反汇编代码
def get_memory_disassembly(address,offset,len):# 反汇编列表dasm_memory_dict = []# 内存列表ref_memory_list = bytearray()# 读取数据for index in range(offset,len):char = dbg.read_memory_byte(address + index)ref_memory_list.append(char)# 执行反汇编md = Cs(CS_ARCH_X86,CS_MODE_32)for item in md.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)return dasm_memory_dict# 反汇编文件中的机器码
def get_file_disassembly(path):opcode_list = []pe = pefile.PE(path)ImageBase = pe.OPTIONAL_HEADER.ImageBasefor item in pe.sections:if str(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 open(path,"rb") as fp:fp.seek(ActualOffset)HexCode = fp.read(VirtualSize)md = Cs(CS_ARCH_X86, CS_MODE_32)for item in 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)return opcode_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://lyshark.exe")# 循环对比内存与文件中的机器码for index in range(0,len(dasm_file_list)):if dasm_memory_list[index] != dasm_file_list[index]:print("地址: {:8} --> 内存反汇编: {:32} --> 磁盘反汇编: {:32}".format(dasm_memory_list[index].get("address"),dasm_memory_list[index].get("opcode"),dasm_file_list[index].get("opcode")))dbg.close()
运行上方代码片段,耐性等待一段时间,则可输出内存与磁盘反汇编指令集列表,输出效果图如下所示;
原文地址
https://www.lyshark.com/post/ccb35246.html
4.7 x64dbg 应用层的钩子扫描相关推荐
- 渗透测试和漏洞扫描的区别
因为最近在探究关于工控安全的研究课题,在渗透测试和漏洞扫描这两个概念上有点区分不太清楚,查了很多资料都觉得不够清楚,难以理解,于是在FreeBuf.COM上看到了一篇文章-<浅谈渗透测试与漏洞扫 ...
- 网络漏洞扫描的原理和相关程序
1 引言 网络扫描,是基于Internet的.探测远端网络或主机信息的一种技术,也是保证系统和网络安全必不可少的一种手段.主机扫描,是指对计算机主机或者其它网络设备进行安全性检测,以找出安全隐患和系统 ...
- 值得收藏!史上最全WINDOWS安全工具锦集
"工欲善其事,必先利其器." 近日,深信服安全团队整理了一些常见的PE工具.调试反汇编工具.应急工具.流量分析工具和WebShell查杀工具,希望可以帮助到一些安全行业的初学者. ...
- 史上最全Windows安全工具锦集
PE工具篇 PEiD 一款著名的PE侦壳工具,可以检测PE常见的一些壳,但是目前已经无法从官网获得: EXEInfoPE PE侦壳工具,PEiD的加强版,可以查看EXE/DLL文件编译器信息.是否加壳 ...
- 你可能不知道的——史上最全Windows安全工具锦集
史上最全Windows安全工具锦集 "工欲善其事,必先利其器." 近日,深信服安全团队整理了一些常见的PE工具.调试反汇编工具.应急工具.流量分析工具和WebShell查杀工具,希 ...
- 过 DNF TP 驱动保护(一)
文章目录: 01. 博文简介: 02. 环境及工具准备: 03. 分析 TP 所做的保护: 04. 干掉 NtOpenProcess 中的 Deep InLine Hook: 05. 干掉 NtOpe ...
- 知物由学 | 驱动反外挂另辟蹊径,让游戏避免看不见的漏洞攻击
工欲善其事,必先利其器.游戏攻防对抗亦是如此,外挂作者通过各种工具提升游戏破解效率,通常防御方会根据其工具特性针对性防御.此种场景下的防御似乎总是后人一步. 难道就没有好的办法了吗?为了解决这个痛点, ...
- 20+HW应急响应工具包合集(附下载地址)
之前分享过应急响应手工排查时的一些技术点,今天分享一批多平台可用的应急响应工具,能够在应急响应时快速发现问题以便于深入分析,同时有些工具也可用于个人电脑,让自己的电脑免受病毒及流氓软件的侵扰. 360 ...
- 20+应急响应工具包合集(附下载地址)
今天分享一批多平台可用的应急响应工具,能够在应急响应时快速发现问题以便于深入分析,同时有些工具也可用于个人电脑,让自己的电脑免受病毒及流氓软件的侵扰. 360星图 优点:一款非常好用的网站访问日志分析 ...
最新文章
- Microsoft Azure 云存储服务概念
- 关于document.referrer的使用需要注意
- 计蒜客 - Distance on the tree(LCA+主席树)
- 有向图生成树是如何画的_漫画:什么是最小生成树?
- 关于telnet: connect to address 190.168.6.6: No route to host 报错处理
- 软考信息安全工程师学习笔记汇总
- C# 中执行 msi 安装
- pivotx的entry和page内容里的日期格式修改
- Android设备间通信(wifi连接)
- python列表的应用与实例_python列表生成式应用案例
- opencv 模板匹配 掩膜 matchtemplate with mask
- python代码服务器上运行报错
- linux在命令行下打开pdf文件
- 从零开始写一个Jison解析器(7/10):解析器生成器 `parser generator` 的迭代式开发流程
- 手机桌面计算机显示,手机如何显示在桌面?敬业签电脑手机同步云便签怎么在桌面显示便签?...
- 操作系统笔记 清华大学陈渝
- 一个五层加密过的表白恢复密码解密的过程
- 170 FPS!YolactEdge:边缘设备上的实时实例分割,已开源!
- Docker Registry 私有镜像仓库批量清理镜像
- Java 适配器模式
热门文章
- puzzle(0413)PuzzleStoneBlocks、平铺楼梯区域
- 兰州理工大学计算机组成原理试题,2017年兰州理工大学计算机与通信学院895计算机组成原理考研仿真模拟题...
- Window远程桌面无法复制粘贴解决
- overleaf 公式_LaTex/Overleaf使用笔记
- trycatch后还会执行finally吗?
- stream流处理List
- csdn程序竞赛第六期-python题解
- .3dl.look.cube文件格式预设怎么使用?.3dl.look.cube文件怎么安装?
- el-cascader设置下拉框样式不生效的问题
- WEB>SSRF(URL Bypass,数字IP Bypass,302跳转Bypass,DNS重绑定Bypass)