
x64dbg findall 命令详解单内存页模式搜索与引用视图自动化遍历【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbgfindall是 x64dbg 中用于在单个内存页范围内搜索字节模式并收集全部命中的核心命令。它不同于find只返回首个命中和findallmem遍历整个内存映射其搜索结果会填充到参考视图Reference View中配合脚本表达式函数ref.addr/ref.count可实现对全部命中的程序化遍历。读完本文你将掌握findall的完整参数语法、通配符模式写法、与find/findallmem的边界关系以及如何用脚本自动化处理搜索结果。命令概述与定位findall的官方描述是 Find all occurrences of a pattern in a memory page即在一个内存页内查找模式的所有出现位置。该命令在 命令注册处 以dbgcmdnew(findall, cbInstrFindAll, true)的形式注册其底层实现位于 cmd-searching.cpp 的cbInstrFindAll函数。理解findall的核心是先理解它的搜索边界搜索范围受限于起始地址所在的单个内存页。当扫描到该页末尾时搜索立即停止因此无法仅凭一次调用覆盖整个进程内存如需跨页全局搜索应使用 findallmem注册名为findallmem/findmemall实现于 cbInstrFindAllMem如果只关心首个命中可使用find命令它将$result设置为命中地址而非计数。从源码角度看cbInstrFindAll 通过MemFindBaseAddr(addr, size, true)查询起始地址所属内存区域的基址与大小然后一次性MemRead整页数据到缓冲区再在其上循环调用patternfind找出全部命中。这意味着搜索是先在起始地址所在页的快照上进行的该页在调用瞬间被读取。参数详解findall的完整语法为findall arg1, arg2 [, arg3]arg1起始搜索地址要开始搜索的地址可以是任意表达式如寄存器、mem.base(cip)等。注意搜索会在该地址所在内存页的末尾终止若地址无效命令会报错 Invalid memory address 并中止见 cbInstrFindAll若内存读取失败会报错 Failed to read memory!见 cbInstrFindAll。arg2字节模式要搜索的字节模式支持通配符?例如EB0?90??8D。?既可以匹配半个字节如0?也可以匹配整个字节??内部以数据 掩码PatternByte.data/PatternByte.mask的方式表示见 handlePatternArgument。此外arg2 支持两种扩展写法String Formatting 字符串格式化可以在模式中嵌入{...}表达式由格式化引擎先展开再作为模式使用。相关语法见 Formatting前缀构造器见 handlePatternArgument以byte:、word:、dword:、qword:仅 64 位或ptr:按架构取 4/8 字节为前缀后面跟一个数值表达式表示按指定宽度的小端序字节序列。例如dword:41414141等价于模式41 41 41 41#...#包裹ODBGScript 兼容模式首尾的#会被自动去除后解析。模式解析失败时会输出 Failed to transform pattern!。[arg3]搜索数据大小可选要搜索的数据字节数默认值为起始地址所在内存区域的剩余大小即区域大小 - (起始地址 - 区域基址)。从 cbInstrFindAll 可以看出其行为若未提供 arg3find_size size - start即从起始地址到页尾的全部数据若提供且能被解析为数值则以该值为搜索长度若提供的值超过页内剩余空间会被自动截断为size - start特殊值data当 arg3 为data时搜索全部剩余数据并切换参考视图第二列的内容——从默认的反汇编Disassembly改为显示匹配处原始字节的数据Data列见 cbInstrFindAll。结果与参考视图执行成功后$result变量被设置为命中的总数即参考视图中的行数见 cbInstrFindAll。同时搜索结果的参考视图被初始化第一列命中地址Address第二列默认显示该地址处的反汇编Disassembly除非使用data切换为原始字节Data视图标题为 Pattern: 模式简写模式简写最多显示 16 个字节超出部分以...结尾见 handlePatternArgument。搜索完成后日志会输出形如N occurrences found in Xms的耗时统计见 cbInstrFindAll可用于评估大范围搜索的性能。需要注意的是单次搜索的结果数量受上限约束默认最多收集maxFindResults 5000条见 maxFindResults 定义循环在refCount maxFindResults时终止见 cbInstrFindAll。若需调整上限可使用 setmaxfindresult即findsetmaxresult命令其实现 cbInstrSetMaxFindResult 会把上限设为num 0x7FFFFFFF。完整示例示例 1在 CIP 所在内存页内搜索调用模式在 CIP 所在页内查找所有0FA2 E8 ???????? C3CPUIDCALL rel32RET模式findall mem.base(cip), 0FA2 E8 ???????? C3mem.base(cip)返回 CIP 所在内存区域的基址确保从页首开始扫描整页E8 ????????中????????匹配 CALL 指令的 32 位相对偏移。示例 2在栈内存页内搜索 CAX 的数值字符串格式化 数据列在栈内存页中查找所有等于 CAX 当前值字节序反转后的出现位置findall mem.base(csp), {bswapcax}{bswapcax}通过字符串格式化把 CAX 的值按小端字节序展开为字节模式bswap对寄存器值做字节交换以匹配内存中的存储顺序适用于在栈上定位压入的某个具体值。示例 3限定搜索大小从地址401000开始只搜索 0x100 字节findall 401000, E8 ????????, 100arg3 会被解析为十六进制0x100搜索范围被限制在该长度内若超出页尾则自动截断。用脚本遍历参考视图findall的结果填充到参考视图后可在脚本中通过表达式函数迭代所有命中。参考视图相关的核心函数包括ref.addr(i)取第 i 条命中地址与ref.count()命中总数完整函数清单见 Expression-functions。官方文档给出的遍历脚本如下i 0 loop: addr ref.addr(i) log reference {d:i} {p:addr} i cmp i, ref.count() jne loop该脚本将参考视图中每条命中地址以十进制索引 十六进制地址的形式写入日志可用于进一步的条件分析或批量处理如逐个下断点、生成报告。注意脚本的终止条件依赖ref.count()其值即$result中保存的命中总数。与 findallmem 的对比与选型维度findallfindallmem/findmemall搜索范围起始地址所在单个内存页整个内存映射从 arg1 开始跨页能力无需自行枚举内存页自动遍历所有 MEM_COMMIT 页可选参数[arg3]搜索大小data切数据列[arg3]大小默认 -1[arg4]过滤user/system/module实现位置cbInstrFindAllcbInstrFindAllMem从 cbInstrFindAllMem 的源码可以看到findallmem会遍历内存映射中所有MEM_COMMIT状态的内存区域并根据 arg4 过滤用户模块、系统模块或全部模块再调用MemFindInMap批量查找因此适合全局模式扫描而findall语义上等价于对单个页做findallmem更适合精确、小范围的定向搜索。小结与注意事项findall的搜索范围是起始地址所在页跨页搜索请用 findallmem模式支持?通配符、字符串格式化{expr}、byte:/word:/dword:/qword:/ptr:前缀以及#...#包裹$result保存命中总数参考视图供人工检查ref.addr/ref.count供脚本遍历默认最多收集 5000 条命中可通过 setmaxfindresult 调整使用data作为 arg3 可让参考视图第二列从反汇编切换为原始字节便于核对匹配内容。以上语法与行为均以当前仓库源码为准命令注册见 x64dbg.cpp核心实现见 cmd-searching.cpp官方命令文档见 findall.md 与 findallmem.md。【免费下载链接】x64dbgAn open-source user mode debugger for Windows. Optimized for reverse engineering and malware analysis.项目地址: https://gitcode.com/gh_mirrors/x6/x64dbg创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考