在建立堆栈帧的位置设置一个代码断点,并在使用目标值的位置设置另一个断点(因此必须已经写入)。
在第一个断点的条件脚本中,您可以为目标位置添加硬件写入断点;它的绝对地址可以在那个时候计算出来,因为你有 ESP 和 EBP 的实际值。第二个断点用于删除该硬件断点。
在硬件断点的条件脚本中,您可以做任何您想做的事情:检查正在写入的特定值,检查周围的值等。
注意:CheatEngine是专门为此类任务编写的。如果您使用 CheatEngine 而不是试图理解 IDA 的贫乏记录 - 通常非常奇怪 - 接口,您可能会更快、更容易地获得结果。
这是一个基本脚本,您可以通过修改 中的测试target_check_()并调整 中的堆栈偏移量来进行调整set_target_breakpoint_()。那里的值来自我为确保代码工作而进行的快速测试。这适用于 IDA 6.7;它绝对不能与免费的 IDA (v5.0) 一起使用。
#include "idc.idc"
static main ()
{
set_helper_breakpoints_(LocByName("test_ufuncs_t"), 0);
}
static target_check_ (ea)
{
auto e;
try
{
Message("DbgDword(%x): %x @ EIP %x\n", ea, DbgDword(ea), EIP);
return DbgDword(ea) == 0x410A10;
}
catch (e) { Message("error: %s\n", e.description); }
return 0;
}
static set_target_breakpoint_ (term_bpt)
{
auto target_ea = ESP - 0x70;
Message("target_ea %a\n", target_ea);
SetBptCndEx(term_bpt, form("DelBpt(0x%x) & 0", target_ea), 0);
AddBptEx(target_ea, 4, BPT_WRITE);
SetBptCndEx(target_ea, form("target_check_(0x%x)", target_ea), 0);
return 0;
}
static set_helper_breakpoints_ (init_bpt, term_bpt)
{
if (term_bpt <= 0)
term_bpt = FindCode(GetFunctionAttr(init_bpt, FUNCATTR_END), SEARCH_UP);
Message("set_helper_breakpoints(): %s %s\n", GetFuncOffset(init_bpt), GetFuncOffset(term_bpt));
AddBptEx(init_bpt, 0, BPT_DEFAULT);
AddBptEx(term_bpt, 0, BPT_DEFAULT);
SetBptCndEx(init_bpt, form("set_target_breakpoint_(0x%x)", term_bpt), 0);
SetBptCndEx(term_bpt, "0", 0);
}