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 pefile
def Disassembly(FilePath):
opcode_list = []
pe = pefile.PE(FilePath)
ImageBase = pe.OPTIONAL_HEADER.ImageBase
for 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.VirtualAddress
VirtualSize = item.Misc_VirtualSize
ActualOffset = item.PointerToRawData
StartVA = ImageBase + VirtualAddress
StopVA = ImageBase + VirtualAddress + VirtualSize
with 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_list
if __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.address
dasm_memory_dict.append({"address": str(addr), "opcode": item.mnemonic + " " + item.op_str})
return dasm_memory_dict
if __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.address
dic = {"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.ImageBase
for 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.VirtualAddress
VirtualSize = item.Misc_VirtualSize
ActualOffset = item.PointerToRawData
StartVA = ImageBase + VirtualAddress
StopVA = ImageBase + VirtualAddress + VirtualSize
with 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_list
if __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 应用层的钩子扫描的更多相关文章
- 过 DNF TP 驱动保护(一)
过 DNF TP 驱动保护(一) 文章目录: 01. 博文简介: 02. 环境及工具准备: 03. 分析 TP 所做的保护: 04. 干掉 NtOpenProc ...
- TIMAC 学习笔记(二)
昨天大体上熟悉了TIMAC自带的CC2530的示范例程,今天先从演示抓包入手,分析四种不同的配置工程在空中传输的差异.随后,会按照扫描.组网.入网等MAC层接口函数入手,结合IEEE 802.15.4 ...
- BT渗透工具使用学习笔记
BT51.信息收集2.扫描工具3.漏洞发现4.社会工程学工具5.运用层攻击MSF6.局域网攻击7.密码破解8.维持访问一.DNS信息收集1.Dnsenum/pentest/enumeration/dn ...
- 【Hook技术】实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展
[Hook技术]实现从"任务管理器"中保护进程不被关闭 + 附带源码 + 进程保护知识扩展 公司有个监控程序涉及到进程的保护问题,需要避免用户通过任务管理器结束掉监控进程,这里使用 ...
- [源码解析] PyTorch 分布式(8) -------- DistributedDataParallel之论文篇
[源码解析] PyTorch 分布式(8) -------- DistributedDataParallel之论文篇 目录 [源码解析] PyTorch 分布式(8) -------- Distrib ...
- 3000本IT书籍下载地址
http://www.shouce.ren/post/d/id/112300 黑客攻防实战入门与提高.pdfhttp://www.shouce.ren/post/d/id/112299 黑 ...
- CE+X64dbg外挂制作教程 [提高篇]
人造指针&基址 实验目标:通过向游戏注入一段特殊汇编代码,实现自动获取动态地址.省略找基址的麻烦 为什么会出现人造指针 ? 1.基址偏移层数太多,很难找 2.有些游戏根本找不到基址 人造指针有 ...
- 关于Win7 x64下过TP保护(应用层)(转)
非常感谢大家那么支持我上一篇教程.Win10 快出了,所以我打算尽快把应用层的部分说完. 调试对象:DXF调试工具:CE.OD.PCHunter.Windbg调试先言:TP的应用层保护做得比较多,包括 ...
- XSS 前端防火墙 —— 无懈可击的钩子
昨天尝试了一系列的可疑模块拦截试验,尽管最终的方案还存在着一些兼容性问题,但大体思路已经明确了: 静态模块:使用 MutationObserver 扫描. 动态模块:通过 API 钩子来拦截路径属性. ...
- C# Winform中无焦点状态下获取键盘输入或者USB扫描枪数据
类文件: C#类文件 using System; using System.Collections.Generic; using System.Text; using System.Runtime.I ...
随机推荐
- day29:计算机网络概念
目录 1.网络开发的两大架构 2.网络概念 3.OSI七层模型 4.ARP协议 5.TCP三次握手和四次挥手 1.网络开发的两大架构 1.没有网络的时候,文件是如何传输的? 早期没有网络 a.py - ...
- windows 添加应用的临时签名
我们需要给应用添加数字签名,比如沃通.DigiCert. 申请购买代码签名证书需要一段时间,或者个人开发的应用签名,所以我们需要临时证书. 打开VS-工具-命令行,下面是添加过程 1. 创建一个测试证 ...
- 深入理解 slab cache 内存分配全链路实现
本文源码部分基于内核 5.4 版本讨论 在经过上篇文章 <从内核源码看 slab 内存池的创建初始化流程> 的介绍之后,我们最终得到下面这幅 slab cache 的完整架构图: 本文笔者 ...
- #Python 利用pandas 合并csv/xlsx文件
上次我们分享了利用powerquery来合并文件进行数据分析,但是Pq有一部分局限性,在现实工作中,我们往往需要合并多个文件去处理数据, 如果面对20个甚至更多的文件,pq中的每一步的步骤都会去读取每 ...
- 2023-03-24:音视频mp3和h264混合(muxer)编码为mp4,用go语言编写。
2023-03-24:音视频mp3和h264混合(muxer)编码为mp4,用go语言编写. 答案2023-03-24: 这是一个使用FFmpeg库将MP3和H.264混合编码为MP4的Go语言程序. ...
- 2023-01-01:remix-ide是浏览器的ide,官方已经提供地址,但是需要连接外网。如果是内网,需要自己在服务器里搭建remix-ide;另一种方式是用remix-ide的桌面版。这里只讨论
2023-01-01:remix-ide是浏览器的ide,官方已经提供地址,但是需要连接外网.如果是内网,需要自己在服务器里搭建remix-ide:另一种方式是用remix-ide的桌面版.这里只讨论 ...
- 2020-10-06:java中垃圾回收器让工作线程停顿下来是怎么做的?
福大大答案2020-10-06: 简单回答:安全点,主动式中断. 中级回答:用户线程暂停,GC 线程要开始工作,但是要确保用户线程暂停的这行字节码指令是不会导致引用关系的变化.所以 JVM 会在字节码 ...
- 2021-04-07:给定一个非负数组arr,长度为N,那么有N-1种方案可以把arr切成左右两部分,每一种方案都有,min{左部分累加和,右部分累加和},求这么多方案中,min{左部分累加和,右部分累加和}的最大值是多少? 整个过程要求时间复杂度O(N)。
2021-04-07:给定一个非负数组arr,长度为N,那么有N-1种方案可以把arr切成左右两部分,每一种方案都有,min{左部分累加和,右部分累加和},求这么多方案中,min{左部分累加和,右部分 ...
- Django中多个app放置同一文件夹中
在pycharm中新建一个管理app的python package目录:apps 将存在的app用拖拽到apps目录下,此时会弹出对话框,取消勾选Search for references(搜索索引) ...
- Linux:论如何在虚拟机上挂载多个镜像?
欢迎来到千汐 博客名称:千秋云染博客网址:https://www.cnblogs.com/skyrainmom 寄语:在混乱不堪的世界里你只管前行,时间替会证明一切 world cookie 我可 ...